Skip to content

Commit

Permalink
use separate pda's for storing strategy data info
Browse files Browse the repository at this point in the history
  • Loading branch information
vito-kovalione committed Nov 8, 2024
1 parent 5d5d0a0 commit faf321b
Show file tree
Hide file tree
Showing 21 changed files with 446 additions and 329 deletions.
4 changes: 2 additions & 2 deletions programs/strategy/src/instructions/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use anchor_spl::{
};

use crate::error::ErrorCode;
use crate::utils::token::transfer_token_to;
use crate::utils::token::transfer;
use crate::utils::unchecked_strategy::UncheckedStrategy;
use crate::constants::UNDERLYING_SEED;

Expand Down Expand Up @@ -39,7 +39,7 @@ pub fn handle_deposit<'info>(
return Err(ErrorCode::MaxDepositReached.into());
}

transfer_token_to(
transfer(
ctx.accounts.token_program.to_account_info(),
ctx.accounts.vault_token_account.to_account_info(),
ctx.accounts.underlying_token_account.to_account_info(),
Expand Down
2 changes: 1 addition & 1 deletion programs/strategy/src/instructions/withdraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn handle_withdraw<'info>(
strategy.withdraw(amount)?;
strategy.save_changes(&mut &mut ctx.accounts.strategy.try_borrow_mut_data()?[8..])?;

token::transfer_token_from(
token::transfer_with_signer(
ctx.accounts.token_program.to_account_info(),
ctx.accounts.underlying_token_account.to_account_info(),
ctx.accounts.vault_token_account.to_account_info(),
Expand Down
2 changes: 1 addition & 1 deletion programs/strategy/src/instructions/withdraw_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub fn handle_withdraw_fee<'info>(
strategy.withdraw_fees(amount)?;
strategy.save_changes(&mut &mut ctx.accounts.strategy.try_borrow_mut_data()?[8..])?;

token::transfer_token_from(
token::transfer_with_signer(
ctx.accounts.token_program.to_account_info(),
ctx.accounts.underlying_token_account.to_account_info(),
ctx.accounts.recipient.to_account_info(),
Expand Down
4 changes: 2 additions & 2 deletions programs/strategy/src/state/simple_strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl Strategy for SimpleStrategy {
return Err(ErrorCode::InsufficientFunds.into());
}

token::transfer_token_to(
token::transfer(
accounts.token_program.to_account_info(),
remaining[0].to_account_info(),
accounts.underlying_token_account.to_account_info(),
Expand Down Expand Up @@ -135,7 +135,7 @@ impl Strategy for SimpleStrategy {
return Err(ErrorCode::InsufficientFunds.into());
}

token::transfer_token_from(
token::transfer_with_signer(
accounts.token_program.to_account_info(),
accounts.underlying_token_account.to_account_info(),
remaining[0].to_account_info(),
Expand Down
6 changes: 3 additions & 3 deletions programs/strategy/src/state/trade_fintech_srategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl Strategy for TradeFintechStrategy {
return Err(ErrorCode::InsufficientFunds.into());
}

token::transfer_token_to(
token::transfer(
accounts.token_program.to_account_info(),
remaining[0].to_account_info(),
accounts.underlying_token_account.to_account_info(),
Expand Down Expand Up @@ -145,7 +145,7 @@ impl Strategy for TradeFintechStrategy {
return Err(ErrorCode::InsufficientFunds.into());
}

token::transfer_token_to(
token::transfer(
accounts.token_program.to_account_info(),
remaining[0].to_account_info(),
accounts.underlying_token_account.to_account_info(),
Expand Down Expand Up @@ -191,7 +191,7 @@ impl Strategy for TradeFintechStrategy {
}

let seeds = self.seeds();
token::transfer_token_from(
token::transfer_with_signer(
accounts.token_program.to_account_info(),
accounts.underlying_token_account.to_account_info(),
remaining[0].to_account_info(),
Expand Down
6 changes: 3 additions & 3 deletions programs/strategy/src/utils/token.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Transfer};

pub fn transfer_token_from<'a>(
pub fn transfer_with_signer<'a>(
token_program: AccountInfo<'a>,
from: AccountInfo<'a>,
to: AccountInfo<'a>,
Expand All @@ -23,13 +23,13 @@ pub fn transfer_token_from<'a>(
)
}

pub fn transfer_token_to<'a>(
pub fn transfer<'a>(
token_program: AccountInfo<'a>,
from: AccountInfo<'a>,
to: AccountInfo<'a>,
authority: AccountInfo<'a>,
amount: u64,
) -> Result<()> {
) -> Result<()> {
token::transfer(
CpiContext::new(
token_program,
Expand Down
1 change: 1 addition & 0 deletions programs/tokenized_vault/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub const SHARES_ACCOUNT_SEED: &str = "shares_account";
pub const UNDERLYING_SEED: &str = "underlying";
pub const ROLES_SEED: &str = "roles";
pub const CONFIG_SEED: &str = "config";
pub const STRATEGY_DATA_SEED: &str = "strategy_data";

pub const MAX_BPS: u64 = 10_000;
pub const FEE_BPS: u64 = 10_000;
Expand Down
6 changes: 3 additions & 3 deletions programs/tokenized_vault/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ pub enum ErrorCode {
#[msg("Zero value")]
ZeroValue,

#[msg("Custom error message")]
CustomError,

#[msg("Invalid strategy data")]
InvalidStrategyData,

Expand Down Expand Up @@ -85,4 +82,7 @@ pub enum ErrorCode {

#[msg("Only KYC verified users can deposit")]
KYCRequired,

#[msg("Strategy cannot be added")]
InvalidStrategyToAdd,
}
30 changes: 26 additions & 4 deletions programs/tokenized_vault/src/instructions/add_strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ use access_control::{
state::{UserRole, Role}
};

use crate::state::Vault;
use crate::errors::ErrorCode;
use crate::constants::STRATEGY_DATA_SEED;
use crate::state::{ StrategyData, Vault};
use crate::utils::strategy;

#[derive(Accounts)]
pub struct AddStrategy<'info> {
#[account(
init,
seeds = [
STRATEGY_DATA_SEED.as_bytes(),
vault.key().as_ref(),
strategy.key().as_ref()
],
bump,
payer = signer,
space = StrategyData::LEN
)]
pub strategy_data: Account<'info, StrategyData>,

#[account(mut)]
pub vault: AccountLoader<'info, Vault>,

Expand All @@ -30,11 +46,17 @@ pub struct AddStrategy<'info> {
#[account(mut, constraint = roles.check_role()?)]
pub signer: Signer<'info>,

pub access_control: Program<'info, AccessControl>
pub access_control: Program<'info, AccessControl>,
pub system_program: Program<'info, System>
}

pub fn handle_add_strategy(ctx: Context<AddStrategy>, max_debt: u64) -> Result<()> {
let vault = &mut ctx.accounts.vault.load_mut()?;
let strategy_vault = strategy::get_vault(&ctx.accounts.strategy.to_account_info())?;

if strategy_vault != *ctx.accounts.vault.to_account_info().key {
return Err(ErrorCode::InvalidStrategyToAdd.into());
}

vault.add_strategy(ctx.accounts.strategy.key(), max_debt)
let strategy_data = &mut ctx.accounts.strategy_data;
strategy_data.init(ctx.accounts.strategy.key(), max_debt)
}
2 changes: 1 addition & 1 deletion programs/tokenized_vault/src/instructions/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn handle_deposit(ctx: Context<Deposit>, amount: u64) -> Result<()> {

let shares = ctx.accounts.vault.load()?.convert_to_shares(amount);

token::transfer_token_to(
token::transfer(
ctx.accounts.token_program.to_account_info(),
ctx.accounts.user_token_account.to_account_info(),
ctx.accounts.vault_token_account.to_account_info(),
Expand Down
9 changes: 2 additions & 7 deletions programs/tokenized_vault/src/instructions/init_vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ use anchor_spl::{
token_interface::{Mint, TokenAccount},
};

use crate::constants::{
CONFIG_SEED,
VAULT_SEED,
UNDERLYING_SEED,
DISCRIMINATOR_LEN,
};
use crate::constants::{CONFIG_SEED, VAULT_SEED, UNDERLYING_SEED};
use crate::state::{Vault, Config, VaultConfig};

#[derive(Accounts)]
Expand All @@ -28,7 +23,7 @@ pub struct InitVault<'info> {
],
bump,
payer = signer,
space = DISCRIMINATOR_LEN + Vault::INIT_SPACE,
space = Vault::LEN,
)]
pub vault: AccountLoader<'info, Vault>,

Expand Down
102 changes: 42 additions & 60 deletions programs/tokenized_vault/src/instructions/process_report.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
use anchor_lang::prelude::*;
use anchor_spl::{
token::Token,
token_interface::{self as token, Burn, Mint, MintTo, TokenAccount},
token_interface::{ Mint, TokenAccount},
};
use access_control::{
constants::USER_ROLE_SEED,
program::AccessControl,
state::{UserRole, Role}
};

use crate::constants::{ MAX_BPS_EXTENDED, SHARES_ACCOUNT_SEED, SHARES_SEED};
use crate::constants::{ MAX_BPS_EXTENDED, SHARES_ACCOUNT_SEED, SHARES_SEED, STRATEGY_DATA_SEED};
use crate::events::StrategyReportedEvent;
use crate::state::Vault;
use crate::utils::strategy;
use crate::utils::accountant;
use crate::state::{Vault, StrategyData};
use crate::utils::{accountant, strategy, token};

#[derive(Accounts)]
pub struct ProcessReport<'info> {
Expand All @@ -24,6 +23,17 @@ pub struct ProcessReport<'info> {
#[account()]
pub strategy: UncheckedAccount<'info>,

#[account(
mut,
seeds = [
STRATEGY_DATA_SEED.as_bytes(),
vault.key().as_ref(),
strategy.key().as_ref()
],
bump,
)]
pub strategy_data: Account<'info, StrategyData>,

#[account(mut, seeds = [SHARES_SEED.as_bytes(), vault.key().as_ref()], bump)]
pub shares_mint: Box<InterfaceAccount<'info, Mint>>,

Expand Down Expand Up @@ -70,7 +80,7 @@ pub fn handle_process_report(ctx: Context<ProcessReport>) -> Result<()> {
burn_unlocked_shares(&ctx)?;
ctx.accounts.vault_shares_token_account.reload()?;

let current_debt = get_current_strategy_debt(&ctx.accounts.vault, strategy.key())?;
let current_debt = ctx.accounts.strategy_data.current_debt;

if strategy_assets > current_debt {
profit = strategy_assets - current_debt;
Expand All @@ -79,8 +89,6 @@ pub fn handle_process_report(ctx: Context<ProcessReport>) -> Result<()> {

handle_profit(&ctx, profit, total_fees)?;

msg!("Issuing fee shares");
msg!("Fee shares: {}", fee_shares);
if fee_shares > 0 {
issue_fee_shares(&ctx, fee_shares)?;
}
Expand All @@ -89,10 +97,7 @@ pub fn handle_process_report(ctx: Context<ProcessReport>) -> Result<()> {
handle_loss(&ctx, loss)?;
}

ctx.accounts
.vault
.load_mut()?
.update_strategy_current_debt(strategy.key(), strategy_assets)?;
ctx.accounts.strategy_data.update_strategy_current_debt(strategy_assets)?;

emit!(StrategyReportedEvent {
strategy_key: strategy.key(),
Expand All @@ -111,16 +116,12 @@ fn issue_fee_shares(ctx: &Context<ProcessReport>, fee_shares: u64) -> Result<u64
let vault = &mut ctx.accounts.vault.load_mut()?;

token::mint_to(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
MintTo {
mint: ctx.accounts.shares_mint.to_account_info(),
to: ctx.accounts.accountant_recipient.to_account_info(),
authority: ctx.accounts.shares_mint.to_account_info(),
},
&[&vault.seeds_shares()],
),
ctx.accounts.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,
&vault.seeds_shares()
)?;

vault.total_shares += fee_shares;
Expand Down Expand Up @@ -167,17 +168,14 @@ fn handle_profit(ctx: &Context<ProcessReport>, profit: u64, fees: u64) -> Result

// mint shares to lock
token::mint_to(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
MintTo {
mint: ctx.accounts.shares_mint.to_account_info(),
to: ctx.accounts.vault_shares_token_account.to_account_info(),
authority: ctx.accounts.shares_mint.to_account_info(),
},
&[&vault.seeds_shares()],
),
ctx.accounts.token_program.to_account_info(),
ctx.accounts.shares_mint.to_account_info(),
ctx.accounts.vault_shares_token_account.to_account_info(),
ctx.accounts.shares_mint.to_account_info(),
shares_to_lock,
&vault.seeds_shares()
)?;

}

vault.total_debt += profit;
Expand All @@ -190,17 +188,13 @@ fn handle_loss(ctx: &Context<ProcessReport>, loss: u64) -> Result<()> {
let loss_shares = ctx.accounts.vault.load()?.convert_to_shares(loss);
let shares_to_burn = std::cmp::min(ctx.accounts.vault_shares_token_account.amount, loss_shares);

token::burn(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
Burn {
mint: ctx.accounts.shares_mint.to_account_info(),
from: ctx.accounts.vault_shares_token_account.to_account_info(),
authority: ctx.accounts.vault.to_account_info(),
},
&[&ctx.accounts.vault.load()?.seeds()],
),
token::burn_with_signer(
ctx.accounts.token_program.to_account_info(),
ctx.accounts.shares_mint.to_account_info(),
ctx.accounts.vault_shares_token_account.to_account_info(),
ctx.accounts.vault.to_account_info(),
shares_to_burn,
&ctx.accounts.vault.load()?.seeds(),
)?;

let vault = &mut ctx.accounts.vault.load_mut()?;
Expand All @@ -221,19 +215,16 @@ fn burn_unlocked_shares(ctx: &Context<ProcessReport>) -> Result<()> {
}

// Burn the shares unlocked.
token::burn(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
Burn {
mint: ctx.accounts.shares_mint.to_account_info(),
from: ctx.accounts.vault_shares_token_account.to_account_info(),
authority: ctx.accounts.vault.to_account_info(),
},
&[&ctx.accounts.vault.load()?.seeds()],
),
token::burn_with_signer(
ctx.accounts.token_program.to_account_info(),
ctx.accounts.shares_mint.to_account_info(),
ctx.accounts.vault_shares_token_account.to_account_info(),
ctx.accounts.vault.to_account_info(),
shares_to_burn,
&ctx.accounts.vault.load()?.seeds(),
)?;


let mut vault = ctx.accounts.vault.load_mut()?;
vault.total_shares -= shares_to_burn;

Expand Down Expand Up @@ -261,13 +252,4 @@ fn get_shares_to_burn(vault_loader: &AccountLoader<Vault>, total_locked: u64) ->

fn get_timestamp() -> Result<u64> {
Ok(Clock::get()?.unix_timestamp as u64)
}

fn get_current_strategy_debt(
vault_loader: &AccountLoader<Vault>,
strategy_key: Pubkey,
) -> Result<u64> {
let vault = vault_loader.load()?;
let strategy_data = vault.get_strategy_data(strategy_key)?;
Ok(strategy_data.current_debt)
}
}
Loading

0 comments on commit faf321b

Please sign in to comment.