First ERC4626 deposit can be exploited to break share calculation #672
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-243
satisfactory
satisfies C4 submission criteria; eligible for awards
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
upgraded by judge
Original issue severity upgraded from QA/Gas by judge
Lines of code
https://github.com/code-423n4/2023-01-popcorn//blob/main/src/vault/Vault.sol#L294-L301
Vulnerability details
Impact
This is a common attack vector involving shares based liquidity pool contracts. An early user can manipulate the price per share and profit from late users' deposits because of the precision loss caused by the rather large value of price per share.
Apparently, the first depositor of an ERC4626 vault can maliciously manipulate the share price by depositing the lowest possible amount with 1 wei of liquidity and then artificially inflating ERC4626.totalAssets.
This can inflate the base share price to as high as 1:1e18, forcing all subsequent deposits to be dictated by this share price as a base. Additionally, due to rounding down, if this malicious initial deposit were to front-run someone else depositing, this depositor would end up receiving 0 shares and losing his deposited assets.
ERC4626 vault share price can be maliciously inflated on the initial deposit, leading to the next depositor losing assets due to precision issues.
Proof of Concept
Here is a typical exploit scenario where:
A vault is using DAI as its underlying asset.
deposit()
.Note: As denoted in the code block below, shares are determined via its return statement, supply == 0 ? assets : assets.mulDiv(supply, totalAssets(), Math.Rounding.Down). In the event of a very high share price, due to
totalAssets()
very much larger thanassets * supply
, shares will be returned 0.File: Vault.sol#L294-L301
Tools Used
Manual inspection
Recommended Mitigation Steps
Consider sending the first 1000 shares to address 0, a mitigation approach adopted by the Uniswap V2 protocol when supply == 0.
Additionally, the protocol could look into implementing slippage protection to further mitigate the situations.
The text was updated successfully, but these errors were encountered: