The LendingTerm:repay and LendingTerm:partialRepay functions can be frontrunned by the malicious user to stake the CREDIT with SurplusGuildMinter:stake or increase gauge weight directly. By doing this malicious actors essentially steal the user’s rewards by staking for only one transaction and unstaking immediately after it.
Proof of Concept
When the borrower repays their loan, the interest is distributed to Guild stakers, credit holders, surplus buffer, and possibly protocols treasury.
The Guild stakers receive CREDIT tokens and GUILD as a reward for staking in the gauge, and the reward is distributed based on the amount of the GUILD staked by the user. The malicious actor can take advantage of this can monitor the mempool for any repay or partialRepay
If he sees any of these transactions coming in he can quickly front-run it and stake his CREDIT or increase the weight with his GUILD in the gauge where profit is coming and steal the large share of reward from other stakers.
Flow
borrow calls repay or partialRepay with principal + interest
attacker front-runs the transaction and increases the weight of the gauge with the large amount
repayment executes and profitManager:notifyPnl is called internally to distribute rewards
attacker receives his share of CREDIT and GUIlD
he unstake immediately in the next transaction and steals those rewards without getting exposed to any risks of staking.
A simple foundry test to show how this will come into play
[PASS] test_frontrunAndStealRewards() (gas: 1484537)
Logs:
Attaker credit bal before 0
Attaker Guild bal before 0
------------------------------------------------------------------
Attaker credit rewards 99990000999900000000 = 99.99 CREDIT
Attaker Guild Reward 499950004999500000000 =499.99 GUILD
------------------------------------------------------------------
Alice credit bal before 0
Alice Guild bal before 0
------------------------------------------------------------------
Alice credit bal after 9999000099990000 = 0.009 CREDIT
Alice Guild bal after 49995000499950000 = 0.049 GUILD
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 10.94ms
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
Tools Used
manual review
foundry
Recommended Mitigation Steps
There should be some lockup period for GUILD stakers to be eligible for the rewards. or rewards should be distributed based on how long a user stake. Synthetix reward mechanism can be used as example
Lines of code
https://github.com/volt-protocol/ethereum-credit-guild/blob/4d33abf95fee69391af0652e3cbe5e0cffa25f9f/src/loan/LendingTerm.sol#L490 https://github.com/volt-protocol/ethereum-credit-guild/blob/4d33abf95fee69391af0652e3cbe5e0cffa25f9f/src/loan/LendingTerm.sol#L567 https://github.com/volt-protocol/ethereum-credit-guild/blob/4d33abf95fee69391af0652e3cbe5e0cffa25f9f/src/loan/SurplusGuildMinter.sol#L114 https://github.com/volt-protocol/ethereum-credit-guild/blob/4d33abf95fee69391af0652e3cbe5e0cffa25f9f/src/loan/SurplusGuildMinter.sol#L158
Vulnerability details
Impact
The
LendingTerm:repay
andLendingTerm:partialRepay
functions can be frontrunned by the malicious user to stake the CREDIT withSurplusGuildMinter:stake
or increase gauge weight directly. By doing this malicious actors essentially steal the user’s rewards by staking for only one transaction and unstaking immediately after it.Proof of Concept
When the borrower repays their loan, the interest is distributed to Guild stakers, credit holders, surplus buffer, and possibly protocols treasury.
The Guild stakers receive CREDIT tokens and GUILD as a reward for staking in the gauge, and the reward is distributed based on the amount of the GUILD staked by the user. The malicious actor can take advantage of this can monitor the mempool for any
repay
orpartialRepay
If he sees any of these transactions coming in he can quickly front-run it and stake his CREDIT or increase the weight with his GUILD in the gauge where profit is coming and steal the large share of reward from other stakers.
Flow
repay
orpartialRepay
with principal + interestprofitManager:notifyPnl
is called internally to distribute rewardsA simple foundry test to show how this will come into play
Output
Tools Used
Recommended Mitigation Steps
There should be some lockup period for GUILD stakers to be eligible for the rewards. or rewards should be distributed based on how long a user stake. Synthetix reward mechanism can be used as example
Assessed type
Rug-Pull