The requirement to deposit TST for participating in liquidations may prevent the full utilisation of liquidation pool funds during liquidation, potentially leading to the appearance of bad debt.
The main invariant of collateralised stablecoins: Issued stable coin value <= collateral value * collateral factor
(or euro value < collateral value / collateralRate
in terms of The Standard protocol), where 0 <= collateral factor <= 1
. This invariant should be valid both for each position and for the whole protocol.
There are two cases of invariant break for a position:
collateral value * collateral factor < Issued stable coin value <= collateral value
- in such cases, the position is liquidated, collateral is sold, and its value is enough to repay (burn) all issued stablecoins.
Issued stable coin value > collateral value
- in such cases, the position is also liquidated, collateral is sold, but its value is not enough to repay (burn) all issued stablecoins:
X - issued stablecoins, Y - repaid and burnt during liquidation stablecoins where Y < X. X-Y is the protocol's bad debt. It means if all users close their positions, X-Y stablecoins are still issued. But this amount is backed by nothing.
When the protocol has bad debt, the fair price of a stablecoin = (Issued stablecoins - Bad debt) / Issued stablecoins
and it is < 1. It means that the stablecoin tends to be unpegged.
To return the peg, the protocol must buy stablecoins from the market and burn them. It means that Bad debt is the direct protocol loss.
In LiquidationPool::distributeAssets()
, collaterals are distributed to holders, and EUROs from holders are repaid and burnt pro rata their stake (see 1@> in the details below). Stake is calculated depending on EUROs and TST amount in the holder's position (see 2@>). There could be cases when the total amount of EUROs is enough to liquidate a vault, but because of insufficient TST amount, not all holder EUROs would be used for repayment and burning (see 3@> and 4@>).
Exaggerated example:
Preconditions:
Fees=0 to simplify calculations.
_collateralRate = 1.1 (as in production).
Eur/BTC price is 10000 EUR/BTC.
User1 deposited 110 BTC.
User1 minted 1_000_000 EUROs.
Liquidation pool's positions are 1_000_000 EUROs.
User2's position is 800_000 EUROs and 300_000 TST (user may not fully understand how the protocol works).
User3's position is 300_000 EUROs and 800_000 TST (prior liquidations used part of User3's initial position).
Falling market, Eur/BTC price is 9500 EUR/BTC.
User1's vault becomes undercollateralised, liquidation is triggered.
Total EUROs amount is 1_100_000 EUROs, which is enough to liquidate User1's vault, but
User2's stake is 300_000 (see 2@> above).
User3's stake is 300_000 (see 2@> above).
_portion
of User2 and User3 is 55 BTC (half of User1's collateral, see 1@>).
475_000 EUROs from User2's position are used for liquidations, and 55 BTC are available for claiming by User2.
Only 300_000 EUROs from User3's position are used for liquidations.
Approximately 35 BTC (300000/475000*55) are available for claiming by User3.
20 BTC goes to LiquidationPoolManager.protocol
(EOA/multisig of the team as explained in the Discord channel).
It will take time for The Protocol team members to sell received collateral, buy and burn EURO to avoid bad debt.
This could be critical on a falling market, as the amount of bought EUROs might not cover all remaining debt.
This situation wouldn't occur if all of User2's funds participated in the liquidations.
Bad debt could appear.
Manual review
In cases where:
Liquidation pool EURO positions are enough to liquidate an undercollateralised vault.
Due to insufficient TST position, not all these EUROs are utilised (and collateral is sent to the LiquidationPoolManager.protocol
address).
EUROs should be utilised regardless of TST positions in the liquidation pool.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.