Skip to content

Commit dd0a964

Browse files
committed
clean up referrer eligibility check, support placeAndTake/Make referral fees
1 parent 413c87d commit dd0a964

File tree

8 files changed

+84
-25
lines changed

8 files changed

+84
-25
lines changed

programs/drift/src/controller/orders.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ use crate::state::state::FeeStructure;
7272
use crate::state::state::*;
7373
use crate::state::traits::Size;
7474
use crate::state::user::{
75-
AssetType, Order, OrderBitFlag, OrderStatus, OrderTriggerCondition, OrderType, ReferrerStatus,
76-
UserStats,
75+
AssetType, Order, OrderBitFlag, OrderStatus, OrderTriggerCondition, OrderType, UserStats,
7776
};
7877
use crate::state::user::{MarketType, User};
7978
use crate::state::user_map::{UserMap, UserStatsMap};
@@ -2285,7 +2284,12 @@ pub fn fulfill_perp_order_with_amm(
22852284
)?;
22862285
}
22872286

2288-
let reward_referrer = can_reward_user_with_perp_pnl(referrer, market.market_index);
2287+
let reward_referrer = can_reward_user_with_referral_reward(
2288+
referrer,
2289+
market.market_index,
2290+
rev_share_escrow,
2291+
builder_referral_feature_enabled,
2292+
);
22892293
let reward_filler = can_reward_user_with_perp_pnl(filler, market.market_index)
22902294
|| can_reward_user_with_perp_pnl(maker, market.market_index);
22912295

@@ -2573,7 +2577,7 @@ pub fn fulfill_perp_order_with_match(
25732577
fee_structure: &FeeStructure,
25742578
oracle_map: &mut OracleMap,
25752579
is_liquidation: bool,
2576-
builder_escrow: &mut Option<&mut RevenueShareEscrowZeroCopyMut>,
2580+
rev_share_escrow: &mut Option<&mut RevenueShareEscrowZeroCopyMut>,
25772581
builder_referral_feature_enabled: bool,
25782582
) -> DriftResult<(u64, u64, u64)> {
25792583
if !are_orders_same_market_but_different_sides(
@@ -2687,7 +2691,7 @@ pub fn fulfill_perp_order_with_match(
26872691
Some(jit_base_asset_amount),
26882692
Some(maker_price), // match the makers price
26892693
is_liquidation,
2690-
builder_escrow,
2694+
rev_share_escrow,
26912695
builder_referral_feature_enabled,
26922696
)?;
26932697

@@ -2781,12 +2785,17 @@ pub fn fulfill_perp_order_with_match(
27812785

27822786
taker_stats.update_taker_volume_30d(market.fuel_boost_taker, quote_asset_amount, now)?;
27832787

2784-
let reward_referrer = can_reward_user_with_perp_pnl(referrer, market.market_index);
2788+
let reward_referrer = can_reward_user_with_referral_reward(
2789+
referrer,
2790+
market.market_index,
2791+
rev_share_escrow,
2792+
builder_referral_feature_enabled,
2793+
);
27852794
let reward_filler = can_reward_user_with_perp_pnl(filler, market.market_index);
27862795

27872796
let (builder_order_idx, referrer_builder_order_idx, builder_order_fee_bps, builder_idx) =
27882797
get_builder_escrow_info(
2789-
builder_escrow,
2798+
rev_share_escrow,
27902799
taker.sub_account_id,
27912800
taker.orders[taker_order_index].order_id,
27922801
market.market_index,
@@ -2825,7 +2834,7 @@ pub fn fulfill_perp_order_with_match(
28252834
)?;
28262835
let builder_fee = builder_fee_option.unwrap_or(0);
28272836

2828-
if let (Some(idx), Some(escrow)) = (builder_order_idx, builder_escrow.as_deref_mut()) {
2837+
if let (Some(idx), Some(escrow)) = (builder_order_idx, rev_share_escrow.as_deref_mut()) {
28292838
let mut order = escrow.get_order_mut(idx)?;
28302839
order.fees_accrued = order.fees_accrued.safe_add(builder_fee)?;
28312840
}
@@ -2887,7 +2896,8 @@ pub fn fulfill_perp_order_with_match(
28872896
filler.update_last_active_slot(slot);
28882897
}
28892898

2890-
if let (Some(idx), Some(escrow)) = (referrer_builder_order_idx, builder_escrow.as_deref_mut()) {
2899+
if let (Some(idx), Some(escrow)) = (referrer_builder_order_idx, rev_share_escrow.as_deref_mut())
2900+
{
28912901
let mut order = escrow.get_order_mut(idx)?;
28922902
order.fees_accrued = order.fees_accrued.safe_add(referrer_reward)?;
28932903
} else if let (Some(referrer), Some(referrer_stats)) =
@@ -2908,7 +2918,7 @@ pub fn fulfill_perp_order_with_match(
29082918
)?;
29092919

29102920
if is_filled {
2911-
if let (Some(idx), Some(escrow)) = (builder_order_idx, builder_escrow.as_deref_mut()) {
2921+
if let (Some(idx), Some(escrow)) = (builder_order_idx, rev_share_escrow.as_deref_mut()) {
29122922
escrow
29132923
.get_order_mut(idx)?
29142924
.add_bit_flag(RevenueShareOrderBitFlag::Completed);
@@ -3432,6 +3442,22 @@ pub fn can_reward_user_with_perp_pnl(user: &mut Option<&mut User>, market_index:
34323442
}
34333443
}
34343444

3445+
pub fn can_reward_user_with_referral_reward(
3446+
user: &mut Option<&mut User>,
3447+
market_index: u16,
3448+
rev_share_escrow: &mut Option<&mut RevenueShareEscrowZeroCopyMut>,
3449+
builder_referral_feature_enabled: bool,
3450+
) -> bool {
3451+
if builder_referral_feature_enabled {
3452+
if let Some(escrow) = rev_share_escrow {
3453+
return escrow.find_or_create_referral_index(market_index).is_some();
3454+
}
3455+
false
3456+
} else {
3457+
can_reward_user_with_perp_pnl(user, market_index)
3458+
}
3459+
}
3460+
34353461
pub fn pay_keeper_flat_reward_for_perps(
34363462
user: &mut User,
34373463
filler: Option<&mut User>,

programs/drift/src/controller/revenue_share.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use crate::math::safe_math::SafeMath;
55
use crate::math::spot_balance::get_token_amount;
66
use crate::state::events::{emit_stack, RevenueShareSettleRecord};
77
use crate::state::perp_market_map::PerpMarketMap;
8-
use crate::state::revenue_share::{
9-
RevenueShareEscrowZeroCopyMut, RevenueShareOrder, RevenueShareOrderBitFlag,
10-
};
8+
use crate::state::revenue_share::{RevenueShareEscrowZeroCopyMut, RevenueShareOrder};
119
use crate::state::revenue_share_map::RevenueShareMap;
1210
use crate::state::spot_market::SpotBalance;
1311
use crate::state::spot_market_map::SpotMarketMap;

programs/drift/src/instructions/keeper.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ fn fill_order<'c: 'info, 'info>(
148148
let builder_codes_enabled = state.builder_codes_enabled();
149149
let builder_referral_enabled = state.builder_referral_enabled();
150150
let mut escrow = if builder_codes_enabled || builder_referral_enabled {
151-
get_revenue_share_escrow_account(&mut remaining_accounts_iter, &load!(ctx.accounts.user)?.authority)?
151+
get_revenue_share_escrow_account(
152+
&mut remaining_accounts_iter,
153+
&load!(ctx.accounts.user)?.authority,
154+
)?
152155
} else {
153156
None
154157
};

programs/drift/src/instructions/user.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,6 +2473,14 @@ pub fn handle_place_and_take_perp_order<'c: 'info, 'info>(
24732473
let user = &mut ctx.accounts.user;
24742474
let order_id = load!(user)?.get_last_order_id();
24752475

2476+
let builder_referral_enabled = state.builder_referral_enabled();
2477+
let builder_codes_enabled = state.builder_codes_enabled();
2478+
let mut escrow = if builder_codes_enabled || builder_referral_enabled {
2479+
get_revenue_share_escrow_account(remaining_accounts_iter, &load!(user)?.authority)?
2480+
} else {
2481+
None
2482+
};
2483+
24762484
let (base_asset_amount_filled, _) = controller::orders::fill_perp_order(
24772485
order_id,
24782486
&ctx.accounts.state,
@@ -2491,8 +2499,8 @@ pub fn handle_place_and_take_perp_order<'c: 'info, 'info>(
24912499
is_immediate_or_cancel || optional_params.is_some(),
24922500
auction_duration_percentage,
24932501
),
2494-
&mut None,
2495-
false,
2502+
&mut escrow.as_mut(),
2503+
builder_referral_enabled,
24962504
)?;
24972505

24982506
let order_unfilled = load!(ctx.accounts.user)?
@@ -2597,7 +2605,10 @@ pub fn handle_place_and_make_perp_order<'c: 'info, 'info>(
25972605
let builder_referral_enabled = state.builder_referral_enabled();
25982606
let builder_codes_enabled = state.builder_codes_enabled();
25992607
let mut escrow = if builder_codes_enabled || builder_referral_enabled {
2600-
get_revenue_share_escrow_account(remaining_accounts_iter, &load!(ctx.accounts.taker)?.authority)?
2608+
get_revenue_share_escrow_account(
2609+
remaining_accounts_iter,
2610+
&load!(ctx.accounts.taker)?.authority,
2611+
)?
26012612
} else {
26022613
None
26032614
};
@@ -2709,7 +2720,10 @@ pub fn handle_place_and_make_signed_msg_perp_order<'c: 'info, 'info>(
27092720
let builder_referral_enabled = state.builder_referral_enabled();
27102721
let builder_codes_enabled = state.builder_codes_enabled();
27112722
let mut escrow = if builder_codes_enabled || builder_referral_enabled {
2712-
get_revenue_share_escrow_account(remaining_accounts_iter, &load!(ctx.accounts.taker)?.authority)?
2723+
get_revenue_share_escrow_account(
2724+
remaining_accounts_iter,
2725+
&load!(ctx.accounts.taker)?.authority,
2726+
)?
27132727
} else {
27142728
None
27152729
};

programs/drift/src/math/fees.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::cmp::{max, min};
22

3-
use anchor_lang::prelude::Pubkey;
43
use num_integer::Roots;
54

65
use crate::error::DriftResult;

programs/drift/src/state/revenue_share.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ pub struct RevenueShareOrder {
6363
/// [`RevenueShareOrderBitFlag::Open`]: this order slot is occupied, `order_id` is the `sub_account_id`'s active order.
6464
/// [`RevenueShareOrderBitFlag::Completed`]: this order has been filled or canceled, and is waiting to be settled into.
6565
/// the builder's account order_id and sub_account_id are no longer relevant, it may be merged with other orders.
66-
/// [`RevenueShareOrderBitFlag::Referral`]: this order stores referral rewards waiting to be settled. If it is set, no
67-
/// other bitflag should be set.
66+
/// [`RevenueShareOrderBitFlag::Referral`]: this order stores referral rewards waiting to be settled for this market.
67+
/// If it is set, no other bitflag should be set.
6868
pub bit_flags: u8,
6969
/// the index into the User's orders list when this RevenueShareOrder was created, make sure to verify that order_id matches.
7070
pub user_order_index: u8,
@@ -399,7 +399,8 @@ impl<'a> RevenueShareEscrowZeroCopyMut<'a> {
399399
None
400400
}
401401

402-
/// Returns the index for the referral order, creating one if necessary.
402+
/// Returns the index for the referral order, creating one if necessary. Returns None if a new order
403+
/// cannot be created.
403404
pub fn find_or_create_referral_index(&mut self, market_index: u16) -> Option<u32> {
404405
// look for an existing referral order
405406
for i in 0..self.orders_len() {
@@ -417,7 +418,7 @@ impl<'a> RevenueShareEscrowZeroCopyMut<'a> {
417418
0,
418419
0,
419420
0,
420-
MarketType::Spot,
421+
MarketType::Perp,
421422
market_index,
422423
RevenueShareOrderBitFlag::Referral as u8,
423424
0,

sdk/src/driftClient.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6638,6 +6638,15 @@ export class DriftClient {
66386638
});
66396639
}
66406640

6641+
remainingAccounts.push({
6642+
pubkey: getRevenueShareEscrowAccountPublicKey(
6643+
this.program.programId,
6644+
this.getUserAccount(subAccountId).authority
6645+
),
6646+
isWritable: true,
6647+
isSigner: false,
6648+
});
6649+
66416650
let optionalParams = null;
66426651
if (auctionDurationPercentage || successCondition) {
66436652
optionalParams =
@@ -6717,6 +6726,15 @@ export class DriftClient {
67176726
});
67186727
}
67196728

6729+
remainingAccounts.push({
6730+
pubkey: getRevenueShareEscrowAccountPublicKey(
6731+
this.program.programId,
6732+
takerInfo.takerUserAccount.authority
6733+
),
6734+
isWritable: true,
6735+
isSigner: false,
6736+
});
6737+
67206738
const takerOrderId = takerInfo.order.orderId;
67216739
return await this.program.instruction.placeAndMakePerpOrder(
67226740
orderParams,

sdk/src/idl/drift.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11280,8 +11280,8 @@
1128011280
"[`RevenueShareOrderBitFlag::Open`]: this order slot is occupied, `order_id` is the `sub_account_id`'s active order.",
1128111281
"[`RevenueShareOrderBitFlag::Completed`]: this order has been filled or canceled, and is waiting to be settled into.",
1128211282
"the builder's account order_id and sub_account_id are no longer relevant, it may be merged with other orders.",
11283-
"[`RevenueShareOrderBitFlag::Referral`]: this order stores referral rewards waiting to be settled. If it is set, no",
11284-
"other bitflag should be set."
11283+
"[`RevenueShareOrderBitFlag::Referral`]: this order stores referral rewards waiting to be settled for this market.",
11284+
"If it is set, no other bitflag should be set."
1128511285
],
1128611286
"type": "u8"
1128711287
},

0 commit comments

Comments
 (0)