Underflow causes users funds to be temporarily frozen until next rewards cycle #210
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-317
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/TokenggAVAX.sol#L241
Vulnerability details
Impact
Users depositing into
ggAVAX
are not able to withdraw all their funds and rewards until rewards are synced and accounting is updated.The funds are frozen even if funds reside in the pool.
(Note: This behavior is dependent on the value of
totalReleasedAssets
to be less then the amount returned intotalAssets
)Proof of Concept
When a user wants to withdraw his funds and rewards,
beforeWithdraw
function is called.https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/TokenggAVAX.sol#L241
As can be seen above
amount
is reduced fromtotalReleasedAssets
.If
amount
is larger thantotalReleasedAssets
the transaction will revert and the user will not be able to withdraw.The
amount
can be larger thantotalReleasedAssets
.Here is an example:
maxWithdraw
is called to calculate theamount
of withdrawable assets.maxWithdraw
usesconvertToAssets
to convert shares to assets. The conversion is done by usingtotalAssets()
.totalAssets()
returns the currenttotalReleasedAssets
plus rewards earned from previous rewards cycle.amount
will be larger thantotalReleasedAssets
.totalAssets()
:https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/TokenggAVAX.sol#L113
The user has to wait until
totalReleasedAssets
is updated to include the rewards in the nextsyncRewards
(14 days).syncRewards
:https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/contracts/contract/tokens/TokenggAVAX.sol#L107
Consider the following scenario:
ggAVAX
.ggAVAX
.syncRewards
is called to distribute the rewards.5.1.
totalReleasedAssets
is not updated with rewards because current cycle did not end.5.2. Bobs withdraw is reverted due to underflow in
beforeWithdraw
.totalReleasedAssets
with rewards contract.Consider the following scenario:
ggAVAX
.ggAVAX
.syncRewards
is called to distribute the rewards (100 AVAX)5.1. Chuck deposits 100 AVAX to
ggAVAX
.5.2. Bob withdraws 2100 AVAX.
syncRewards
function is called again.Foundry POC
The POC will demonstrate the first scenario mentioned above
Add the following to
TokenggAVAX.t.sol
:https://github.com/code-423n4/2022-12-gogopool/blob/aec9928d8bdce8a5a4efe45f54c39d4fc7313731/test/unit/TokenggAVAX.t.sol#L108
To run the POC execute:
Expected output:
Tools Used
VS Code, Foundry
Recommended Mitigation Steps
In
beforeWithdraw
check if the amount to withdraw is larger thantotalReleasedAssets
. If so, updatetotalReleasedAssets
to include the last rewards.Additionally, it is possible to cap the amount returned in
maxWithdraw
tototalReleasedAssets
iftotalReleasedAssets
is smaller then the assets of the user.The text was updated successfully, but these errors were encountered: