Token deposit: Split into signed and permissionless ix
Token accounts are a limited resource, so allowing other users to make use of them can cause problems.
This commit is contained in:
parent
bafaf73745
commit
b906e3dc78
|
@ -344,6 +344,7 @@ impl MangoClient {
|
|||
&mango_v4::accounts::TokenDeposit {
|
||||
group: self.group(),
|
||||
account: self.mango_account_address,
|
||||
owner: self.owner(),
|
||||
bank: mint_info.first_bank(),
|
||||
vault: mint_info.first_vault(),
|
||||
oracle: mint_info.oracle,
|
||||
|
|
|
@ -11,8 +11,9 @@ use crate::util::checked_math as cm;
|
|||
|
||||
use crate::logs::{DepositLog, TokenBalanceLog};
|
||||
|
||||
// Same as TokenDeposit, but without the owner signing
|
||||
#[derive(Accounts)]
|
||||
pub struct TokenDeposit<'info> {
|
||||
pub struct TokenDepositIntoExisting<'info> {
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group)]
|
||||
|
@ -41,8 +42,50 @@ pub struct TokenDeposit<'info> {
|
|||
pub token_program: Program<'info, Token>,
|
||||
}
|
||||
|
||||
impl<'info> TokenDeposit<'info> {
|
||||
pub fn transfer_ctx(&self) -> CpiContext<'_, '_, '_, 'info, token::Transfer<'info>> {
|
||||
#[derive(Accounts)]
|
||||
pub struct TokenDeposit<'info> {
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
#[account(mut, has_one = group, has_one = owner)]
|
||||
pub account: AccountLoaderDynamic<'info, MangoAccount>,
|
||||
pub owner: Signer<'info>,
|
||||
|
||||
#[account(
|
||||
mut,
|
||||
has_one = group,
|
||||
has_one = vault,
|
||||
has_one = oracle,
|
||||
// the mints of bank/vault/token_account are implicitly the same because
|
||||
// spl::token::transfer succeeds between token_account and vault
|
||||
)]
|
||||
pub bank: AccountLoader<'info, Bank>,
|
||||
|
||||
#[account(mut)]
|
||||
pub vault: Account<'info, TokenAccount>,
|
||||
|
||||
/// CHECK: The oracle can be one of several different account types
|
||||
pub oracle: UncheckedAccount<'info>,
|
||||
|
||||
#[account(mut)]
|
||||
pub token_account: Box<Account<'info, TokenAccount>>,
|
||||
pub token_authority: Signer<'info>,
|
||||
|
||||
pub token_program: Program<'info, Token>,
|
||||
}
|
||||
|
||||
struct DepositCommon<'a, 'info> {
|
||||
pub group: &'a AccountLoader<'info, Group>,
|
||||
pub account: &'a AccountLoaderDynamic<'info, MangoAccount>,
|
||||
pub bank: &'a AccountLoader<'info, Bank>,
|
||||
pub vault: &'a Account<'info, TokenAccount>,
|
||||
pub oracle: &'a UncheckedAccount<'info>,
|
||||
pub token_account: &'a Box<Account<'info, TokenAccount>>,
|
||||
pub token_authority: &'a Signer<'info>,
|
||||
pub token_program: &'a Program<'info, Token>,
|
||||
}
|
||||
|
||||
impl<'a, 'info> DepositCommon<'a, 'info> {
|
||||
fn transfer_ctx(&self) -> CpiContext<'_, '_, '_, 'info, token::Transfer<'info>> {
|
||||
let program = self.token_program.to_account_info();
|
||||
let accounts = token::Transfer {
|
||||
from: self.token_account.to_account_info(),
|
||||
|
@ -51,39 +94,42 @@ impl<'info> TokenDeposit<'info> {
|
|||
};
|
||||
CpiContext::new(program, accounts)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn token_deposit(ctx: Context<TokenDeposit>, amount: u64) -> Result<()> {
|
||||
fn deposit_into_existing(
|
||||
&self,
|
||||
remaining_accounts: &[AccountInfo],
|
||||
amount: u64,
|
||||
allow_token_account_closure: bool,
|
||||
) -> Result<()> {
|
||||
require_msg!(amount > 0, "deposit amount must be positive");
|
||||
|
||||
let token_index = ctx.accounts.bank.load()?.token_index;
|
||||
let token_index = self.bank.load()?.token_index;
|
||||
|
||||
// Get the account's position for that token index
|
||||
let mut account = ctx.accounts.account.load_mut()?;
|
||||
let mut account = self.account.load_mut()?;
|
||||
|
||||
let (position, raw_token_index, _active_token_index) =
|
||||
account.ensure_token_position(token_index)?;
|
||||
let (position, raw_token_index) = account.token_position_mut(token_index)?;
|
||||
|
||||
let amount_i80f48 = I80F48::from(amount);
|
||||
let position_is_active = {
|
||||
let mut bank = ctx.accounts.bank.load_mut()?;
|
||||
let mut bank = self.bank.load_mut()?;
|
||||
bank.deposit(position, amount_i80f48)?
|
||||
};
|
||||
|
||||
// Transfer the actual tokens
|
||||
token::transfer(ctx.accounts.transfer_ctx(), amount)?;
|
||||
token::transfer(self.transfer_ctx(), amount)?;
|
||||
|
||||
let indexed_position = position.indexed_position;
|
||||
let bank = ctx.accounts.bank.load()?;
|
||||
let oracle_price = bank.oracle_price(&AccountInfoRef::borrow(ctx.accounts.oracle.as_ref())?)?;
|
||||
let bank = self.bank.load()?;
|
||||
let oracle_price = bank.oracle_price(&AccountInfoRef::borrow(self.oracle.as_ref())?)?;
|
||||
|
||||
// Update the net deposits - adjust by price so different tokens are on the same basis (in USD terms)
|
||||
let amount_usd = cm!(amount_i80f48 * oracle_price).to_num::<i64>();
|
||||
cm!(account.fixed.net_deposits += amount_usd);
|
||||
|
||||
emit!(TokenBalanceLog {
|
||||
mango_group: ctx.accounts.group.key(),
|
||||
mango_account: ctx.accounts.account.key(),
|
||||
mango_group: self.group.key(),
|
||||
mango_account: self.account.key(),
|
||||
token_index,
|
||||
indexed_position: indexed_position.to_bits(),
|
||||
deposit_index: bank.deposit_index.to_bits(),
|
||||
|
@ -98,7 +144,7 @@ pub fn token_deposit(ctx: Context<TokenDeposit>, amount: u64) -> Result<()> {
|
|||
//
|
||||
if !account.fixed.is_in_health_region() {
|
||||
let retriever =
|
||||
new_fixed_order_account_retriever(ctx.remaining_accounts, &account.borrow())?;
|
||||
new_fixed_order_account_retriever(remaining_accounts, &account.borrow())?;
|
||||
let health = compute_health(&account.borrow(), HealthType::Init, &retriever)
|
||||
.context("post-deposit init health")?;
|
||||
msg!("health: {}", health);
|
||||
|
@ -111,18 +157,56 @@ pub fn token_deposit(ctx: Context<TokenDeposit>, amount: u64) -> Result<()> {
|
|||
// deactivated.
|
||||
// Deposits can deactivate a position if they cancel out a previous borrow.
|
||||
//
|
||||
if !position_is_active {
|
||||
account.deactivate_token_position_and_log(raw_token_index, ctx.accounts.account.key());
|
||||
if allow_token_account_closure && !position_is_active {
|
||||
account.deactivate_token_position_and_log(raw_token_index, self.account.key());
|
||||
}
|
||||
|
||||
emit!(DepositLog {
|
||||
mango_group: ctx.accounts.group.key(),
|
||||
mango_account: ctx.accounts.account.key(),
|
||||
signer: ctx.accounts.token_authority.key(),
|
||||
mango_group: self.group.key(),
|
||||
mango_account: self.account.key(),
|
||||
signer: self.token_authority.key(),
|
||||
token_index,
|
||||
quantity: amount,
|
||||
price: oracle_price.to_bits(),
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn token_deposit(ctx: Context<TokenDeposit>, amount: u64) -> Result<()> {
|
||||
{
|
||||
let token_index = ctx.accounts.bank.load()?.token_index;
|
||||
let mut account = ctx.accounts.account.load_mut()?;
|
||||
account.ensure_token_position(token_index)?;
|
||||
}
|
||||
|
||||
DepositCommon {
|
||||
group: &ctx.accounts.group,
|
||||
account: &ctx.accounts.account,
|
||||
bank: &ctx.accounts.bank,
|
||||
vault: &ctx.accounts.vault,
|
||||
oracle: &ctx.accounts.oracle,
|
||||
token_account: &ctx.accounts.token_account,
|
||||
token_authority: &ctx.accounts.token_authority,
|
||||
token_program: &ctx.accounts.token_program,
|
||||
}
|
||||
.deposit_into_existing(ctx.remaining_accounts, amount, true)
|
||||
}
|
||||
|
||||
pub fn token_deposit_into_existing(
|
||||
ctx: Context<TokenDepositIntoExisting>,
|
||||
amount: u64,
|
||||
) -> Result<()> {
|
||||
DepositCommon {
|
||||
group: &ctx.accounts.group,
|
||||
account: &ctx.accounts.account,
|
||||
bank: &ctx.accounts.bank,
|
||||
vault: &ctx.accounts.vault,
|
||||
oracle: &ctx.accounts.oracle,
|
||||
token_account: &ctx.accounts.token_account,
|
||||
token_authority: &ctx.accounts.token_authority,
|
||||
token_program: &ctx.accounts.token_program,
|
||||
}
|
||||
.deposit_into_existing(ctx.remaining_accounts, amount, false)
|
||||
}
|
||||
|
|
|
@ -211,6 +211,13 @@ pub mod mango_v4 {
|
|||
instructions::token_deposit(ctx, amount)
|
||||
}
|
||||
|
||||
pub fn token_deposit_into_existing(
|
||||
ctx: Context<TokenDepositIntoExisting>,
|
||||
amount: u64,
|
||||
) -> Result<()> {
|
||||
instructions::token_deposit_into_existing(ctx, amount)
|
||||
}
|
||||
|
||||
pub fn token_withdraw(
|
||||
ctx: Context<TokenWithdraw>,
|
||||
amount: u64,
|
||||
|
|
|
@ -564,6 +564,7 @@ pub struct TokenDepositInstruction {
|
|||
pub amount: u64,
|
||||
|
||||
pub account: Pubkey,
|
||||
pub owner: TestKeypair,
|
||||
pub token_account: Pubkey,
|
||||
pub token_authority: TestKeypair,
|
||||
pub bank_index: usize,
|
||||
|
@ -607,6 +608,76 @@ impl ClientInstruction for TokenDepositInstruction {
|
|||
)
|
||||
.await;
|
||||
|
||||
let accounts = Self::Accounts {
|
||||
group: account.fixed.group,
|
||||
account: self.account,
|
||||
owner: self.owner.pubkey(),
|
||||
bank: mint_info.banks[self.bank_index],
|
||||
vault: mint_info.vaults[self.bank_index],
|
||||
oracle: mint_info.oracle,
|
||||
token_account: self.token_account,
|
||||
token_authority: self.token_authority.pubkey(),
|
||||
token_program: Token::id(),
|
||||
};
|
||||
|
||||
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![self.token_authority, self.owner]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TokenDepositIntoExistingInstruction {
|
||||
pub amount: u64,
|
||||
|
||||
pub account: Pubkey,
|
||||
pub token_account: Pubkey,
|
||||
pub token_authority: TestKeypair,
|
||||
pub bank_index: usize,
|
||||
}
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl ClientInstruction for TokenDepositIntoExistingInstruction {
|
||||
type Accounts = mango_v4::accounts::TokenDepositIntoExisting;
|
||||
type Instruction = mango_v4::instruction::TokenDepositIntoExisting;
|
||||
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 {
|
||||
amount: self.amount,
|
||||
};
|
||||
|
||||
// load account so we know its mint
|
||||
let token_account: TokenAccount = account_loader.load(&self.token_account).await.unwrap();
|
||||
let account = account_loader
|
||||
.load_mango_account(&self.account)
|
||||
.await
|
||||
.unwrap();
|
||||
let mint_info = Pubkey::find_program_address(
|
||||
&[
|
||||
b"MintInfo".as_ref(),
|
||||
account.fixed.group.as_ref(),
|
||||
token_account.mint.as_ref(),
|
||||
],
|
||||
&program_id,
|
||||
)
|
||||
.0;
|
||||
let mint_info: MintInfo = account_loader.load(&mint_info).await.unwrap();
|
||||
|
||||
let health_check_metas = derive_health_check_remaining_account_metas(
|
||||
&account_loader,
|
||||
&account,
|
||||
Some(mint_info.banks[self.bank_index]),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
|
||||
let accounts = Self::Accounts {
|
||||
group: account.fixed.group,
|
||||
account: self.account,
|
||||
|
|
|
@ -178,6 +178,7 @@ pub async fn create_funded_account(
|
|||
TokenDepositInstruction {
|
||||
amount: amounts,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer.token_accounts[mint.index],
|
||||
token_authority: payer.key,
|
||||
bank_index,
|
||||
|
|
|
@ -59,6 +59,7 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: 10,
|
||||
account: vault_account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -94,6 +95,7 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit1_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[2],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -106,6 +108,7 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit2_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[3],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -354,6 +357,7 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: vault_amount,
|
||||
account: vault_account,
|
||||
owner,
|
||||
token_account,
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 1,
|
||||
|
@ -369,6 +373,7 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: 10,
|
||||
account: vault_account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -404,6 +409,7 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit1_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[2],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -416,6 +422,7 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit2_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[3],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -84,6 +84,7 @@ async fn test_basic() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint0_account,
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -145,6 +145,7 @@ async fn test_health_compute_serum() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: 10,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -264,6 +265,7 @@ async fn test_health_compute_perp() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: 10,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -63,6 +63,7 @@ async fn test_health_wrap() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: 1,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -89,6 +90,7 @@ async fn test_health_wrap() -> Result<(), TransportError> {
|
|||
tx.add_instruction(TokenDepositInstruction {
|
||||
amount: repay_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[1],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -94,6 +94,7 @@ async fn test_liq_perps_force_cancel() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: 1,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[1],
|
||||
token_authority: payer,
|
||||
bank_index: 0,
|
||||
|
@ -307,6 +308,7 @@ async fn test_liq_perps_base_position_and_bankruptcy() -> Result<(), TransportEr
|
|||
TokenDepositInstruction {
|
||||
amount: 1,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[1],
|
||||
token_authority: payer,
|
||||
bank_index: 0,
|
||||
|
|
|
@ -233,6 +233,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: 100000,
|
||||
account: vault_account,
|
||||
owner,
|
||||
token_account,
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -269,6 +270,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit1_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[2],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -281,6 +283,7 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit2_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[3],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -89,6 +89,7 @@ async fn test_margin_trade() -> Result<(), BanksClientError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit_amount_initial,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint0_account,
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -80,6 +80,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit_amount,
|
||||
account: account_0,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -93,6 +94,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit_amount,
|
||||
account: account_0,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[1],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -110,6 +112,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit_amount,
|
||||
account: account_1,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -123,6 +126,7 @@ async fn test_perp_settle_fees() -> Result<(), TransportError> {
|
|||
TokenDepositInstruction {
|
||||
amount: deposit_amount,
|
||||
account: account_1,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[1],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -71,14 +71,30 @@ async fn test_position_lifetime() -> Result<()> {
|
|||
{
|
||||
let start_balance = solana.token_account_balance(payer_mint_accounts[0]).await;
|
||||
|
||||
// this activates the positions
|
||||
let deposit_amount = 100;
|
||||
|
||||
// cannot deposit_into_existing if no token deposit exists
|
||||
assert!(send_tx(
|
||||
solana,
|
||||
TokenDepositIntoExistingInstruction {
|
||||
amount: deposit_amount,
|
||||
account,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer,
|
||||
bank_index: 0,
|
||||
}
|
||||
)
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
// this activates the positions
|
||||
for &payer_token in payer_mint_accounts {
|
||||
send_tx(
|
||||
solana,
|
||||
TokenDepositInstruction {
|
||||
amount: deposit_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_token,
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -88,6 +104,20 @@ async fn test_position_lifetime() -> Result<()> {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
// now depositing into an active account works
|
||||
send_tx(
|
||||
solana,
|
||||
TokenDepositIntoExistingInstruction {
|
||||
amount: deposit_amount,
|
||||
account,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer,
|
||||
bank_index: 0,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// this closes the positions
|
||||
for &payer_token in payer_mint_accounts {
|
||||
send_tx(
|
||||
|
@ -131,6 +161,7 @@ async fn test_position_lifetime() -> Result<()> {
|
|||
TokenDepositInstruction {
|
||||
amount: collateral_amount,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[0],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
@ -167,6 +198,7 @@ async fn test_position_lifetime() -> Result<()> {
|
|||
// deposit withdraw amount + some more to cover loan origination fees
|
||||
amount: borrow_amount + 2,
|
||||
account,
|
||||
owner,
|
||||
token_account: payer_mint_accounts[1],
|
||||
token_authority: payer.clone(),
|
||||
bank_index: 0,
|
||||
|
|
|
@ -809,6 +809,7 @@ export class MangoClient {
|
|||
.accounts({
|
||||
group: group.publicKey,
|
||||
account: mangoAccount.publicKey,
|
||||
owner: mangoAccount.owner,
|
||||
bank: bank.publicKey,
|
||||
vault: bank.vault,
|
||||
oracle: bank.oracle,
|
||||
|
|
|
@ -1076,6 +1076,62 @@ export type MangoV4 = {
|
|||
},
|
||||
{
|
||||
"name": "tokenDeposit",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "bank",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "vault",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "oracle",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "tokenAccount",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "tokenAuthority",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tokenDepositIntoExisting",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
|
@ -7282,6 +7338,62 @@ export const IDL: MangoV4 = {
|
|||
},
|
||||
{
|
||||
"name": "tokenDeposit",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "bank",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "vault",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "oracle",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "tokenAccount",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "tokenAuthority",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tokenDepositIntoExisting",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
|
|
Loading…
Reference in New Issue