-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Malicious borrower can decrease Guild holders reward #994
Comments
0xSorryNotSorry marked the issue as sufficient quality report |
The issue is well demonstrated, properly formatted, contains a coded POC. |
0xSorryNotSorry marked the issue as high quality report |
0xSorryNotSorry marked the issue as primary issue |
The root cause seems to be the same with #877 but duping differently as the issue slightly differs. |
eswak marked the issue as disagree with severity |
Trumpero changed the severity to 2 (Med Risk) |
Trumpero marked the issue as satisfactory |
Trumpero marked the issue as selected for report |
Hey @Trumpero, could you please take a second review at this? How an exploiter can take a $10 million USDC flashloan and then wait for 150 days. Aren't flashloans meant to be repaid in the same transaction? Also, in repaying Alice's position, the repay() function uses msg.sender. Note for warden: I'm interested in taking some of them flashloans myself. Any assistance on that would be appreciated. |
Hey @0xbtk,
About that, yes there was a mistake in the steps, Alice will repay it, lowering all other rewards. This is a simpler sandwich attack. |
Hey @Slavchew, I did review your PoC carefully, in your PoC you said that the attacker will take 10m flashloan here: gUSDC.mint(EXPLOITER, 10_000_000e18); Following that, you used vm.warp(block.timestamp + 150 days);
uint256 interest = _computeAliceLoanInterest(borrowTime, 100e18); Could you please explain how can the exploiter do that in a real world scenario? |
Hey @0xbtk, I did review the PoC again, and yes, you are right. I made a mistake in where the blocks should pass, but even if they pass before the Exploiter takes the flashloan, the result is the same, since as I wrote in #1026, staking is based on staked amount, not time. Here's the fixed test, the Alice part can also be ignored because it's not used anywhere, I just forgot to remove it while writing the finding. Alice is not needed at all in the execution of the problem, Exploiter borrow, then wait, get the flashloan, stake, trigger notifyPnL, unstake, return the loan. https://gist.github.com/Slavchew/acff9a9c094d475b5d4806901eb61b64
Regarding that, the repay function uses msg.sender, but this is the repayer, as I mentioned if you create the attack with 2 accounts like in the PoC steps, you need to transfer your credit tokens to the Exploiter to pay off your loan and trigger notifyPnL(). Let me know if you have any other concerns, but I'm sure the problem is valid. |
Lines of code
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L114-L155
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L158-L212
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/SurplusGuildMinter.sol#L216-L290
Vulnerability details
Impact
A malicious borrower can reduce all Guild holders’ rewards with a big flashloan, upon full repayment.
Borrower opens a loan with the minimum borrowable amount in term with no mandatory partial repayment. Wait for the loan to accumulate interest, then transfer the funds to an alternative account - EXPLOITER. EXPLOITER takes a flash loan, stakes the amount through
SurplusGuildMinter
, repays the original loan, lowering the rewards for all other GUILD holders by increasing the_gaugeWeight
with his staked tokens. Afterward, the EXPLOITER unstakes and returns the flashloan.The attacker ends up with his collateral, his loan repaid, credit reward and a big percentage of the reward intended for
GUILD
holders since he is the largest staker for this term at the time of the attack. He receives significant credit and guild rewards as a staker, which is incorrect because he was a staker only for that specific transaction.He only pays the unavoidable interest payment, typically around $4-5, along with gas costs in the scenario described below.
Proof of Concept
The exploiter has two accounts:
notifyPnL()
.Here are the detailed steps to execute the described attack:
PSM
.notifyPnL()
.notifyPnL()
updates the_gaugeProfitIndex
, reducing rewards for other Guild holders.Coded PoC
Create new file in
test/unit/loan
calledDeflateGuildHoldersRewards.t.sol
There are tests for both cases – one without the attack and another with the attack scenario.
Run them with:
Tools Used
Manual
Recommended Mitigation Steps
Providing recommendations is challenging due to the large codebase, and code changes might affect other parts of the system.
The things we came up with to protect against this are: to not allow staking and unstaking in the same block, implementing staking/unstaking fee, or implementing a "warm-up period" during which stakers are unable to accumulate interest.
We are open to collaborate with the development team to find a proper mitigation for the problem.
Assessed type
Context
The text was updated successfully, but these errors were encountered: