# Immediate liquidation ## Overview When a CDP is liquidated, liquidation mechanisms are used in the order of priority: 1. Immediate liquidation. 2. Collateral auctions. Immediate liquidation is executed with on-chain participants, including the Acala/Karura DEX and smart contracts. If immediate liquidation failed, the collateral auctions would be initiated. ## Immediate liquidation process ```rust fn liquidate(owner, currency_id, amount, target) ``` 1. [Liquidation via DEX](https://hackmd.io/u_OhjYRVRAyyTSc1yvQR9A#Liquidation-via-DEX) is tried first. - If `collateral_liquidated_price / collateral_oracle_price` is at least `ImmediateLiquidationPriceRatio` (the CDP engine module config), the liquidation is done, or the state is rolled back. - Else if below this ratio, liquidation via Contracts will be tried as follows. 2. [Liquidation via contracts](https://hackmd.io/u_OhjYRVRAyyTSc1yvQR9A#Liquidation-via-contracts) is tried. - If it's successful, the liquidation is done. - Else, the best price ratio from contracts liquidation is compared with the price ratio from DEX as follows. 3. DEX and contracts price ratio comparison: - If the DEX price ratio is better and it's greater than `MinLiquidationPriceRatio` (the CDP engine module config), the liquidation is executed by the DEX. - Or if the contract price ratio is better and it's greater than `MinLiquidationPriceRatio`, the liquidation is executed by the smart contract. 4. If the above approaches all fails, the immediate liquidation fails and the `LiquidationFailed` error is returned. - As mentioned in overview section, collateral auctions would be created then. ### Liquidation via DEX ```rust fn liquidate_via_dex(owner, currency_id, amount, target) ``` - The CDP treasury module is called to swap `amount` of collateral to at least `target` amount of aUSD. The actual collateral supply and target amount is returned from the call. - The refundable collateral amount is `amount - acutal_supply`. If it's not zero, it is transferred from the CDP treasury module account to `owner`. - The refundable aUSD amount is `actual_target - target`. If it's not zero, it is transferred from the CDP treasury module account to `owner`. ### Liquidation via contracts ```rust fn try_immediate_liquidation_via_contracts(currency_id, amount, target, collateral_oracle_price) ``` - The module storage `LiquidationContracts` stores a list of registered liquidation contract addresses. Each of them is tried to liquidate in the following order: - The contract at the register list index `current_block_number % list_length` is selected as the first. If it fails, the next contract is tried and vice versa. - When the last in the liquidation contracts list fails, the first contract in the list will be tried, until the contract at the index `current_block_number % list_length` is reached again. - A contract liquidates with the following steps: - The liquidate function of the contract is called via module config `LiquidationEvmBridge`. If the call is successful, the contract is expected to transfer target amount of aUSD to the CDP engine module account. - If enough aUSD payment is received from the contract, `amount` of collateral is transferred from the CDP treasury module account to the contract address, and the contract will be notified the collateral transfer is finished via the EVM bridge. - The liquidation by this contract is successful if `collateral_liquidated_price / collateral_oracle_price` is at least `ImmediateLiquidationPriceRatio`, or the state is rolled back and the price ratio is kept record. - If all the contracts failed to liquidate with `ImmediateLiquidationPriceRatio` requirements, their price ratios is compared and the highest is returned along with the contract address. ## Examples Current state: - `ImmediateLiquidationPriceRatio` is 0.9. - `MinLiquidationPriceRatio` is 0.85. - DOT oracle price: 5.5 ### Example 1 Alice's DOT position is to be liquidated: 100 DOT for 460 aUSD. Try to liquidate via DEX: - Swapped 100 DOT to 535 aUSD. - The price ratio is `5.35 / 5.5 = 0.9728`, which is greater than 0.9. - 75 aUSD is refunded to Alice. - Liquidation is successful. Result: immediate liquidation is successful via DEX. ### Example 2 Alice's DOT position is to be liquidated: 1000 DOT for 4600 aUSD. Try to liquidate via DEX: - Swapped 1000 DOT to 4900 aUSD. - The price ratio is `4.9 / 5.5 = 0.891`, which is smaller than 0.9. - State rolled back. Try to liquidate via contracts: - Try the first contract: - The contract can liquidate 1000 DOT for 4910 aUSD. - The price ratio is `4.91 / 5.5 = 0.8928`, which is smaller than 0.9. - State rolled back. - Try the second contract: - The contract can liquidate 1000 DOT for 5200 aUSD. - The price ratio is `5.2 / 5.5 = 0.945`, which is greater than 0.9. - Liquidation is successful. Result: immediate liquidation is successful via a smart contract. ### Example 3 Alice's DOT position is to be liquidated: 2000 DOT for 9000 aUSD. Try to liquidate via DEX: - Swapped 2000 DOT to 9600 aUSD. - The price ratio is `4.8 / 5.5 = 0.8727`, which is smaller than 0.9. - State rolled back. Try to liquidate via contracts: - No contracts can liquidate with above 0.9 price ratio, the best is 0.86. - State rolled back. The price ratio of DEX 0.87 is higher and it's greater than 0.85. - Swap 2000 DOT to 9600 aUSD. - Refund 600 aUSD to Alice. - Liquidation is successful. Result: immediate liquidation is successful via DEX. ### Example 4 Alice's DOT position is to be liquidated: 5000 DOT for 23000 aUSD. Try to liquidate via DEX: - Swapped 5000 DOT to 23100. - The price ratio is `4.62 / 5.5 = 0.84`, which is smaller than 0.9. - State rolled back. Try to liquidate via contracts: - No contracts can liquidate with above 0.9 price ratio, the best is 0.845. - State rolled back. Both DEX and contracts price ratios are below 0.85. Result: immediate liquidation failed, 5000 DOT will be auctioned.