Skip to content

Commit

Permalink
anchor: program migration (#377)
Browse files Browse the repository at this point in the history
  • Loading branch information
yurushao authored Jan 28, 2025
1 parent 1b9e254 commit 7ff0fdb
Show file tree
Hide file tree
Showing 55 changed files with 2,413 additions and 4,451 deletions.
4 changes: 1 addition & 3 deletions anchor/Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ wallet = "~/.config/solana/id.json"

[scripts]
test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_crud"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_vault"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_share_class"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_mint"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_investor"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_drift"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_marinade"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_staking"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_jupiter"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_openfunds"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_wsol"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_sol_msol"
#test = "../node_modules/.bin/nx run --skip-nx-cache anchor:jest --verbose --testPathPattern tests/ --testNamePattern glam_policy_hook"

[test]
Expand Down
4 changes: 2 additions & 2 deletions anchor/libs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn share_class_signer_seeds(_attr: TokenStream, item: TokenStream) -> TokenS
// We assume the fund account and the treasury bump seed are available in the context
let state_key = ctx.accounts.state.key();
let seeds = &[
"share".as_bytes(),
"mint".as_bytes(),
&[share_class_id],
state_key.as_ref(),
&[ctx.bumps.share_class_mint],
Expand Down Expand Up @@ -71,7 +71,7 @@ pub fn vault_signer_seeds(_attr: TokenStream, item: TokenStream) -> TokenStream
// We assume the fund account and the vault bump seed are available in the context
let state_key = ctx.accounts.state.key();
let seeds = [
"treasury".as_ref(),
"vault".as_ref(),
state_key.as_ref(),
&[ctx.bumps.vault],
];
Expand Down
18 changes: 9 additions & 9 deletions anchor/programs/glam/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ use anchor_lang::prelude::*;
use solana_program::pubkey;

#[constant]
pub const SEED_STATE: &str = "fund";
pub const SEED_STATE: &str = "state";
#[constant]
pub const SEED_VAULT: &str = "treasury";
pub const SEED_VAULT: &str = "vault";
#[constant]
pub const SEED_METADATA: &str = "openfunds";
pub const SEED_METADATA: &str = "metadata";
#[constant]
pub const SEED_MINT: &str = "share";
pub const SEED_MINT: &str = "mint";

pub const DEFAULT_DRIFT_USER_NAME: [u8; 32] = [
b'G', b'L', b'A', b'M', b' ', b'*', b'.', b'+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
];

pub const MAX_ASSETS: usize = 5;
pub const MAX_SHARE_CLASSES: usize = 3;
pub const MAX_SIZE_NAME: usize = 50;
pub const MAX_SIZE_SYMBOL: usize = 20;
pub const MAX_SIZE_URI: usize = 100;
pub const MAX_ASSETS: usize = 100;
pub const MAX_MINTS: usize = 1;
pub const MAX_SIZE_SYMBOL: usize = 32;
pub const MAX_SIZE_NAME: usize = 64;
pub const MAX_SIZE_URI: usize = 128;

pub const WSOL: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const MSOL: Pubkey = pubkey!("mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So");
Expand Down
12 changes: 9 additions & 3 deletions anchor/programs/glam/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,23 @@ pub enum AccessError {

#[msg("Integration is disabled")]
IntegrationDisabled,

#[msg("Wrong state account type")]
WrongStateType,
}

#[error_code]
pub enum StateError {
#[msg("Name too long: max 50 chars")]
#[msg("Invalid account type")]
InvalidAccountType,

#[msg("Name too long: max 64 chars")]
InvalidName,

#[msg("Symbol too long: max 50 chars")]
#[msg("Symbol too long: max 32 chars")]
InvalidSymbol,

#[msg("Uri too long: max 20")]
#[msg("Uri too long: max 128 chars")]
InvalidUri,

#[msg("Too many assets: max 100")]
Expand Down
18 changes: 9 additions & 9 deletions anchor/programs/glam/src/instructions/drift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub struct DriftInitialize<'info> {
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftInitialize))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn initialize_handler(ctx: Context<DriftInitialize>) -> Result<()> {
initialize_user_stats(CpiContext::new_with_signer(
Expand Down Expand Up @@ -102,7 +102,7 @@ pub struct DriftUpdate<'info> {
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftUpdateUser))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn update_user_custom_margin_ratio_handler(
ctx: Context<DriftUpdate>,
Expand All @@ -126,7 +126,7 @@ pub fn update_user_custom_margin_ratio_handler(
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftUpdateUser))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn update_user_margin_trading_enabled_handler(
ctx: Context<DriftUpdate>,
Expand All @@ -150,7 +150,7 @@ pub fn update_user_margin_trading_enabled_handler(
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftUpdateUser))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn update_user_delegate_handler(
ctx: Context<DriftUpdate>,
Expand Down Expand Up @@ -204,7 +204,7 @@ pub struct DriftDeposit<'info> {
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftDeposit))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn deposit_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftDeposit<'info>>,
Expand Down Expand Up @@ -267,7 +267,7 @@ pub struct DriftWithdraw<'info> {
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftWithdraw))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn withdraw_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftWithdraw<'info>>,
Expand Down Expand Up @@ -324,7 +324,7 @@ pub struct DriftDeleteUser<'info> {
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftDeleteUser))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn delete_user_handler(ctx: Context<DriftDeleteUser>) -> Result<()> {
delete_user(CpiContext::new_with_signer(
Expand Down Expand Up @@ -365,7 +365,7 @@ pub struct DriftPlaceOrders<'info> {
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftPlaceOrders))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn place_orders_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftPlaceOrders<'info>>,
Expand Down Expand Up @@ -452,7 +452,7 @@ pub struct DriftCancelOrders<'info> {
}

#[access_control(acl::check_access(&ctx.accounts.state, &ctx.accounts.signer.key, Permission::DriftCancelOrders))]
#[access_control(acl::check_integration(&ctx.accounts.state, IntegrationName::Drift))]
#[access_control(acl::check_integration(&ctx.accounts.state, Integration::Drift))]
#[vault_signer_seeds]
pub fn cancel_orders_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, DriftCancelOrders<'info>>,
Expand Down
45 changes: 20 additions & 25 deletions anchor/programs/glam/src/instructions/investor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use anchor_spl::token::Token;
use anchor_spl::token_interface::{
burn, mint_to, transfer_checked, Burn, Mint, MintTo, Token2022, TokenAccount, TransferChecked,
};
use glam_macros::share_class_signer_seeds;
use glam_macros::vault_signer_seeds;
use marinade::state::delayed_unstake_ticket::TicketAccountData;
use pyth_solana_receiver_sdk::price_update::Price;
Expand All @@ -24,7 +25,7 @@ fn log_decimal(amount: u64, minus_decimals: i32) -> f64 {
}

#[derive(Accounts)]
#[instruction(_share_class_id: u8)]
#[instruction(share_class_id: u8)]
pub struct Subscribe<'info> {
#[account()]
pub state: Box<Account<'info, StateAccount>>,
Expand All @@ -35,16 +36,16 @@ pub struct Subscribe<'info> {
// the shares to mint
#[account(
mut,
seeds = [SEED_MINT.as_bytes(), &[_share_class_id], state.key().as_ref()],
seeds = [SEED_MINT.as_bytes(), &[share_class_id], state.key().as_ref()],
bump,
mint::authority = share_class,
mint::authority = share_class_mint,
mint::token_program = token_2022_program
)]
pub share_class: Box<InterfaceAccount<'info, Mint>>,
pub share_class_mint: Box<InterfaceAccount<'info, Mint>>,

#[account(
mut,
associated_token::mint = share_class,
associated_token::mint = share_class_mint,
associated_token::authority = signer,
associated_token::token_program = token_2022_program
)]
Expand Down Expand Up @@ -83,14 +84,15 @@ pub struct Subscribe<'info> {
pub token_2022_program: Program<'info, Token2022>,
}

#[share_class_signer_seeds]
pub fn subscribe_handler<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, Subscribe<'info>>,
_share_class_id: u8,
share_class_id: u8,
amount: u64,
skip_state: bool,
) -> Result<()> {
let state = &ctx.accounts.state;
require!(state.is_enabled(), StateError::Disabled);
require!(state.enabled, StateError::Disabled);

let external_vault_accounts =
state.get_pubkeys_from_engine_field(EngineFieldName::ExternalVaultAccounts);
Expand All @@ -107,7 +109,7 @@ pub fn subscribe_handler<'c: 'info, 'info>(
}
require!(state.mints.len() > 0, StateError::NoShareClass);
require!(
state.mints[0] == ctx.accounts.share_class.key(),
state.mints[0] == ctx.accounts.share_class_mint.key(),
InvestorError::InvalidShareClass
);

Expand Down Expand Up @@ -154,7 +156,7 @@ pub fn subscribe_handler<'c: 'info, 'info>(
}
}

let state_assets = state.assets().unwrap();
let state_assets = &state.assets;
let asset_idx = state_assets
.iter()
.position(|&asset| asset == ctx.accounts.asset.key());
Expand All @@ -168,14 +170,14 @@ pub fn subscribe_handler<'c: 'info, 'info>(
//
// Compute amount of shares to mint
//
let share_class = &ctx.accounts.share_class;
let share_class = &ctx.accounts.share_class_mint;
let share_expo = -(share_class.decimals as i32);
let total_shares = share_class.supply;
let use_fixed_price = total_shares == 0;

let aum_components = get_aum_components(
Action::Subscribe,
state_assets,
&state_assets,
ctx.remaining_accounts,
&ctx.accounts.vault,
&external_vault_accounts,
Expand Down Expand Up @@ -256,23 +258,16 @@ pub fn subscribe_handler<'c: 'info, 'info>(
if skip_state {
// TODO: we should read share class symbol from metadata so that we don't need to pass it as an argument
// mint shares to signer
let state_key = ctx.accounts.state.key();
let seeds = &[
"share".as_bytes(),
&[0u8],
state_key.as_ref(),
&[ctx.bumps.share_class],
];
let signer_seeds = &[&seeds[..]];

mint_to(
CpiContext::new_with_signer(
ctx.accounts.token_2022_program.to_account_info(),
MintTo {
authority: ctx.accounts.share_class.to_account_info(),
authority: ctx.accounts.share_class_mint.to_account_info(),
to: ctx.accounts.signer_share_ata.to_account_info(),
mint: ctx.accounts.share_class.to_account_info(),
mint: ctx.accounts.share_class_mint.to_account_info(),
},
signer_seeds,
share_class_signer_seeds,
),
amount_shares,
)?;
Expand Down Expand Up @@ -325,7 +320,7 @@ pub fn redeem_handler<'c: 'info, 'info>(
skip_state: bool,
) -> Result<()> {
let state = &ctx.accounts.state;
require!(state.is_enabled(), StateError::Disabled);
require!(state.enabled, StateError::Disabled);

let external_vault_accounts =
state.get_pubkeys_from_engine_field(EngineFieldName::ExternalVaultAccounts);
Expand Down Expand Up @@ -397,11 +392,11 @@ pub fn redeem_handler<'c: 'info, 'info>(
share_expo,
);

let assets = state.assets().unwrap();
let assets = &state.assets;
let skip_prices = should_transfer_everything || in_kind;
let aum_components = get_aum_components(
Action::Redeem,
assets,
&assets,
ctx.remaining_accounts,
&ctx.accounts.vault,
&external_vault_accounts,
Expand Down
Loading

0 comments on commit 7ff0fdb

Please sign in to comment.