Open code423n4 opened 2 years ago
We've been aware of this issue for some time.. ended up including the AaveYield file in the scope by mistake! We do not plan to include the Aave strategy in our launch (we maintain a strategy registry that allows us to add/drop yield strategies), and as noted in #128, we will be utilizing wrapper contracts that mimics behaviour of non-rebasing LP tokens
going to side with the warden since they believed the contract to be in scope and it's a valid concern.
Handle
cmichel
Vulnerability details
When depositing into Aave through the
AaveYield.lockTokens
contract strategy, one receives thesharesReceived
amount corresponding to the diff ofaToken
balance, which is just always the deposited amount as aave is a rebasing token and1.0 aToken = 1.0 underlying
at each deposit / withdrawal.Note that this
sharesReceived
(the underlying deposit amount) is cached in abalanceInShares
map inSavingsAccount.deposit
which makes this share static and not dynamically rebasing anymore:However, the
getTokensForShares
function uses a rebasing total share supply ofIERC20(aToken).balanceOf(this)
.POC
balanceInShares[user][dai][aave]
.withdraw
s 1000 aDAI shares for user which callsAaveYield.unlockTokens
. The user receives only 1000 DAI. The interest owed to the user is not paid out.getTokensForShares
also returns the wrong amount as1200 * 1000 / 1200 = 1000
Impact
Interest is not paid out to users. Pool collateral is measured without the interest accrued as it uses
getTokensForShares
which will lead to early liquidations and further loss.Recommended Mitigation Steps
If the user shares are not rebasing, you cannot have the "total shares supply" (the shares in the contract) be rebasing as in
getTokensForShares
. Also withdrawing the share amount directly from Aave as in_withdrawERC
does not withdraw the yield. A fix could be to create a non-rebasing wrapper LP token that is paid out to the user proportional to the current strategy TVL at time of user deposit.