From b09c15cdadbde40169ec5569a6ccafe6f5d5bc53 Mon Sep 17 00:00:00 2001 From: wphan Date: Thu, 2 Oct 2025 17:05:22 -0700 Subject: [PATCH 1/3] dont panic on settle-pnl when no position --- programs/drift/src/instructions/keeper.rs | 24 +++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/programs/drift/src/instructions/keeper.rs b/programs/drift/src/instructions/keeper.rs index 3fb3db113a..7216f74698 100644 --- a/programs/drift/src/instructions/keeper.rs +++ b/programs/drift/src/instructions/keeper.rs @@ -1107,7 +1107,7 @@ pub fn handle_settle_pnl<'c: 'info, 'info>( ) .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; - controller::pnl::settle_pnl( + let res = controller::pnl::settle_pnl( market_index, user, ctx.accounts.authority.key, @@ -1119,8 +1119,14 @@ pub fn handle_settle_pnl<'c: 'info, 'info>( state, None, SettlePnlMode::MustSettle, - ) - .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; + ); + if let Err(e) = res { + if e != ErrorCode::UserHasNoPositionInMarket { + return Err(e.into()); + } else { + msg!("User has no position in market {}", market_index); + } + } } if state.builder_codes_enabled() || state.builder_referral_enabled() { @@ -1223,7 +1229,7 @@ pub fn handle_settle_multiple_pnls<'c: 'info, 'info>( ) .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; - controller::pnl::settle_pnl( + let res = controller::pnl::settle_pnl( *market_index, user, ctx.accounts.authority.key, @@ -1235,8 +1241,14 @@ pub fn handle_settle_multiple_pnls<'c: 'info, 'info>( state, Some(meets_margin_requirement), mode, - ) - .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; + ); + if let Err(e) = res { + if e != ErrorCode::UserHasNoPositionInMarket { + return Err(e.into()); + } else { + msg!("User has no position in market {}", market_index); + } + } } if state.builder_codes_enabled() || state.builder_referral_enabled() { From 4eba379db7b64ea621a3d17c54b1c40196634fce Mon Sep 17 00:00:00 2001 From: wphan Date: Thu, 2 Oct 2025 20:57:25 -0700 Subject: [PATCH 2/3] move check inside settle_pnl, ensure balance checks are done --- programs/drift/src/controller/pnl.rs | 11 ++++++++++- programs/drift/src/instructions/keeper.rs | 22 ++++------------------ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/programs/drift/src/controller/pnl.rs b/programs/drift/src/controller/pnl.rs index c46d46763d..c08912beb5 100644 --- a/programs/drift/src/controller/pnl.rs +++ b/programs/drift/src/controller/pnl.rs @@ -79,7 +79,16 @@ pub fn settle_pnl( drop(market); - let position_index = get_position_index(&user.perp_positions, market_index)?; + let position_index = match get_position_index(&user.perp_positions, market_index) { + Ok(index) => index, + Err(e) => { + return mode.result( + e, + market_index, + &format!("User has no position in market {}", market_index), + ) + } + }; let unrealized_pnl = user.perp_positions[position_index].get_unrealized_pnl(oracle_price)?; // cannot settle negative pnl this way on a user who is in liquidation territory diff --git a/programs/drift/src/instructions/keeper.rs b/programs/drift/src/instructions/keeper.rs index 7216f74698..98305de73b 100644 --- a/programs/drift/src/instructions/keeper.rs +++ b/programs/drift/src/instructions/keeper.rs @@ -1107,7 +1107,7 @@ pub fn handle_settle_pnl<'c: 'info, 'info>( ) .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; - let res = controller::pnl::settle_pnl( + controller::pnl::settle_pnl( market_index, user, ctx.accounts.authority.key, @@ -1119,14 +1119,7 @@ pub fn handle_settle_pnl<'c: 'info, 'info>( state, None, SettlePnlMode::MustSettle, - ); - if let Err(e) = res { - if e != ErrorCode::UserHasNoPositionInMarket { - return Err(e.into()); - } else { - msg!("User has no position in market {}", market_index); - } - } + )?; } if state.builder_codes_enabled() || state.builder_referral_enabled() { @@ -1229,7 +1222,7 @@ pub fn handle_settle_multiple_pnls<'c: 'info, 'info>( ) .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; - let res = controller::pnl::settle_pnl( + controller::pnl::settle_pnl( *market_index, user, ctx.accounts.authority.key, @@ -1241,14 +1234,7 @@ pub fn handle_settle_multiple_pnls<'c: 'info, 'info>( state, Some(meets_margin_requirement), mode, - ); - if let Err(e) = res { - if e != ErrorCode::UserHasNoPositionInMarket { - return Err(e.into()); - } else { - msg!("User has no position in market {}", market_index); - } - } + )?; } if state.builder_codes_enabled() || state.builder_referral_enabled() { From 7305bb7059e3c12b84d46315d7e0d904c7cdc58f Mon Sep 17 00:00:00 2001 From: wphan Date: Thu, 2 Oct 2025 22:55:53 -0700 Subject: [PATCH 3/3] remove unnecessary error map --- programs/drift/src/instructions/keeper.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/programs/drift/src/instructions/keeper.rs b/programs/drift/src/instructions/keeper.rs index 98305de73b..cc8c87b321 100644 --- a/programs/drift/src/instructions/keeper.rs +++ b/programs/drift/src/instructions/keeper.rs @@ -1104,8 +1104,7 @@ pub fn handle_settle_pnl<'c: 'info, 'info>( &mut oracle_map, state, &clock, - ) - .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; + )?; controller::pnl::settle_pnl( market_index, @@ -1219,8 +1218,7 @@ pub fn handle_settle_multiple_pnls<'c: 'info, 'info>( &mut oracle_map, state, &clock, - ) - .map(|_| ErrorCode::InvalidOracleForSettlePnl)?; + )?; controller::pnl::settle_pnl( *market_index,