user's funds lock and incorrect code behavior because users withdrawal amount won't get reset for all users in each userPeriodLength in WithdrawHook contract #325
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-116
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")
Lines of code
https://github.com/prepo-io/prepo-monorepo/blob/3541bc704ab185a969f300e96e2f744a572a3640/apps/smart-contracts/core/contracts/WithdrawHook.sol#L53-L79
Vulnerability details
Impact
according to the comments in code: "Every time
userPeriodLength
seconds passes, the amount withdrawn for all users will be reset to 0" (https://github.com/prepo-io/prepo-monorepo/blob/3541bc704ab185a969f300e96e2f744a572a3640/apps/smart-contracts/core/contracts/interfaces/IWithdrawHook.sol#L64-L76). but in current implementation only one of the usersuserToAmountWithdrawnThisPeriod[]
value gets reset and this will cause users to not be able to withdraw their tokens even if they follow the limitation. users which has high withdrawal amount only can withdraw when they reset the value ofuserPeriodLength
and in each period only one user can do that because in eachuserPeriodLength
only one user withdraw amounts gets reset. so over time in each period only one user could withdraw. for example ifuserPeriodLength
was 1 day, in each day 1 user can withdraw and if protocol had 100K user some users would never withdraw in their life time.Proof of Concept
This is
hook()
code inWithdrawHook
:As you can see when the
lastUserPeriodReset + userPeriodLength < block.timestamp
happens(which means last period finished) only the callersuserToAmountWithdrawnThisPeriod[]
value changes and other don't get changed. and in the else case (when period is not finished) if user'suserToAmountWithdrawnThisPeriod[user] + amount
succeeduserWithdrawLimitPerPeriod
code would revert. so during periods users with high withdraw amount can't withdraw and in each period only one user withdraw amount gets new value so overtime all users get high withdraw amounts and in each period 1 user cant get his withdraws and users tokens would stuck in the contract literally forever. POC:userToAmountWithdrawnThisPeriod[user1]
would be 90. max allowed withdraw in each period for users is 100 token.userToAmountWithdrawnThisPeriod[user1]
is still 90 and 90+20 is bigger than 100 and user1 can't be able to withdraw.Tools Used
VIM
Recommended Mitigation Steps
reset all users withdrawal amounts in each period start time.
The text was updated successfully, but these errors were encountered: