Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

anchor_spl::dex referral to fee discount account, referral to referrer for host #874

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions spl/src/dex/cpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn new_order_v3<'info>(
client_order_id: u64,
limit: u16,
) -> ProgramResult {
let referral = ctx.remaining_accounts.get(0);
let fee_discount_account = ctx.remaining_accounts.get(0);
let ix = serum_dex::instruction::new_order(
ctx.accounts.market.key,
ctx.accounts.open_orders.key,
Expand All @@ -40,7 +40,7 @@ pub fn new_order_v3<'info>(
ctx.accounts.pc_vault.key,
ctx.accounts.token_program.key,
ctx.accounts.rent.key,
referral.map(|r| r.key),
fee_discount_account.map(|r| r.key),
&ID,
side,
limit_price,
Expand Down Expand Up @@ -86,7 +86,7 @@ pub fn cancel_order_v2<'info>(
pub fn settle_funds<'info>(
ctx: CpiContext<'_, '_, '_, 'info, SettleFunds<'info>>,
) -> ProgramResult {
let referral = ctx.remaining_accounts.get(0);
let referrer = ctx.remaining_accounts.get(0);
let ix = serum_dex::instruction::settle_funds(
&ID,
ctx.accounts.market.key,
Expand All @@ -97,7 +97,7 @@ pub fn settle_funds<'info>(
ctx.accounts.coin_wallet.key,
ctx.accounts.pc_vault.key,
ctx.accounts.pc_wallet.key,
referral.map(|r| r.key),
referrer.map(|r| r.key),
ctx.accounts.vault_signer.key,
)?;
solana_program::program::invoke_signed(
Expand Down
20 changes: 10 additions & 10 deletions spl/src/dex/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,23 +404,23 @@ impl MarketMiddleware for Logger {
}

/// Enforces referal fees being sent to the configured address.
pub struct ReferralFees {
referral: Pubkey,
pub struct ReferrerFees {
referrer: Pubkey,
}

impl ReferralFees {
pub fn new(referral: Pubkey) -> Self {
Self { referral }
impl ReferrerFees {
pub fn new(referrer: Pubkey) -> Self {
Self { referrer }
}
}

impl MarketMiddleware for ReferralFees {
impl MarketMiddleware for ReferrerFees {
/// Accounts:
///
/// .. serum_dex::MarketInstruction::SettleFunds.
fn settle_funds(&self, ctx: &mut Context) -> ProgramResult {
let referral = token::accessor::authority(&ctx.accounts[9])?;
require!(referral == self.referral, ErrorCode::InvalidReferral);
let referrer = token::accessor::authority(&ctx.accounts[9])?;
require!(referrer == self.referrer, ErrorCode::InvalidReferrer);
Ok(())
}
}
Expand Down Expand Up @@ -502,8 +502,8 @@ pub enum ErrorCode {
InvalidInstruction,
#[msg("Could not unpack the instruction")]
CannotUnpack,
#[msg("Invalid referral address given")]
InvalidReferral,
#[msg("Invalid referrer address given")]
InvalidReferrer,
#[msg("The user didn't sign")]
UnauthorizedUser,
#[msg("Not enough accounts were provided")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use anchor_lang::prelude::*;
use anchor_spl::dex::serum_dex::instruction::{CancelOrderInstructionV2, NewOrderInstructionV3};
use anchor_spl::dex::{
Context, Logger, MarketMiddleware, MarketProxy, OpenOrdersPda, ReferralFees,
Context, Logger, MarketMiddleware, MarketProxy, OpenOrdersPda, ReferrerFees,
};
use solana_program::account_info::AccountInfo;
use solana_program::entrypoint::ProgramResult;
Expand All @@ -25,7 +25,7 @@ declare_id!("HmbTLCmaGvZhKnn1Zfa1JVnp7vkMV4DYVxPLWBVoN65L");
/// who can trade on a given market.
///
/// For example, this example forces all trades that execute on this market
/// to set the referral to a hardcoded address--`referral::ID`--and requires
/// to set the referrer to a hardcoded address--`referrer::ID`--and requires
/// the client to pass in an identity token, authorizing the user.
///
/// # Extending the proxy via middleware
Expand Down Expand Up @@ -60,7 +60,7 @@ pub mod permissioned_markets_middleware {
MarketProxy::new()
.middleware(&mut Logger)
.middleware(&mut Identity)
.middleware(&mut ReferralFees::new(referral::ID))
.middleware(&mut ReferrerFees::new(referrer::ID))
.middleware(&mut OpenOrdersPda::new())
.run(program_id, accounts, data)
}
Expand Down Expand Up @@ -151,7 +151,7 @@ pub enum ErrorCode {

// Constants.

pub mod referral {
pub mod referrer {
// This is a dummy address for testing. Do not use in production.
solana_program::declare_id!("3oSfkjQZKCneYvsCTZc9HViGAPqR8pYr4h9YeGB5ZxHf");
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,10 @@ pub mod permissioned_markets {
let (market, user) = {
let market = &acc_infos[0];
let user = &acc_infos[2];
let referral = &acc_infos[9];
let referrer = &acc_infos[9];

if !DISABLE_REFERRAL && referral.key != &referral::ID {
return Err(ErrorCode::InvalidReferral.into());
if !DISABLE_REFERRAL && referrer.key != &referrer::ID {
return Err(ErrorCode::InvalidReferrer.into());
}
if !user.is_signer {
return Err(ErrorCode::UnauthorizedUser.into());
Expand Down Expand Up @@ -359,8 +359,8 @@ pub enum ErrorCode {
InvalidInstruction,
#[msg("Could not unpack the instruction")]
CannotUnpack,
#[msg("Invalid referral address given")]
InvalidReferral,
#[msg("Invalid referrer address given")]
InvalidReferrer,
#[msg("The user didn't sign")]
UnauthorizedUser,
#[msg("Not enough accounts were provided")]
Expand Down Expand Up @@ -466,12 +466,12 @@ macro_rules! open_orders_init_authority {
// b"serum".len() + b"padding".len().
const SERUM_PADDING: usize = 12;

// True if we don't care about referral access control (for testing).
// True if we don't care about referrer access control (for testing).
const DISABLE_REFERRAL: bool = true;

/// The address that will receive all fees for all markets controlled by this
/// program. Note: this is a dummy address. Do not use in production.
pub mod referral {
pub mod referrer {
solana_program::declare_id!("2k1bb16Hu7ocviT2KC3wcCgETtnC8tEUuvFBH4C5xStG");
}

Expand Down
10 changes: 5 additions & 5 deletions tests/permissioned-markets/tests/permissioned-markets.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const {
OpenOrders,
OpenOrdersPda,
Logger,
ReferralFees,
ReferrerFees,
MarketProxyBuilder,
} = serum;
const { initMarket, sleep } = require("./utils");
Expand All @@ -43,7 +43,7 @@ describe("permissioned-markets", () => {
let marketProxy, tokenAccount, usdcAccount;
let openOrders, openOrdersBump, openOrdersInitAuthority, openOrdersBumpinit;
let usdcPosted;
let referralTokenAddress;
let referrerTokenAddress;

it("BOILERPLATE: Initializes an orderbook", async () => {
const getAuthority = async (market) => {
Expand All @@ -66,7 +66,7 @@ describe("permissioned-markets", () => {
dexProgramId: DEX_PID,
})
)
.middleware(new ReferralFees())
.middleware(new ReferrerFees())
.middleware(new Identity())
.middleware(new Logger())
.load({
Expand Down Expand Up @@ -94,7 +94,7 @@ describe("permissioned-markets", () => {
provider.wallet.payer
);

referral = await usdcClient.createAccount(REFERRAL_AUTHORITY);
referrer = await usdcClient.createAccount(REFERRAL_AUTHORITY);
});

it("BOILERPLATE: Calculates open orders addresses", async () => {
Expand Down Expand Up @@ -228,7 +228,7 @@ describe("permissioned-markets", () => {
provider.wallet.publicKey,
tokenAccount,
usdcAccount,
referral
referrer
)
);
await provider.send(tx);
Expand Down
44 changes: 22 additions & 22 deletions tests/swap/programs/swap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ pub mod swap {
amount: u64,
min_expected_swap_amount: u64,
) -> Result<()> {
// Optional referral account (earns a referral fee).
let referral = ctx.remaining_accounts.iter().next().map(Clone::clone);
// Optional referrer account (earns a referrer fee).
let referrer = ctx.remaining_accounts.iter().next().map(Clone::clone);

// Side determines swap direction.
let (from_token, to_token) = match side {
Expand All @@ -57,10 +57,10 @@ pub mod swap {
// Execute trade.
let orderbook: OrderbookClient<'info> = (&*ctx.accounts).into();
match side {
Side::Bid => orderbook.buy(amount, referral.clone())?,
Side::Ask => orderbook.sell(amount, referral.clone())?,
Side::Bid => orderbook.buy(amount, None)?,
Side::Ask => orderbook.sell(amount, None)?,
};
orderbook.settle(referral)?;
orderbook.settle(referrer)?;

// Token balances after the trade.
let from_amount_after = token::accessor::amount(from_token)?;
Expand Down Expand Up @@ -111,8 +111,8 @@ pub mod swap {
amount: u64,
min_expected_swap_amount: u64,
) -> Result<()> {
// Optional referral account (earns a referral fee).
let referral = ctx.remaining_accounts.iter().next().map(Clone::clone);
// Optional referrer account (earns a referrer fee).
let referrer = ctx.remaining_accounts.iter().next().map(Clone::clone);

// Leg 1: Sell Token A for USD(x) (or whatever quote currency is used).
let (from_amount, sell_proceeds) = {
Expand All @@ -122,8 +122,8 @@ pub mod swap {

// Execute the trade.
let orderbook = ctx.accounts.orderbook_from();
orderbook.sell(amount, referral.clone())?;
orderbook.settle(referral.clone())?;
orderbook.sell(amount, None)?;
orderbook.settle(referrer.clone())?;

// Token balances after the trade.
let base_after = token::accessor::amount(&ctx.accounts.from.coin_wallet)?;
Expand All @@ -144,8 +144,8 @@ pub mod swap {

// Execute the trade.
let orderbook = ctx.accounts.orderbook_to();
orderbook.buy(sell_proceeds, referral.clone())?;
orderbook.settle(referral)?;
orderbook.buy(sell_proceeds, None)?;
orderbook.settle(referrer)?;

// Token balances after the trade.
let base_after = token::accessor::amount(&ctx.accounts.to.coin_wallet)?;
Expand Down Expand Up @@ -274,7 +274,7 @@ impl<'info> OrderbookClient<'info> {
//
// `base_amount` is the "native" amount of the base currency, i.e., token
// amount including decimals.
fn sell(&self, base_amount: u64, referral: Option<AccountInfo<'info>>) -> ProgramResult {
fn sell(&self, base_amount: u64, fee_discount_account: Option<AccountInfo<'info>>) -> ProgramResult {
let limit_price = 1;
let max_coin_qty = {
// The loaded market must be dropped before CPI.
Expand All @@ -287,7 +287,7 @@ impl<'info> OrderbookClient<'info> {
max_coin_qty,
max_native_pc_qty,
Side::Ask,
referral,
fee_discount_account,
)
}

Expand All @@ -296,7 +296,7 @@ impl<'info> OrderbookClient<'info> {
//
// `quote_amount` is the "native" amount of the quote currency, i.e., token
// amount including decimals.
fn buy(&self, quote_amount: u64, referral: Option<AccountInfo<'info>>) -> ProgramResult {
fn buy(&self, quote_amount: u64, fee_discount_account: Option<AccountInfo<'info>>) -> ProgramResult {
let limit_price = u64::MAX;
let max_coin_qty = u64::MAX;
let max_native_pc_qty = quote_amount;
Expand All @@ -305,7 +305,7 @@ impl<'info> OrderbookClient<'info> {
max_coin_qty,
max_native_pc_qty,
Side::Bid,
referral,
fee_discount_account,
)
}

Expand All @@ -316,14 +316,14 @@ impl<'info> OrderbookClient<'info> {
// * `max_native_pc_qty` - the max number of quote currency in native token
// units (includes decimals).
// * `side` - bid or ask, i.e. the type of order.
// * `referral` - referral account, earning a fee.
// * `fee_discount_account` - fee discount account, for fee tier calculation.
fn order_cpi(
&self,
limit_price: u64,
max_coin_qty: u64,
max_native_pc_qty: u64,
side: Side,
referral: Option<AccountInfo<'info>>,
fee_discount_account: Option<AccountInfo<'info>>,
) -> ProgramResult {
// Client order id is only used for cancels. Not used here so hardcode.
let client_order_id = 0;
Expand All @@ -347,8 +347,8 @@ impl<'info> OrderbookClient<'info> {
rent: self.rent.clone(),
};
let mut ctx = CpiContext::new(self.dex_program.clone(), dex_accs);
if let Some(referral) = referral {
ctx = ctx.with_remaining_accounts(vec![referral]);
if let Some(fee_discount_account) = fee_discount_account {
ctx = ctx.with_remaining_accounts(vec![fee_discount_account]);
}
dex::new_order_v3(
ctx,
Expand All @@ -363,7 +363,7 @@ impl<'info> OrderbookClient<'info> {
)
}

fn settle(&self, referral: Option<AccountInfo<'info>>) -> ProgramResult {
fn settle(&self, referrer: Option<AccountInfo<'info>>) -> ProgramResult {
let settle_accs = dex::SettleFunds {
market: self.market.market.clone(),
open_orders: self.market.open_orders.clone(),
Expand All @@ -376,8 +376,8 @@ impl<'info> OrderbookClient<'info> {
token_program: self.token_program.clone(),
};
let mut ctx = CpiContext::new(self.dex_program.clone(), settle_accs);
if let Some(referral) = referral {
ctx = ctx.with_remaining_accounts(vec![referral]);
if let Some(referrer) = referrer {
ctx = ctx.with_remaining_accounts(vec![referrer]);
}
dex::settle_funds(ctx)
}
Expand Down