Skip to content

Commit b43dbbc

Browse files
committed
final tests for base debt
1 parent 5ebbf56 commit b43dbbc

2 files changed

Lines changed: 116 additions & 371 deletions

File tree

packages/margin_trading/tests/margin_manager_math_tests.move

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ fun test_liquidation_quote_debt_partial_ok() {
5353
test_liquidation_quote_debt_partial();
5454
}
5555

56+
#[test]
57+
fun test_liquidation_base_debt_default_ok() {
58+
test_liquidation_base_debt_default();
59+
}
60+
5661
#[test]
5762
fun test_liquidation_base_debt_ok() {
5863
test_liquidation_base_debt();
@@ -427,7 +432,7 @@ fun test_liquidation_quote_debt_partial() {
427432
cleanup_margin_test(registry, admin_cap, maintainer_cap, clock, scenario);
428433
}
429434

430-
fun test_liquidation_base_debt() {
435+
fun test_liquidation_base_debt_default() {
431436
let (
432437
mut scenario,
433438
clock,
@@ -509,7 +514,7 @@ fun test_liquidation_base_debt() {
509514
// Remaining_repay_coin = 1 - 0.3597 = 0.6403 BTC
510515
// The liquidator should receive 0.3492 * 1.05 = 0.36666 BTC = 1100 USD. The net profit is 0.36666 - 0.3597 = 0.00696 BTC
511516
// 0.00696 BTC / 0.3492 BTC = 2% reward
512-
// The 0.2 BTC will be used first. 1100 - 0.2 * 3000 = 500 USD. Then the remaining 500 USD will be taken as USDC..
517+
// The 0.2 BTC will be used first. 1100 - 0.2 * 3000 = 500 USD. Then the remaining 500 USD will be taken as USDC.
513518
let (base_coin, quote_coin, remaining_repay_coin) = mm.liquidate<BTC, USDC, BTC>(
514519
&registry,
515520
&btc_price_3000,
@@ -536,6 +541,115 @@ fun test_liquidation_base_debt() {
536541
cleanup_margin_test(registry, admin_cap, maintainer_cap, clock, scenario);
537542
}
538543

544+
fun test_liquidation_base_debt() {
545+
let (
546+
mut scenario,
547+
clock,
548+
admin_cap,
549+
maintainer_cap,
550+
btc_pool_id,
551+
usdc_pool_id,
552+
_pool_id,
553+
) = setup_btc_usd_margin_trading();
554+
555+
let btc_price = build_btc_price_info_object(&mut scenario, 500, &clock);
556+
let usdc_price = build_demo_usdc_price_info_object(&mut scenario, &clock);
557+
558+
scenario.next_tx(test_constants::user1());
559+
let mut pool = scenario.take_shared<Pool<BTC, USDC>>();
560+
let registry = scenario.take_shared<MarginRegistry>();
561+
margin_manager::new<BTC, USDC>(&pool, &registry, &clock, scenario.ctx());
562+
563+
scenario.next_tx(test_constants::user1());
564+
let mut mm = scenario.take_shared<MarginManager<BTC, USDC>>();
565+
let usdc_pool = scenario.take_shared_by_id<MarginPool<USDC>>(usdc_pool_id);
566+
let mut btc_pool = scenario.take_shared_by_id<MarginPool<BTC>>(btc_pool_id);
567+
568+
// Deposit 500 USDC
569+
mm.deposit<BTC, USDC, USDC>(
570+
&registry,
571+
mint_coin<USDC>(500 * usdc_multiplier(), scenario.ctx()),
572+
scenario.ctx(),
573+
);
574+
575+
// Borrow $200 BTC (0.4 BTC). Risk ratio = (500 + 200) / 200 = 3.5
576+
mm.borrow_base<BTC, USDC>(
577+
&registry,
578+
&mut btc_pool,
579+
&btc_price,
580+
&usdc_price,
581+
&pool,
582+
40000000,
583+
&clock,
584+
scenario.ctx(),
585+
);
586+
587+
assert!(
588+
mm.risk_ratio(&registry, &btc_price, &usdc_price, &pool, &btc_pool, &clock) == 3_500_000_000,
589+
0,
590+
);
591+
592+
// Now we withdraw 0.2 BTC. This should be allowed since risk ratio >= 2;
593+
let withdraw_btc = mm.withdraw<BTC, USDC, BTC>(
594+
&registry,
595+
&btc_pool,
596+
&usdc_pool,
597+
&btc_price,
598+
&usdc_price,
599+
&pool,
600+
20000000,
601+
&clock,
602+
scenario.ctx(),
603+
);
604+
withdraw_btc.burn_for_testing();
605+
606+
// Risk ratio is now (500 + 100) / 200 = 3.0
607+
assert!(
608+
mm.risk_ratio(&registry, &btc_price, &usdc_price, &pool, &btc_pool, &clock) == 3_000_000_000,
609+
0,
610+
);
611+
612+
// Perform liquidation and check rewards
613+
scenario.next_tx(test_constants::liquidator());
614+
615+
// We now have 0.2 BTC ($440) and 500 USDC ($500), with a debt of 0.4 BTC ($880)
616+
// At BTC price 2200, Risk ratio = (440 + 500) / 880 = 1.0681818 < 1.1, can liquidate
617+
let repay_coin = mint_coin<BTC>(1 * btc_multiplier(), scenario.ctx());
618+
let btc_price_2200 = build_btc_price_info_object(&mut scenario, 2200, &clock);
619+
620+
assert!(
621+
mm.risk_ratio(&registry, &btc_price_2200, &usdc_price, &pool, &btc_pool, &clock) == 1_068_181_825,
622+
0,
623+
);
624+
625+
// 0.37454 BTC will be used to liquidate. 0.3636 BTC for repayment of loan, 0.01094 BTC for pool liquidation fee.
626+
// Since 0.3636 BTC is used for repayment, the liquidator should receive 0.3636 * 0.02 = 0.007272 as a reward.
627+
// Risk ratio after liquidation = (940 - 824 - 16) / (880 - 800) = 1.25
628+
// Remaining_repay_coin = 1 - 0.37454 = 0.62546 BTC
629+
// The liquidator should receive 0.3636 * 1.05 = 0.38178 BTC = 840 USD.
630+
// The 0.2 BTC will be used first (0.2 BTC = 440 USD). Then the remaining 400 USD will be taken as USDC.
631+
let (base_coin, quote_coin, remaining_repay_coin) = mm.liquidate<BTC, USDC, BTC>(
632+
&registry,
633+
&btc_price_2200,
634+
&usdc_price,
635+
&mut btc_pool,
636+
&mut pool,
637+
repay_coin,
638+
&clock,
639+
scenario.ctx(),
640+
);
641+
642+
assert!(base_coin.value() == 20000000, 0); // 0.2 BTC
643+
assert!(quote_coin.value() == 399999930, 0); // ~400 USDC
644+
assert!(remaining_repay_coin.value() == 62545457, 0); // 0.62545457 BTC
645+
646+
destroy_3!(remaining_repay_coin, base_coin, quote_coin);
647+
return_shared_3!(mm, usdc_pool, pool);
648+
destroy_3!(btc_price, usdc_price, btc_price_2200);
649+
destroy(btc_pool);
650+
cleanup_margin_test(registry, admin_cap, maintainer_cap, clock, scenario);
651+
}
652+
539653
/// Test liquidation with BTC/SUI pair where both assets are volatile
540654
/// BTC: 8 decimals, SUI: 9 decimals
541655
fun test_btc_sui_liquidation(error_code: u64) {

0 commit comments

Comments
 (0)