A well known attack vector for almost all shares based liquidity pool contracts, where 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. This vulnerability is mentioned in a previous C4 contest here, and in this Trail of Bits audit (issue 003).
Vulnerability Detail:
The attack works in the following way:
A malicious early user can deposit() with 1 wei of asset token as the first depositor of the LToken, and get 1 wei of shares.
Then the attacker can send 10000e18 - 1 of asset tokens and inflate the price per share from 1.0000 to an extreme value of 1.0000e22 ( from (1 + 10000e18 - 1) / 1).
As a result, the future user who deposits 19999e18 will only receive 1 wei (from 19999e18 * 1 / 10000e18) of shares token.
They will immediately lose 9999e18 or half of their deposits if they redeem() right after the deposit().
For a more detailed description, refer to this one from OpenZeppelin.
Consider requiring a minimal amount of share tokens to be minted for the first minter, and send a portion of the initial mints as a reserve to the DAO/ burn so that the price per share can be more resistant to manipulation. Refer to OpenZeppelin's ERC4626 implementation for more details on the vulnerability and a coded example of a workaround.
Lines of code
https://github.com/code-423n4/2023-08-goodentry/blob/main/contracts/GeVault.sol#L247-L284
Vulnerability details
Impact
A well known attack vector for almost all shares based liquidity pool contracts, where 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. This vulnerability is mentioned in a previous C4 contest here, and in this Trail of Bits audit (issue 003).
Vulnerability Detail:
The attack works in the following way:
deposit()
with1 wei
ofasset
token as the first depositor of the LToken, and get1 wei
of shares.10000e18 - 1
ofasset
tokens and inflate the price per share from 1.0000 to an extreme value of 1.0000e22 ( from(1 + 10000e18 - 1) / 1
).19999e18
will only receive1 wei
(from19999e18 * 1 / 10000e18
) of shares token.9999e18
or half of their deposits if theyredeem()
right after thedeposit()
.For a more detailed description, refer to this one from OpenZeppelin.
Proof of Concept
Tools Used
Manual review
Recommended Mitigation Steps
Consider requiring a minimal amount of share tokens to be minted for the first minter, and send a portion of the initial mints as a reserve to the DAO/ burn so that the price per share can be more resistant to manipulation. Refer to OpenZeppelin's ERC4626 implementation for more details on the vulnerability and a coded example of a workaround.
Assessed type
ERC4626