Platform: Code4rena
Start Date: 09/12/2022
Pot Size: $36,500 USDC
Total HM: 9
Participants: 69
Period: 3 days
Judge: Picodes
Total Solo HM: 2
Id: 190
League: ETH
Rank: 28/69
Findings: 2
Award: $238.90
🌟 Selected for report: 0
🚀 Solo Findings: 0
210.7761 USDC - $210.78
Checks for Global and User Withdraw Limit Per Period are missing for the first withdrawal request right AFTER period length expires and a new period begins. First withdrawal request amount after period length expires can be way higher than globalAmountWithdrawnThisPeriod
.
Since timestamp when a next period begins is known well in advance, a large whale can time his withdrawal exactly when a period ends. By dumping a large size of $preCT tokens, a whale can create serious arbitrage opportunities viz-a-viz Uniswap V3 pool. Since this can have a significant short term disruption in supply, I've marked it as HIGH risk
In the WithdrawHook contract line 59, when block.timestamp > lastGlobalPeriodReset + globalPeriodLength
, two variables lastGlobalPeriodReset
and globalAmountWithdrawnThisPeriod
are being reset.
However, for the first withdrawal request when the two above variables are being reset, check if _amountBeforeFee
exceeds globalWithdrawLimitPerPeriod
is missing. This check is done for the next request in line 63 when lastGlobalPeriodReset
is set to previous block timestamp
Same problem also exists for lastUserPeriodReset
and userToAmountWithdrawnThisPeriod[_sender]
variables in
If a user makes a large withdrawal request right after a period expires, that request will be honored in existing codebase. This is in direct violation of the designed logic that puts restriction on global withdrawal and user specific withdrawal in each period
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
Suppose global withdrawal limit per period if 10m USDC and each period is for 100 seconds. Let's say current timestamp is 10000 -> Bob, a whale depositor times a withdrawal request at exactly 10100 sec for 50m USDC -> Bob sources this liquidity of preCT tokens by dumping Long/Short tokens and draining preCT from UniV3 pools. This can cause massive mispricing of these tokens in short term
Although it can create massive arbitrage opportunities-> in current bear markets with low liquidity, such arbitrage might not be quickly closed. This can result in user panic & loss of confidence in protocol.
Add the check when period gets reset. Added checks to following code block
//global limit check if (lastGlobalPeriodReset + globalPeriodLength < block.timestamp) { lastGlobalPeriodReset = block.timestamp; / require(_amountBeforeFee <= globalWithdrawLimitPerPeriod, "global withdraw limit exceeded"); globalAmountWithdrawnThisPeriod = _amountBeforeFee; / } else { require(globalAmountWithdrawnThisPeriod + _amountBeforeFee <= globalWithdrawLimitPerPeriod, "global withdraw limit exceeded"); globalAmountWithdrawnThisPeriod += _amountBeforeFee; } // user limit check if (lastUserPeriodReset + userPeriodLength < block.timestamp) { lastUserPeriodReset = block.timestamp; require(_amountBeforeFee <= userWithdrawLimitPerPeriod, "user withdraw limit exceeded"); userToAmountWithdrawnThisPeriod[_sender] = _amountBeforeFee; } else { require(userToAmountWithdrawnThisPeriod[_sender] + _amountBeforeFee <= userWithdrawLimitPerPeriod, "user withdraw limit exceeded"); userToAmountWithdrawnThisPeriod[_sender] += _amountBeforeFee; }
#0 - hansfriese
2022-12-13T14:54:39Z
duplicate of #310
#1 - c4-judge
2022-12-13T19:11:03Z
Picodes marked the issue as duplicate of #310
#2 - c4-judge
2023-01-01T17:19:13Z
Picodes marked the issue as satisfactory
🌟 Selected for report: 0xSmartContract
Also found by: 0Kage, 0x52, 0xAgro, 0xNazgul, 0xTraub, 0xhacksmithh, Awesome, Aymen0909, Bnke0x0, Englave, Janio, Mukund, Parth, RaymondFam, Rolezn, SmartSek, Tointer, UdarTeam, Udsen, Zarf, caventa, chaduke, csanuragjain, deliriusz, gz627, idkwhatimdoing, izhelyazkov, joestakey, neumo, obront, oyc_109, rvierdiiev, shark, trustindistrust, wait, yongskiws
28.124 USDC - $28.12
Code Documentation errors
Inline documentation of code has following minor errors that can be corrected
Natspec for IPrePOMarket
event has duplicate entries
Parameter definition for amountAfterFee
in Redemption
event is incorrect
Comments in IMarketHook
incorrectly label parameters
Recommendations
* @param shortToken Market Short token address
in line 20 of IPrePOMarket
* @param amountAfterFee The amount of Long/Short tokens minted
with * @param amountAfterFee The amount of Long/Short tokens redeemed
in line 39 of IPrePOMarket
amountBeforeFee
with amountAfterFee
in line 16 of IMarketHook
#0 - c4-judge
2022-12-19T13:46:48Z
Picodes marked the issue as grade-b