Submitted by niroh, also found by EV_om, carrotsmuggler, EllipticPoint, rvierdiiev, and kaden
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/LendingTerm.sol#L291
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/LendingTerm.sol#L303
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/LendingTerm.sol#L317
https://github.com/code-423n4/2023-12-ethereumcreditguild/blob/2376d9af792584e3d15ec9c32578daa33bb56b43/src/loan/LendingTerm.sol#L324
The debtCeiling function uses the minimum of hardCap and credit minter remaining buffer (creditMinterBuffer) as a hard limit on the terms debtCeiling in two places:
Line 298:
Line 324:
However, unlike hardCap, the creditMinterBuffer-induced limit should be issuance + creditMinterBuffer instead. This is because the buffer is a limit on additional borrows, not on the total of current issuance and additional borrows. This error triggers a revert in GuildToken::_decrementGaugeWeight whenever a gauges current issuance exceeds the remaining buffer. This occurs even if the post-decrement true debtCeiling is above the issuance.
Consequently, guild voters and surplusGuildMinder stakers are unjustifiably prevented from removing their votes/stakes from a gauge. This situation is likely to occur naturally when borrowing demand is high, or as a DOS attack where a malicious actor borrows the sum needed to keep a terms issuance above the remaining buffer, blocking voters and surplus stakers from exiing their positions.
Preventing guild voters/surplus stakers from removing votes/stakes from gauges they see as unsafe breaks the main system mechanism, through which term quality is maintained and risk is reduced. In addition, voters/surplus stakers who are unable to exit their positions from term they consider too risky may later have those votes slashed when the term incurs a loss, causing them considerable financial damage.
This POC shows how a single term with a single voter can not remove 2% of the votes because the terms issuance is above the current buffer. 
Note: there is another issue with debtCeiling() (see my other submission on the matter) that would prevent removing more than 16.666% of the votes of a single-term market; however, removing 2% should have succeeded in spite of the other issue.
To run:
Add the code below to the test file integrationTestBadDebtFlows.sol. Forge test --match-test 'testRemoveVotesSingleTerm' --fork-url $ETH_RPC_URL -vvv:
Foundry
In debtCeiling() use issuance + creditMinterBuffer instead of creditMinterBuffer.
TrungOre (judge) commented:
eswak (Ethereum Credit Guild) confirmed
