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 assetsContract 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 eTokensContract 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 eTokenContract 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 reservesExchange 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