Skip to content

Commit cb96b3b

Browse files
committed
Merge remote-tracking branch 'origin/master' into wphan/builder_codes
2 parents 3dc10eb + 1ba87a7 commit cb96b3b

File tree

25 files changed

+605
-276
lines changed

25 files changed

+605
-276
lines changed

CHANGELOG.md

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

1010
### Features
1111

12+
### Fixes
13+
14+
### Breaking
15+
16+
## [2.139.0] - 2025-09-25
17+
18+
### Features
19+
20+
- program: all token 22 use immutable owner ([#1904](https://github.com/drift-labs/protocol-v2/pull/1904))
21+
- program: allow resolve perp pnl deficit if pnl pool isnt 0 but at deficit ([#1909](https://github.com/drift-labs/protocol-v2/pull/1909))
1222
- program: auction order params account for twap divergence ([#1882](https://github.com/drift-labs/protocol-v2/pull/1882))
1323
- program: add delegate stake if ([#1859](https://github.com/drift-labs/protocol-v2/pull/1859))
1424

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

programs/drift/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "drift"
3-
version = "2.138.0"
3+
version = "2.139.0"
44
description = "Created with Anchor"
55
edition = "2018"
66

programs/drift/src/controller/amm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::controller::spot_balance::{
1111
};
1212
use crate::error::{DriftResult, ErrorCode};
1313
use crate::get_then_update_id;
14-
use crate::math::amm::calculate_quote_asset_amount_swapped;
14+
use crate::math::amm::{calculate_net_user_pnl, calculate_quote_asset_amount_swapped};
1515
use crate::math::amm_spread::{calculate_spread_reserves, get_spread_reserves};
1616
use crate::math::casting::Cast;
1717
use crate::math::constants::{
@@ -942,7 +942,7 @@ pub fn calculate_perp_market_amm_summary_stats(
942942
.safe_add(fee_pool_token_amount)?
943943
.cast()?;
944944

945-
let net_user_pnl = amm::calculate_net_user_pnl(&perp_market.amm, perp_market_oracle_price)?;
945+
let net_user_pnl = calculate_net_user_pnl(&perp_market.amm, perp_market_oracle_price)?;
946946

947947
// amm's mm_fee can be incorrect with drifting integer math error
948948
let mut new_total_fee_minus_distributions = pnl_tokens_available.safe_sub(net_user_pnl)?;

programs/drift/src/controller/insurance.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ pub fn add_insurance_fund_stake(
112112
user_stats: &mut UserStats,
113113
spot_market: &mut SpotMarket,
114114
now: i64,
115+
admin_deposit: bool,
115116
) -> DriftResult {
116117
validate!(
117118
!(insurance_vault_amount == 0 && spot_market.insurance_fund.total_shares != 0),
@@ -161,7 +162,11 @@ pub fn add_insurance_fund_stake(
161162
emit!(InsuranceFundStakeRecord {
162163
ts: now,
163164
user_authority: user_stats.authority,
164-
action: StakeAction::Stake,
165+
action: if admin_deposit {
166+
StakeAction::AdminDeposit
167+
} else {
168+
StakeAction::Stake
169+
},
165170
amount,
166171
market_index: spot_market.market_index,
167172
insurance_vault_amount_before: insurance_vault_amount,
@@ -843,11 +848,20 @@ pub fn resolve_perp_pnl_deficit(
843848
&SpotBalanceType::Deposit,
844849
)?;
845850

851+
let net_user_pnl = calculate_net_user_pnl(
852+
&market.amm,
853+
market
854+
.amm
855+
.historical_oracle_data
856+
.last_oracle_price_twap_5min,
857+
)?;
858+
846859
validate!(
847-
pnl_pool_token_amount == 0,
860+
pnl_pool_token_amount.cast::<i128>()? < net_user_pnl,
848861
ErrorCode::SufficientPerpPnlPool,
849-
"pnl_pool_token_amount > 0 (={})",
850-
pnl_pool_token_amount
862+
"pnl_pool_token_amount >= net_user_pnl ({} >= {})",
863+
pnl_pool_token_amount,
864+
net_user_pnl
851865
)?;
852866

853867
update_spot_market_cumulative_interest(spot_market, None, now)?;

programs/drift/src/controller/insurance/tests.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub fn basic_stake_if_test() {
4141
&mut user_stats,
4242
&mut spot_market,
4343
0,
44+
false,
4445
)
4546
.unwrap();
4647
assert_eq!(if_stake.unchecked_if_shares(), amount as u128);
@@ -104,6 +105,7 @@ pub fn basic_stake_if_test() {
104105
&mut user_stats,
105106
&mut spot_market,
106107
0,
108+
false,
107109
)
108110
.unwrap();
109111
assert_eq!(if_stake.cost_basis, 1234);
@@ -141,6 +143,7 @@ pub fn basic_seeded_stake_if_test() {
141143
&mut user_stats,
142144
&mut spot_market,
143145
0,
146+
false,
144147
)
145148
.unwrap();
146149

@@ -202,6 +205,7 @@ pub fn basic_seeded_stake_if_test() {
202205
&mut user_stats,
203206
&mut spot_market,
204207
0,
208+
false,
205209
)
206210
.unwrap();
207211
assert_eq!(if_stake.cost_basis, 1234);
@@ -245,6 +249,7 @@ pub fn large_num_seeded_stake_if_test() {
245249
&mut user_stats,
246250
&mut spot_market,
247251
0,
252+
false,
248253
)
249254
.unwrap();
250255

@@ -334,6 +339,7 @@ pub fn large_num_seeded_stake_if_test() {
334339
&mut user_stats,
335340
&mut spot_market,
336341
20,
342+
false,
337343
)
338344
.unwrap();
339345
assert_eq!(if_stake.cost_basis, 199033744205760);
@@ -346,6 +352,7 @@ pub fn large_num_seeded_stake_if_test() {
346352
&mut user_stats,
347353
&mut spot_market,
348354
30,
355+
false,
349356
)
350357
.unwrap();
351358
assert_eq!(if_stake.cost_basis, 398067488411520);
@@ -378,6 +385,7 @@ pub fn gains_stake_if_test() {
378385
&mut user_stats,
379386
&mut spot_market,
380387
0,
388+
false,
381389
)
382390
.unwrap();
383391
assert_eq!(if_stake.unchecked_if_shares(), amount as u128);
@@ -502,6 +510,7 @@ pub fn losses_stake_if_test() {
502510
&mut user_stats,
503511
&mut spot_market,
504512
0,
513+
false,
505514
)
506515
.unwrap();
507516
assert_eq!(if_stake.unchecked_if_shares(), amount as u128);
@@ -631,6 +640,7 @@ pub fn escrow_losses_stake_if_test() {
631640
&mut user_stats,
632641
&mut spot_market,
633642
0,
643+
false,
634644
)
635645
.unwrap();
636646
assert_eq!(if_stake.unchecked_if_shares(), amount as u128);
@@ -729,7 +739,8 @@ pub fn escrow_gains_stake_if_test() {
729739
&mut if_stake,
730740
&mut user_stats,
731741
&mut spot_market,
732-
0
742+
0,
743+
false,
733744
)
734745
.is_err());
735746

@@ -741,6 +752,7 @@ pub fn escrow_gains_stake_if_test() {
741752
&mut user_stats,
742753
&mut spot_market,
743754
0,
755+
false,
744756
)
745757
.unwrap();
746758

@@ -858,6 +870,7 @@ pub fn drained_stake_if_test_rebase_on_new_add() {
858870
&mut user_stats,
859871
&mut spot_market,
860872
0,
873+
false,
861874
)
862875
.is_err());
863876

@@ -877,6 +890,7 @@ pub fn drained_stake_if_test_rebase_on_new_add() {
877890
&mut user_stats,
878891
&mut spot_market,
879892
0,
893+
false,
880894
)
881895
.unwrap();
882896
if_balance += amount;
@@ -912,6 +926,7 @@ pub fn drained_stake_if_test_rebase_on_new_add() {
912926
&mut orig_user_stats,
913927
&mut spot_market,
914928
0,
929+
false,
915930
)
916931
.unwrap();
917932

@@ -1010,6 +1025,7 @@ pub fn drained_stake_if_test_rebase_on_old_remove_all() {
10101025
&mut user_stats,
10111026
&mut spot_market,
10121027
0,
1028+
false,
10131029
)
10141030
.unwrap();
10151031

@@ -1210,6 +1226,7 @@ pub fn drained_stake_if_test_rebase_on_old_remove_all_2() {
12101226
&mut user_stats,
12111227
&mut spot_market,
12121228
0,
1229+
false,
12131230
)
12141231
.unwrap();
12151232
if_balance += 10_000_000_000_000;
@@ -1254,6 +1271,7 @@ pub fn multiple_if_stakes_and_rebase() {
12541271
&mut user_stats_1,
12551272
&mut spot_market,
12561273
0,
1274+
false,
12571275
)
12581276
.unwrap();
12591277

@@ -1266,6 +1284,7 @@ pub fn multiple_if_stakes_and_rebase() {
12661284
&mut user_stats_2,
12671285
&mut spot_market,
12681286
0,
1287+
false,
12691288
)
12701289
.unwrap();
12711290

@@ -1392,6 +1411,7 @@ pub fn multiple_if_stakes_and_rebase_and_admin_remove() {
13921411
&mut user_stats_1,
13931412
&mut spot_market,
13941413
0,
1414+
false,
13951415
)
13961416
.unwrap();
13971417

@@ -1404,6 +1424,7 @@ pub fn multiple_if_stakes_and_rebase_and_admin_remove() {
14041424
&mut user_stats_2,
14051425
&mut spot_market,
14061426
0,
1427+
false,
14071428
)
14081429
.unwrap();
14091430

programs/drift/src/controller/token.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,16 @@ pub fn initialize_token_account<'info>(
217217

218218
Ok(())
219219
}
220+
221+
pub fn initialize_immutable_owner<'info>(
222+
token_program: &Interface<'info, TokenInterface>,
223+
account: &AccountInfo<'info>,
224+
) -> Result<()> {
225+
let accounts = ::anchor_spl::token_interface::InitializeImmutableOwner {
226+
account: account.to_account_info(),
227+
};
228+
let cpi_ctx = anchor_lang::context::CpiContext::new(token_program.to_account_info(), accounts);
229+
::anchor_spl::token_interface::initialize_immutable_owner(cpi_ctx)?;
230+
231+
Ok(())
232+
}

programs/drift/src/instructions/admin.rs

Lines changed: 11 additions & 1 deletion
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, initialize_token_account};
13+
use crate::controller::token::{close_vault, initialize_immutable_owner, 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::*;
@@ -148,6 +148,16 @@ pub fn handle_initialize_spot_market(
148148
let state = &mut ctx.accounts.state;
149149
let spot_market_pubkey = ctx.accounts.spot_market.key();
150150

151+
let is_token_2022 = *ctx.accounts.spot_market_mint.to_account_info().owner == Token2022::id();
152+
if is_token_2022 {
153+
initialize_immutable_owner(&ctx.accounts.token_program, &ctx.accounts.spot_market_vault)?;
154+
155+
initialize_immutable_owner(
156+
&ctx.accounts.token_program,
157+
&ctx.accounts.insurance_fund_vault,
158+
)?;
159+
}
160+
151161
initialize_token_account(
152162
&ctx.accounts.token_program,
153163
&ctx.accounts.spot_market_vault,

programs/drift/src/instructions/constraints.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,13 @@ pub fn get_vault_len(mint: &InterfaceAccount<Mint>) -> anchor_lang::Result<usize
159159
let mint_state = StateWithExtensions::<Mint>::unpack(&mint_data)?;
160160
let mint_extensions = match mint_state.get_extension_types() {
161161
Ok(extensions) => extensions,
162-
// If we cant deserialize the mint, we use the default token account length
162+
// If we cant deserialize the mint, try assuming no extensions
163163
// Init token will fail if this size doesnt work, so worst case init account just fails
164-
Err(_) => {
165-
msg!("Failed to deserialize mint. Falling back to default token account length");
166-
return Ok(::anchor_spl::token::TokenAccount::LEN);
167-
}
164+
Err(_) => vec![],
168165
};
169-
let required_extensions =
166+
let mut required_extensions =
170167
ExtensionType::get_required_init_account_extensions(&mint_extensions);
168+
required_extensions.push(ExtensionType::ImmutableOwner);
171169
ExtensionType::try_calculate_account_len::<Account>(&required_extensions)?
172170
} else {
173171
::anchor_spl::token::TokenAccount::LEN

0 commit comments

Comments
 (0)