Skip to content

Commit 85a1ca2

Browse files
authored
program: token 22 scaled ui support (#1894)
* init * program: scaled ui working * cargo fmt -- * ts lint
1 parent dc5120b commit 85a1ca2

File tree

6 files changed

+547
-18
lines changed

6 files changed

+547
-18
lines changed

programs/drift/src/controller/token.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,21 @@ pub fn transfer_checked_with_transfer_hook<'info>(
199199

200200
solana_program::program::invoke_signed(&ix, &account_infos, signer_seeds).map_err(Into::into)
201201
}
202+
203+
pub fn initialize_token_account<'info>(
204+
token_program: &Interface<'info, TokenInterface>,
205+
account: &AccountInfo<'info>,
206+
owner: &AccountInfo<'info>,
207+
mint: &InterfaceAccount<'info, Mint>,
208+
) -> Result<()> {
209+
let cpi_program = token_program.to_account_info();
210+
let accounts = ::anchor_spl::token_interface::InitializeAccount3 {
211+
account: account.to_account_info(),
212+
mint: mint.to_account_info(),
213+
authority: owner.to_account_info(),
214+
};
215+
let cpi_ctx = anchor_lang::context::CpiContext::new(cpi_program, accounts);
216+
::anchor_spl::token_interface::initialize_account3(cpi_ctx)?;
217+
218+
Ok(())
219+
}

programs/drift/src/instructions/admin.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use pyth_solana_receiver_sdk::cpi::accounts::InitPriceUpdate;
1010
use pyth_solana_receiver_sdk::program::PythSolanaReceiver;
1111
use serum_dex::state::ToAlignedBytes;
1212

13-
use crate::controller::token::close_vault;
13+
use crate::controller::token::{close_vault, initialize_token_account};
1414
use crate::error::ErrorCode;
1515
use crate::ids::{admin_hot_wallet, amm_spread_adjust_wallet, mm_oracle_crank_wallet};
1616
use crate::instructions::constraints::*;
@@ -146,15 +146,19 @@ pub fn handle_initialize_spot_market(
146146
let state = &mut ctx.accounts.state;
147147
let spot_market_pubkey = ctx.accounts.spot_market.key();
148148

149-
// protocol must be authority of collateral vault
150-
if ctx.accounts.spot_market_vault.owner != state.signer {
151-
return Err(ErrorCode::InvalidSpotMarketAuthority.into());
152-
}
149+
initialize_token_account(
150+
&ctx.accounts.token_program,
151+
&ctx.accounts.spot_market_vault,
152+
&ctx.accounts.drift_signer,
153+
&ctx.accounts.spot_market_mint,
154+
)?;
153155

154-
// protocol must be authority of collateral vault
155-
if ctx.accounts.insurance_fund_vault.owner != state.signer {
156-
return Err(ErrorCode::InvalidInsuranceFundAuthority.into());
157-
}
156+
initialize_token_account(
157+
&ctx.accounts.token_program,
158+
&ctx.accounts.insurance_fund_vault,
159+
&ctx.accounts.drift_signer,
160+
&ctx.accounts.spot_market_mint,
161+
)?;
158162

159163
validate_borrow_rate(optimal_utilization, optimal_borrow_rate, max_borrow_rate, 0)?;
160164

@@ -280,7 +284,7 @@ pub fn handle_initialize_spot_market(
280284
historical_oracle_data: historical_oracle_data_default,
281285
historical_index_data: historical_index_data_default,
282286
mint: ctx.accounts.spot_market_mint.key(),
283-
vault: *ctx.accounts.spot_market_vault.to_account_info().key,
287+
vault: ctx.accounts.spot_market_vault.key(),
284288
revenue_pool: PoolBalance {
285289
scaled_balance: 0,
286290
market_index: spot_market_index,
@@ -337,7 +341,7 @@ pub fn handle_initialize_spot_market(
337341
pool_id: 0,
338342
padding: [0; 40],
339343
insurance_fund: InsuranceFund {
340-
vault: *ctx.accounts.insurance_fund_vault.to_account_info().key,
344+
vault: ctx.accounts.insurance_fund_vault.key(),
341345
unstaking_period: THIRTEEN_DAY,
342346
total_factor: if_total_factor,
343347
user_factor: if_total_factor / 2,
@@ -4945,25 +4949,28 @@ pub struct InitializeSpotMarket<'info> {
49454949
payer = admin
49464950
)]
49474951
pub spot_market: AccountLoader<'info, SpotMarket>,
4952+
#[account(
4953+
mint::token_program = token_program,
4954+
)]
49484955
pub spot_market_mint: Box<InterfaceAccount<'info, Mint>>,
49494956
#[account(
49504957
init,
49514958
seeds = [b"spot_market_vault".as_ref(), state.number_of_spot_markets.to_le_bytes().as_ref()],
49524959
bump,
49534960
payer = admin,
4954-
token::mint = spot_market_mint,
4955-
token::authority = drift_signer
4961+
space = get_vault_len(&spot_market_mint)?,
4962+
owner = token_program.key()
49564963
)]
4957-
pub spot_market_vault: Box<InterfaceAccount<'info, TokenAccount>>,
4964+
pub spot_market_vault: AccountInfo<'info>,
49584965
#[account(
49594966
init,
49604967
seeds = [b"insurance_fund_vault".as_ref(), state.number_of_spot_markets.to_le_bytes().as_ref()],
49614968
bump,
49624969
payer = admin,
4963-
token::mint = spot_market_mint,
4964-
token::authority = drift_signer
4970+
space = get_vault_len(&spot_market_mint)?,
4971+
owner = token_program.key()
49654972
)]
4966-
pub insurance_fund_vault: Box<InterfaceAccount<'info, TokenAccount>>,
4973+
pub insurance_fund_vault: AccountInfo<'info>,
49674974
#[account(
49684975
constraint = state.signer.eq(&drift_signer.key())
49694976
)]

programs/drift/src/instructions/constraints.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use anchor_lang::accounts::account::Account;
22
use anchor_lang::accounts::account_loader::AccountLoader;
33
use anchor_lang::accounts::signer::Signer;
4+
use anchor_lang::prelude::*;
45
use anchor_lang::prelude::{AccountInfo, Pubkey};
6+
use anchor_spl::token_interface::Mint;
57

68
use crate::error::ErrorCode;
79
use crate::msg;
@@ -145,3 +147,28 @@ pub fn exchange_not_paused(state: &Account<State>) -> anchor_lang::Result<()> {
145147
}
146148
Ok(())
147149
}
150+
151+
pub fn get_vault_len(mint: &InterfaceAccount<Mint>) -> anchor_lang::Result<usize> {
152+
let mint_info = mint.to_account_info();
153+
let len = if *mint_info.owner == ::anchor_spl::token_2022::Token2022::id() {
154+
use ::anchor_spl::token_2022::spl_token_2022::extension::{
155+
BaseStateWithExtensions, ExtensionType, StateWithExtensions,
156+
};
157+
use ::anchor_spl::token_2022::spl_token_2022::state::{Account, Mint};
158+
let mint_data = mint_info.try_borrow_data()?;
159+
let mint_state = StateWithExtensions::<Mint>::unpack(&mint_data)?;
160+
let mint_extensions = match mint_state.get_extension_types() {
161+
Ok(extensions) => extensions,
162+
// If we cant deserialize the mint, we use the default token account length
163+
// Init token will fail if this size doesnt work, so worst case init account just fails
164+
Err(_) => return Ok(::anchor_spl::token::TokenAccount::LEN),
165+
};
166+
let required_extensions =
167+
ExtensionType::get_required_init_account_extensions(&mint_extensions);
168+
ExtensionType::try_calculate_account_len::<Account>(&required_extensions)?
169+
} else {
170+
::anchor_spl::token::TokenAccount::LEN
171+
};
172+
173+
Ok(len)
174+
}

test-scripts/single-anchor-test.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ fi
66

77
export ANCHOR_WALLET=~/.config/solana/id.json
88

9-
test_files=(admin.ts)
9+
test_files=(
10+
spotDepositWithdraw22ScaledUI.ts
11+
)
1012

1113
for test_file in ${test_files[@]}; do
1214
ts-mocha -t 300000 ./tests/${test_file}

tests/fixtures/token_2022_test.so

1.32 MB
Binary file not shown.

0 commit comments

Comments
 (0)