Skip to content

Commit

Permalink
anchor: glam macro crate (#301)
Browse files Browse the repository at this point in the history
I'm tired of computing treasury seeds in almost every glam method.
Created a macro for it.
  • Loading branch information
yurushao authored Nov 13, 2024
1 parent fc2190f commit b02d2c5
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 341 deletions.
9 changes: 9 additions & 0 deletions anchor/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion anchor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["programs/*"]
members = ["libs/*", "programs/*"]
resolver = "2"

[profile.release]
Expand Down Expand Up @@ -33,3 +33,5 @@ drift = { path = "./deps/drift" }
marinade = { package = "marinade-finance", git = "https://github.com/glamsystems/liquid-staking-program", branch = "anchor-0.30.1", features = [
"cpi",
] }

glam_macros = { path = "./libs/macros" }
11 changes: 11 additions & 0 deletions anchor/libs/macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "glam_macros"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

[dependencies]
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
33 changes: 33 additions & 0 deletions anchor/libs/macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn};

#[proc_macro_attribute]
pub fn treasury_signer_seeds(_attr: TokenStream, item: TokenStream) -> TokenStream {
// Parse the input as a function
let input = parse_macro_input!(item as ItemFn);
let func_attrs = &input.attrs;
let func_vis = &input.vis;
let func_sig = &input.sig;
let func_block = &input.block;

// Generate the modified function with `treasury_signer_seeds` added at the start of the body
let expanded = quote! {
#(#func_attrs)*
#func_vis #func_sig {
// We assume the fund account and the treasury bump seed are available in the context
let fund_key = ctx.accounts.fund.key();
let seeds = [
b"treasury".as_ref(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let treasury_signer_seeds = &[&seeds[..]];

// Original function body follows
#func_block
}
};

TokenStream::from(expanded)
}
1 change: 1 addition & 0 deletions anchor/programs/glam/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ phf = { workspace = true }

drift = { workspace = true }
marinade = { workspace = true }
glam_macros = { workspace = true }
102 changes: 20 additions & 82 deletions anchor/programs/glam/src/instructions/drift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anchor_lang::prelude::*;
use anchor_spl::token::Token;
use anchor_spl::token_interface::TokenAccount;
use drift::{MarketType, PositionDirection};
use glam_macros::treasury_signer_seeds;

use crate::state::*;

Expand Down Expand Up @@ -45,15 +46,8 @@ pub struct DriftInitialize<'info> {

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftInitialize))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_initialize_handler(ctx: Context<DriftInitialize>) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

initialize_user_stats(CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
InitializeUserStats {
Expand All @@ -64,7 +58,7 @@ pub fn drift_initialize_handler(ctx: Context<DriftInitialize>) -> Result<()> {
rent: ctx.accounts.rent.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
))?;

let mut name = [0u8; 32];
Expand All @@ -82,7 +76,7 @@ pub fn drift_initialize_handler(ctx: Context<DriftInitialize>) -> Result<()> {
rent: ctx.accounts.rent.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
),
0,
name,
Expand Down Expand Up @@ -111,27 +105,20 @@ pub struct DriftUpdate<'info> {

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftUpdateUser))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_update_user_custom_margin_ratio_handler(
ctx: Context<DriftUpdate>,
sub_account_id: u16,
margin_ratio: u32,
) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

update_user_custom_margin_ratio(
CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
UpdateUserCustomMarginRatio {
user: ctx.accounts.user.to_account_info(),
authority: ctx.accounts.treasury.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
),
sub_account_id,
margin_ratio,
Expand All @@ -142,27 +129,20 @@ pub fn drift_update_user_custom_margin_ratio_handler(

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftUpdateUser))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_update_user_margin_trading_enabled_handler(
ctx: Context<DriftUpdate>,
sub_account_id: u16,
margin_trading_enabled: bool,
) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

update_user_margin_trading_enabled(
CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
UpdateUserMarginTradingEnabled {
user: ctx.accounts.user.to_account_info(),
authority: ctx.accounts.treasury.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
),
sub_account_id,
margin_trading_enabled,
Expand All @@ -173,27 +153,20 @@ pub fn drift_update_user_margin_trading_enabled_handler(

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftUpdateUser))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_update_user_delegate_handler(
ctx: Context<DriftUpdate>,
sub_account_id: u16,
delegate: Pubkey,
) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

update_user_delegate(
CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
UpdateUserDelegate {
user: ctx.accounts.user.to_account_info(),
authority: ctx.accounts.treasury.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
),
sub_account_id,
delegate,
Expand Down Expand Up @@ -234,19 +207,12 @@ pub struct DriftDeposit<'info> {

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftDeposit))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_deposit_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftDeposit<'info>>,
market_index: u16,
amount: u64,
) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

deposit(
CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
Expand All @@ -259,7 +225,7 @@ pub fn drift_deposit_handler<'c: 'info, 'info>(
user_token_account: ctx.accounts.treasury_ata.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
)
.with_remaining_accounts(ctx.remaining_accounts.to_vec()),
market_index,
Expand Down Expand Up @@ -304,19 +270,12 @@ pub struct DriftWithdraw<'info> {

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftWithdraw))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_withdraw_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftWithdraw<'info>>,
market_index: u16,
amount: u64,
) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

withdraw(
CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
Expand All @@ -330,7 +289,7 @@ pub fn drift_withdraw_handler<'c: 'info, 'info>(
token_program: ctx.accounts.token_program.to_account_info(),
drift_signer: ctx.accounts.drift_signer.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
)
.with_remaining_accounts(ctx.remaining_accounts.to_vec()),
market_index,
Expand Down Expand Up @@ -368,15 +327,8 @@ pub struct DriftDeleteUser<'info> {

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftDeleteUser))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_delete_user_handler(ctx: Context<DriftDeleteUser>) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

delete_user(CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
DeleteUser {
Expand All @@ -385,7 +337,7 @@ pub fn drift_delete_user_handler(ctx: Context<DriftDeleteUser>) -> Result<()> {
state: ctx.accounts.state.to_account_info(),
authority: ctx.accounts.treasury.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
))?;

Ok(())
Expand Down Expand Up @@ -416,6 +368,7 @@ pub struct DriftPlaceOrders<'info> {

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftPlaceOrders))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_place_orders_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftPlaceOrders<'info>>,
order_params: Vec<OrderParams>,
Expand Down Expand Up @@ -460,14 +413,6 @@ pub fn drift_place_orders_handler<'c: 'info, 'info>(
}
}

let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

place_orders(
CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
Expand All @@ -476,7 +421,7 @@ pub fn drift_place_orders_handler<'c: 'info, 'info>(
state: ctx.accounts.state.to_account_info(),
authority: ctx.accounts.treasury.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
)
.with_remaining_accounts(ctx.remaining_accounts.to_vec()),
order_params,
Expand Down Expand Up @@ -510,20 +455,13 @@ pub struct DriftCancelOrders<'info> {

#[access_control(acl::check_access(&ctx.accounts.fund, &ctx.accounts.manager.key, Permission::DriftCancelOrders))]
#[access_control(acl::check_integration(&ctx.accounts.fund, IntegrationName::Drift))]
#[treasury_signer_seeds]
pub fn drift_cancel_orders_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftCancelOrders<'info>>,
market_type: Option<MarketType>,
market_index: Option<u16>,
direction: Option<PositionDirection>,
) -> Result<()> {
let fund_key = ctx.accounts.fund.key();
let seeds = &[
"treasury".as_bytes(),
fund_key.as_ref(),
&[ctx.bumps.treasury],
];
let signer_seeds = &[&seeds[..]];

cancel_orders(
CpiContext::new_with_signer(
ctx.accounts.drift_program.to_account_info(),
Expand All @@ -532,7 +470,7 @@ pub fn drift_cancel_orders_handler<'c: 'info, 'info>(
state: ctx.accounts.state.to_account_info(),
authority: ctx.accounts.treasury.to_account_info(),
},
signer_seeds,
treasury_signer_seeds,
)
.with_remaining_accounts(ctx.remaining_accounts.to_vec()),
market_type,
Expand Down
Loading

0 comments on commit b02d2c5

Please sign in to comment.