title | description |
---|---|
Euler Earn known limitations and security considerations |
Known limitations and security considerations when interacting or integrating with Euler Earn protocol |
- Earn vault shares should not be used as collateral & the share price should not be used as an oracle
- Frontrunning loss socialization
- Interest smearing mechanism create MEV-opportunity
- maxWithdraw()/maxRedeem() does not always return optimal maximum amount
- Strategy's previewRedeem() might be manipulable
- Strategies with fees not properly supported
- Performance fee is instantly given to fee recipient
- Rebalance mechanism is impacted by the order of the giving strategies array
Earn vault shares should not be used as collateral & the share price should not be used as an oracle
During the call to harvest()
or to toggleStrategyEmergencyStatus()
, the realized net negative yield amount or the loss suffered by that specific strategy is socialized across all the depositors after the interest removal.
If the vault's shares are deposited on another protocol, the sudden price drops could cause liquidations.
Users can monitor the net yield amount that will be harvested prior to the execution of the harvest()
function, and in the case of that net amount being negative, they can frontrun the harvest transaction to withdraw from Earn vault, as long as their withdrawal amount does not trigger an automatic harvest.
The same apply for toggling a faulty strategy to Emergency
status.
The harvested positive yield is smeared as interest over a certain smearing period, minimum 1 day.
Large interest events like turning switching a strategy back from the Emergency
status to Active
will spike the APR for this period and new depositors can come in to earn a share of the large interest, bringing down the APR as the fixed smeared interest is distributed over a larger set of depositors. This might feel unfair for depositors who suffered the loss when the strategy was emergency-removed.
The same apply after harvesting a big amount of positive yield.
When performing a withdrawal, a harvest is skipped if withdrawn only from the cash reserve. Otherwise, a harvest could be performed (depending on the harvest cooldown) which can result in a loss.
The current algorithm starts by estimating the max amount to withdraw as the user's entire amount (share balance * share price)
and simulates the harvest conditions based on that.
However, it could happen that the user's entire amount results in withdrawing more than the cash reserve which results in a harvest ending up with a loss, reducing the share price and the amount the user receives. Whereas if the user only withdrew the cash reserve, they would have skipped the loss and withdrawn more.
Euler Earn uses the current implementation to not incentivize users to frontrun harvesting a negative yield and the execution of loss deduction.
The EulerEarn vault uses .previewRedeem()
to measure the value allocated to a certain strategy. EIP-4626 warns that this value might be manipulable and is not always safe to be used as an oracle:
The preview methods return values that are as close as possible to exact as possible. For that reason, they are manipulable by altering the on-chain conditions and are not always safe to be used as price oracles. This specification includes convert methods that are allowed to be inexact and therefore can be implemented as robust price oracles.
Before enabling a strategy, make sure to check that the previewRedeem()
function cannot be manipulated, for example, through "read-only reentrancy". Otherwise, the value might be over-/underestimated which can be exploited to book a profit or loss.
When allocating to a strategy via rebalance(), the strategy's allocated amount is set to the deposited amount, instead of what the received shares are worth, through a IERC4626(_strategy).previewRedeem()
call:
IERC4626(_strategy).deposit(amountToRebalance, address(this));
$.strategies[_strategy].allocated = (strategyData.allocated + amountToRebalance).toUint120();
There might be a discrepancy between these two values if the strategy takes fees. This loss is only booked once harvest()
is called and the previewRedeem()
value is fetched and compared to the allocated amount.
The loss will be socialized among all depositors. Even users that join after a large depositor will take that depositor's deposit/withdrawal fee loss once harvest is called which might be considered unfair.
As strategies with fees on the principal (management fees) will incur a loss on every rebalance, they shouldn't be supported. Ensure that the following invariant holds for every enabled strategy:
depositing/withdrawing assets should increase/decrease previewRedeem(strategy.balanceOf(this)) by assets
.(in practice, most vaults will incur a tiny rounding loss as deposit mints fewer shares to the depositor and previewRedeem further underestimates the assets the depositor receivers for the shares).
When performance fee is activated, and in the case of a harvested positive yield, this yield is smeared and earned by the depositors over the smearing period. However, the performance fee taken on the yield and minted instantly to the fee recipient in the form of EarnVault shares. Therefore, fee recipient will also be earning future smeared interest on positive yield, as well as impacted by any future loss socialization.
The rebalance()
function depends on the order of strategies. It should be called such that all the withdrawals happen first, and all the deposits afterwards. Otherwise, one could end up skipping a deposit when being temporarily short on cash, but it would become available after a withdraw from another strategy that had surplus in funds based on it's amount of allocation points.