Fork of Anchor Protocol's implementation with slight modifications
The Liquidation contract enables users to submit CDP token bids for a Cw20 or native sdk token. Bidders can submit a bid to one of the bid pools; each of the pools deposited funds are used to buy the liquidated collateral at different discount rates. There are 21 slots per collateral, from 0% to 20%; users can bid on one or more slots.
Upon execution of a bid, collateral tokens are allocated to the bidder, while the bidder's bid tokens are sent to repay the liquidated position.
Bids are consumed from the bid pools in increasing order of premium rate (e.g 2% bids are only consumed after 0% and 1% pools are emptied). The liquidated collateral is then allocated to the bidders in the affected pools in proportion to their bid amount. The respective collateral has to be claimed manually by the bidders.
To prevent bots from sniping loans, submitted bids are only activated after wait_period has expired, unless the total bid amount falls under the bid_threshold, in which case bids will be directly activated upon submission.
Warning:The cumulative threshold of the frequented slots should be larger than the largest single liquidation amount to prevent waiting bids from causing InsufficientBids errors.
Automatic activation after wait_period elaspes. This increases computation time in return for less reliance on external contract calls.
Liquidations send the RepayMsg for the position in the Positions contract
Prices are taken from input by the Positions contract, the messages are guaranteed the same block so the price can be up to block_time +Position's config oracle_time_limit second's old.
The position is assumed insolvent since called by the Positions contract, ie there is no additional solvency check in this contract.
ExecuteMsg::Liquidate doesn't take any assets up front, instead receiving assets in the Reply fn of the Positions contract
Removed bid_with, instead saving the bid_asset from the Positions contract
Added minimum_bid amount & maximum_waiting_bids to config
Created a separate Vector for PremiumSlot waiting bids
Submitted bids on the (bid) threshold get split into 1 active bid & 1 waiting bid
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
ClaimLiquidations {
bid_for: AssetInfo,
bid_ids: Option<Vec<Uint128>>, //None = All bids in the queue
}
}
* = optional
AddQueue
Add Queue to the contract
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
AddQueue{
bid_for: AssetInfo,
max_premium: Uint128, //A slot for each premium is created when queue is created
bid_threshold: Uint256, //Minimum bid amount. Unlocks waiting bids if total_bids is less than.
}
}
UpdateQueue
Update existing Queue
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
UpdateQueue{
bid_for: AssetInfo, //To signla which queue to edit. You can't edit the bid_for asset.
max_premium: Option<Uint128>,
bid_threshold: Option<Uint256>,
},