Open c4-bot-8 opened 6 months ago
0xSorryNotSorry marked the issue as sufficient quality report
0xSorryNotSorry marked the issue as primary issue
Confirming, I think the fix will look like this :
I'd argue no user funds are at risk (this would be detected upon deployment of a 2nd market, before users can use it) so this is more fit for Medium
eswak (sponsor) confirmed
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
Lines of code
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/tokens/GuildToken.sol#L123-L129 https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/tokens/GuildToken.sol#L41
Vulnerability details
Impact
In
GuildToken.sol
, there's a mistake whereprofitManager
is set in the constructor. This is problematic because different markets have differentProfitManagers
, and the logic was initially designed for only one market (e.g.,gUSDC
). As a result, callingnotifyPnL()
with negative value (viaforgive()
oronBid()
in other type of terms(e.g.gWETH
)), it triggersGuildToken::notifyGaugeLoss()
. However, this always results in a revert for other term types because the caller is the ProfitManager of that type, whereasGuildToken::notifyGaugeLoss()
expects the one set in the constructor.As a result, this means that loans from other markets won't be removed unless users repay them, resulting in bad debt for the protocol.
GuildToken::notifyGaugeLoss()
Proof of Concept
Conditions:
gUSDC
,gWETH
, …)notifyPnL()
(viaforgive()
oronBid()
)Coded PoC
Firstly, you need to add additional variables for other term type and include them in the
setUp()
.Modify
SurplusGuildMinter.t.sol
as shown.Place the test in the same
SurplusGuildMinter.t.sol
and run with:Tools Used
Manual Review
Recommended Mitigation Steps
In the
GuildToken.sol
,ProfitManager
need to be dynamically called, because there will be differentProfitManager
for each market.Since the caller of the
notifyGaugeLoss()
need to be the profitManager of the passed gauge here is the refactored logic.You should also rework
_decrementGaugeWeight()
and_incrementGaugeWeight()
as follows.Assessed type
DoS