Open code423n4 opened 2 years ago
This is a plausible but unlikely scenario since it assumes that only Alice has deposited into the yield source and that the interest rate is so high that 1 more wBTC is now in the yield source.
Also, the calculation is wrong since 1 wBTC would represent 1 ether or 1000000000000000000
wei. So the actual calculation would return (1000000000000000000 * 1000000000000000000) / 2000000000000000000 = 500000000000000000
wei or 0.5 wBTC.
We also periodically capture the interest accumulated in the yield source by calling the PrizeFlush contract: https://github.com/pooltogether/v4-periphery/blob/8cc717af440aa23e41e0f24d699647320efd7b04/contracts/PrizeFlush.sol#L105 The capture of the interest happens here: https://github.com/pooltogether/v4-core/blob/e6f2d9ddb303cc4fb1a64582b12ba3e9df85e21c/contracts/prize-strategy/PrizeSplitStrategy.sol#L51
For these reasons, I've acknowledged the issue but we won't change how shares are calculated.
Downgraded severity as this is more of a value leakage situation, especially given the unlikely edge case of an ERC20 token that sets decimals to 0 and uses low base values.
Lines of code
https://github.com/pooltogether/aave-v3-yield-source/blob/e63d1b0e396a5bce89f093630c282ca1c6627e44/contracts/AaveV3YieldSource.sol#L352-L374
Vulnerability details
https://docs.aave.com/developers/tokens/atoken
Impact
Incorrect share conversions lead to incorrect pricig of assets and loss of principal. aTokens are rebasing tokens, which means that holders of the token have their
balanceof()
increase over time, but each token is still redeemable for exactly one underlying asset. Any formula that does not return one out for one in is incorrect.Proof of Concept
https://github.com/pooltogether/aave-v3-yield-source/blob/e63d1b0e396a5bce89f093630c282ca1c6627e44/contracts/AaveV3YieldSource.sol#L352-L374
The above code is used for both
supplyTokenTo()
andredeemToken()
and does not return one for one. Consider the following chain of events:balanceOf(this)
(tokens{1} * totalSupply(){1}) / aToken.balanceOf(this){2}
is zeroTools Used
Code inspection
Recommended Mitigation Steps
There does not need to be a conversion function - one share must always equal one token