Skip to content

Commit ce41149

Browse files
committed
merge master
2 parents 27588b2 + b098a69 commit ce41149

File tree

20 files changed

+1499
-66
lines changed

20 files changed

+1499
-66
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Features
1111

12+
- program: support scaled ui extension ([#1894](https://github.com/drift-labs/protocol-v2/pull/1894))
13+
1214
### Fixes
1315

1416
### Breaking
@@ -20,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2022
- program: post only respects reduce only ([#1878](https://github.com/drift-labs/protocol-v2/pull/1878))
2123
- program: add sequence id to exchange/mm oracle ([#1834](https://github.com/drift-labs/protocol-v2/pull/1834))
2224
- program: perp position max margin ratio ([#1847](https://github.com/drift-labs/protocol-v2/pull/1847))
25+
- program: add padding to swift messages ([#1845](https://github.com/drift-labs/protocol-v2/pull/1845))
2326
- program: rm lp ([#1755](https://github.com/drift-labs/protocol-v2/pull/1755))
2427

2528
### Fixes

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: 26 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,30 @@ 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+
/// CHECK: checked in `initialize_spot_market`
4965+
pub spot_market_vault: AccountInfo<'info>,
49584966
#[account(
49594967
init,
49604968
seeds = [b"insurance_fund_vault".as_ref(), state.number_of_spot_markets.to_le_bytes().as_ref()],
49614969
bump,
49624970
payer = admin,
4963-
token::mint = spot_market_mint,
4964-
token::authority = drift_signer
4971+
space = get_vault_len(&spot_market_mint)?,
4972+
owner = token_program.key()
49654973
)]
4966-
pub insurance_fund_vault: Box<InterfaceAccount<'info, TokenAccount>>,
4974+
/// CHECK: checked in `initialize_spot_market`
4975+
pub insurance_fund_vault: AccountInfo<'info>,
49674976
#[account(
49684977
constraint = state.signer.eq(&drift_signer.key())
49694978
)]

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+
}

programs/drift/src/instructions/keeper.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,10 @@ pub fn place_signed_msg_taker_order<'c: 'info, 'info>(
762762
return Ok(());
763763
}
764764

765+
if let Some(max_margin_ratio) = verified_message_and_signature.max_margin_ratio {
766+
taker.update_perp_position_max_margin_ratio(market_index, max_margin_ratio)?;
767+
}
768+
765769
// Dont place order if signed msg order already exists
766770
let mut taker_order_id_to_use = taker.next_order_id;
767771
let mut signed_msg_order_id =

programs/drift/src/state/events.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,3 +737,112 @@ pub fn emit_buffers<T: AnchorSerialize + Discriminator>(
737737

738738
Ok(())
739739
}
740+
741+
#[event]
742+
#[derive(Default)]
743+
pub struct LPSettleRecord {
744+
pub record_id: u64,
745+
// previous settle unix timestamp
746+
pub last_ts: i64,
747+
// previous settle slot
748+
pub last_slot: u64,
749+
// current settle unix timestamp
750+
pub ts: i64,
751+
// current slot
752+
pub slot: u64,
753+
// amm perp market index
754+
pub perp_market_index: u16,
755+
// token amount to settle to lp (positive is from amm to lp, negative lp to amm)
756+
pub settle_to_lp_amount: i64,
757+
// quote pnl of amm since last settle
758+
pub perp_amm_pnl_delta: i64,
759+
// exchange fees earned by market/amm since last settle
760+
pub perp_amm_ex_fee_delta: i64,
761+
// current aum of lp
762+
pub lp_aum: u128,
763+
// current mint price of lp
764+
pub lp_price: u128,
765+
}
766+
767+
#[event]
768+
#[derive(Default)]
769+
pub struct LPSwapRecord {
770+
pub ts: i64,
771+
pub slot: u64,
772+
pub authority: Pubkey,
773+
/// precision: out market mint precision, gross fees
774+
pub out_amount: u128,
775+
/// precision: in market mint precision, gross fees
776+
pub in_amount: u128,
777+
/// precision: fee on amount_out, in market mint precision
778+
pub out_fee: i128,
779+
/// precision: fee on amount_in, out market mint precision
780+
pub in_fee: i128,
781+
// out spot market index
782+
pub out_spot_market_index: u16,
783+
// in spot market index
784+
pub in_spot_market_index: u16,
785+
// out constituent index
786+
pub out_constituent_index: u16,
787+
// in constituent index
788+
pub in_constituent_index: u16,
789+
/// precision: PRICE_PRECISION
790+
pub out_oracle_price: i64,
791+
/// precision: PRICE_PRECISION
792+
pub in_oracle_price: i64,
793+
/// LPPool last_aum, QUOTE_PRECISION
794+
pub last_aum: u128,
795+
pub last_aum_slot: u64,
796+
/// PERCENTAGE_PRECISION
797+
pub in_market_current_weight: i64,
798+
/// PERCENTAGE_PRECISION
799+
pub out_market_current_weight: i64,
800+
/// PERCENTAGE_PRECISION
801+
pub in_market_target_weight: i64,
802+
/// PERCENTAGE_PRECISION
803+
pub out_market_target_weight: i64,
804+
pub in_swap_id: u64,
805+
pub out_swap_id: u64,
806+
}
807+
808+
impl Size for LPSwapRecord {
809+
const SIZE: usize = 376;
810+
}
811+
812+
#[event]
813+
#[derive(Default)]
814+
pub struct LPMintRedeemRecord {
815+
pub ts: i64,
816+
pub slot: u64,
817+
pub authority: Pubkey,
818+
pub description: u8,
819+
/// precision: continutent mint precision, gross fees
820+
pub amount: u128,
821+
/// precision: fee on amount, constituent market mint precision
822+
pub fee: i128,
823+
// spot market index
824+
pub spot_market_index: u16,
825+
// constituent index
826+
pub constituent_index: u16,
827+
/// precision: PRICE_PRECISION
828+
pub oracle_price: i64,
829+
/// token mint
830+
pub mint: Pubkey,
831+
/// lp amount, lp mint precision
832+
pub lp_amount: u64,
833+
/// lp fee, lp mint precision
834+
pub lp_fee: i64,
835+
/// the fair price of the lp token, PRICE_PRECISION
836+
pub lp_price: u128,
837+
pub mint_redeem_id: u64,
838+
/// LPPool last_aum
839+
pub last_aum: u128,
840+
pub last_aum_slot: u64,
841+
/// PERCENTAGE_PRECISION
842+
pub in_market_current_weight: i64,
843+
pub in_market_target_weight: i64,
844+
}
845+
846+
impl Size for LPMintRedeemRecord {
847+
const SIZE: usize = 328;
848+
}

programs/drift/src/state/order_params.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ pub struct SignedMsgOrderParamsMessage {
864864
pub uuid: [u8; 8],
865865
pub take_profit_order_params: Option<SignedMsgTriggerOrderParams>,
866866
pub stop_loss_order_params: Option<SignedMsgTriggerOrderParams>,
867+
pub max_margin_ratio: Option<u16>,
867868
}
868869

869870
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default, Eq, PartialEq, Debug)]
@@ -874,6 +875,7 @@ pub struct SignedMsgOrderParamsDelegateMessage {
874875
pub uuid: [u8; 8],
875876
pub take_profit_order_params: Option<SignedMsgTriggerOrderParams>,
876877
pub stop_loss_order_params: Option<SignedMsgTriggerOrderParams>,
878+
pub max_margin_ratio: Option<u16>,
877879
}
878880

879881
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default, Eq, PartialEq, Debug)]

0 commit comments

Comments
 (0)