parent
4fcaf09c09
commit
b3b4cc8223
|
@ -1790,6 +1790,36 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "healthCheck",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"relations": [
|
||||
"group"
|
||||
]
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "minHealthValue",
|
||||
"type": "f64"
|
||||
},
|
||||
{
|
||||
"name": "checkKind",
|
||||
"type": {
|
||||
"defined": "HealthCheckKind"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stubOracleCreate",
|
||||
"accounts": [
|
||||
|
@ -10674,6 +10704,32 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HealthCheckKind",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"variants": [
|
||||
{
|
||||
"name": "Maint"
|
||||
},
|
||||
{
|
||||
"name": "Init"
|
||||
},
|
||||
{
|
||||
"name": "LiquidationEnd"
|
||||
},
|
||||
{
|
||||
"name": "MaintRatio"
|
||||
},
|
||||
{
|
||||
"name": "InitRatio"
|
||||
},
|
||||
{
|
||||
"name": "LiquidationEndRatio"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Serum3SelfTradeBehavior",
|
||||
"docs": [
|
||||
|
@ -11031,6 +11087,9 @@
|
|||
},
|
||||
{
|
||||
"name": "SequenceCheck"
|
||||
},
|
||||
{
|
||||
"name": "HealthCheck"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -14383,6 +14442,11 @@
|
|||
"code": 6071,
|
||||
"name": "InvalidSequenceNumber",
|
||||
"msg": "invalid sequence number"
|
||||
},
|
||||
{
|
||||
"code": 6072,
|
||||
"name": "InvalidHealth",
|
||||
"msg": "invalid health"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
use crate::error::*;
|
||||
use crate::state::*;
|
||||
use anchor_lang::prelude::*;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
|
||||
#[derive(Clone, Copy, TryFromPrimitive, IntoPrimitive, AnchorSerialize, AnchorDeserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum HealthCheckKind {
|
||||
Maint = 0b0000,
|
||||
Init = 0b0010,
|
||||
LiquidationEnd = 0b0100,
|
||||
MaintRatio = 0b0001,
|
||||
InitRatio = 0b0011,
|
||||
LiquidationEndRatio = 0b0101,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct HealthCheck<'info> {
|
||||
#[account(
|
||||
constraint = group.load()?.is_ix_enabled(IxGate::SequenceCheck) @ MangoError::IxIsDisabled,
|
||||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
constraint = account.load()?.is_operational() @ MangoError::AccountIsFrozen
|
||||
)]
|
||||
pub account: AccountLoader<'info, MangoAccountFixed>,
|
||||
}
|
|
@ -16,6 +16,7 @@ pub use group_close::*;
|
|||
pub use group_create::*;
|
||||
pub use group_edit::*;
|
||||
pub use group_withdraw_insurance_fund::*;
|
||||
pub use health_check::*;
|
||||
pub use health_region::*;
|
||||
pub use ix_gate_set::*;
|
||||
pub use openbook_v2_cancel_order::*;
|
||||
|
@ -95,6 +96,7 @@ mod group_close;
|
|||
mod group_create;
|
||||
mod group_edit;
|
||||
mod group_withdraw_insurance_fund;
|
||||
mod health_check;
|
||||
mod health_region;
|
||||
mod ix_gate_set;
|
||||
mod openbook_v2_cancel_order;
|
||||
|
|
|
@ -149,6 +149,8 @@ pub enum MangoError {
|
|||
BorrowsRequireHealthAccountBank,
|
||||
#[msg("invalid sequence number")]
|
||||
InvalidSequenceNumber,
|
||||
#[msg("invalid health")]
|
||||
InvalidHealth,
|
||||
}
|
||||
|
||||
impl MangoError {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use fixed::types::I80F48;
|
||||
|
||||
use crate::accounts_ix::*;
|
||||
use crate::error::{Contextable, MangoError};
|
||||
use crate::health::{
|
||||
new_fixed_order_account_retriever_with_optional_banks,
|
||||
new_health_cache_skipping_missing_banks_and_bad_oracles, HealthType,
|
||||
};
|
||||
use crate::state::*;
|
||||
use crate::util::clock_now;
|
||||
|
||||
pub fn health_check(
|
||||
ctx: Context<HealthCheck>,
|
||||
min_value: f64,
|
||||
health_check_kind: HealthCheckKind,
|
||||
) -> Result<()> {
|
||||
let account = ctx.accounts.account.load_full_mut()?;
|
||||
let (now_ts, now_slot) = clock_now();
|
||||
|
||||
let retriever = new_fixed_order_account_retriever_with_optional_banks(
|
||||
ctx.remaining_accounts,
|
||||
&account.borrow(),
|
||||
now_slot,
|
||||
)?;
|
||||
let health_cache = new_health_cache_skipping_missing_banks_and_bad_oracles(
|
||||
&account.borrow(),
|
||||
&retriever,
|
||||
now_ts,
|
||||
)
|
||||
.context("health_check health cache")?;
|
||||
|
||||
let min_value = I80F48::from_num(min_value);
|
||||
let actual_value = match health_check_kind {
|
||||
HealthCheckKind::Maint => health_cache.health(HealthType::Maint),
|
||||
HealthCheckKind::Init => health_cache.health(HealthType::Init),
|
||||
HealthCheckKind::LiquidationEnd => health_cache.health(HealthType::LiquidationEnd),
|
||||
HealthCheckKind::MaintRatio => health_cache.health_ratio(HealthType::Maint),
|
||||
HealthCheckKind::InitRatio => health_cache.health_ratio(HealthType::Init),
|
||||
HealthCheckKind::LiquidationEndRatio => {
|
||||
health_cache.health_ratio(HealthType::LiquidationEnd)
|
||||
}
|
||||
};
|
||||
|
||||
// msg!("{}", actual_value);
|
||||
require_gte!(actual_value, min_value, MangoError::InvalidHealth);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -97,6 +97,7 @@ pub fn ix_gate_set(ctx: Context<IxGateSet>, ix_gate: u128) -> Result<()> {
|
|||
log_if_changed(&group, ix_gate, IxGate::Serum3PlaceOrderV2);
|
||||
log_if_changed(&group, ix_gate, IxGate::TokenForceWithdraw);
|
||||
log_if_changed(&group, ix_gate, IxGate::SequenceCheck);
|
||||
log_if_changed(&group, ix_gate, IxGate::HealthCheck);
|
||||
|
||||
group.ix_gate = ix_gate;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ pub use group_close::*;
|
|||
pub use group_create::*;
|
||||
pub use group_edit::*;
|
||||
pub use group_withdraw_insurance_fund::*;
|
||||
pub use health_check::*;
|
||||
pub use health_region::*;
|
||||
pub use ix_gate_set::*;
|
||||
pub use perp_cancel_all_orders::*;
|
||||
|
@ -86,6 +87,7 @@ mod group_close;
|
|||
mod group_create;
|
||||
mod group_edit;
|
||||
mod group_withdraw_insurance_fund;
|
||||
mod health_check;
|
||||
mod health_region;
|
||||
mod ix_gate_set;
|
||||
mod perp_cancel_all_orders;
|
||||
|
|
|
@ -464,6 +464,16 @@ pub mod mango_v4 {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn health_check(
|
||||
ctx: Context<HealthCheck>,
|
||||
min_health_value: f64,
|
||||
check_kind: HealthCheckKind,
|
||||
) -> Result<()> {
|
||||
#[cfg(feature = "enable-gpl")]
|
||||
instructions::health_check(ctx, min_health_value, check_kind)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// todo:
|
||||
// ckamm: generally, using an I80F48 arg will make it harder to call
|
||||
// because generic anchor clients won't know how to deal with it
|
||||
|
|
|
@ -247,6 +247,7 @@ pub enum IxGate {
|
|||
Serum3PlaceOrderV2 = 71,
|
||||
TokenForceWithdraw = 72,
|
||||
SequenceCheck = 73,
|
||||
HealthCheck = 74,
|
||||
// NOTE: Adding new variants requires matching changes in ts and the ix_gate_set instruction.
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ mod test_collateral_fees;
|
|||
mod test_delegate;
|
||||
mod test_fees_buyback_with_mngo;
|
||||
mod test_force_close;
|
||||
mod test_health_check;
|
||||
mod test_health_compute;
|
||||
mod test_health_region;
|
||||
mod test_ix_gate_set;
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
use crate::cases::{
|
||||
create_funded_account, mango_setup, send_tx, tokio, HealthAccountSkipping,
|
||||
HealthCheckInstruction, TestContext, TestKeypair, TokenWithdrawInstruction,
|
||||
};
|
||||
use crate::send_tx_expect_error;
|
||||
use mango_v4::accounts_ix::{HealthCheck, HealthCheckKind};
|
||||
use mango_v4::error::MangoError;
|
||||
use solana_sdk::transport::TransportError;
|
||||
|
||||
// TODO FAS
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_health_check() -> Result<(), TransportError> {
|
||||
let context = TestContext::new().await;
|
||||
let solana = &context.solana.clone();
|
||||
|
||||
let admin = TestKeypair::new();
|
||||
let owner = context.users[0].key;
|
||||
let payer = context.users[1].key;
|
||||
let payer_token_accounts = &context.users[1].token_accounts;
|
||||
let mints = &context.mints[0..3];
|
||||
|
||||
let mango_setup::GroupWithTokens { group, tokens, .. } = mango_setup::GroupWithTokensConfig {
|
||||
admin,
|
||||
payer,
|
||||
mints: mints.to_vec(),
|
||||
zero_token_is_quote: true,
|
||||
..mango_setup::GroupWithTokensConfig::default()
|
||||
}
|
||||
.create(solana)
|
||||
.await;
|
||||
|
||||
// Funding to fill the vaults
|
||||
create_funded_account(
|
||||
&solana,
|
||||
group,
|
||||
owner,
|
||||
0,
|
||||
&context.users[1],
|
||||
&mints,
|
||||
1_000_000,
|
||||
0,
|
||||
)
|
||||
.await;
|
||||
|
||||
let account = create_funded_account(
|
||||
&solana,
|
||||
group,
|
||||
owner,
|
||||
1,
|
||||
&context.users[1],
|
||||
&mints[0..2],
|
||||
1000,
|
||||
0,
|
||||
)
|
||||
.await;
|
||||
|
||||
send_tx(
|
||||
solana,
|
||||
TokenWithdrawInstruction {
|
||||
amount: 775,
|
||||
allow_borrow: true,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_token_accounts[2],
|
||||
bank_index: 0,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
//
|
||||
// TEST (Health is about 93% with all banks, 7% without banks 1)
|
||||
//
|
||||
|
||||
send_tx(
|
||||
solana,
|
||||
HealthCheckInstruction {
|
||||
account,
|
||||
owner,
|
||||
min_health_value: 20.0,
|
||||
check_kind: HealthCheckKind::MaintRatio,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
send_tx(
|
||||
solana,
|
||||
HealthCheckInstruction {
|
||||
account,
|
||||
owner,
|
||||
min_health_value: 500.0,
|
||||
check_kind: HealthCheckKind::Init,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
send_tx_expect_error!(
|
||||
solana,
|
||||
HealthCheckInstruction {
|
||||
owner,
|
||||
account,
|
||||
min_health_value: 600.0,
|
||||
check_kind: HealthCheckKind::Init,
|
||||
},
|
||||
MangoError::InvalidHealth
|
||||
);
|
||||
|
||||
send_tx(
|
||||
solana,
|
||||
HealthCheckInstruction {
|
||||
account,
|
||||
owner,
|
||||
min_health_value: 800.0,
|
||||
check_kind: HealthCheckKind::Maint,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
send_tx_expect_error!(
|
||||
solana,
|
||||
HealthCheckInstruction {
|
||||
owner,
|
||||
account,
|
||||
min_health_value: 100.0,
|
||||
check_kind: HealthCheckKind::MaintRatio,
|
||||
},
|
||||
MangoError::InvalidHealth
|
||||
);
|
||||
|
||||
send_tx(
|
||||
solana,
|
||||
HealthAccountSkipping {
|
||||
inner: HealthCheckInstruction {
|
||||
owner,
|
||||
account,
|
||||
min_health_value: 5.0,
|
||||
check_kind: HealthCheckKind::MaintRatio,
|
||||
},
|
||||
skip_banks: vec![tokens[1].bank],
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
send_tx_expect_error!(
|
||||
solana,
|
||||
HealthAccountSkipping {
|
||||
inner: HealthCheckInstruction {
|
||||
owner,
|
||||
account,
|
||||
min_health_value: 10.0,
|
||||
check_kind: HealthCheckKind::MaintRatio,
|
||||
},
|
||||
skip_banks: vec![tokens[1].bank],
|
||||
},
|
||||
MangoError::InvalidHealth
|
||||
);
|
||||
|
||||
send_tx_expect_error!(
|
||||
solana,
|
||||
HealthAccountSkipping {
|
||||
inner: HealthCheckInstruction {
|
||||
owner,
|
||||
account,
|
||||
min_health_value: 10.0,
|
||||
check_kind: HealthCheckKind::MaintRatio,
|
||||
},
|
||||
skip_banks: vec![tokens[2].bank],
|
||||
},
|
||||
MangoError::InvalidBank
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -7,7 +7,7 @@ use anchor_spl::token::{Token, TokenAccount};
|
|||
use fixed::types::I80F48;
|
||||
use itertools::Itertools;
|
||||
use mango_v4::accounts_ix::{
|
||||
InterestRateParams, Serum3OrderType, Serum3SelfTradeBehavior, Serum3Side,
|
||||
HealthCheckKind, InterestRateParams, Serum3OrderType, Serum3SelfTradeBehavior, Serum3Side,
|
||||
};
|
||||
use mango_v4::state::{MangoAccount, MangoAccountValue};
|
||||
use solana_program::instruction::Instruction;
|
||||
|
@ -5208,3 +5208,52 @@ impl ClientInstruction for SequenceCheckInstruction {
|
|||
vec![self.owner]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HealthCheckInstruction {
|
||||
pub account: Pubkey,
|
||||
pub owner: TestKeypair,
|
||||
pub min_health_value: f64,
|
||||
pub check_kind: HealthCheckKind,
|
||||
}
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ClientInstruction for HealthCheckInstruction {
|
||||
type Accounts = mango_v4::accounts::HealthCheck;
|
||||
type Instruction = mango_v4::instruction::HealthCheck;
|
||||
async fn to_instruction(
|
||||
&self,
|
||||
account_loader: &(impl ClientAccountLoader + 'async_trait),
|
||||
) -> (Self::Accounts, instruction::Instruction) {
|
||||
let program_id = mango_v4::id();
|
||||
let instruction = Self::Instruction {
|
||||
min_health_value: self.min_health_value,
|
||||
check_kind: self.check_kind,
|
||||
};
|
||||
|
||||
let account = account_loader
|
||||
.load_mango_account(&self.account)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let accounts = Self::Accounts {
|
||||
group: account.fixed.group,
|
||||
account: self.account,
|
||||
};
|
||||
|
||||
let health_check_metas = derive_health_check_remaining_account_metas(
|
||||
account_loader,
|
||||
&account,
|
||||
None,
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut instruction = make_instruction(program_id, &accounts, &instruction);
|
||||
instruction.accounts.extend(health_check_metas.into_iter());
|
||||
(accounts, instruction)
|
||||
}
|
||||
|
||||
fn signers(&self) -> Vec<TestKeypair> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ import {
|
|||
import { Id } from './ids';
|
||||
import { IDL, MangoV4 } from './mango_v4';
|
||||
import { I80F48 } from './numbers/I80F48';
|
||||
import { FlashLoanType, OracleConfigParams } from './types';
|
||||
import { FlashLoanType, HealthCheckKind, OracleConfigParams } from './types';
|
||||
import {
|
||||
I64_MAX_BN,
|
||||
U64_MAX_BN,
|
||||
|
@ -1048,6 +1048,30 @@ export class MangoClient {
|
|||
.instruction();
|
||||
}
|
||||
|
||||
public async healthCheckIx(
|
||||
group: Group,
|
||||
mangoAccount: MangoAccount,
|
||||
minHealthValue: number,
|
||||
checkKind: HealthCheckKind,
|
||||
): Promise<TransactionInstruction> {
|
||||
const healthRemainingAccounts: PublicKey[] =
|
||||
this.buildHealthRemainingAccounts(group, [mangoAccount], [], [], []);
|
||||
|
||||
return await this.program.methods
|
||||
.healthCheck(minHealthValue, checkKind)
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
account: mangoAccount.publicKey,
|
||||
})
|
||||
.remainingAccounts(
|
||||
healthRemainingAccounts.map(
|
||||
(pk) =>
|
||||
({ pubkey: pk, isWritable: false, isSigner: false } as AccountMeta),
|
||||
),
|
||||
)
|
||||
.instruction();
|
||||
}
|
||||
|
||||
public async getMangoAccount(
|
||||
mangoAccountPk: PublicKey,
|
||||
loadSerum3Oo = false,
|
||||
|
|
|
@ -1790,6 +1790,36 @@ export type MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "healthCheck",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"relations": [
|
||||
"group"
|
||||
]
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "minHealthValue",
|
||||
"type": "f64"
|
||||
},
|
||||
{
|
||||
"name": "checkKind",
|
||||
"type": {
|
||||
"defined": "HealthCheckKind"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stubOracleCreate",
|
||||
"accounts": [
|
||||
|
@ -10674,6 +10704,32 @@ export type MangoV4 = {
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HealthCheckKind",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"variants": [
|
||||
{
|
||||
"name": "Maint"
|
||||
},
|
||||
{
|
||||
"name": "Init"
|
||||
},
|
||||
{
|
||||
"name": "LiquidationEnd"
|
||||
},
|
||||
{
|
||||
"name": "MaintRatio"
|
||||
},
|
||||
{
|
||||
"name": "InitRatio"
|
||||
},
|
||||
{
|
||||
"name": "LiquidationEndRatio"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Serum3SelfTradeBehavior",
|
||||
"docs": [
|
||||
|
@ -11031,6 +11087,9 @@ export type MangoV4 = {
|
|||
},
|
||||
{
|
||||
"name": "SequenceCheck"
|
||||
},
|
||||
{
|
||||
"name": "HealthCheck"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -14383,6 +14442,11 @@ export type MangoV4 = {
|
|||
"code": 6071,
|
||||
"name": "InvalidSequenceNumber",
|
||||
"msg": "invalid sequence number"
|
||||
},
|
||||
{
|
||||
"code": 6072,
|
||||
"name": "InvalidHealth",
|
||||
"msg": "invalid health"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -16179,6 +16243,36 @@ export const IDL: MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "healthCheck",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"relations": [
|
||||
"group"
|
||||
]
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "minHealthValue",
|
||||
"type": "f64"
|
||||
},
|
||||
{
|
||||
"name": "checkKind",
|
||||
"type": {
|
||||
"defined": "HealthCheckKind"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stubOracleCreate",
|
||||
"accounts": [
|
||||
|
@ -25063,6 +25157,32 @@ export const IDL: MangoV4 = {
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HealthCheckKind",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"variants": [
|
||||
{
|
||||
"name": "Maint"
|
||||
},
|
||||
{
|
||||
"name": "Init"
|
||||
},
|
||||
{
|
||||
"name": "LiquidationEnd"
|
||||
},
|
||||
{
|
||||
"name": "MaintRatio"
|
||||
},
|
||||
{
|
||||
"name": "InitRatio"
|
||||
},
|
||||
{
|
||||
"name": "LiquidationEndRatio"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Serum3SelfTradeBehavior",
|
||||
"docs": [
|
||||
|
@ -25420,6 +25540,9 @@ export const IDL: MangoV4 = {
|
|||
},
|
||||
{
|
||||
"name": "SequenceCheck"
|
||||
},
|
||||
{
|
||||
"name": "HealthCheck"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -28772,6 +28895,11 @@ export const IDL: MangoV4 = {
|
|||
"code": 6071,
|
||||
"name": "InvalidSequenceNumber",
|
||||
"msg": "invalid sequence number"
|
||||
},
|
||||
{
|
||||
"code": 6072,
|
||||
"name": "InvalidHealth",
|
||||
"msg": "invalid health"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -18,6 +18,23 @@ export namespace FlashLoanType {
|
|||
export const swapWithoutFee = { swapWithoutFee: {} };
|
||||
}
|
||||
|
||||
export type HealthCheckKind =
|
||||
| { maint: Record<string, never> }
|
||||
| { init: Record<string, never> }
|
||||
| { liquidationEnd: Record<string, never> }
|
||||
| { maintRatio: Record<string, never> }
|
||||
| { initRatio: Record<string, never> }
|
||||
| { liquidationEndRatio: Record<string, never> };
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace HealthCheckKind {
|
||||
export const maint = { maint: {} };
|
||||
export const init = { init: {} };
|
||||
export const liquidationEnd = { liquidationEnd: {} };
|
||||
export const maintRatio = { maintRatio: {} };
|
||||
export const initRatio = { initRatio: {} };
|
||||
export const liquidationEndRatio = { liquidationEndRatio: {} };
|
||||
}
|
||||
|
||||
export class InterestRateParams {
|
||||
util0: number;
|
||||
rate0: number;
|
||||
|
|
Loading…
Reference in New Issue