Don't incentivise using asset tokens with high liquidation fee during liquidation (#536)
* Don't incentivise using non-usdc coins to liquidate tokens Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * fix tests Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * fix tests Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * review: add back test comment --------- Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> Co-authored-by: Christian Kamm <mail@ckamm.de>
This commit is contained in:
parent
61a4f62ea4
commit
2dca3003df
|
@ -115,16 +115,13 @@ pub(crate) fn liquidation_action(
|
|||
// Liquidation fees work by giving the liqor more assets than the oracle price would
|
||||
// indicate. Specifically we choose
|
||||
// assets =
|
||||
// liabs * liab_oracle_price/asset_oracle_price * (1 + liab_liq_fee + asset_liq_fee)
|
||||
// Which means that we use a increased liab oracle price and reduced asset oracle price for
|
||||
// the conversion.
|
||||
// It would be more fully correct to use (1+liab_liq_fee)*(1+asset_liq_fee), but for small
|
||||
// fee amounts that is nearly identical.
|
||||
// liabs * liab_oracle_price/asset_oracle_price * (1 + liab_liq_fee)
|
||||
// Which means that we use a increased liab oracle price for the conversion.
|
||||
// For simplicity we write
|
||||
// assets = liabs * liab_oracle_price / asset_oracle_price * fee_factor
|
||||
// assets = liabs * liab_oracle_price_adjusted / asset_oracle_price
|
||||
// = liabs * lopa / aop
|
||||
let fee_factor = I80F48::ONE + asset_bank.liquidation_fee + liab_bank.liquidation_fee;
|
||||
let fee_factor = I80F48::ONE + liab_bank.liquidation_fee;
|
||||
let liab_oracle_price_adjusted = liab_oracle_price * fee_factor;
|
||||
|
||||
let init_asset_weight = asset_bank.init_asset_weight;
|
||||
|
|
|
@ -184,7 +184,7 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> {
|
|||
assert!(account_position_closed(solana, account, collateral_token1.bank).await);
|
||||
assert_eq!(
|
||||
account_position(solana, account, borrow_token1.bank).await,
|
||||
(-350.0f64 + (1000.0 / 20.0 / 1.04)).round() as i64
|
||||
(-350.0f64 + (1000.0 / 20.0 / 1.02)).round() as i64
|
||||
);
|
||||
let liqee = get_mango_account(solana, account).await;
|
||||
assert!(liqee.being_liquidated());
|
||||
|
@ -206,7 +206,7 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> {
|
|||
.await
|
||||
.unwrap();
|
||||
assert!(account_position_closed(solana, account, collateral_token2.bank).await);
|
||||
let borrow1_after_liq = -350.0f64 + (1000.0 / 20.0 / 1.04) + (20.0 / 20.0 / 1.04);
|
||||
let borrow1_after_liq = -350.0f64 + (1000.0 / 20.0 / 1.02) + (20.0 / 20.0 / 1.02);
|
||||
assert_eq!(
|
||||
account_position(solana, account, borrow_token1.bank).await,
|
||||
borrow1_after_liq.round() as i64
|
||||
|
|
|
@ -331,10 +331,10 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
// the we only have 20 collateral2, and can trade them for 20 / 1.04 = 19.2 borrow2
|
||||
// the we only have 20 collateral2, and can trade them for 20 / 1.02 = 19.6 borrow2
|
||||
assert_eq!(
|
||||
account_position(solana, account, borrow_token2.bank).await,
|
||||
-50 + 19
|
||||
-50 + 20
|
||||
);
|
||||
assert!(account_position_closed(solana, account, collateral_token2.bank).await,);
|
||||
let liqee = get_mango_account(solana, account).await;
|
||||
|
@ -360,11 +360,11 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
// the asset cost for 50-19=31 borrow2 is 31 * 1.04 = 32.24
|
||||
// the asset cost for 50-19=31 borrow2 is 31 * 1.02 = 31.62
|
||||
assert!(account_position_closed(solana, account, borrow_token2.bank).await);
|
||||
assert_eq!(
|
||||
account_position(solana, account, collateral_token1.bank).await,
|
||||
1000 - 32
|
||||
1000 - 31
|
||||
);
|
||||
let liqee = get_mango_account(solana, account).await;
|
||||
assert!(liqee.being_liquidated());
|
||||
|
@ -388,14 +388,14 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
// the asset cost for 10 borrow1 is 10 * 2 * 1.04 = 20.8
|
||||
// the asset cost for 10 borrow1 is 10 * 2 * 1.02 = 20.4
|
||||
assert_eq!(
|
||||
account_position(solana, account, borrow_token1.bank).await,
|
||||
-350 + 10
|
||||
);
|
||||
assert_eq!(
|
||||
account_position(solana, account, collateral_token1.bank).await,
|
||||
1000 - 32 - 21
|
||||
1000 - 31 - 20
|
||||
);
|
||||
let liqee = get_mango_account(solana, account).await;
|
||||
assert!(liqee.being_liquidated());
|
||||
|
@ -420,16 +420,16 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
.unwrap();
|
||||
|
||||
// health after borrow2 liquidation was (1000-32) * 0.6 - 350 * 2 * 1.4 = -399.2
|
||||
// borrow1 needed 399.2 / (1.4*2 - 0.6*2*1.04) = 257.2
|
||||
// asset cost = 257.2 * 2 * 1.04 = 535
|
||||
// borrow1 needed 399.2 / (1.4*2 - 0.6*2*1.02) = 253.29
|
||||
// asset cost = 253.29 * 2 * 1.02 = 516.7
|
||||
// loan orignation fee = 1
|
||||
assert_eq!(
|
||||
account_position(solana, account, borrow_token1.bank).await,
|
||||
-350 + 257
|
||||
-350 + 253
|
||||
);
|
||||
assert_eq!(
|
||||
account_position(solana, account, collateral_token1.bank).await,
|
||||
1000 - 32 - 535 - 1
|
||||
1000 - 31 - 516 - 1
|
||||
);
|
||||
let liqee = get_mango_account(solana, account).await;
|
||||
assert!(!liqee.being_liquidated());
|
||||
|
@ -474,12 +474,11 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
// Liqee's remaining collateral got dusted, only borrows remain
|
||||
// but the borrow amount is so tiny, that being_liquidated is already switched off
|
||||
// Liqee's remaining collateral got dusted, only borrows remain: the account is bankrupt
|
||||
let liqee = get_mango_account(solana, account).await;
|
||||
assert_eq!(liqee.active_token_positions().count(), 1);
|
||||
assert!(account_position_f64(solana, account, borrow_token1.bank).await > -1.0);
|
||||
assert!(!liqee.being_liquidated());
|
||||
assert!(account_position_f64(solana, account, borrow_token1.bank).await > -2.74);
|
||||
assert!(liqee.being_liquidated());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -339,6 +339,10 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
)
|
||||
.await
|
||||
.unwrap();
|
||||
<<<<<<< HEAD
|
||||
|
||||
=======
|
||||
>>>>>>> dev
|
||||
// No change
|
||||
{
|
||||
let perp_market = solana.get_account::<PerpMarket>(perp_market).await;
|
||||
|
|
Loading…
Reference in New Issue