IPOR stETH Index
Lido conducts a rebase approximately once a day, generally at a fixed time. After the rebase, it becomes possible to determine the Annual Percentage Rate (APR) given that we understand how Lido's account balance is computed.
The LIDO documentation provides insights into calculating the staked Ethereum (StETH) account balance as:
Where:
shares - A map representing the share amount of individual users. Upon depositing ether, this ether gets converted into shares and is added to the user's existing share count.
totalShares- The collective sum of shares across all user accounts listed in the shares map.
totalPooledEther Represents the aggregate of three distinct types of ether held by the protocol:
buffered balance: Ether retained on the contract, neither deposited nor designated for withdrawals.
transient balance: Ether sent to the official Deposit contract but not yet acknowledged in the beacon state.
beacon balance: The accumulated amount of ether in validator accounts. This quantity, relayed by oracles, is pivotal in determining the stETH total supply adjustments.
For APR calculation, if we know the balance before and after the rebase, the equation is:
However, if a user's shares remain unchanged between rebases, the formula can be simplified by calculating exchange rates before and after
For simplicity, we assume that the time between rebases was exactly 24 hours.
How to calculate the APR at any given moment between rebases?
To determine the APR at any specific time between rebases, we must ascertain the exchange rate at that particular moment. For this purpose, one can refer to the LIDO Oracle codebase and review the following method:
Upon examining this method, it becomes evident that the crux of this simulation is the handleOracleReport function within the Lido contract. This function requires several arguments to execute the transaction.
Upon examining the output of this method, we observe that it provides two values that are particularly interesting to us:
If we divide these values, then we have the exchange rate at any point in time:
Calculating the 24-hour Window APR
When trying to calculate the APR over 24 hours based on exchange rates:
Obtain Current Exchange Rate: Secure the exchange rate at the given time between rebases.
Secure Historical Data: Ensure we have data that dates back to at least more than 24 hours prior.
Determine the Exchange Rate from 24 hours ago: Retrieve the exchange rate from precisely 24 hours ago using the historical data.
Calculate Current APR: We can now determine the APR with the current and 24-hour-old exchange rates at our disposal. The formula is:
Gathering Arguments for the handleOracleReport method
reportTimestamp - This refers to the timestamp of the block for which we want to determine the exchange rate
timeElapsed - Represents the duration from the last report to the desired time point. It can be easily computed using the equation:
clValidators - Represents the total count of Lido validators currently on the Consensus Layer.
clBalance - Refers to the aggregate balance of all Lido validators on the Consensus Layer.
To retrieve these values:
Make a call to the Lido Keys API. Running a local instance of this API can be much faster than accessing the public one. The repository for the API can be found at Lido Keys API GitHub.
Additionally, initiate a call to the Beacon Chain to fetch the list of validators. By comparing this list with the one from the Lido Keys, we can determine which validators are associated with Lido for a specific block.
clValidators - Count the number of Lido-associated validators.
clBalance - Aggregate the balances of these Lido validators
withdrawalVaultBalance - This indicates the balance of the withdrawal vault on the Execution Layer at the given reportTimestamp
One must query the Ethereum balance of the WithdrawalVault contract on the Execution Layer.
elRewardsVaultBalance - vault balance on Execution Layer at reportTimestamp
One must query the Ethereum balance of the LidoExecutionLayerRewardsVault contract on the Execution Layer.
sharesRequestedToBurn - shares requested to burn through Burner at reportTimestamp.
A call should be made to the getSharesRequestedToBurn method of the Lido Burner contract. This method produces two output values: coverShares and nonCoverShares. The cumulative sum of these two outputs provides the sharesRequestedToBurn value."
withdrawalFinalizationBatches - This is an array of withdrawal request IDs organized in ascending order.
It is derived by calling the calculateFinalizationBatches method of the WithdrawalQueue contract.
Within a simulation context, an empty array indicates no withdrawal requests pending finalization.
simulatedShareRate - This refers to the share rate that Oracle projected when the report data was established. When conducting a simulation, the oracle assigns this parameter a value of 0.
Last updated