Closed c4-bot-3 closed 9 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 duplicate of #877
0xSorryNotSorry marked the issue as not a duplicate
0xSorryNotSorry marked the issue as duplicate of #994
Trumpero changed the severity to 2 (Med Risk)
Trumpero marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L142 https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/governance/ProfitManager.sol#L396-L400 https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L247-L269
Vulnerability details
Impact
A malicious actor could steal some part of the interest with a
sandwich
attack when a borrowerrepays
a loan. The attacker carries no risk of slashing but enjoys free rewards. Using aflashbots
service to carry out the sandwich bundles he can guarantee profit with0 risk
. The more funds the attacker possesses the more the rewards can be stolen.Proof of Concept
There is no limitation for a user to not stake and unstake in the same block. Because it is possible to stake and unstake in the same block the malicious actor could
sandwich
therepay
call from anyone as follows.stake => repay => unstake
When a user stakes the
getRewards
for that user is called and theProfitManager(profitManager).claimRewards(address(this))
is invoked for theSGM
.This will update the
userStake.profitIndex
to the latestprofitIndex
After the user stakes the repay call is executed. The repay call invokes
notifyPnL(gauge, amount)
with interest that is repaid as the amount variable. This updates thegaugeProfitIndex
to a greaterprofitIndex
.Now as a third call the unstake is executed
Here the rewards are calculated for the user unstaking and minted out. Calculations are made based on the
profitIndexes
. Since the global index was increased after the user staked it is now greater than theuserProfitIndex
which results in thedeltaIndex > 0
. User get rewards minted having only staked before the repayment.Tools Used
Manual review
Recommended Mitigation Steps
Prevent users staking and unstaking in the same block to receive rewards even if there is profit from the repayment, as normal users wouldn't do that. Or add a minimum stake time.
Assessed type
Timing