Earn Tokens (eTokens)
Overview
Earn Tokens (eTokens) are Curvance's lending market tokens that enable users to earn interest on deposited assets. eTokens function similarly to interest-bearing tokens in other lending protocols but with a focus on enhanced security and flexibility. Users who deposit underlying assets receive eTokens representing their share of the lending pool, which increase in value as borrowers pay interest.
Core Architecture
eTokens operate within a network of contracts:
EToken: The core implementation of the Earn Token functionality.
ETokenWithGauge: Extension that integrates with Curvance's Gauge system for additional rewards.
MarketManager: Manages risk parameters, collateral requirements, and market health.
CentralRegistry: Provides protocol-wide configuration and permissions.
InterestRateModel: Determines interest rates based on market utilization.
State and Data Model
eTokens maintain several key state variables:
The exchangeRate
is a critical parameter that determines the conversion between eTokens (shares) and underlying assets. It increases over time as interest accrues, allowing eToken holders to claim more underlying assets for the same number of tokens.
Data Flow
Deposit Flow
User calls
mint()
with underlying assets.Contract accrues any pending interest.
Contract calculates shares based on current exchange rate.
Underlying tokens are transferred from the user to the contract.
eTokens are minted to the user.
MarketManager is notified of the deposit (if needed).
Withdrawal Flow
User calls
redeem()
with eTokens.Contract accrues any pending interest.
Contract calculates assets based on current exchange rate.
Underlying tokens are transferred from the contract to the user.
eTokens are burned.
MarketManager is notified of the withdrawal.
Borrowing Flow
User must first deposit collateral into a pToken.
User calls
borrow()
on an eToken.Contract accrues any pending interest.
MarketManager checks if user has sufficient collateral.
Debt is recorded for the user.
Underlying tokens are transferred to the user.
Repayment Flow
User calls
repay()
orrepayFor()
.Contract accrues any pending interest.
Current debt is calculated.
Underlying tokens are transferred from the user to the contract.
User's debt is reduced or eliminated.
MarketManager is updated regarding the user's position.
Interest Accrual Mechanism
Interest accrual is a key feature of eTokens, handled through the accrueInterest()
function:
Time elapsed since last update is calculated.
InterestRateModel determines appropriate interest rate based on market utilization.
Interest is applied to total borrows.
A portion of interest (determined by
interestFactor
) is allocated to protocol reserves.Exchange rate is updated, increasing the value of all eTokens.
This process occurs automatically when users interact with any of the main functions, ensuring up-to-date state before transactions execute.
Exchange Rate Calculation
The exchange rate is calculated by:
exchangeRate = (marketUnderlyingHeld + totalBorrows) * WAD / (totalSupply + totalReserves)
This rate determines how many underlying tokens each eToken is worth and increases over time as interest accrues.
Integration with Market Manager
eTokens work closely with the MarketManager, which:
Defines which assets can be used as collateral (pTokens).
Sets borrowing parameters like collateral factor and liquidation threshold.
Authorizes borrowing based on user's collateral.
Manages the liquidation process for underwater positions.
Enforces market-wide caps and security measures.
Safety Features
eTokens incorporate multiple security features:
Reentrancy protection on all critical functions.
Safe variants of functions for external protocol integration.
Accrual of interest before any state-changing operations.
Minimum hold periods to prevent flash loan attacks.
Multiple layer validation for borrowing and collateralization.
Protocol Revenue
The eToken contracts generate protocol revenue through:
Interest Factor: A portion of all interest paid by borrowers goes to protocol reserves.
These reserves can be withdrawn by the DAO using
processWithdrawReserves()
.For eTokens with gauges, additional rewards may be distributed to depositors based on their contribution.
User Interaction Functions
Share/Assets
convertToShares()
Contract: eToken
Description: Converts an amount of underlying assets to equivalent eToken shares using the current exchange rate.
Function signature:
uint256
amount
The number of underlying tokens to theoretically convert to eTokens
Return data:
uint256
The number of eTokens a user would receive for the given amount of underlying
Mint Functions (Depositing Assets)
mint()
Contract: eToken
Description: Users deposit underlying assets into the market and receive eTokens in return.
Function signature:
uint256
amount
The amount of the underlying asset to deposit
Return Data:
uint256
The amount of eTokens minted
mintfor()
Contract: eToken
Description: Deposits underlying assets into the market, and recipient receives eTokens.
Function signature:
uint256
amount
The amount of the underlying asset to deposit
address
recipient
The account that should receive the eTokens
Return data:
uint256
The amount of eTokens minted
Redeem Functions (Withdrawing Assets)
redeem()
Contract: eToken
Description: Redeems eTokens in exchange for the underlying asset
Function signature:
uint256
tokens
The number of eTokens to redeem for underlying tokens
address
recipient
The account who will receive the underlying assets
Return data:
uint256
The amount of underlying asset redeemed
redeemFor()
Contract: eToken
Description: Used by a delegated user to redeem eTokens in exchange for the underlying asset, on behalf of account.
Function signature:
Return data:
uint256
The amount of underlying asset redeemed
Borrow Functions
borrow()
Contract: eToken
Description: Borrows underlying tokens from lenders, based on collateral posted inside this market.
Function signature:
uint256
amount
The amount of the underlying asset to borrow
borrowFor()
Contract: eToken
Description: Used by a delegated user to borrow underlying tokens from lenders, based on collateral posted inside this market by account
Function signature:
address
account
The account who will have their assets borrowed against
address
recipient
The account who will receive the borrowed assets
uint256
amount
The amount of the underlying asset to borrow
Repay Functions
repay()
Contract: eToken
Description: Repays underlying tokens to lenders, freeing up their collateral posted inside this market and updates interest before executing the repayment.
Function signature:
uint256
amount
The amount of the underlying asset to repay, or 0 for the full outstanding amount
repayFor()
Contract: eToken
Description: Repays underlying tokens to lenders, on behalf of account
, freeing up their collateral posted inside this market.
Function signature:
address
account
The account address to repay on behalf of.
uint256
amount
The amount to repay, or 0 for the full outstanding amount.
Interest Accrual Mechanism
Interest is accrued on borrowed assets and distributed to eToken holders through the increasing exchange rate. The accrual process is managed by the accrueInterest
function.
accrueInterest()
Contract: eToken
Function signature:
This function:
Calculates time elapsed since the last interest accrual.
Fetches the current interest rate from the interest rate model.
Computes the interest amount based on current total borrows.
Updates total borrows with the new interest.
Allocates a portion of interest to protocol reserves based on the interestFactor.
Updates the exchange rate to reflect the new value of each eToken.
Interest accrues automaically when users interact with the protocol (mint, redeem, borrow, repay) as these functions call accrueInterest
internally.
Exchange Rate Calculation
exchangeRateWithUpdate()
Contract: eToken
Description: Returns the current exchange rate after updating interest, used to determine how many underlying tokens each eToken is worth:
Function signature:
Return data:
uint256
Calculated exchange rate, in WAD
.
Safe Functions for External Integration
Curvance provides safe versions of key functions with additional reentrancy protection. These should be used when integrating with external protocols to minimize security risks.
exchangeRateWithUpdateSafe()
Contract: eToken
Description: Updates pending interest and returns the up-to-date exchange rate from the underlying to the eToken, with inherent reentrancy protection.
Function signature:
Return data:
uint256
Calculated exchange rate, in WAD
.
balanceOfUnderlyingSafe()
Contract: eToken
Description: Updates pending interest and returns the up-to-date balance of account
, in underlying assets, with inherent reentrancy protection.
Function signature:
Return data:
uint256
The amount of underlying owned by account
.
debtBalanceWithUpdateSafe()
Contract: eToken
Description: Updates pending interest and returns the current debt balance for account
with inherent reentrancy protection.
Function signature:
Return data:
uint256
The current balance index of account
, with pending interest applied.
Debt Tracking
debtBalanceCached()
Contract: eToken
Description: Returns the current debt balance for a given account without accruing interest. This is a gas-efficient view function that uses the cached exchange rate.
Function signature:
address
account
The address whose debt balance should be calculated
Return data:
uint256
The current balance of debt for the account
debtBalanceAtTimestamp()
Contract: eToken
Description: Returns the estimated future debt balance for an account at a specific timestamp, assuming interest rates remain constant.
Function signature:
address
account
The address whose debt balance should be calculated
uint256
timestamp
The unix timestamp to calculate the account's debt balance with
Return data:
uint256
The estimated debt balance at the specified timestamp
Market Utilization and Rates
getBorrowRatePerYear()
Contract: eToken
Description: Returns the current yearly borrow interest rate for the market, calculated from the interest rate model.
Function signature:
Return data:
uint256
The borrow interest rate per year, in WAD format (1e18)
getSupplyRatePerYear()
Contract: eToken
Description: Returns the current yearly supply interest rate for lenders, derived from the borrow rate and adjusted by the interest factor.
Function signature:
Return data:
uint256
The supply interest rate per year, in WAD format (1e18)
Last updated