Closed c4-bot-9 closed 8 months ago
The issue is well demonstrated, properly formatted, contains a coded POC. Marking as HQ.
0xSorryNotSorry marked the issue as high quality report
0xSorryNotSorry marked the issue as primary issue
0xSorryNotSorry marked the issue as duplicate of #1164
Trumpero marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/main/src/loan/SurplusGuildMinter.sol#L229
Vulnerability details
Impact
SurplusGuildMinter
enables users to stake their CREDIT tokens in order to support gauges, obtaining rewards in the form of GUILD and CREDIT tokens in exchange. This is thought as a safety mechanism: users who stake in favor of a properly-behaved lending term will get rewarded, while users who stake for a gauge that causes losses to the protocol will get their staked balance slashed.In order to apply slashing in the staking mechanism, the
getRewards()
function is used, which willlastGaugeLoss()
of the term being staked for. The last gauge loss is the timestamp of the last loss that impacted the gauge.lastGaugeLoss()
, it will mean that the user is slashable (user’s lastGaugeLoss is set to the staking timestamp, meaning that if a loss occurs AFTER the user has staked, the user will be slashable)The problem with the
getRewards()
is that the user staked status stored in the contract’s storage is actually fetched AFTER performing the slashing check. The previous code snippet shows how_stakes[user][term]
is loaded into the memory variableuserStake
after checking the slashing status.userStake.lastGaugeLoss
is used in order to verify if the user is slashable (if (lastGaugeLoss > uint256(userStake.lastGaugeLoss))
), but its value will always be zero because its actual data stored in storage will be obtained later anduserStake
is never initialized (it is a named return parameter).Users staking after a gauge loss should not be slashable (only users that were staking prior or during a loss should be elegible of being slashed). However, the previously described issue makes ALL stakers that stake after any loss incurred by the gauge be automatically slashable, effectively losing their all of their staked CREDIT tokens.
Proof of Concept
The following proof of concept shows how user2 will lose all of their staked balance due to the previous issue. In order to reproduce the PoC, just copy the function into
./test/unit/loan/SurplusGuildMinter.sol
and execute it.Tools Used
Manual review, foundry
Recommended Mitigation Steps
The mitigation is fairly easy. The user stake stored in storage needs to be loaded to
userStake
prior to executing the slashing check, likeso:Assessed type
Other