Open code423n4 opened 1 year ago
Best POC overall
GalloDaSballo marked the issue as primary issue
emersoncloud marked the issue as sponsor confirmed
The Warden has shown how, by performing a small deposit, followed by a transfer, shares can be rebased, causing a grief in the best case, and complete fund loss in the worst case for every subsequent depositor.
While the finding is fairly known, it's impact should not be understated, and because of this I agree with High Severity.
I recommend watching this presentation by Riley Holterhus which shows possible mitigations for the attack: https://youtu.be/_pO2jDgL0XE?t=601
GalloDaSballo marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/upgradeable/ERC4626Upgradeable.sol#L123
Vulnerability details
Impact
Inflation of
ggAVAX
share price can be done by depositing as soon as the vault is created.Impact:
Proof of Concept
If
ggAVAX
is not seeded as soon as it is created, a malicious depositor can deposit 1 WEI of AVAX to receive 1 share. The depositor can donate WAVAX to the vault and callsyncRewards
. This will start inflating the price.When the attacker front-runs the creation of the vault, the attacker:
depositAVAX
to receive 1 shareWAVAX
toggAVAX
syncRewards
to inflate exchange rateThe issue exists because the exchange rate is calculated as the ratio between the
totalSupply
of shares and thetotalAssets()
. When the attacker transfersWAVAX
and callssyncRewards()
, thetotalAssets()
increases gradually and therefore the exchange rate also increases.convertToShares
: https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/upgradeable/ERC4626Upgradeable.sol#L123Its important to note that while it is true that cycle length is 14 days, in practice time between cycles can very between 0-14 days. This is because syncRewards validates that the next reward cycle is evenly divided by the length (14 days).
syncRewards
: https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/TokenggAVAX.sol#L102Therefore:
syncRewards
is to the next evenly divisible value ofrewardsCycleLength
, the closer the nextrewardsCycleEnd
will be.syncRewards
calls is, the higher revenue the attacker will get.Edge case example:
syncRewards
is called with the timestamp 1672876799,syncRewards
will be able to be called again 1 second later.(1672876799 + 14 days) / 14 days) * 14 days) = 1672876800
Additionally, the price inflation causes a revert for users who want to deposit less then the donation (WAVAX transfer) amount, due to precision rounding when depositing.
depositAVAX
: https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/TokenggAVAX.sol#L166previewDeposit
andconvertToShares
: https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/upgradeable/ERC4626Upgradeable.sol#L133 https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/upgradeable/ERC4626Upgradeable.sol#L123Foundry POC
The POC will demonstrate the below scenario:
syncRewards
when block.timestamp =1672876799
.syncRewards
again. Share price fully inflated.Additionally, the POC will show that depositors trying to deposit less then the donation amount will revert.
Add the following test to
TokenggAVAX.t.sol
: https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/test/unit/TokenggAVAX.t.sol#L108To run the POC, execute:
Expected output:
Tools Used
VS Code, Foundry
Recommended Mitigation Steps
When creating the vault add initial funds in order to make it harder to inflate the price. Best practice would add initial funds as part of the initialization of the contract (to prevent front-running).