Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Protocol insolvency
Description
Brief/Intro
When the TCR is smaller than the MCR, the TCR continues to be smaller if redeemer redeem debt token, and to suppress this, eBTC protocol does not allow redeem debt token when the TCR is smaller than the MCR.
As you can see on the redemption description page, Redemptions are disabled whenever the Total Collateral Ratio (TCR) goes below the Minimum Collateral Ratio (MCR) of 110%.
The problem is that an attacker can bypass this require and continue to redeem it even when the TCR is smaller than the MCR.
Attack Scenario
Let's look at the case where TCR is very close to MCR and larger than the MCR, but now TCR becomes smaller than the MCR with full redemption to the first ICR that is larger than the MCR. When this redemption is made, TCR becomes smaller than MCR, so the redemption cannot proceed until TCR becomes larger than MCR again.
However, if an attacker redeems multiple CDPs, not just CDP(the first ICR), multiple redemptions can proceed despite the fact that the TCR is smaller than the MCR with the repayment of the first CDP.
Attached below is the PoC test code explaining these scenarios.
You can create PoC_CDPManager.redemptions.t.sol file in foundry_test folder.
And run this in terminal.
forge test -vvv --match-contract PoC_CDPManagerRedemptionsTest.
Ran 2 tests for foundry_test/PoC_CDPManager.redemptions.t.sol:PoC_CDPManagerRedemptionsTest
[PASS] test_PoC1SingleRedemption() (gas: 652421)
Logs:
block.timestamp 1
========= Configration ==========
Set price for: MCR < TCR < FirstIcrGteMcr
CDP0Icr: 1074380165289256190
CDP1Icr: 1157024793388429741
CDP2Icr: 1173553719008264454
TCRBeforeRedemption: 1103047565120524000
------- Test SingleRedemption -------
- Redeem CDP1 fully
TCRAfterFirstRedemption: 1092850884463283517
- Try to Redeem CDP2 fully
Revert - CdpManager: Cannot redeem when TCR < MCR
The require works very well in this case!!!
[PASS] test_PoC2MultiRedemption() (gas: 617344)
Logs:
block.timestamp 1
========= Configration ==========
Set price for: MCR < TCR < FirstIcrGteMcr
CDP0Icr: 1074380165289256190
CDP1Icr: 1157024793388429741
CDP2Icr: 1173553719008264454
TCRBeforeRedemption: 1103047565120524000
------- Test MultiRedemption -------
- Redeem CDP1 and CDP2 fully
TCRAfterMultiRedemption: 1074380165289256190
!!!CdpManager.redeemCollateral doesn't check (TCR < MCR) since the second CDPs!!!
Test result: ok. 2 passed; 0 failed; 0 skipped; finished in 23.33ms
Impact Details
An attacker can exploit this vulnerability to send the TCR quickly down the MCR and launch an attack whenever the TCR rises above the MCR to prevent the protocol from returning to normal. There is no direct benefit to the attacker, but it interferes with the normal operation of the protocol, which continues to be present in recovery mode. This prevents the borrowers from disposing of their CDP, resulting in the destruction of community. If this continues, the protocol will go bankrupt.
References
To solve this vulnerability, we can simply check the TCR whenever the function proceeds with a CDP.
Let's look at the case where TCR is very close to MCR and larger than the MCR, but now TCR becomes smaller than the MCR with full redemption to the first ICR that is larger than the MCR. When this redemption is made, TCR becomes smaller than MCR, so the redemption cannot proceed until TCR becomes larger than MCR again.
However, if an attacker redeems multiple CDPs, not just CDP(the first ICR), multiple redemptions can proceed despite the fact that the TCR is smaller than the MCR with the repayment of the first CDP.
Attached below is the PoC test code explaining these scenarios.
You can create PoC_CDPManager.redemptions.t.sol file in foundry_test folder.
And run this in terminal.
forge test -vvv --match-contract PoC_CDPManagerRedemptionsTest.