From 73c069ec1432471c16bb85e3c01c75f09833ca55 Mon Sep 17 00:00:00 2001 From: Vitalii Koval Date: Tue, 17 Dec 2024 17:36:05 +0400 Subject: [PATCH 1/6] implements entry/redemption fees --- .../accountant/src/instructions/set_fee.rs | 28 ++++++++-- programs/accountant/src/lib.rs | 12 ++++- .../accountant/src/state/base_accountant.rs | 12 +++-- .../src/state/generic_accountant.rs | 32 +++++++++--- .../src/utils/unchecked_accountant.rs | 25 +-------- .../src/instructions/deposit.rs | 33 ++++++++++-- .../src/instructions/direct_deposit.rs | 39 +++++++++++--- .../src/instructions/withdraw.rs | 52 ++++++++++++++++++- .../tokenized_vault/src/utils/accountant.rs | 10 ++++ 9 files changed, 194 insertions(+), 49 deletions(-) diff --git a/programs/accountant/src/instructions/set_fee.rs b/programs/accountant/src/instructions/set_fee.rs index a0c2f80..c0f57fb 100644 --- a/programs/accountant/src/instructions/set_fee.rs +++ b/programs/accountant/src/instructions/set_fee.rs @@ -30,12 +30,34 @@ pub struct SetFee<'info> { pub access_control: Program<'info, AccessControl> } -pub fn handle_set_fee( +pub fn handle_set_performance_fee( ctx: Context, fee: u64, ) -> Result<()> { let accountant = &mut ctx.accounts.accountant.from_unchecked()?; - accountant.set_fee(fee)?; + accountant.set_performance_fee(fee)?; accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..]) -} \ No newline at end of file +} + + +pub fn handle_set_entry_fee( + ctx: Context, + fee: u64, +) -> Result<()> { + let accountant = &mut ctx.accounts.accountant.from_unchecked()?; + + accountant.set_entry_fee(fee)?; + accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..]) +} + +pub fn handle_set_redemption_fee( + ctx: Context, + fee: u64, +) -> Result<()> { + let accountant = &mut ctx.accounts.accountant.from_unchecked()?; + + accountant.set_redemption_fee(fee)?; + accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..]) +} + diff --git a/programs/accountant/src/lib.rs b/programs/accountant/src/lib.rs index ecbaf4f..2a916c8 100644 --- a/programs/accountant/src/lib.rs +++ b/programs/accountant/src/lib.rs @@ -45,7 +45,15 @@ pub mod accountant { handle_distribute(ctx) } - pub fn set_fee(ctx: Context, fee: u64) -> Result<()> { - handle_set_fee(ctx, fee) + pub fn set_performance_fee(ctx: Context, fee: u64) -> Result<()> { + handle_set_performance_fee(ctx, fee) + } + + pub fn set_redemption_fee(ctx: Context, fee: u64) -> Result<()> { + handle_set_redemption_fee(ctx, fee) + } + + pub fn set_entry_fee(ctx: Context, fee: u64) -> Result<()> { + handle_set_entry_fee(ctx, fee) } } diff --git a/programs/accountant/src/state/base_accountant.rs b/programs/accountant/src/state/base_accountant.rs index da4d672..d923bda 100644 --- a/programs/accountant/src/state/base_accountant.rs +++ b/programs/accountant/src/state/base_accountant.rs @@ -9,12 +9,18 @@ pub trait Accountant { fn init(&mut self, index: u64, bump: u8) -> Result<()>; fn report(&self, profit: u64, loss: u64) -> Result<(u64,u64)>; + fn enter(&self, amount: u64) -> Result; + fn redeem(&self, amount: u64) -> Result; + fn distribute(&mut self, accounts: &Distribute) -> Result<()>; - fn set_fee_recipient(&mut self, recipient: Pubkey) -> Result<()>; - fn set_fee(&mut self, fee: u64) -> Result<()>; + fn set_performance_fee(&mut self, fee: u64) -> Result<()>; + fn set_redemption_fee(&mut self, fee: u64) -> Result<()>; + fn set_entry_fee(&mut self, fee: u64) -> Result<()>; + + fn entry_fee(&self) -> u64; + fn redemption_fee(&self) -> u64; fn performance_fee(&self) -> u64; - fn fee_recipient(&self) -> Pubkey; fn seeds(&self) -> [&[u8]; 2]; fn save_changes(&self, writer: &mut dyn std::io::Write) -> Result<()>; diff --git a/programs/accountant/src/state/generic_accountant.rs b/programs/accountant/src/state/generic_accountant.rs index 38bfb87..a23aa50 100644 --- a/programs/accountant/src/state/generic_accountant.rs +++ b/programs/accountant/src/state/generic_accountant.rs @@ -12,8 +12,9 @@ pub struct GenericAccountant { pub index_buffer: [u8; 8], pub bump: [u8; 1], + pub entry_fee: u64, + pub redemption_fee: u64, pub performance_fee: u64, - pub fee_recipient: Pubkey, } impl Accountant for GenericAccountant { @@ -36,6 +37,16 @@ impl Accountant for GenericAccountant { Ok((total_fees, total_refunds)) } + fn enter(&self, amount: u64) -> Result { + let fee = self.entry_fee * amount / FEE_BPS; + Ok(fee) + } + + fn redeem(&self, amount: u64) -> Result { + let fee = self.redemption_fee * amount / FEE_BPS; + Ok(fee) + } + fn distribute(&mut self, accounts: &Distribute) -> Result<()> { let total = accounts.token_account.amount; @@ -53,13 +64,18 @@ impl Accountant for GenericAccountant { ) } - fn set_fee(&mut self, fee: u64) -> Result<()> { + fn set_performance_fee(&mut self, fee: u64) -> Result<()> { self.performance_fee = fee; Ok(()) } - fn set_fee_recipient(&mut self, recipient: Pubkey) -> Result<()> { - self.fee_recipient = recipient; + fn set_redemption_fee(&mut self, fee: u64) -> Result<()> { + self.redemption_fee = fee; + Ok(()) + } + + fn set_entry_fee(&mut self, fee: u64) -> Result<()> { + self.entry_fee = fee; Ok(()) } @@ -67,8 +83,12 @@ impl Accountant for GenericAccountant { self.performance_fee } - fn fee_recipient(&self) -> Pubkey { - self.fee_recipient + fn entry_fee(&self) -> u64 { + self.entry_fee + } + + fn redemption_fee(&self) -> u64 { + self.redemption_fee } fn save_changes(&self, writer: &mut dyn std::io::Write) -> Result<()> { diff --git a/programs/accountant/src/utils/unchecked_accountant.rs b/programs/accountant/src/utils/unchecked_accountant.rs index 141b618..3d99d49 100644 --- a/programs/accountant/src/utils/unchecked_accountant.rs +++ b/programs/accountant/src/utils/unchecked_accountant.rs @@ -45,27 +45,4 @@ impl<'a> UncheckedAccountant for UncheckedAccount<'a> { Ok(()) } -} - -// pub fn from_unchecked(strategy_acc: &UncheckedAccount) -> Result> { -// let strategy_data = strategy_acc.try_borrow_data()?; -// let discriminator = get_discriminator(strategy_acc)?; - -// match discriminator { -// GenericAccountant::DISCRIMINATOR => { -// let strategy = GenericAccountant::try_from_slice(&strategy_data[8..]) -// .map_err(|_| ErrorCode::InvalidData)?; -// Ok(Box::new(strategy)) -// } -// _ => { -// msg!("Invalid discriminator"); -// Err(ErrorCode::InvalidDiscriminator.into()) -// } -// } -// } - -// fn get_discriminator(acc_info: &UncheckedAccount) -> Result<[u8; 8]> { -// let data = acc_info.try_borrow_data()?; -// let discriminator = data[0..8].try_into().map_err(|_| ErrorCode::InvalidData)?; -// Ok(discriminator) -// } \ No newline at end of file +} \ No newline at end of file diff --git a/programs/tokenized_vault/src/instructions/deposit.rs b/programs/tokenized_vault/src/instructions/deposit.rs index d34dc8b..fd86919 100644 --- a/programs/tokenized_vault/src/instructions/deposit.rs +++ b/programs/tokenized_vault/src/instructions/deposit.rs @@ -13,13 +13,24 @@ use crate::constants::{SHARES_SEED, UNDERLYING_SEED, WHITELISTED_SEED}; use crate::events::VaultDepositEvent; use crate::state::Vault; -use crate::utils::{token, vault}; +use crate::utils::{accountant, token, vault}; #[derive(Accounts)] pub struct Deposit<'info> { #[account(mut)] pub vault: AccountLoader<'info, Vault>, + /// CHECK: + #[account(mut, address = vault.load()?.accountant)] + pub accountant: UncheckedAccount<'info>, + + #[account( + mut, + associated_token::mint = shares_mint, + associated_token::authority = accountant, + )] + pub accountant_recipient: Box>, + #[account(mut)] pub user_token_account: InterfaceAccount<'info, TokenAccount>, @@ -67,15 +78,18 @@ pub struct Deposit<'info> { } pub fn handle_deposit(ctx: Context, amount: u64) -> Result<()> { + let enter_fee = accountant::enter(&ctx.accounts.accountant, amount)?; + let amount_to_deposit = amount - enter_fee; + vault::validate_deposit( &ctx.accounts.vault, ctx.accounts.kyc_verified.to_account_info(), ctx.accounts.whitelisted.to_account_info(), false, - amount + amount_to_deposit )?; - let shares = ctx.accounts.vault.load()?.convert_to_shares(amount); + let mut shares = ctx.accounts.vault.load()?.convert_to_shares(amount_to_deposit); token::transfer( ctx.accounts.token_program.to_account_info(), @@ -95,6 +109,19 @@ pub fn handle_deposit(ctx: Context, amount: u64) -> Result<()> { &ctx.accounts.vault.load()?.seeds_shares(), )?; + if enter_fee > 0 { + let fee_shares = ctx.accounts.vault.load()?.convert_to_shares(enter_fee); + shares += fee_shares; + token::mint_to( + ctx.accounts.shares_token_program.to_account_info(), + ctx.accounts.shares_mint.to_account_info(), + ctx.accounts.accountant_recipient.to_account_info(), + ctx.accounts.shares_mint.to_account_info(), + fee_shares, + &ctx.accounts.vault.load()?.seeds_shares(), + )?; + } + let mut vault = ctx.accounts.vault.load_mut()?; vault.handle_deposit(amount, shares); diff --git a/programs/tokenized_vault/src/instructions/direct_deposit.rs b/programs/tokenized_vault/src/instructions/direct_deposit.rs index 8621f6a..e1907f1 100644 --- a/programs/tokenized_vault/src/instructions/direct_deposit.rs +++ b/programs/tokenized_vault/src/instructions/direct_deposit.rs @@ -6,7 +6,7 @@ use access_control::{ use anchor_lang::prelude::*; use anchor_spl::{ token::Token, - token_interface::{Mint, TokenAccount}, + token_interface::{Mint, TokenAccount, TokenInterface}, }; use strategy::program::Strategy; @@ -14,14 +14,24 @@ use crate::constants::{SHARES_SEED, STRATEGY_DATA_SEED, UNDERLYING_SEED, WHITELI use crate::events::{VaultDepositEvent, UpdatedCurrentDebtForStrategyEvent}; use crate::state::{Vault, StrategyData}; -use crate::utils::{token, vault}; -use crate::utils::strategy as strategy_utils; +use crate::utils::{accountant, strategy as strategy_utils, token, vault}; #[derive(Accounts)] pub struct DirectDeposit<'info> { #[account(mut)] pub vault: AccountLoader<'info, Vault>, + /// CHECK: + #[account(mut, address = vault.load()?.accountant)] + pub accountant: UncheckedAccount<'info>, + + #[account( + mut, + associated_token::mint = shares_mint, + associated_token::authority = accountant, + )] + pub accountant_recipient: Box>, + #[account(mut)] pub user_token_account: InterfaceAccount<'info, TokenAccount>, @@ -86,21 +96,25 @@ pub struct DirectDeposit<'info> { #[account(mut)] pub user: Signer<'info>, - pub token_program: Program<'info, Token>, + pub shares_token_program: Program<'info, Token>, + pub token_program: Interface<'info, TokenInterface>, pub access_control: Program<'info, AccessControl>, pub strategy_program: Program<'info, Strategy>, } pub fn handle_direct_deposit<'info>(ctx: Context<'_, '_, '_, 'info, DirectDeposit<'info>>, amount: u64) -> Result<()> { + let enter_fee = accountant::enter(&ctx.accounts.accountant, amount)?; + let amount_to_deposit = amount - enter_fee; + vault::validate_deposit( &ctx.accounts.vault, ctx.accounts.kyc_verified.to_account_info(), ctx.accounts.whitelisted.to_account_info(), true, - amount + amount_to_deposit )?; - let shares = ctx.accounts.vault.load()?.convert_to_shares(amount); + let mut shares = ctx.accounts.vault.load()?.convert_to_shares(amount_to_deposit); token::transfer( ctx.accounts.token_program.to_account_info(), @@ -135,6 +149,19 @@ pub fn handle_direct_deposit<'info>(ctx: Context<'_, '_, '_, 'info, DirectDeposi &ctx.accounts.vault.load()?.seeds_shares(), )?; + if enter_fee > 0 { + let fee_shares = ctx.accounts.vault.load()?.convert_to_shares(enter_fee); + shares += fee_shares; + token::mint_to( + ctx.accounts.shares_token_program.to_account_info(), + ctx.accounts.shares_mint.to_account_info(), + ctx.accounts.accountant_recipient.to_account_info(), + ctx.accounts.shares_mint.to_account_info(), + fee_shares, + &ctx.accounts.vault.load()?.seeds_shares(), + )?; + } + let mut vault = ctx.accounts.vault.load_mut()?; ctx.accounts.strategy_data.increase_current_debt(amount)?; diff --git a/programs/tokenized_vault/src/instructions/withdraw.rs b/programs/tokenized_vault/src/instructions/withdraw.rs index 24b75f0..5d9f570 100644 --- a/programs/tokenized_vault/src/instructions/withdraw.rs +++ b/programs/tokenized_vault/src/instructions/withdraw.rs @@ -8,8 +8,7 @@ use strategy::program::Strategy; use crate::events::VaultWithdrawlEvent; use crate::state::{StrategyDataAccInfo, Vault}; -use crate::utils::strategy as strategy_utils; -use crate::utils::token; +use crate::utils::{accountant, strategy as strategy_utils, token}; use crate::errors::ErrorCode; use crate::constants::{ UNDERLYING_SEED, @@ -28,6 +27,17 @@ pub struct Withdraw<'info> { #[account(mut, seeds = [UNDERLYING_SEED.as_bytes(), vault.key().as_ref()], bump)] pub vault_token_account: InterfaceAccount<'info, TokenAccount>, + /// CHECK: + #[account(mut, address = vault.load()?.accountant)] + pub accountant: UncheckedAccount<'info>, + + #[account( + mut, + associated_token::mint = shares_mint, + associated_token::authority = accountant, + )] + pub accountant_recipient: Box>, + #[account(mut, seeds = [SHARES_SEED.as_bytes(), vault.key().as_ref()], bump)] pub shares_mint: InterfaceAccount<'info, Mint>, @@ -66,15 +76,42 @@ struct StrategyAccounts<'info> { } pub fn handle_withdraw<'info>( + ctx: Context<'_, '_, '_, 'info, Withdraw<'info>>, + amount: u64, + max_loss: u64, + remaining_accounts_map: AccountsMap +) -> Result<()> { + let redemtion_fee = accountant::redeem(&ctx.accounts.accountant, amount)?; + let assets_to_withdraw = amount - redemtion_fee; + + let fee_shares = ctx.accounts.vault.load()?.convert_to_shares(redemtion_fee); + let shares_to_burn = ctx.accounts.vault.load()?.convert_to_shares(assets_to_withdraw); + handle_internal(ctx, assets_to_withdraw, shares_to_burn, fee_shares, max_loss, remaining_accounts_map) +} + +pub fn handle_redeem<'info>( + ctx: Context<'_, '_, '_, 'info, Withdraw<'info>>, + shares: u64, + max_loss: u64, + remaining_accounts_map: AccountsMap +) -> Result<()> { + let redemtion_fee_shares = accountant::redeem(&ctx.accounts.accountant, shares)?; + let amount = ctx.accounts.vault.load()?.convert_to_underlying(shares-redemtion_fee_shares); + handle_internal(ctx, amount, shares-redemtion_fee_shares, redemtion_fee_shares, max_loss, remaining_accounts_map) +} + +fn handle_internal<'info>( ctx: Context<'_, '_, '_, 'info, Withdraw<'info>>, assets: u64, shares_to_burn: u64, + fee_shares: u64, max_loss: u64, remaining_accounts_map: AccountsMap ) -> Result<()> { if assets == 0 || shares_to_burn == 0 { return Err(ErrorCode::ZeroValue.into()); } + let vault_token_account = &mut ctx.accounts.vault_token_account; let user_shares_balance = ctx.accounts.user_shares_account.amount; let remaining_accounts = ctx.remaining_accounts; @@ -119,6 +156,17 @@ pub fn handle_withdraw<'info>( shares_to_burn )?; + if fee_shares > 0 { + token::transfer( + ctx.accounts.token_program.to_account_info(), + ctx.accounts.user_shares_account.to_account_info(), + ctx.accounts.accountant_recipient.to_account_info(), + ctx.accounts.user.to_account_info(), + &ctx.accounts.shares_mint, + fee_shares, + )?; + } + token::transfer_with_signer( ctx.accounts.token_program.to_account_info(), ctx.accounts.vault_token_account.to_account_info(), diff --git a/programs/tokenized_vault/src/utils/accountant.rs b/programs/tokenized_vault/src/utils/accountant.rs index 393c23f..7024b95 100644 --- a/programs/tokenized_vault/src/utils/accountant.rs +++ b/programs/tokenized_vault/src/utils/accountant.rs @@ -10,6 +10,16 @@ pub fn report(acccountant: &UncheckedAccount, profit: u64, loss: u64) -> Result< ) } +pub fn redeem(acccountant: &UncheckedAccount, amount: u64) -> Result{ + let acc = acccountant.from_unchecked()?; + acc.redeem(amount) +} + +pub fn enter(acccountant: &UncheckedAccount, amount: u64) -> Result{ + let acc = acccountant.from_unchecked()?; + acc.enter(amount) +} + pub fn performance_fee(acccountant: &UncheckedAccount) -> Result{ let acc = acccountant.from_unchecked()?; Ok(acc.performance_fee()) From 181be4d1c6e891bf07688a45c5d3f46493d4e8f1 Mon Sep 17 00:00:00 2001 From: Vitalii Koval Date: Tue, 17 Dec 2024 19:47:45 +0400 Subject: [PATCH 2/6] fix tests --- .../tests/rolesPermissions.test.ts | 287 +++++++++++++++++- .../tests/vaultUserOperations/deposit.test.ts | 23 ++ 2 files changed, 305 insertions(+), 5 deletions(-) diff --git a/tests/integration/tests/rolesPermissions.test.ts b/tests/integration/tests/rolesPermissions.test.ts index 1a7c722..26e2172 100644 --- a/tests/integration/tests/rolesPermissions.test.ts +++ b/tests/integration/tests/rolesPermissions.test.ts @@ -370,7 +370,7 @@ describe("Roles and Permissions Tests", () => { it("Accountant Admin - Calling set fee method is successful", async function () { await accountantProgram.methods - .setFee(new BN(500)) + .setPerformanceFee(new BN(500)) .accounts({ accountant: accountantOne, signer: accountantAdmin.publicKey, @@ -899,10 +899,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -1228,10 +1247,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -1372,11 +1410,30 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + try { await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: accountantAdmin.publicKey, userTokenAccount: tokenAccount, userSharesAccount: sharesAccount, @@ -1477,7 +1534,7 @@ describe("Roles and Permissions Tests", () => { it("Strategies Manager - Calling set fee method should revert", async function () { try { await accountantProgram.methods - .setFee(new BN(100)) + .setPerformanceFee(new BN(100)) .accounts({ accountant: accountantOne, signer: strategiesManager.publicKey, @@ -1991,10 +2048,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -2320,10 +2396,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -2457,11 +2552,30 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + try { await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: strategiesManager.publicKey, userTokenAccount: strategiesManagerOneTokenAccount, userSharesAccount: sharesAccount, @@ -2855,10 +2969,21 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vaultOne, + accountant: accountantOne, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccountVaultOne, @@ -3091,7 +3216,7 @@ describe("Roles and Permissions Tests", () => { it("Vaults Admin - Calling set fee method should revert", async function () { try { await accountantProgram.methods - .setFee(new BN(100)) + .setPerformanceFee(new BN(100)) .accounts({ accountant: accountantOne, signer: vaultsAdmin.publicKey, @@ -3236,10 +3361,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -3380,11 +3524,30 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + try { await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: vaultsAdmin.publicKey, userTokenAccount: tokenAccount, userSharesAccount: sharesAccount, @@ -3528,7 +3691,7 @@ describe("Roles and Permissions Tests", () => { it("Reporting Manager - Calling set fee method should revert", async function () { try { await accountantProgram.methods - .setFee(new BN(100)) + .setPerformanceFee(new BN(100)) .accounts({ accountant: accountantOne, signer: reportingManager.publicKey, @@ -4042,10 +4205,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -4369,11 +4551,30 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + try { await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: reportingManager.publicKey, userTokenAccount: tokenAccount, userSharesAccount: sharesAccount, @@ -4478,10 +4679,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: userSharesAccount, @@ -4558,7 +4778,7 @@ describe("Roles and Permissions Tests", () => { it("KYC Verified User - Calling set fee method should revert", async function () { try { await accountantProgram.methods - .setFee(new BN(100)) + .setPerformanceFee(new BN(100)) .accounts({ accountant: accountantOne, signer: kycVerifiedUser.publicKey, @@ -5095,10 +5315,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -5428,10 +5667,29 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccount, @@ -5556,11 +5814,30 @@ describe("Roles and Permissions Tests", () => { accessControlProgram.programId )[0]; + const accountantType = { generic: {} }; + + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: accountantAdmin.publicKey, + }) + .signers([accountantAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: accountantAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([accountantAdmin]) + .rpc(); + try { await vaultProgram.methods .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: nonVerifiedUser.publicKey, userTokenAccount: nonVerifiedUserTokenAccount, userSharesAccount: userSharesAccount, diff --git a/tests/integration/tests/vaultUserOperations/deposit.test.ts b/tests/integration/tests/vaultUserOperations/deposit.test.ts index 51f1fda..5763eae 100644 --- a/tests/integration/tests/vaultUserOperations/deposit.test.ts +++ b/tests/integration/tests/vaultUserOperations/deposit.test.ts @@ -433,6 +433,7 @@ describe("Vault User Operations: Deposit Tests", () => { .deposit(new BN(depositAmount)) .accounts({ vault: vaultOne, + accountant: accountantOne, user: kycVerifiedUser.publicKey, userTokenAccount: kycVerifiedUserTokenAccount, userSharesAccount: kycVerifiedUserSharesAccountVaultOne, @@ -497,6 +498,7 @@ describe("Vault User Operations: Deposit Tests", () => { .deposit(new BN(depositAmount)) .accounts({ vault: vaultOne, + accountant: accountantOne, user: whitelistedUser.publicKey, userTokenAccount: whitelistedUserTokenAccount, userSharesAccount: whitelistedUserSharesAccountVaultOne, @@ -561,6 +563,7 @@ describe("Vault User Operations: Deposit Tests", () => { .deposit(new BN(depositAmount)) .accounts({ vault: vaultOne, + accountant: accountantOne, user: kycVerifiedWhitelistedUser.publicKey, userTokenAccount: kycVerifiedWhitelistedUserTokenAccount, userSharesAccount: kycVerifiedWhitelistedUserSharesAccountVaultOne, @@ -628,6 +631,7 @@ describe("Vault User Operations: Deposit Tests", () => { .deposit(new BN(depositAmount)) .accounts({ vault: vaultOne, + accountant: accountantOne, user: kycVerifiedWhitelistedUser.publicKey, userTokenAccount: kycVerifiedWhitelistedUserTokenAccount, userSharesAccount: kycVerifiedWhitelistedUserSharesAccountVaultOne, @@ -695,6 +699,7 @@ describe("Vault User Operations: Deposit Tests", () => { .deposit(new BN(depositAmount)) .accounts({ vault: vaultOne, + accountant: accountantOne, user: kycVerifiedWhitelistedUser.publicKey, userTokenAccount: kycVerifiedWhitelistedUserTokenAccount, userSharesAccount: kycVerifiedWhitelistedUserSharesAccountVaultOne, @@ -804,6 +809,22 @@ describe("Vault User Operations: Deposit Tests", () => { accessControlProgram.programId )[0]; + await accountantProgram.methods.initAccountant(accountantType) + .accounts({ + signer: generalAdmin.publicKey, + }) + .signers([generalAdmin]) + .rpc(); + + await accountantProgram.methods.initTokenAccount() + .accounts({ + accountant: accountant, + signer: generalAdmin.publicKey, + underlyingMint: sharesMint, + }) + .signers([generalAdmin]) + .rpc(); + await vaultProgram.methods .shutdownVault() .accounts({ vault, signer: generalAdmin.publicKey }) @@ -815,6 +836,7 @@ describe("Vault User Operations: Deposit Tests", () => { .deposit(new BN(depositAmount)) .accounts({ vault: vault, + accountant: accountant, user: kycVerifiedWhitelistedUser.publicKey, userTokenAccount: kycVerifiedWhitelistedUserTokenAccount, userSharesAccount: userSharesAccount, @@ -874,6 +896,7 @@ describe("Vault User Operations: Deposit Tests", () => { .deposit(new BN(depositAmount)) .accounts({ vault: vaultOne, + accountant: accountantOne, user: kycVerifiedWhitelistedUser.publicKey, userTokenAccount: kycVerifiedWhitelistedUserTokenAccount, userSharesAccount: kycVerifiedWhitelistedUserSharesAccountVaultOne, From 95fc24ef68656d26c2d64298c0980205b005ef62 Mon Sep 17 00:00:00 2001 From: Vitalii Koval Date: Wed, 18 Dec 2024 11:40:50 +0400 Subject: [PATCH 3/6] add events --- programs/accountant/src/events.rs | 19 +++++++++++++ .../accountant/src/instructions/set_fee.rs | 28 +++++++++++++++++-- programs/accountant/src/lib.rs | 1 + 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 programs/accountant/src/events.rs diff --git a/programs/accountant/src/events.rs b/programs/accountant/src/events.rs new file mode 100644 index 0000000..55b6d06 --- /dev/null +++ b/programs/accountant/src/events.rs @@ -0,0 +1,19 @@ +use anchor_lang::prelude::*; + +#[event] +pub struct PerformanceFeeUpdatedEvent { + pub accountant_key: Pubkey, + pub performance_fee: u64, +} + +#[event] +pub struct EntryFeeUpdatedEvent { + pub accountant_key: Pubkey, + pub entry_fee: u64, +} + +#[event] +pub struct RedemptionFeeUpdatedEvent { + pub accountant_key: Pubkey, + pub redemption_fee: u64, +} \ No newline at end of file diff --git a/programs/accountant/src/instructions/set_fee.rs b/programs/accountant/src/instructions/set_fee.rs index c0f57fb..df26c85 100644 --- a/programs/accountant/src/instructions/set_fee.rs +++ b/programs/accountant/src/instructions/set_fee.rs @@ -5,6 +5,7 @@ use access_control::{ state::{UserRole, Role} }; +use crate::events::{EntryFeeUpdatedEvent, PerformanceFeeUpdatedEvent, RedemptionFeeUpdatedEvent}; use crate::utils::unchecked_accountant::UncheckedAccountant; #[derive(Accounts)] @@ -37,7 +38,14 @@ pub fn handle_set_performance_fee( let accountant = &mut ctx.accounts.accountant.from_unchecked()?; accountant.set_performance_fee(fee)?; - accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..]) + accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..])?; + + emit!(PerformanceFeeUpdatedEvent { + accountant_key: ctx.accounts.accountant.key(), + performance_fee: fee, + }); + + Ok(()) } @@ -48,7 +56,14 @@ pub fn handle_set_entry_fee( let accountant = &mut ctx.accounts.accountant.from_unchecked()?; accountant.set_entry_fee(fee)?; - accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..]) + accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..])?; + + emit!(EntryFeeUpdatedEvent { + accountant_key: ctx.accounts.accountant.key(), + entry_fee: fee, + }); + + Ok(()) } pub fn handle_set_redemption_fee( @@ -58,6 +73,13 @@ pub fn handle_set_redemption_fee( let accountant = &mut ctx.accounts.accountant.from_unchecked()?; accountant.set_redemption_fee(fee)?; - accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..]) + accountant.save_changes(&mut &mut ctx.accounts.accountant.try_borrow_mut_data()?[8..])?; + + emit!(RedemptionFeeUpdatedEvent { + accountant_key: ctx.accounts.accountant.key(), + redemption_fee: fee, + }); + + Ok(()) } diff --git a/programs/accountant/src/lib.rs b/programs/accountant/src/lib.rs index 2a916c8..30cb38e 100644 --- a/programs/accountant/src/lib.rs +++ b/programs/accountant/src/lib.rs @@ -2,6 +2,7 @@ use anchor_lang::prelude::*; pub mod constants; pub mod error; +pub mod events; pub mod instructions; pub mod state; pub mod utils; From 814857e9e681bb21ac775c05a9e3f3deb74d461e Mon Sep 17 00:00:00 2001 From: Vitalii Koval Date: Wed, 18 Dec 2024 11:57:31 +0400 Subject: [PATCH 4/6] add missing changes --- programs/tokenized_vault/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/programs/tokenized_vault/src/lib.rs b/programs/tokenized_vault/src/lib.rs index 4ebcc65..32a3e73 100644 --- a/programs/tokenized_vault/src/lib.rs +++ b/programs/tokenized_vault/src/lib.rs @@ -42,8 +42,7 @@ pub mod tokenized_vault { max_loss: u64, remaining_accounts_map: AccountsMap ) -> Result<()> { - let shares = ctx.accounts.vault.load()?.convert_to_shares(amount); - handle_withdraw(ctx, amount, shares, max_loss, remaining_accounts_map) + handle_withdraw(ctx, amount, max_loss, remaining_accounts_map) } pub fn redeem<'info>( @@ -52,8 +51,7 @@ pub mod tokenized_vault { max_loss: u64, remaining_accounts_map: AccountsMap ) -> Result<()> { - let amount = ctx.accounts.vault.load()?.convert_to_underlying(shares); - handle_withdraw(ctx, amount, shares, max_loss, remaining_accounts_map) + handle_redeem(ctx, shares, max_loss, remaining_accounts_map) } pub fn add_strategy(ctx: Context, max_debt: u64) -> Result<()> { From 03a0ff8e147e4238ac146aae0889fdffc496f494 Mon Sep 17 00:00:00 2001 From: Vitalii Koval Date: Wed, 18 Dec 2024 13:49:35 +0400 Subject: [PATCH 5/6] add validation; variable renaming --- programs/accountant/src/error.rs | 3 +++ .../src/instructions/init_token_account.rs | 4 ++-- programs/accountant/src/state/generic_accountant.rs | 12 ++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/programs/accountant/src/error.rs b/programs/accountant/src/error.rs index c5910ee..21cb0b5 100644 --- a/programs/accountant/src/error.rs +++ b/programs/accountant/src/error.rs @@ -10,4 +10,7 @@ pub enum ErrorCode { #[msg("Serialization error")] SerializationError, + + #[msg("Fee is invalid")] + InvalidFee, } diff --git a/programs/accountant/src/instructions/init_token_account.rs b/programs/accountant/src/instructions/init_token_account.rs index f4f3d58..659f8e8 100644 --- a/programs/accountant/src/instructions/init_token_account.rs +++ b/programs/accountant/src/instructions/init_token_account.rs @@ -18,13 +18,13 @@ pub struct InitTokenAccount<'info> { #[account( init_if_needed, payer = signer, - associated_token::mint = underlying_mint, + associated_token::mint = mint, associated_token::authority = accountant, )] pub token_account: Box>, #[account(mut)] - pub underlying_mint: Box>, + pub mint: Box>, /// CHECK: We want to hadle all accountant types here #[account(mut)] diff --git a/programs/accountant/src/state/generic_accountant.rs b/programs/accountant/src/state/generic_accountant.rs index a23aa50..0ff8ee9 100644 --- a/programs/accountant/src/state/generic_accountant.rs +++ b/programs/accountant/src/state/generic_accountant.rs @@ -65,16 +65,28 @@ impl Accountant for GenericAccountant { } fn set_performance_fee(&mut self, fee: u64) -> Result<()> { + if fee > FEE_BPS { + return Err(ErrorCode::InvalidFee.into()); + } + self.performance_fee = fee; Ok(()) } fn set_redemption_fee(&mut self, fee: u64) -> Result<()> { + if fee > FEE_BPS { + return Err(ErrorCode::InvalidFee.into()); + } + self.redemption_fee = fee; Ok(()) } fn set_entry_fee(&mut self, fee: u64) -> Result<()> { + if fee > FEE_BPS { + return Err(ErrorCode::InvalidFee.into()); + } + self.entry_fee = fee; Ok(()) } From bed1d386c95306b73987b0c611eb9d01e35b44ee Mon Sep 17 00:00:00 2001 From: Vitalii Koval Date: Wed, 18 Dec 2024 14:17:31 +0400 Subject: [PATCH 6/6] fix tests --- .../tests/rolesPermissions.test.ts | 32 +++++++++---------- .../tests/vaultUserOperations/deposit.test.ts | 6 ++-- tests/integration/vault.ts | 8 +++-- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/tests/integration/tests/rolesPermissions.test.ts b/tests/integration/tests/rolesPermissions.test.ts index 26e2172..7979184 100644 --- a/tests/integration/tests/rolesPermissions.test.ts +++ b/tests/integration/tests/rolesPermissions.test.ts @@ -259,7 +259,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountantOne, signer: accountantAdmin.publicKey, - underlyingMint: sharesMintOne, + mint: sharesMintOne, }) .signers([accountantAdmin]) .rpc(); @@ -269,7 +269,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountantOne, signer: accountantAdmin.publicKey, - underlyingMint: underlyingMint, + mint: underlyingMint, }) .signers([accountantAdmin]) .rpc(); @@ -912,7 +912,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -1260,7 +1260,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -1423,7 +1423,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -2061,7 +2061,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -2409,7 +2409,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -2565,7 +2565,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -3374,7 +3374,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -3537,7 +3537,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -4218,7 +4218,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -4564,7 +4564,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -4692,7 +4692,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -5328,7 +5328,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -5680,7 +5680,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); @@ -5827,7 +5827,7 @@ describe("Roles and Permissions Tests", () => { .accounts({ accountant: accountant, signer: accountantAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([accountantAdmin]) .rpc(); diff --git a/tests/integration/tests/vaultUserOperations/deposit.test.ts b/tests/integration/tests/vaultUserOperations/deposit.test.ts index 5763eae..903e6d6 100644 --- a/tests/integration/tests/vaultUserOperations/deposit.test.ts +++ b/tests/integration/tests/vaultUserOperations/deposit.test.ts @@ -292,7 +292,7 @@ describe("Vault User Operations: Deposit Tests", () => { .accounts({ accountant: accountantOne, signer: generalAdmin.publicKey, - underlyingMint: sharesMintOne, + mint: sharesMintOne, }) .signers([generalAdmin]) .rpc(); @@ -302,7 +302,7 @@ describe("Vault User Operations: Deposit Tests", () => { .accounts({ accountant: accountantOne, signer: generalAdmin.publicKey, - underlyingMint: underlyingMint, + mint: underlyingMint, }) .signers([generalAdmin]) .rpc(); @@ -820,7 +820,7 @@ describe("Vault User Operations: Deposit Tests", () => { .accounts({ accountant: accountant, signer: generalAdmin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([generalAdmin]) .rpc(); diff --git a/tests/integration/vault.ts b/tests/integration/vault.ts index 0aed44c..00ed5d3 100644 --- a/tests/integration/vault.ts +++ b/tests/integration/vault.ts @@ -296,7 +296,7 @@ describe("tokenized_vault", () => { console.log("Accountant inited"); - await accountantProgram.methods.setFee(new BN(500)) + await accountantProgram.methods.setPerformanceFee(new BN(500)) .accounts({ accountant: accountant, signer: admin.publicKey, @@ -382,7 +382,7 @@ describe("tokenized_vault", () => { .accounts({ accountant: accountant, signer: admin.publicKey, - underlyingMint: sharesMint, + mint: sharesMint, }) .signers([admin]) .rpc(); @@ -391,7 +391,7 @@ describe("tokenized_vault", () => { .accounts({ accountant: accountant, signer: admin.publicKey, - underlyingMint: underlyingMint, + mint: underlyingMint, }) .signers([admin]) .rpc(); @@ -540,6 +540,7 @@ describe("tokenized_vault", () => { .accounts({ vault, underlyingMint, + accountant, // strategy, user: user.publicKey, userTokenAccount, @@ -1105,6 +1106,7 @@ describe("tokenized_vault", () => { await vaultProgram.methods.deposit(new BN(100)) .accounts({ vault, + accountant, underlyingMint, user: user.publicKey, userTokenAccount,