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: fix error codes #381

Merged
merged 1 commit into from
Feb 1, 2025
Merged
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
88 changes: 44 additions & 44 deletions anchor/programs/glam/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
use anchor_lang::prelude::*;

#[error_code]
pub enum AccessError {
pub enum GlamError {
// Access control errors (42000-)
#[msg("Signer is not authorized")]
NotAuthorized,
NotAuthorized = 42000,

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

#[msg("Wrong state account type")]
WrongStateType,
}
#[msg("State account is disabled")]
StateAccountDisabled,

#[error_code]
pub enum StateError {
#[msg("Invalid signer ata")]
InvalidSignerAccount,

// State & mint errors (43000-)
#[msg("Invalid account type")]
InvalidAccountType,
InvalidAccountType = 43000,

#[msg("Name too long: max 64 chars")]
InvalidName,
Expand All @@ -29,71 +31,69 @@ pub enum StateError {
#[msg("Too many assets: max 100")]
InvalidAssetsLen,

#[msg("State account is disabled")]
Disabled,
#[msg("Error closing state account: not empty")]
CloseNotEmptyError,

#[msg("No share class found")]
NoShareClass,

#[msg("Glam state account can't be closed. Close share classes first")]
ShareClassesNotClosed,

#[msg("Error closing state account: not empty")]
CloseNotEmptyError,
#[msg("Share class not allowed to subscribe")]
InvalidShareClass,

#[msg("Asset not allowed to subscribe")]
InvalidAssetSubscribe,

#[msg("Invalid oracle for asset price")]
InvalidPricingOracle,

#[msg("Invalid accounts: the transaction is malformed")]
InvalidRemainingAccounts,

#[msg("Invalid vault ata")]
InvalidVaultTokenAccount,

#[msg("Share class mint supply not zero")]
ShareClassNotEmpty,

// Vault errors (44000-)
#[msg("Withdraw denied. Only vaults allow withdraws (funds and mints don't)")]
WithdrawDenied,
}
WithdrawDenied = 44000,

#[error_code]
pub enum SwapError {
#[msg("Asset cannot be swapped")]
InvalidAssetForSwap,

#[msg("Swap failed")]
InvalidSwap,
}

#[error_code]
pub enum InvestorError {
#[msg("Share class not allowed to subscribe")]
InvalidShareClass,
#[msg("Asset not allowed to subscribe")]
InvalidAssetSubscribe,
#[msg("Invalid oracle for asset price")]
InvalidPricingOracle,
#[msg("Invalid accounts: the transaction is malformed")]
InvalidRemainingAccounts,
#[msg("Invalid treasury ata")]
InvalidTreasuryAccount,
#[msg("Invalid signer ata")]
InvalidSignerAccount,
#[msg("Invalid token account")]
InvalidTokenAccount,

// Subscription & redemption errors (45000-)
#[msg("Invalid asset price")]
InvalidAssetPrice,
InvalidAssetPrice = 45000,

#[msg("Subscription not allowed: invalid stable coin price")]
InvalidStableCoinPriceForSubscribe,

#[msg("Fund is disabled for subscription and redemption")]
SubscribeRedeemDisable,

#[msg("Policy account is mandatory")]
InvalidPolicyAccount,

#[msg("Price is too old")]
PriceTooOld,
}

#[error_code]
pub enum ShareClassError {
#[msg("Share class mint supply not zero")]
ShareClassNotEmpty,
#[msg("Invalid token account")]
InvalidTokenAccount,
}

#[error_code]
pub enum PolicyError {
// Transfer hook errors (46000-)
#[msg("Policy violation: transfers disabled")]
TransfersDisabled,
TransfersDisabled = 46000,

#[msg("Policy violation: amount too big")]
AmountTooBig,

#[msg("Policy violation: lock-up period")]
LockUp,
}
8 changes: 4 additions & 4 deletions anchor/programs/glam/src/instructions/drift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anchor_spl::token_interface::TokenAccount;
use drift::{MarketType, PositionDirection};
use glam_macros::vault_signer_seeds;

use crate::error::AccessError;
use crate::error::GlamError;
use crate::{constants::*, state::*};

use drift::cpi::accounts::{
Expand Down Expand Up @@ -385,7 +385,7 @@ pub fn place_orders_handler<'c: 'info, 'info>(
if drift_market_indexes_spot.len() > 0 {
require!(
drift_market_indexes_spot.contains(&(order.market_index as u32)),
AccessError::NotAuthorized
GlamError::NotAuthorized
);
}
}
Expand All @@ -395,7 +395,7 @@ pub fn place_orders_handler<'c: 'info, 'info>(
if drift_market_indexes_perp.len() > 0 {
require!(
drift_market_indexes_perp.contains(&(order.market_index as u32)),
AccessError::NotAuthorized
GlamError::NotAuthorized
);
}
}
Expand All @@ -405,7 +405,7 @@ pub fn place_orders_handler<'c: 'info, 'info>(
if drift_order_types.len() > 0 {
require!(
drift_order_types.contains(&(order.order_type as u32)),
AccessError::NotAuthorized
GlamError::NotAuthorized
);
}
}
Expand Down
50 changes: 25 additions & 25 deletions anchor/programs/glam/src/instructions/investor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use pyth_solana_receiver_sdk::price_update::Price;
use solana_program::stake::state::warmup_cooldown_rate;

use crate::constants::{self, WSOL};
use crate::error::{InvestorError, PolicyError, StateError};
use crate::error::GlamError;
use crate::instructions::policy_hook::PolicyAccount;
use crate::state::pyth_price::PriceExt;
use crate::{constants::*, state::*};
Expand Down Expand Up @@ -92,25 +92,25 @@ pub fn subscribe_handler<'c: 'info, 'info>(
skip_state: bool,
) -> Result<()> {
let state = &ctx.accounts.state;
require!(state.enabled, StateError::Disabled);
require!(state.enabled, GlamError::StateAccountDisabled);

let external_vault_accounts =
state.get_pubkeys_from_engine_field(EngineFieldName::ExternalVaultAccounts);

// If system program is in the external vault accounts, it means that
// the state is disabled for subscription and redemption.
if external_vault_accounts.contains(&system_program::ID) {
return err!(InvestorError::SubscribeRedeemDisable);
return err!(GlamError::SubscribeRedeemDisable);
}

if state.mints.len() > 1 {
// we need to define how to split the total amount into share classes
panic!("not implemented")
}
require!(state.mints.len() > 0, StateError::NoShareClass);
require!(state.mints.len() > 0, GlamError::NoShareClass);
require!(
state.mints[0] == ctx.accounts.share_class_mint.key(),
InvestorError::InvalidShareClass
GlamError::InvalidShareClass
);

if let Some(share_class_blocklist) = state.share_class_blocklist(0) {
Expand All @@ -119,7 +119,7 @@ pub fn subscribe_handler<'c: 'info, 'info>(
|| !share_class_blocklist
.iter()
.any(|&k| k == ctx.accounts.signer.key()),
InvestorError::InvalidShareClass
GlamError::InvalidShareClass
);
}

Expand All @@ -129,7 +129,7 @@ pub fn subscribe_handler<'c: 'info, 'info>(
|| share_class_allowlist
.iter()
.any(|&k| k == ctx.accounts.signer.key()),
InvestorError::InvalidShareClass
GlamError::InvalidShareClass
);
}

Expand All @@ -138,7 +138,7 @@ pub fn subscribe_handler<'c: 'info, 'info>(
if lock_up > 0 {
require!(
ctx.accounts.signer_policy.is_some(),
InvestorError::InvalidPolicyAccount
GlamError::InvalidPolicyAccount
);
let signer_policy = ctx.accounts.signer_policy.as_mut().unwrap();

Expand All @@ -160,7 +160,7 @@ pub fn subscribe_handler<'c: 'info, 'info>(
let asset_idx = state_assets
.iter()
.position(|&asset| asset == ctx.accounts.asset.key());
require!(asset_idx.is_some(), InvestorError::InvalidAssetSubscribe);
require!(asset_idx.is_some(), GlamError::InvalidAssetSubscribe);
// msg!("asset={:?} idx={:?}", asset_key, asset_idx);

let asset_idx = asset_idx.unwrap();
Expand Down Expand Up @@ -320,25 +320,25 @@ pub fn redeem_handler<'c: 'info, 'info>(
skip_state: bool,
) -> Result<()> {
let state = &ctx.accounts.state;
require!(state.enabled, StateError::Disabled);
require!(state.enabled, GlamError::StateAccountDisabled);

let external_vault_accounts =
state.get_pubkeys_from_engine_field(EngineFieldName::ExternalVaultAccounts);

// If system program is in the external vault accounts, it means that
// the state is disabled for subscription and redemption.
if external_vault_accounts.contains(&system_program::ID) {
return err!(InvestorError::SubscribeRedeemDisable);
return err!(GlamError::SubscribeRedeemDisable);
}

if ctx.accounts.state.mints.len() > 1 {
// we need to define how to split the total amount into share classes
panic!("not implemented")
}
require!(state.mints.len() > 0, StateError::NoShareClass);
require!(state.mints.len() > 0, GlamError::NoShareClass);
require!(
state.mints[0] == ctx.accounts.share_class.key(),
InvestorError::InvalidShareClass
GlamError::InvalidShareClass
);

// Lock-up
Expand All @@ -347,7 +347,7 @@ pub fn redeem_handler<'c: 'info, 'info>(
if lock_up > 0 {
require!(
ctx.accounts.signer_policy.is_some(),
InvestorError::InvalidPolicyAccount
GlamError::InvalidPolicyAccount
);
let signer_policy = &ctx.accounts.signer_policy.clone().unwrap();

Expand All @@ -367,7 +367,7 @@ pub fn redeem_handler<'c: 'info, 'info>(

let cur_timestamp = Clock::get()?.unix_timestamp;
if cur_timestamp < locked_until_ts {
return err!(PolicyError::LockUp);
return err!(GlamError::LockUp);
}

// If the lock-up period has expired, we can delete the
Expand Down Expand Up @@ -499,7 +499,7 @@ pub fn redeem_handler<'c: 'info, 'info>(
);
require!(
!att.vault_ata.is_none(),
InvestorError::InvalidTreasuryAccount
GlamError::InvalidVaultTokenAccount
);

let signer_asset_ata = att.signer_asset_ata.clone().unwrap();
Expand Down Expand Up @@ -587,20 +587,20 @@ pub fn get_aum_components<'info>(

require!(
stake_accounts.len() + marinade_tickets.len() == external_vault_accounts.len(),
InvestorError::InvalidRemainingAccounts
GlamError::InvalidRemainingAccounts
);

for account in stake_accounts.iter().chain(marinade_tickets.iter()) {
require!(
external_vault_accounts.contains(&account.key()),
InvestorError::InvalidRemainingAccounts
GlamError::InvalidRemainingAccounts
);
}

let num_accounts = if action == Action::Subscribe { 2 } else { 4 };
require!(
accounts_for_pricing.len() == num_accounts * assets.len(),
InvestorError::InvalidRemainingAccounts
GlamError::InvalidRemainingAccounts
);

//
Expand Down Expand Up @@ -661,15 +661,15 @@ pub fn get_aum_components<'info>(
);
require!(
pricing_account.key().to_string().as_str() == expected_pricing_account,
InvestorError::InvalidPricingOracle
GlamError::InvalidPricingOracle
);

let (asset, signer_asset_ata) = if action == Action::Redeem {
// Parse and deser asset mint account
let asset_account = &accounts[2];
require!(
asset_account.key() == assets[i],
InvestorError::InvalidRemainingAccounts
GlamError::InvalidRemainingAccounts
);
let asset = InterfaceAccount::<Mint>::try_from(asset_account).expect("invalid asset");

Expand All @@ -682,11 +682,11 @@ pub fn get_aum_components<'info>(
));
require!(
signer_asset_ata.mint == cur_asset,
InvestorError::InvalidSignerAccount
GlamError::InvalidSignerAccount
);
require!(
signer_asset_ata.owner == signer.key(),
InvestorError::InvalidSignerAccount
GlamError::InvalidSignerAccount
);

(Some(asset), Some(signer_asset_ata))
Expand All @@ -700,11 +700,11 @@ pub fn get_aum_components<'info>(
let mut asset_amount = if let Ok(vault_ata) = &maybe_vault_ata {
require!(
vault_ata.mint == cur_asset,
InvestorError::InvalidTreasuryAccount
GlamError::InvalidVaultTokenAccount
);
require!(
vault_ata.owner == vault.key(),
InvestorError::InvalidTreasuryAccount
GlamError::InvalidVaultTokenAccount
);
vault_ata.amount
} else {
Expand Down
Loading