Merge pull request #219 from blockworks-foundation/cj/max_settle_u64
Changed max_settle_amount to u64
This commit is contained in:
commit
451d8a8d22
|
@ -29,7 +29,7 @@ pub struct PerpSettleFees<'info> {
|
|||
pub quote_bank: AccountLoader<'info, Bank>,
|
||||
}
|
||||
|
||||
pub fn perp_settle_fees(ctx: Context<PerpSettleFees>, max_settle_amount: I80F48) -> Result<()> {
|
||||
pub fn perp_settle_fees(ctx: Context<PerpSettleFees>, max_settle_amount: u64) -> Result<()> {
|
||||
// max_settle_amount must greater than zero
|
||||
require!(
|
||||
max_settle_amount > 0,
|
||||
|
@ -71,7 +71,7 @@ pub fn perp_settle_fees(ctx: Context<PerpSettleFees>, max_settle_amount: I80F48)
|
|||
let settlement = pnl
|
||||
.abs()
|
||||
.min(perp_market.fees_accrued.abs())
|
||||
.min(max_settle_amount);
|
||||
.min(I80F48::from(max_settle_amount));
|
||||
perp_position.change_quote_position(settlement);
|
||||
perp_market.fees_accrued = cm!(perp_market.fees_accrued - settlement);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ pub struct PerpSettlePnl<'info> {
|
|||
pub quote_bank: AccountLoader<'info, Bank>,
|
||||
}
|
||||
|
||||
pub fn perp_settle_pnl(ctx: Context<PerpSettlePnl>, max_settle_amount: I80F48) -> Result<()> {
|
||||
pub fn perp_settle_pnl(ctx: Context<PerpSettlePnl>, max_settle_amount: u64) -> Result<()> {
|
||||
// Cannot settle with yourself
|
||||
require!(
|
||||
ctx.accounts.account_a.to_account_info().key
|
||||
|
@ -83,7 +83,10 @@ pub fn perp_settle_pnl(ctx: Context<PerpSettlePnl>, max_settle_amount: I80F48) -
|
|||
require!(b_pnl.is_negative(), MangoError::ProfitabilityMismatch);
|
||||
|
||||
// Settle for the maximum possible capped to max_settle_amount
|
||||
let settlement = a_pnl.abs().min(b_pnl.abs()).min(max_settle_amount);
|
||||
let settlement = a_pnl
|
||||
.abs()
|
||||
.min(b_pnl.abs())
|
||||
.min(I80F48::from(max_settle_amount));
|
||||
a_perp_position.change_quote_position(-settlement);
|
||||
b_perp_position.change_quote_position(settlement);
|
||||
|
||||
|
|
|
@ -499,11 +499,11 @@ pub mod mango_v4 {
|
|||
instructions::perp_update_funding(ctx)
|
||||
}
|
||||
|
||||
pub fn perp_settle_pnl(ctx: Context<PerpSettlePnl>, max_settle_amount: I80F48) -> Result<()> {
|
||||
pub fn perp_settle_pnl(ctx: Context<PerpSettlePnl>, max_settle_amount: u64) -> Result<()> {
|
||||
instructions::perp_settle_pnl(ctx, max_settle_amount)
|
||||
}
|
||||
|
||||
pub fn perp_settle_fees(ctx: Context<PerpSettleFees>, max_settle_amount: I80F48) -> Result<()> {
|
||||
pub fn perp_settle_fees(ctx: Context<PerpSettleFees>, max_settle_amount: u64) -> Result<()> {
|
||||
instructions::perp_settle_fees(ctx, max_settle_amount)
|
||||
}
|
||||
// TODO
|
||||
|
|
|
@ -2517,7 +2517,7 @@ pub struct PerpSettlePnlInstruction {
|
|||
pub perp_market: Pubkey,
|
||||
pub oracle: Pubkey,
|
||||
pub quote_bank: Pubkey,
|
||||
pub max_settle_amount: I80F48,
|
||||
pub max_settle_amount: u64,
|
||||
}
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ClientInstruction for PerpSettlePnlInstruction {
|
||||
|
@ -2571,7 +2571,7 @@ pub struct PerpSettleFeesInstruction {
|
|||
pub perp_market: Pubkey,
|
||||
pub oracle: Pubkey,
|
||||
pub quote_bank: Pubkey,
|
||||
pub max_settle_amount: I80F48,
|
||||
pub max_settle_amount: u64,
|
||||
}
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ClientInstruction for PerpSettleFeesInstruction {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#![cfg(all(feature = "test-bpf"))]
|
||||
|
||||
use anchor_lang::prelude::Pubkey;
|
||||
use fixed::types::I80F48;
|
||||
use fixed_macro::types::I80F48;
|
||||
use mango_v4::state::*;
|
||||
use program_test::*;
|
||||
|
@ -458,7 +457,7 @@ async fn test_perp() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await
|
||||
|
@ -471,7 +470,7 @@ async fn test_perp() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await
|
||||
|
|
|
@ -321,7 +321,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[1].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -342,7 +342,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[1].oracle, // Using oracle for token 1 not 0
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -363,7 +363,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -384,7 +384,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market: perp_market_2,
|
||||
oracle: tokens[1].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -396,27 +396,25 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
);
|
||||
|
||||
// max_settle_amount must be greater than zero
|
||||
for max_amnt in vec![I80F48::ZERO, I80F48::from(-100)] {
|
||||
let result = send_tx(
|
||||
solana,
|
||||
PerpSettlePnlInstruction {
|
||||
group,
|
||||
account_a: account_0,
|
||||
account_b: account_1,
|
||||
perp_market: perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: max_amnt,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
let result = send_tx(
|
||||
solana,
|
||||
PerpSettlePnlInstruction {
|
||||
group,
|
||||
account_a: account_0,
|
||||
account_b: account_1,
|
||||
perp_market: perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: 0,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_mango_error(
|
||||
&result,
|
||||
MangoError::MaxSettleAmountMustBeGreaterThanZero.into(),
|
||||
"max_settle_amount must be greater than zero".to_string(),
|
||||
);
|
||||
}
|
||||
assert_mango_error(
|
||||
&result,
|
||||
MangoError::MaxSettleAmountMustBeGreaterThanZero.into(),
|
||||
"max_settle_amount must be greater than zero".to_string(),
|
||||
);
|
||||
|
||||
// TODO: Test funding settlement
|
||||
|
||||
|
@ -460,7 +458,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -480,7 +478,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -523,7 +521,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
}
|
||||
|
||||
// Partially execute the settle
|
||||
let partial_settle_amount = I80F48::from(200);
|
||||
let partial_settle_amount = 200;
|
||||
send_tx(
|
||||
solana,
|
||||
PerpSettlePnlInstruction {
|
||||
|
@ -557,32 +555,33 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
|
||||
assert_eq!(
|
||||
mango_account_0.perps[0].quote_position_native().round(),
|
||||
I80F48::from(-100_020) - partial_settle_amount,
|
||||
I80F48::from(-100_020) - I80F48::from(partial_settle_amount),
|
||||
"quote position reduced for profitable position by max_settle_amount"
|
||||
);
|
||||
assert_eq!(
|
||||
mango_account_1.perps[0].quote_position_native().round(),
|
||||
I80F48::from(100_000) + partial_settle_amount,
|
||||
I80F48::from(100_000 + partial_settle_amount),
|
||||
"quote position increased for losing position by opposite of first account"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mango_account_0.tokens[0].native(&bank).round(),
|
||||
I80F48::from(initial_token_deposit) + partial_settle_amount,
|
||||
I80F48::from(initial_token_deposit + partial_settle_amount),
|
||||
"account 0 token native position increased (profit) by max_settle_amount"
|
||||
);
|
||||
assert_eq!(
|
||||
mango_account_1.tokens[0].native(&bank).round(),
|
||||
I80F48::from(initial_token_deposit) - partial_settle_amount,
|
||||
I80F48::from(initial_token_deposit) - I80F48::from(partial_settle_amount),
|
||||
"account 1 token native position decreased (loss) by max_settle_amount"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mango_account_0.net_settled, partial_settle_amount,
|
||||
mango_account_0.net_settled, partial_settle_amount as i64,
|
||||
"net_settled on account 0 updated with profit from settlement"
|
||||
);
|
||||
assert_eq!(
|
||||
mango_account_1.net_settled, -partial_settle_amount,
|
||||
mango_account_1.net_settled,
|
||||
-(partial_settle_amount as i64),
|
||||
"net_settled on account 1 updated with loss from settlement"
|
||||
);
|
||||
}
|
||||
|
@ -597,7 +596,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await
|
||||
|
@ -692,7 +691,7 @@ async fn test_perp_settle_pnl() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await
|
||||
|
|
|
@ -318,7 +318,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[1].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -338,7 +338,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[1].oracle, // Using oracle for token 1 not 0
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -358,7 +358,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
perp_market: perp_market_2,
|
||||
oracle: tokens[1].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -370,26 +370,24 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
);
|
||||
|
||||
// max_settle_amount must be greater than zero
|
||||
for max_amnt in vec![I80F48::ZERO, I80F48::from(-100)] {
|
||||
let result = send_tx(
|
||||
solana,
|
||||
PerpSettleFeesInstruction {
|
||||
group,
|
||||
account: account_1,
|
||||
perp_market: perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: max_amnt,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
let result = send_tx(
|
||||
solana,
|
||||
PerpSettleFeesInstruction {
|
||||
group,
|
||||
account: account_1,
|
||||
perp_market: perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: 0,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_mango_error(
|
||||
&result,
|
||||
MangoError::MaxSettleAmountMustBeGreaterThanZero.into(),
|
||||
"max_settle_amount must be greater than zero".to_string(),
|
||||
);
|
||||
}
|
||||
assert_mango_error(
|
||||
&result,
|
||||
MangoError::MaxSettleAmountMustBeGreaterThanZero.into(),
|
||||
"max_settle_amount must be greater than zero".to_string(),
|
||||
);
|
||||
|
||||
// TODO: Test funding settlement
|
||||
|
||||
|
@ -430,7 +428,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -507,7 +505,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
}
|
||||
|
||||
// Partially execute the settle
|
||||
let partial_settle_amount = I80F48::from(10);
|
||||
let partial_settle_amount = 10;
|
||||
send_tx(
|
||||
solana,
|
||||
PerpSettleFeesInstruction {
|
||||
|
@ -535,24 +533,25 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
|
||||
assert_eq!(
|
||||
mango_account_1.perps[0].quote_position_native().round(),
|
||||
I80F48::from(100_000) + partial_settle_amount,
|
||||
I80F48::from(100_000 + partial_settle_amount),
|
||||
"quote position increased for losing position by fee settle amount"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mango_account_1.tokens[0].native(&bank).round(),
|
||||
I80F48::from(initial_token_deposit) - partial_settle_amount,
|
||||
I80F48::from(initial_token_deposit - partial_settle_amount),
|
||||
"account 1 token native position decreased (loss) by max_settle_amount"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
mango_account_1.net_settled, -partial_settle_amount,
|
||||
mango_account_1.net_settled,
|
||||
-(partial_settle_amount as i64),
|
||||
"net_settled on account 1 updated with loss from settlement"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
perp_market.fees_accrued.round(),
|
||||
initial_fees - partial_settle_amount,
|
||||
initial_fees - I80F48::from(partial_settle_amount),
|
||||
"Fees accrued have been reduced by partial settle"
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -571,7 +570,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
perp_market,
|
||||
oracle: tokens[0].oracle,
|
||||
quote_bank: tokens[0].bank,
|
||||
max_settle_amount: I80F48::MAX,
|
||||
max_settle_amount: u64::MAX,
|
||||
},
|
||||
)
|
||||
.await
|
||||
|
|
Loading…
Reference in New Issue