-
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 voter will steal all interest on open loans when loss is notified and term is offboarded #379
Comments
0xSorryNotSorry marked the issue as sufficient quality report |
0xSorryNotSorry marked the issue as duplicate of #878 |
Trumpero changed the severity to QA (Quality Assurance) |
Trumpero marked the issue as grade-b |
This previously downgraded issue has been upgraded by Trumpero |
Trumpero changed the severity to QA (Quality Assurance) |
Trumpero marked the issue as grade-c |
Hi @Trumpero, I think the primary issue (#878) doesn't describe the full impact of this issue and, therefore, the sponsor downgraded it to QA. I think it should be HIGH severity, considering that an attacker will steal matured yield that should be distributed to all voters. As per sponsor's comment on the primary issue:
In the case that a term generates a loss, the GUILD token holders are going to offboard it and call all loans. During the time that auctions for those loans are running, a malicious voter can start slashing other voters on the term in order to reduce their voting power on that term. A malicious voter can slash all other voters until he's the only voter left on that term. When other voters try to slash the attacker, the transaction will revert because issuance won't be zero. Therefore, when all auctions are closed, it's probable that some of those loans are going to generate interest that must be distributed between all term voters. Because the attacker is the only voter for that term at that point (all other voters have been slashed), all the interest generated by the auctioned loans is going be redirected to that malicious voter. After all loans have been closed, the malicious voter will also be slashed but he will keep all the interest from the last auctioned loans. Check my PoC for clarification. Thanks a lot for your time! |
This statement is not true. The attacker can only slash while the debt ceiling is higher than the issuance, so the profit of each liquidation will be distributed among the remaining Guild holders. The attacker needs to repeat it and slash promptly to optimize their rewards received. This action is allowed and it's the expected behavior for users, as the sponsor confirmed. |
Lines of code
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/main/src/tokens/GuildToken.sol#L225-L231
Vulnerability details
Description
When a lending term accumulates bad debt, the protocol dictates that all
GUILD
voters associated with that term should be penalized by losing their tokens voted for that gauge. Ideally, when a term becomes too risky, itsGUILD
voters are expected to offboard it and liquidate the loans through an auction. This process is designed to prevent the accumulation of bad debt by incentivizing voters to responsibly manage the terms they support.However, a loophole exists where, if a loss is reported and the term is immediately offboarded, some open loans might remain. The interest from these loans, once repaid through auction, is meant to be distributed among the gauge voters at the time the auction closes. A malicious voter can exploit this by applying the loss to all other voters, effectively claiming all the interest from the auctioned loans for themselves. This is particularly concerning when other voters can't counteract due to debt ceiling limitations, allowing the last malicious voter to monopolize the interest.
To apply a loss to a voter, the function
applyGaugeLoss()
must be called. This one will decrement the voter weight on that slashed gauge calling_decrementGaugeWeight()
, which will check first for the current debtCeiling on that term:This check for the debt ceiling on
_decrementGaugeWeight()
will make that when the last voter on a gauge is going to be slashed,debtCeiling()
will return zero. This will cause that the voter won't be slashed untilissuance
is also zero, meaning all borrows of that term have been closed. This behavior will result on that the last voter to be slashed on an offboarded term will monopolize all the interest from the auctioned loans.Impact
When a lending term generates some bad debt and is offboarded with still some open loans, a malicious voter will be able to slash the rest of the voters first and will keep all the interest generated from the last open loans on the term.
Proof of Concept
The following POC can be pasted in
LendingTerm.t.sol
.The test can be run with the command:
forge test --match-test testAttackerKeepsAllInterest
.Tools Used
Manual Review
Recommended Mitigation Steps
To address this vulnerability, it's proposed to modify the
GuildToken._decrementGaugeWeight()
function. The suggested change involves allowing GUILD voters to decrement their weight on a term if it has been offboarded. This adjustment ensures that all gauge voters can be slashed when a term accrues bad debt and is subsequently offboarded, preventing a single voter from unfairly capitalizing on the situation.Assessed type
Timing
The text was updated successfully, but these errors were encountered: