Merge branch 'dev' into feature/close-mango-account
This commit is contained in:
commit
3077f57c2f
|
@ -11,7 +11,6 @@ jobs:
|
|||
format:
|
||||
name: Format
|
||||
runs-on: ubuntu-latest
|
||||
if: (github.actor != 'dependabot[bot]')
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
@ -31,7 +30,6 @@ jobs:
|
|||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
if: (github.actor != 'dependabot[bot]')
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
@ -51,7 +49,6 @@ jobs:
|
|||
unit-test:
|
||||
name: Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
if: (github.actor != 'dependabot[bot]')
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
@ -71,7 +68,6 @@ jobs:
|
|||
semgrep:
|
||||
name: Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: (github.actor != 'dependabot[bot]')
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
|
||||
|
@ -80,6 +76,12 @@ jobs:
|
|||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run semgrep
|
||||
run: semgrep ci
|
||||
run: semgrep ci --sarif --output=semgrep-results.sarif
|
||||
env:
|
||||
SEMGREP_RULES: p/typescript
|
||||
|
||||
- name: Upload output
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: semgrep-results.sarif
|
||||
|
|
|
@ -25,12 +25,11 @@ jobs:
|
|||
trivy:
|
||||
name: Dependency Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: (github.actor != 'dependabot[bot]')
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Report all vulnerabilities in CI output
|
||||
# Report all vulnerabilities in security tab
|
||||
- name: Report on all vulnerabilities
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
|
@ -38,7 +37,8 @@ jobs:
|
|||
scan-ref: 'Cargo.lock'
|
||||
ignore-unfixed: true
|
||||
hide-progress: true
|
||||
format: 'table'
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
|
||||
# Fail the job on critical vulnerabiliies with fix available
|
||||
- name: Fail on critical vulnerabilities
|
||||
|
@ -51,3 +51,9 @@ jobs:
|
|||
format: 'table'
|
||||
severity: 'CRITICAL'
|
||||
exit-code: '1'
|
||||
|
||||
- name: Upload output
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
|
@ -11,12 +11,11 @@ jobs:
|
|||
trivy:
|
||||
name: Dependency Scan
|
||||
runs-on: ubuntu-latest
|
||||
if: (github.actor != 'dependabot[bot]')
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Report all vulnerabilities in CI output
|
||||
# Report all vulnerabilities in security tab
|
||||
- name: Report on all vulnerabilities
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
|
@ -24,7 +23,8 @@ jobs:
|
|||
scan-ref: 'yarn.lock'
|
||||
ignore-unfixed: true
|
||||
hide-progress: true
|
||||
format: 'table'
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
|
||||
# Fail the job on critical vulnerabiliies with fix available
|
||||
- name: Fail on critical vulnerabilities
|
||||
|
@ -37,3 +37,9 @@ jobs:
|
|||
format: 'table'
|
||||
severity: 'CRITICAL'
|
||||
exit-code: '1'
|
||||
|
||||
- name: Upload output
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
37
CHANGELOG.md
37
CHANGELOG.md
|
@ -1,42 +1,55 @@
|
|||
# Mango v4 Program Change Log
|
||||
|
||||
Update this for each mainnet deployment.
|
||||
Update this for each program release and mainnet deployment.
|
||||
|
||||
## not on mainnet
|
||||
|
||||
## mainnet
|
||||
|
||||
Jan 5, 2023 Central European Standard Time
|
||||
### v0.2.0, 2023-1-13
|
||||
|
||||
Deployment: Jan 13, 2023 at 11:31:05 Central European Standard Time, https://explorer.solana.com/tx/4yGRUk6QwntvC4umECDPDZJNcbevSJ1fdZi75Mz9rGa9SHKzUtjMF3V5FCTkzBZqAETQTccqv63BYw6yX8JNxiur
|
||||
|
||||
- Add an optional security authority with the ability to halt a group or
|
||||
temporarily freeze user accounts.
|
||||
- Extend perp pnl settle limits to apply to realized pnl
|
||||
- Rename perp_liq_bankruptcy to perp_liq_quote_and_bankruptcy and extend it to
|
||||
cover taking over the liqee's negative pnl while the settle limits and perp
|
||||
settle health allow it.
|
||||
- Perp bankruptcy is now allowed when settling is impossible, even when there are
|
||||
spot assets remaining.
|
||||
|
||||
### Jan 5, 2023 Central European Standard Time
|
||||
|
||||
- Change max staleness slots from -1 to 600 for trustless token registering
|
||||
|
||||
Jan 4, 2023 Central European Standard Time
|
||||
### Jan 4, 2023 Central European Standard Time
|
||||
|
||||
- Reduce only mode for tokens, and perp markets
|
||||
- Perp settlement applies no loan origination fee
|
||||
|
||||
Dec 16, 2022 at 16:40 Central European Standard Time
|
||||
### Dec 16, 2022 at 16:40 Central European Standard Time
|
||||
|
||||
Oct 8, 2022 at 14:38:31 Central European Summer Time
|
||||
### Oct 8, 2022 at 14:38:31 Central European Summer Time
|
||||
https://explorer.solana.com/tx/3m8EDohkgwJZyiwpGXztBWARWQVxyhnSNDVuH467D7FPS2wxJerr79HhdhDEed5hpConHgGsKHvxtW1HJP6GixX9
|
||||
|
||||
Oct 8, 2022 at 14:38:31 Central European Summer Time
|
||||
### Oct 8, 2022 at 14:38:31 Central European Summer Time
|
||||
https://explorer.solana.com/tx/3m8EDohkgwJZyiwpGXztBWARWQVxyhnSNDVuH467D7FPS2wxJerr79HhdhDEed5hpConHgGsKHvxtW1HJP6GixX9
|
||||
|
||||
- New ix `TokenDepositIntoExisting`
|
||||
|
||||
Sep 1, 2022 at 10:24:35 Central European Summer Time
|
||||
### Sep 1, 2022 at 10:24:35 Central European Summer Time
|
||||
https://explorer.solana.com/tx/3NnX13A3QwsREKKKo3iYR4jqgoongpCjdhhXuJ3y5iP6FwfPcNieVop623tpgPbyreC7m7KtphwdWdoHYE5YC394
|
||||
|
||||
- Add HealthRegionBegin, -End instructions
|
||||
- Add explicit "oracle" account argument for TokenDeposit and TokenWithdraw instructions
|
||||
|
||||
Aug 20, 2022 at 19:58:29 Central European Summer Time
|
||||
### Aug 20, 2022 at 19:58:29 Central European Summer Time
|
||||
https://explorer.solana.com/tx/3R4frko1AekQKJmmQ5T6k3mdXF9uZVHTR7oocdspTPsc82xX7qrbgnG61r28UdhCxsjMxtQHgBqMc37FSvoHQfCN
|
||||
|
||||
- loan fee logging for off-chain services
|
||||
|
||||
Aug 18, 2022 at 17:17:40 Central European Summer Time
|
||||
### Aug 18, 2022 at 17:17:40 Central European Summer Time
|
||||
https://explorer.solana.com/tx/4Xnyswcwx98y6khw8ptNVmdhQZwJjuNy2BvmQg2pJayoThFiw8kmS2ecRAg5cg2DncvW3NQgn2vtP8mCUtv6Q1yB
|
||||
|
||||
- liq_token_bankruptcy: removed liab_token_index argument
|
||||
|
@ -82,13 +95,13 @@ https://explorer.solana.com/tx/4Xnyswcwx98y6khw8ptNVmdhQZwJjuNy2BvmQg2pJayoThFiw
|
|||
marginTrade takes inputMintPk and outputMintPk instead of inputToken and outputToken
|
||||
marginTrade takes flashLoanType as an argument
|
||||
|
||||
Aug 8, 2022 at 18:56:04 Central European Summer Time
|
||||
### Aug 8, 2022 at 18:56:04 Central European Summer Time
|
||||
https://explorer.solana.com/tx/yjZggRTrcDNquMkftNvBKLv77Dk4xp5yQPYXgN3qvBHTBWWJVhLPGHxqpGwosmEq3j8byHZMa13oxLLerBWUdgW
|
||||
|
||||
- improved logging for off chain services
|
||||
- `AccountCreate` ix takes explicit input for sizes of various features
|
||||
|
||||
Aug 4, 2022 at 09:30:00 Central European Summer Time
|
||||
### Aug 4, 2022 at 09:30:00 Central European Summer Time
|
||||
|
||||
ts/client changes
|
||||
|
||||
|
@ -114,7 +127,7 @@ New features
|
|||
- `TokenRegistration` and `TokenRegisterTrustless` ixs dont take a bank_num anymore, hardcoded to 0.
|
||||
- Enforced a minimum maximum rate of 50% so that rates don't fall so low that they cannot recover.
|
||||
|
||||
Jul 14, 2022 at 09:33:52 Central European Summer Time
|
||||
### Jul 14, 2022 at 09:33:52 Central European Summer Time
|
||||
https://explorer.solana.com/tx/vZ5hP1vGp37fgzBfG9nb4nfA5ZdmYgk8meq53YPR4ReFxrcTwBUxTYBQUgnfAnq9u5fH36S3QTfb9mVkBXt5A6C
|
||||
|
||||
- Account data was rearranged to put fields that are often used with gPA first
|
||||
|
|
|
@ -1094,7 +1094,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anchor-client",
|
||||
"anchor-lang",
|
||||
|
@ -1118,7 +1118,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "client"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anchor-client",
|
||||
"anchor-lang",
|
||||
|
@ -2846,7 +2846,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "keeper"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anchor-client",
|
||||
"anchor-lang",
|
||||
|
@ -3121,7 +3121,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mango-v4"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anchor-lang",
|
||||
"anchor-spl",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "client"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "keeper"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "mango-v4"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
description = "Created with Anchor"
|
||||
edition = "2021"
|
||||
|
||||
|
|
|
@ -537,21 +537,6 @@ impl HealthCache {
|
|||
self.has_spot_borrows() || perp_borrows
|
||||
}
|
||||
|
||||
pub fn has_liquidatable_spot_or_perp_base(&self) -> bool {
|
||||
let spot_liquidatable = self.has_spot_assets();
|
||||
let serum3_cancelable = self.has_serum3_open_orders_funds();
|
||||
let perp_liquidatable = self.perp_infos.iter().any(|p| {
|
||||
// can use perp_liq_base_position
|
||||
p.base_lots != 0
|
||||
// can use perp_liq_force_cancel_orders
|
||||
|| p.has_open_orders
|
||||
// A remaining quote position can be reduced with perp_settle_pnl and that can improve health.
|
||||
// However, since it's not guaranteed that there is a counterparty, a positive perp quote position
|
||||
// does not prevent bankruptcy.
|
||||
});
|
||||
spot_liquidatable || serum3_cancelable || perp_liquidatable
|
||||
}
|
||||
|
||||
pub(crate) fn compute_serum3_reservations(
|
||||
&self,
|
||||
health_type: HealthType,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use fixed::types::I80F48;
|
||||
|
||||
pub trait ClampedToNum {
|
||||
pub trait ClampToInt {
|
||||
fn clamp_to_i64(&self) -> i64;
|
||||
fn clamp_to_u64(&self) -> u64;
|
||||
}
|
||||
|
||||
impl ClampedToNum for I80F48 {
|
||||
impl ClampToInt for I80F48 {
|
||||
fn clamp_to_i64(&self) -> i64 {
|
||||
if *self <= i64::MIN {
|
||||
i64::MIN
|
||||
|
@ -27,7 +27,7 @@ impl ClampedToNum for I80F48 {
|
|||
}
|
||||
}
|
||||
|
||||
impl ClampedToNum for f64 {
|
||||
impl ClampToInt for f64 {
|
||||
fn clamp_to_i64(&self) -> i64 {
|
||||
if *self <= i64::MIN as f64 {
|
||||
i64::MIN
|
||||
|
@ -49,7 +49,7 @@ impl ClampedToNum for f64 {
|
|||
}
|
||||
}
|
||||
|
||||
impl ClampedToNum for u64 {
|
||||
impl ClampToInt for u64 {
|
||||
fn clamp_to_i64(&self) -> i64 {
|
||||
if *self >= i64::MAX as u64 {
|
||||
i64::MAX
|
||||
|
|
|
@ -71,24 +71,8 @@ pub fn perp_liq_base_position(
|
|||
let liqee_init_health = liqee_health_cache.health(HealthType::Init);
|
||||
liqee_health_cache.require_after_phase1_liquidation()?;
|
||||
|
||||
// Once maint_health falls below 0, we want to start liquidating,
|
||||
// we want to allow liquidation to continue until init_health is positive,
|
||||
// to prevent constant oscillation between the two states
|
||||
if liqee.being_liquidated() {
|
||||
if liqee
|
||||
.fixed
|
||||
.maybe_recover_from_being_liquidated(liqee_init_health)
|
||||
{
|
||||
msg!("Liqee init_health above zero");
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
let maint_health = liqee_health_cache.health(HealthType::Maint);
|
||||
require!(
|
||||
maint_health < I80F48::ZERO,
|
||||
MangoError::HealthMustBeNegative
|
||||
);
|
||||
liqee.fixed.set_being_liquidated(true);
|
||||
if !liqee.check_liquidatable(&liqee_health_cache)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut perp_market = ctx.accounts.perp_market.load_mut()?;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use fixed::types::I80F48;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::health::*;
|
||||
|
@ -47,22 +46,20 @@ pub fn perp_liq_force_cancel_orders(
|
|||
let health_cache =
|
||||
new_health_cache(&account.borrow(), &retriever).context("create health cache")?;
|
||||
|
||||
if account.being_liquidated() {
|
||||
let init_health = health_cache.health(HealthType::Init);
|
||||
if account
|
||||
.fixed
|
||||
.maybe_recover_from_being_liquidated(init_health)
|
||||
{
|
||||
msg!("Liqee init_health above zero");
|
||||
return Ok(());
|
||||
{
|
||||
let result = account.check_liquidatable(&health_cache);
|
||||
if account.fixed.is_operational() {
|
||||
if !result? {
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
// Frozen accounts can always have their orders cancelled
|
||||
if let Err(Error::AnchorError(ref inner)) = result {
|
||||
if inner.error_code_number != MangoError::HealthMustBeNegative as u32 {
|
||||
result?;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let maint_health = health_cache.health(HealthType::Maint);
|
||||
require!(
|
||||
maint_health < I80F48::ZERO,
|
||||
MangoError::HealthMustBeNegative
|
||||
);
|
||||
account.fixed.set_being_liquidated(true);
|
||||
}
|
||||
|
||||
health_cache
|
||||
|
|
|
@ -118,24 +118,8 @@ pub fn perp_liq_quote_and_bankruptcy(
|
|||
let liqee_settle_health = liqee_health_cache.perp_settle_health();
|
||||
liqee_health_cache.require_after_phase2_liquidation()?;
|
||||
|
||||
// Once maint_health falls below 0, we want to start liquidating,
|
||||
// we want to allow liquidation to continue until init_health is positive,
|
||||
// to prevent constant oscillation between the two states
|
||||
if liqee.being_liquidated() {
|
||||
if liqee
|
||||
.fixed
|
||||
.maybe_recover_from_being_liquidated(liqee_init_health)
|
||||
{
|
||||
msg!("Liqee init_health above zero");
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
let maint_health = liqee_health_cache.health(HealthType::Maint);
|
||||
require!(
|
||||
maint_health < I80F48::ZERO,
|
||||
MangoError::HealthMustBeNegative
|
||||
);
|
||||
liqee.fixed.set_being_liquidated(true);
|
||||
if !liqee.check_liquidatable(&liqee_health_cache)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// check positions exist/create them, done early for nicer error messages
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use anchor_spl::token::{Token, TokenAccount};
|
||||
use fixed::types::I80F48;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::health::*;
|
||||
|
@ -126,22 +125,21 @@ pub fn serum3_liq_force_cancel_orders(
|
|||
let health_cache =
|
||||
new_health_cache(&account.borrow(), &retriever).context("create health cache")?;
|
||||
|
||||
if account.being_liquidated() {
|
||||
let init_health = health_cache.health(HealthType::Init);
|
||||
if account
|
||||
.fixed
|
||||
.maybe_recover_from_being_liquidated(init_health)
|
||||
{
|
||||
msg!("Liqee init_health above zero");
|
||||
return Ok(());
|
||||
{
|
||||
let result = account.check_liquidatable(&health_cache);
|
||||
if account.fixed.is_operational() {
|
||||
if !result? {
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
// Frozen accounts can always have their orders cancelled
|
||||
if let Err(Error::AnchorError(ref inner)) = result {
|
||||
if inner.error_code_number != MangoError::HealthMustBeNegative as u32 {
|
||||
// propagate all unexpected errors
|
||||
result?;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let maint_health = health_cache.health(HealthType::Maint);
|
||||
require!(
|
||||
maint_health < I80F48::ZERO,
|
||||
MangoError::HealthMustBeNegative
|
||||
);
|
||||
account.fixed.set_being_liquidated(true);
|
||||
}
|
||||
|
||||
health_cache
|
||||
|
|
|
@ -69,21 +69,8 @@ pub fn token_liq_with_token(
|
|||
let init_health = liqee_health_cache.health(HealthType::Init);
|
||||
liqee_health_cache.require_after_phase1_liquidation()?;
|
||||
|
||||
// Once maint_health falls below 0, we want to start liquidating,
|
||||
// we want to allow liquidation to continue until init_health is positive,
|
||||
// to prevent constant oscillation between the two states
|
||||
if liqee.being_liquidated() {
|
||||
if liqee.fixed.maybe_recover_from_being_liquidated(init_health) {
|
||||
msg!("Liqee init_health above zero");
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
let maint_health = liqee_health_cache.health(HealthType::Maint);
|
||||
require!(
|
||||
maint_health < I80F48::ZERO,
|
||||
MangoError::HealthMustBeNegative
|
||||
);
|
||||
liqee.fixed.set_being_liquidated(true);
|
||||
if !liqee.check_liquidatable(&liqee_health_cache)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -86,7 +86,7 @@ pub struct MangoAccount {
|
|||
/// Init health as calculated during HealthReginBegin, rounded up.
|
||||
pub health_region_begin_init_health: i64,
|
||||
|
||||
pub frozen_until: i64,
|
||||
pub frozen_until: u64,
|
||||
|
||||
pub reserved: [u8; 232],
|
||||
|
||||
|
@ -968,6 +968,30 @@ impl<
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check_liquidatable(&mut self, health_cache: &HealthCache) -> Result<bool> {
|
||||
// Once maint_health falls below 0, we want to start liquidating,
|
||||
// we want to allow liquidation to continue until init_health is positive,
|
||||
// to prevent constant oscillation between the two states
|
||||
if self.being_liquidated() {
|
||||
let init_health = health_cache.health(HealthType::Init);
|
||||
if self
|
||||
.fixed_mut()
|
||||
.maybe_recover_from_being_liquidated(init_health)
|
||||
{
|
||||
msg!("Liqee init_health above zero");
|
||||
return Ok(false);
|
||||
}
|
||||
} else {
|
||||
let maint_health = health_cache.health(HealthType::Maint);
|
||||
require!(
|
||||
maint_health < I80F48::ZERO,
|
||||
MangoError::HealthMustBeNegative
|
||||
);
|
||||
self.fixed_mut().set_being_liquidated(true);
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
// writes length of tokens vec at appropriate offset so that borsh can infer the vector length
|
||||
// length used is that present in the header
|
||||
fn write_token_length(&mut self) {
|
||||
|
|
|
@ -6,7 +6,7 @@ use static_assertions::const_assert_eq;
|
|||
use std::cmp::Ordering;
|
||||
use std::mem::size_of;
|
||||
|
||||
use crate::i80f48::ClampedToNum;
|
||||
use crate::i80f48::ClampToInt;
|
||||
use crate::state::*;
|
||||
|
||||
pub const FREE_ORDER_SLOT: PerpMarketIndex = PerpMarketIndex::MAX;
|
||||
|
|
|
@ -58,7 +58,7 @@ import {
|
|||
} from './utils';
|
||||
import { sendTransaction } from './utils/rpc';
|
||||
|
||||
enum AccountRetriever {
|
||||
export enum AccountRetriever {
|
||||
Scanning,
|
||||
Fixed,
|
||||
}
|
||||
|
@ -2657,9 +2657,7 @@ export class MangoClient {
|
|||
);
|
||||
}
|
||||
|
||||
/// private
|
||||
|
||||
private buildHealthRemainingAccounts(
|
||||
public buildHealthRemainingAccounts(
|
||||
retriever: AccountRetriever,
|
||||
group: Group,
|
||||
mangoAccounts: MangoAccount[],
|
||||
|
@ -2699,12 +2697,12 @@ export class MangoClient {
|
|||
const tokenPositionIndices = mangoAccount.tokens.map((t) => t.tokenIndex);
|
||||
for (const bank of banks) {
|
||||
const tokenPositionExists =
|
||||
tokenPositionIndices.indexOf(bank.tokenIndex) > 0;
|
||||
tokenPositionIndices.indexOf(bank.tokenIndex) > -1;
|
||||
if (!tokenPositionExists) {
|
||||
const inactiveTokenPosition = tokenPositionIndices.findIndex(
|
||||
(index) => index === TokenPosition.TokenIndexUnset,
|
||||
);
|
||||
if (inactiveTokenPosition) {
|
||||
if (inactiveTokenPosition != -1) {
|
||||
tokenPositionIndices[inactiveTokenPosition] = bank.tokenIndex;
|
||||
}
|
||||
}
|
||||
|
@ -2724,12 +2722,12 @@ export class MangoClient {
|
|||
const perpPositionIndices = mangoAccount.perps.map((p) => p.marketIndex);
|
||||
for (const perpMarket of perpMarkets) {
|
||||
const perpPositionExists =
|
||||
perpPositionIndices.indexOf(perpMarket.perpMarketIndex) > 0;
|
||||
perpPositionIndices.indexOf(perpMarket.perpMarketIndex) > -1;
|
||||
if (!perpPositionExists) {
|
||||
const inactivePerpPosition = perpPositionIndices.find(
|
||||
const inactivePerpPosition = perpPositionIndices.findIndex(
|
||||
(perpIdx) => perpIdx === PerpPosition.PerpMarketIndexUnset,
|
||||
);
|
||||
if (inactivePerpPosition) {
|
||||
if (inactivePerpPosition != -1) {
|
||||
perpPositionIndices[inactivePerpPosition] =
|
||||
perpMarket.perpMarketIndex;
|
||||
}
|
||||
|
@ -2753,15 +2751,16 @@ export class MangoClient {
|
|||
const ooPositionExists =
|
||||
serumPositionIndices.findIndex(
|
||||
(i) => i.marketIndex === serum3Market.marketIndex,
|
||||
) > 0;
|
||||
) > -1;
|
||||
if (!ooPositionExists) {
|
||||
const inactiveSerumPosition = serumPositionIndices.find(
|
||||
const inactiveSerumPosition = serumPositionIndices.findIndex(
|
||||
(serumPos) =>
|
||||
serumPos.marketIndex === Serum3Orders.Serum3MarketIndexUnset,
|
||||
);
|
||||
if (inactiveSerumPosition) {
|
||||
inactiveSerumPosition.marketIndex = serum3Market.marketIndex;
|
||||
inactiveSerumPosition.openOrders = openOrderPk;
|
||||
if (inactiveSerumPosition != -1) {
|
||||
serumPositionIndices[inactiveSerumPosition].marketIndex =
|
||||
serum3Market.marketIndex;
|
||||
serumPositionIndices[inactiveSerumPosition].openOrders = openOrderPk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export type MangoV4 = {
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"name": "mango_v4",
|
||||
"instructions": [
|
||||
{
|
||||
|
@ -4030,7 +4030,7 @@ export type MangoV4 = {
|
|||
},
|
||||
{
|
||||
"name": "frozenUntil",
|
||||
"type": "i64"
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "reserved",
|
||||
|
@ -7717,7 +7717,7 @@ export type MangoV4 = {
|
|||
};
|
||||
|
||||
export const IDL: MangoV4 = {
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"name": "mango_v4",
|
||||
"instructions": [
|
||||
{
|
||||
|
@ -11748,7 +11748,7 @@ export const IDL: MangoV4 = {
|
|||
},
|
||||
{
|
||||
"name": "frozenUntil",
|
||||
"type": "i64"
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "reserved",
|
||||
|
|
|
@ -509,6 +509,45 @@ async function makePerpMarketReduceOnly() {
|
|||
);
|
||||
}
|
||||
|
||||
async function makePerpMarketUntrusted() {
|
||||
const result = await buildAdminClient();
|
||||
const client = result[0];
|
||||
const admin = result[1];
|
||||
const creator = result[2];
|
||||
|
||||
const group = await client.getGroupForCreator(creator.publicKey, GROUP_NUM);
|
||||
const perpMarket = group.getPerpMarketByName('BTC-PERP');
|
||||
await client.perpEditMarket(
|
||||
group,
|
||||
perpMarket.perpMarketIndex,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
}
|
||||
|
||||
async function createAndPopulateAlt() {
|
||||
const result = await buildAdminClient();
|
||||
const client = result[0];
|
||||
|
@ -669,6 +708,7 @@ async function main() {
|
|||
try {
|
||||
// await registerPerpMarkets();
|
||||
// await makePerpMarketReduceOnly();
|
||||
// await makePerpMarketUntrusted();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue