Skip to content

Black Swan

There are two potential black swan scenarios that are accounted for to mitigate damages to the system:

  1. Global: when the underlying collateral (like stETH, rETH) is worth less than the equivalent amount of ETH. (ex: stETH drops in value compared to ETH).

    It's not safe to assume that LST ETH is worth 1:1 to ETH, even if most of the time it is. The risk of something like stETH de-pegging (as in the past) is less when withdrawals are open, but there is still smart contract risk. This kind of assumption was also broken with USDC given the events surrounding SVB.

  2. Local: when ETH drops in value compared to the asset being minted (ex: ETH compared to USD) to the point where enough shortRecords become undercollateralized to break the price peg of the stable asset.

Global Black Swan

The system does two things in this scenario:

  • Prevents yield from being updated if the ETH value of the underlying LST in a Vault is lower than the last saved value
  • If dethTotalNew <= dethTotal, haircut anyone that exits the system (on withdraw)

Note: it is disadvantageous for a user to withdraw() in a time of negative yield due to the penalty fee but it is allowed.

  • updateYield() calls getDethTotal() which gives the total amount of dETH value in the system by adding up dETH in every type of collateral where total dETH = total stETH + total rETH.
  • getDethTotal() should usually be higher or at least equal to what was last saved in storage, s.uintVault[vault].dethTotal. If not,revert with if (dethTotalNew <= dethTotal) revert Errors.NoYield();
  • If there is less dETH than before (like a slashing event), then getDethTotal() will be lower. Anyone that withdraws during this temporary period of negative yield receives less than 1:1 ETH at the ratio of negative yield to account for this loss in ETH. Instead of withdrawing amount, they have to withdraw amount.mul(dethTotalNew).div(dethTotal).

Local Black Swan


The Treasury Asset Protection Pool (TAPP) is used for bolstering the stability of market pegged assets during periods of large price shock movements. It is shared across markets within DittoETH and thus any market has access to TAPP funds to prevent the default of low and under-collateralized shortRecords. Its various parameters can be managed by DAO controlled governance voting.

The TAPP is funded when DittoETH takes a tithe from earned rewards of staked ETH and also from Primary Liquidation penalty fees. The fund generally attempts to pay back the under-collateralized debt and any penalty or gas fees that need to be distributed when a liquidated shortRecord lacks the collateral to do so itself. In events when the CR of a shorter is below 1, the Primary Liquidation Method will use the TAPP to take on losses of the under-collateralized shortRecord.

The TAPP will also be contributed additional dETH when a shortRecord's CR is below or equal to 1.1. When a shortRecord is liquidated with a CR at these levels, any remaining collateral that was not used to settle the debt will be given to the TAPP, and the shorter will be returned nothing.

Note: In the future, when the TAPP is sufficiently large enough, the community may choose to distribute fees earned on the protocol to the governance token holders.

When a shortRecord is liquidated through the primary liquidate() method and it does not have enough dETH to pay down its debt, as well as cover penalty and base gas fee reimbursements, the TAPP will automatically be used. In these instances, the TAPP's dETH balance will be used as the forced bid for the liquidation. Afterwards, the entire collateral of the shortRecord will be given to the TAPP and the shortRecord will be closed out with nothing. However, if the forced bid can only settle a portion of the debt, then the remainder of collateral will remain with the TAPP and not be given back to the shorter. Effectively, the shortRecord will be given to the TAPP. This will occur in cases when there are not enough orders to perform a full liquidation.

Note: It is possible the TAPP could be used above 1.1, if base gas fees are very high. In this situation, since the TAPP will be needed to cover the base gas fees to close the shortRecord, the shorter will lose all remaining collateral and be closed out. This will occur because the liquidation will put the CR below 1.1 after accounting for base gas fees.

Most likely these approaches will not be needed. The system has a large number of ways to mitigate the risks of a black swan unwind, including requiring high CR to create a shortRecord and the fact that TAPP will receive dETH accumulated over time from the fee charged to the overall yield of the protocol.


When ETH value as collateral drops precipitously and the TAPP has low amounts of dETH, all orderbooks have the same mechanism in place to save the asset peg by always allowing execution of liquidations. Instead of freezing the market upon the first instance of an under-collateralized shortRecord, the unbacked asset debt is socialized over every shortRecord in proportion to each position's ercDebt balance. As long as the CR of the entire system is above 1, this allows market operations to continue indefinitely and undisturbed unless:

  1. The DAO steps in and freezes/dissolves the market
  2. The max ercDebtRate is reached (uint64 max ~18.45x)

ercDebtRate is calculated as ercDebt[socialized] / (ercDebt[Asset] - ercDebt[socialized]) and is written to every shortRecord record to modify each position's ercDebt amount. This functions in the same manner as yield rate, but affects the asset debt instead of dETH. The formulation of ercDebtRate is as follows:

  • short.collateral is added to s.vaultUser[m.vault][address(this)].ethEscrowed (where address(this) = TAPP) and checked against m.ethDebt, where m.ethDebt = m.short.ercDebt.mul(m.oraclePrice).mul(m.forcedBidPriceBuffer + m.tappFeePct + m.callerFeePct). This checks against the worst case scenario of a forced bid match at oraclePrice * forcedBidPriceBuffer and the subsequent fees. If this condition is not met, ercDebt is removed from the shortRecord to the point where a worst case forced bid can be guaranteed fulfillment. Thus, tappFee, callerFee and the possibility of a full liquidation are guaranteed by the removal of ercDebt.
  • The ercDebt removed from the shortRecord is then socialized among all remaining shortRecords of the asset orderbook by an increased ercDebtRate.

Assuming penaltyCR = 1.1, forcedBidPriceBuffer = 1.1, tappFee = 2.5%, callerFee = 0.5%, CR Combined = ethEscrowed (short collateral + Tapp balance) against ercDebt, loseCollateral = shorter loses leftover collateral:

ShortTAPPCR CombinedDescriptionloseCollateral
CR = 1.13CR = 01.13ercDebtSocialized = 0No
CR = 1.12CR = 01.12*ercDebtSocialized > 0Yes
CR = 0.90CR = 0.51.40ercDebtSocialized = 0Yes

Note: It is possible for a shorter to be penalized at a CR higher than the penaltyCR when the TAPP is low or empty in order to guarantee liquidation execution. In the highly unlikely scenario of a low/empty TAPP, it is arguable that the market has already entered black swan territory, hence the over-conservative reallocation of ercDebt to save the asset peg. See (*)

Emergency Market Shutdown

In the event a market cannot be salvaged by redistributing bad debt to other shortRecords, the DITTO admin or DITTO DAO can permanently freeze that market by calling shutdownMarket once the CR of the entire asset breaches the threshold set by penaltyCR.

  • It is assumed that shutdownMarket will be called shortly after the c-ratio of the asset falls since the last saved Oracle price before freezing is used to facilitate asset conversions back to dETH.
  • It is in the best interest of asset holders to freeze the market and guarantee redemptions closer to par. Due to the time sensitivity of a volatile market move, both the admin and DAO can call this function.

In this worst case scenario, the asset will need to be discontinued and a redemption claims process (redeemErc) automatically becomes available:

amtDeth = amtErc * price * assetCR;
  • amtErc can be redeemed from one of or both Wallet balance and Escrow balance
  • price is the last saved oracle price
  • if assetCR is between 1 and penaltyCR > 1, collateral is sent to TAPP to make assetCR = 1
  • assetCR less than 1 is unmodified

The redemption mechanism functions similarly to the secondary liquidation methods which allow redemptions of asset from wallets and escrowed balances. However, instead of targeting a specific shortRecord, all of the collateralized dETH is bundled together into one singular balance whereby asset holders can make automatic redemptions based on the frozen price and assetCR. Due to market closure, there is no need to track individual shortRecords and at this point all shorter collateral is lost. To reinstate the asset orderbook, a new contract will need to be established.