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

DTF Strategy #47

Merged
merged 53 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
eb8a1cd
VLT-230 introducing orca_strategy
codinghistorian Nov 12, 2024
374dd7e
VLT-230 in progress of orca-strategy setup on devnet
codinghistorian Nov 13, 2024
d654431
Merge branch 'dev' into VLT-230-SOL-20-latest
codinghistorian Nov 13, 2024
7cfd25b
VLT-230 orca-strategy deploy-fund & free-fund test on devnet
codinghistorian Nov 13, 2024
b3c5898
VLT-230 adding event and silencing unused variable warning inside orc…
codinghistorian Nov 13, 2024
da2069b
VLT-230 testing on devnet one orca-strategy & two asset swaps
codinghistorian Nov 14, 2024
9d49670
VLT-230 init_token_account for strategy in progress
codinghistorian Nov 15, 2024
748f865
VLT-230 init_token_account compile fix, typo fix
codinghistorian Nov 15, 2024
883a950
VLT-230 strategy account now creates asset token account with seeds
codinghistorian Nov 15, 2024
617590b
Merge branch 'dev' into VLT-230-SOL-20-latest
codinghistorian Nov 15, 2024
badb381
VLT-230 minot adjustment after conflict resolution
codinghistorian Nov 15, 2024
c868759
VLT-230 making the swap direction configurable
codinghistorian Nov 18, 2024
2650ce2
VLT-230 PR review fixes and swap config fix
codinghistorian Nov 18, 2024
4cd47ff
VLT-230-orca_purchase_asset instruction in progress
codinghistorian Nov 20, 2024
23a3787
VLT-230 adding restriction on orca_purchase_assets so that it can onl…
codinghistorian Nov 21, 2024
b1bd0f5
VLT-230 underlying token balance check before and after swap and save…
codinghistorian Nov 21, 2024
ad94900
VLT-230 Invest_tracker account init instruction added
codinghistorian Nov 21, 2024
235641a
VLT-230 invest_tracker update logic added to orca_purchase_assets
codinghistorian Nov 22, 2024
61c84b7
VLT-230 adding more to InvestTracker
codinghistorian Nov 22, 2024
aa1c853
VLT-230 orca strategy test script for devnet, uses LUT for vault.redeem
codinghistorian Nov 23, 2024
25ae887
VLT-230 Adding ComputeBudgetProgram to set manual CU
codinghistorian Nov 23, 2024
717a46a
VLT-230 Invest Tracker account check before and after vault.redeem
codinghistorian Nov 24, 2024
06efd32
VLT-230 invest_tracker account management enhancement
codinghistorian Nov 26, 2024
18825af
VLT-230 update_invest_tracker instruction to update state
codinghistorian Nov 27, 2024
046f8c4
VLT-230 asset purchase logic adjustment so it would allocate amount o…
codinghistorian Nov 28, 2024
1839fef
VLT-230 devnet testing of update_invest_tracker
codinghistorian Nov 28, 2024
a1ffe13
VLT-230 free_funds function logic adjustment to decide amount based o…
codinghistorian Nov 29, 2024
35696c6
VLT-230 allow free fund instruction for OrcaStrategy
codinghistorian Nov 29, 2024
5c0cafc
VLT-230 rebalance function introduction
codinghistorian Dec 1, 2024
10ce032
VLT-230 process_report for orca added
codinghistorian Dec 2, 2024
1bddebb
VLT-230 deploy_funds introduction, good bye orca_purchase_assets
codinghistorian Dec 2, 2024
2dd3475
VLT-230 refactoring util methods for orca
codinghistorian Dec 2, 2024
6969851
VLT-230 refactoring orca_strategy.rs
codinghistorian Dec 3, 2024
f12fd7b
VLT-230 adding events for indexing
codinghistorian Dec 3, 2024
8fdc8da
VLT-230 fixing total_invested accounting
codinghistorian Dec 3, 2024
32121d9
Merge branch 'dev' into VLT-230-atomic-deposit
codinghistorian Dec 3, 2024
735fbcd
VLT-230 changing update_strategy_current_debt to update_current_debt …
codinghistorian Dec 3, 2024
d6f88ec
add token 2022 support
vito-kovalione Dec 4, 2024
c8e62db
VLT-230 adding vault.process_report flow to devnet testing for orca
codinghistorian Dec 4, 2024
a481d81
VLT-230 allowing deposit to call deploy_funds & direct_deposit to tes…
codinghistorian Dec 5, 2024
38d5377
Merge branch 'dev' into token-2022-support
vito-kovalione Dec 5, 2024
ccf119d
VLT-230 discount rate to assetValue in DTFStrategy
codinghistorian Dec 6, 2024
f87554c
VLT-230 refactoring
codinghistorian Dec 6, 2024
eb103ef
VLT-230 double_borrowing issue fix
codinghistorian Dec 6, 2024
2ee8103
VLT-230 returning comment for cleaner PR
codinghistorian Dec 7, 2024
28e1dd5
Adjusting direct_deposit.rs to follow token-2022 updates
codinghistorian Dec 9, 2024
ec64817
Merge branch 'dev' into token-2022-support-merging-test
codinghistorian Dec 9, 2024
809e0cd
Integration tests: Updated tests according to token-2022 program changes
DavitMkhitaryan Dec 9, 2024
e5d7dab
Merge branch 'dev' into token-2022-support
codinghistorian Dec 9, 2024
3ce320c
Merge branch 'dev' into VLT-230-DTF-latest-dev-merge-test
codinghistorian Dec 10, 2024
09e7507
VLT-230 adjust orca devnet script to have whitelisting
codinghistorian Dec 10, 2024
ccd2a44
Merge branch 'token-2022-support' into VLT-230-DTF-latest-dev-merge-test
codinghistorian Dec 10, 2024
eaeebae
VLT-230 adjusting to follow token-2022-support
codinghistorian Dec 10, 2024
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
24 changes: 23 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,29 @@
"init_trade_fi": "npx ts-node scripts/create_vault_with_trade_fi_strategy.ts",
"underlying_mint": "npx ts-node scripts/create-underlying-mint.ts",
"initialize": "npx ts-node scripts/initialize.ts",
"shutdown_vault": "npx ts-node scripts/shutdown_vault.ts"
"shutdown_vault": "npx ts-node scripts/shutdown_vault.ts",
"init_orca_strategy": "npx ts-node scripts/orca/0_init_orca_strategy.ts",
"init_token_account": "npx ts-node scripts/orca/1_init_token_account.ts",
"init_invest_tracker": "npx ts-node scripts/orca/2_init_invest_tracker.ts",
"direct_deposit": "npx ts-node scripts/orca/3_4_5_direct_deposit.ts",
"deposit_update": "npx ts-node scripts/orca/3_deposit_update.ts",
"updateDebt": "npx ts-node scripts/orca/4_updateDebt.ts",
"deploy_funds": "npx ts-node scripts/orca/5_deploy_funds.ts",
"update_invest_tracker": "npx ts-node scripts/orca/6_update_invest_tracker.ts",
"free_funds_with_vault_redeem": "npx ts-node scripts/orca/7_free_funds_with_vault_redeem.ts",
"free_funds_directly": "npx ts-node scripts/orca/8_free_funds_directly.ts",
"rebalance": "npx ts-node scripts/orca/9_rebalance.ts",
"report_profit": "npx ts-node scripts/orca/10_report_profit.ts",
"clean": "anchor clean && rm -rf target/*",
"build": "anchor build",
"sync": "anchor keys sync",
"deploy": "anchor deploy",
"deploy-for-orca": "anchor deploy --program-name tokenized_vault && anchor deploy --program-name access_control && anchor deploy --program-name strategy",
"full-test-orca": "npm run clean && rm -rf target/* && npm run build && npm run sync && npm run sync && npm run build && npm run deploy-for-orca && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_orca_strategy && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_token_account && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run deposit_update && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run updateDebt && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run deploy_funds && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run free_funds_with_vault_redeem && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run report_profit",
"full-test-orca-direct-deposit": "npm run clean && rm -rf target/* && npm run build && npm run sync && npm run sync && npm run build && npm run deploy-for-orca && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_orca_strategy && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_token_account && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run direct_deposit && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run free_funds_with_vault_redeem && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run report_profit",
"till-allocate-buy-assets": "npm run clean && rm -rf target/* && npm run build && npm run sync && npm run sync && npm run build && npm run deploy-for-orca && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_orca_strategy && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_token_account && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run deposit_update && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run updateDebt && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run deploy_funds",
"till-rebalance": "npm run clean && rm -rf target/* && npm run build && npm run sync && npm run sync && npm run build && npm run deploy-for-orca && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_orca_strategy && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_token_account && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run deposit_update && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run updateDebt && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run deploy_funds && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run free_funds_directly && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run rebalance && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run report_profit",
"till-rebalance-direct-deposit": "npm run clean && rm -rf target/* && npm run build && npm run sync && npm run sync && npm run build && npm run deploy-for-orca && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_orca_strategy && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_token_account && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run init_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run direct_deposit && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run free_funds_directly && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run rebalance && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run report_profit"
},
"dependencies": {
"@coral-xyz/anchor": "^0.30.1",
Expand Down
4 changes: 3 additions & 1 deletion programs/strategy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ idl-build = [
[dependencies]
anchor-lang = "0.30.1"
anchor-spl = { version = "0.30.1", features = ["metadata"] }
access_control = { path = "../access_control", features=["no-entrypoint", "cpi"] }
access_control = { path = "../access_control", features=["no-entrypoint", "cpi"] }
whirlpool-cpi = { git = "https://github.com/orca-so/whirlpool-cpi", branch = "anchor/0.30.1" }
uint = "=0.9.5"
17 changes: 16 additions & 1 deletion programs/strategy/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,22 @@ pub const VAULT_SEED: &str = "vault";
pub const SHARES_SEED: &str = "shares";
pub const UNDERLYING_SEED: &str = "underlying";
pub const CONFIG_SEED: &str = "config";
pub const TOKEN_ACCOUNT_SEED: &str = "token_account";
pub const INVEST_TRACKER_SEED: &str = "invest_tracker";

pub const REMAINING_ACCOUNTS_MIN: usize = 9;
pub const AMOUNT_SPECIFIED_IS_INPUT: bool = true;
pub const MAX_SQRT_PRICE_X64: u128 = 79226673515401279992447579055;
pub const MIN_SQRT_PRICE_X64: u128 = 4295048016;
pub const FEE_BPS: u64 = 10_000;

pub const DISCRIMINATOR_LEN: usize = 8;
pub const NO_EXPLICIT_SQRT_PRICE_LIMIT: u128 = 0;
pub const NUM_REWARDS: usize = 3;
pub const MAX_ASSIGNED_WEIGHT: u16 = 10000; // 100% in bps

// Asset value discount constant
pub const ASSET_VALUE_DISCOUNT_BPS: u16 = 30; // 0.3% discount 30 bps

// Orca strategy specific constants
pub const ORCA_ACCOUNTS_PER_SWAP: usize = 12;
pub const ORCA_INVEST_TRACKER_OFFSET: usize = 10;
9 changes: 9 additions & 0 deletions programs/strategy/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ pub enum ErrorCode {

#[msg("Loss is too high")]
LossTooHigh,

#[msg("Invalid strategy type")]
InvalidStrategyType,

#[msg("Invalid tracker setup")]
InvalidTrackerSetup,

#[msg("Math overflow")]
MathOverflow,
}
35 changes: 35 additions & 0 deletions programs/strategy/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,39 @@ pub struct StrategyWithdrawEvent {
pub struct SetPerformanceFeeEvent {
pub account_key: Pubkey,
pub fee: u64,
}

#[event]
pub struct AMMStrategyInitEvent {
pub account_key: Pubkey,
pub strategy_type: String,
pub vault: Pubkey,
pub underlying_mint: Pubkey,
pub underlying_token_acc: Pubkey,
pub undelying_decimals: u8,
pub deposit_limit: u64,
}

#[event]
pub struct InvestTrackerUpdateEvent {
pub asset_mint: Pubkey,
pub asset_amount: u64,
pub asset_price: u128,
pub asset_value: u128,
pub timestamp: i64,
}

#[event]
pub struct HarvestAndReportDTF {
pub total_assets: u128,
pub timestamp: i64,
}

#[event]
pub struct InvestTrackerSwapEvent {
pub asset_mint: Pubkey,
pub invested_underlying_amount: u64,
pub asset_amount: u64,
pub asset_price: u128,
pub timestamp: i64,
}
16 changes: 10 additions & 6 deletions programs/strategy/src/instructions/deploy_funds.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use anchor_lang::prelude::*;
use anchor_spl::{
token::Token,
token_interface::TokenAccount,
};
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};

use crate::utils::unchecked_strategy::UncheckedStrategy;
use crate::error::ErrorCode;
Expand All @@ -17,10 +14,17 @@ pub struct DeployFunds<'info> {
#[account(mut, seeds = [UNDERLYING_SEED.as_bytes(), strategy.key().as_ref()], bump)]
pub underlying_token_account: InterfaceAccount<'info, TokenAccount>,

#[account(mut, constraint = signer.key() == strategy.manager() @ErrorCode::AccessDenied)]
#[account(mut, constraint = underlying_mint.key() == strategy.underlying_mint())]
pub underlying_mint: InterfaceAccount<'info, Mint>,

#[account(mut, constraint =
signer.key() == strategy.manager() ||
signer.key() == strategy.vault()
@ErrorCode::AccessDenied
)]
pub signer: Signer<'info>,

pub token_program: Program<'info, Token>,
pub token_program: Interface<'info, TokenInterface>,
}

pub fn handle_deploy_funds<'info>(ctx: Context<'_, '_, '_, 'info, DeployFunds<'info>>, amount: u64) -> Result<()> {
Expand Down
39 changes: 29 additions & 10 deletions programs/strategy/src/instructions/deposit.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use anchor_lang::prelude::*;
use anchor_spl::{
token::Token,
token_interface::TokenAccount,
};
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};

use crate::error::ErrorCode;
use crate::utils::token::transfer;
use crate::utils::unchecked_strategy::UncheckedStrategy;
use crate::constants::UNDERLYING_SEED;
use crate::StrategyType;
use crate::instructions::deploy_funds::DeployFunds;

#[derive(Accounts)]
pub struct Deposit<'info> {
Expand All @@ -21,14 +20,17 @@ pub struct Deposit<'info> {
#[account(mut)]
pub vault_token_account: InterfaceAccount<'info, TokenAccount>,

#[account(mut, constraint = underlying_mint.key() == strategy.underlying_mint())]
pub underlying_mint: InterfaceAccount<'info, Mint>,

#[account(constraint = signer.key() == strategy.vault() @ErrorCode::AccessDenied)]
pub signer: Signer<'info>,

pub token_program: Program<'info, Token>,
pub token_program: Interface<'info, TokenInterface>,
}

pub fn handle_deposit<'info>(
ctx: Context<Deposit<'info>>,
ctx: Context<'_, '_, '_, 'info, Deposit<'info>>,
amount: u64,
) -> Result<()> {
let mut strategy = ctx.accounts.strategy.from_unchecked()?;
Expand All @@ -39,14 +41,31 @@ pub fn handle_deposit<'info>(
return Err(ErrorCode::MaxDepositReached.into());
}

strategy.deposit(amount)?;
strategy.save_changes(&mut &mut ctx.accounts.strategy.try_borrow_mut_data()?[8..])?;

transfer(
ctx.accounts.token_program.to_account_info(),
ctx.accounts.vault_token_account.to_account_info(),
ctx.accounts.underlying_token_account.to_account_info(),
ctx.accounts.signer.to_account_info(),
&ctx.accounts.underlying_mint,
amount
)
)?;

strategy.deposit(amount)?;

//if strategy type is orca, we need to call deploy_funds
if strategy.strategy_type() == StrategyType::Orca {
// Create DeployFunds accounts struct from existing Deposit accounts
let deploy_funds = DeployFunds {
strategy: ctx.accounts.strategy.clone(),
underlying_token_account: ctx.accounts.underlying_token_account.clone(),
underlying_mint: ctx.accounts.underlying_mint.clone(),
signer: ctx.accounts.signer.clone(),
token_program: ctx.accounts.token_program.clone(),
};
strategy.deploy_funds(&deploy_funds, &ctx.remaining_accounts, amount)?;
}

strategy.save_changes(&mut &mut ctx.accounts.strategy.try_borrow_mut_data()?[8..])?;

Ok(())
}
10 changes: 5 additions & 5 deletions programs/strategy/src/instructions/free_funds.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use anchor_lang::prelude::*;
use anchor_spl::{
token::Token,
token_interface::TokenAccount,
};
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};

use crate::utils::unchecked_strategy::UncheckedStrategy;
use crate::error::ErrorCode;
Expand All @@ -17,10 +14,13 @@ pub struct FreeFunds<'info> {
#[account(mut, seeds = [UNDERLYING_SEED.as_bytes(), strategy.key().as_ref()], bump)]
pub underlying_token_account: InterfaceAccount<'info, TokenAccount>,

#[account(mut, constraint = underlying_mint.key() == strategy.underlying_mint())]
pub underlying_mint: InterfaceAccount<'info, Mint>,

#[account(mut, constraint = signer.key() == strategy.manager() @ErrorCode::AccessDenied)]
pub signer: Signer<'info>,

pub token_program: Program<'info, Token>,
pub token_program: Interface<'info, TokenInterface>,
}

// difference between freed and actual is the loss or gain
Expand Down
103 changes: 103 additions & 0 deletions programs/strategy/src/instructions/init_invest_tracker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use anchor_lang::prelude::*;
use anchor_spl::{
token::{ Token },
token_interface::Mint,
};
use access_control::{
constants::USER_ROLE_SEED,
program::AccessControl,
state::{UserRole, Role}
};

use crate::constants::{INVEST_TRACKER_SEED, MAX_ASSIGNED_WEIGHT};
use crate::state::invest_tracker::*;
use crate::state::whirlpool::*;
use crate::error::ErrorCode;
use crate::ID;

//This instruction initializes an invest tracker for the strategy
#[derive(Accounts)]
#[instruction()]
pub struct InitInvestTracker<'info> {
#[account(
init,
space = 8 + InvestTracker::INIT_SPACE,
seeds = [
INVEST_TRACKER_SEED.as_bytes(),
&asset_mint.key().to_bytes(),
strategy.key().as_ref(),
],
bump,
payer = signer,
)]
pub invest_tracker: Box<Account<'info, InvestTracker>>,
/// CHECK: This is a Whirlpool account owned by Orca's Whirlpool program.
/// The account ownership and data are not yet verified in the instruction handler.
pub whirlpool: AccountInfo<'info>,

/// CHECK: can be any strategy
#[account(owner = ID)]
pub strategy: UncheckedAccount<'info>,

pub asset_mint: Box<InterfaceAccount<'info, Mint>>,
pub underlying_mint: Box<InterfaceAccount<'info, Mint>>,

#[account(
seeds = [
USER_ROLE_SEED.as_bytes(),
signer.key().as_ref(),
Role::StrategiesManager.to_seed().as_ref()
],
bump,
seeds::program = access_control.key()
)]
pub roles: Account<'info, UserRole>,

#[account(mut, constraint = roles.check_role()?)]
pub signer: Signer<'info>,

pub token_program: Program<'info, Token>,
pub system_program: Program<'info, System>,
pub rent: Sysvar<'info, Rent>,
pub access_control: Program<'info, AccessControl>,
}

pub fn handle_init_invest_tracker(ctx: Context<InitInvestTracker>, a_to_b_for_purchase: bool, assigned_weight: u16) -> Result<()> {
msg!("Invest tracker initialized");
let invest_tracker = &mut ctx.accounts.invest_tracker;

// Deserialize the whirlpool account
let account_data = ctx.accounts.whirlpool.data.borrow();
let whirlpool = Whirlpool::try_from_slice(&account_data[8..])?;

let asset_mint = &ctx.accounts.asset_mint;
let underlying_mint = &ctx.accounts.underlying_mint;
if a_to_b_for_purchase {
require!(
whirlpool.token_mint_a == underlying_mint.key() &&
whirlpool.token_mint_b == asset_mint.key(),
ErrorCode::InvalidTrackerSetup
);
} else {
require!(
whirlpool.token_mint_a == asset_mint.key() &&
whirlpool.token_mint_b == underlying_mint.key(),
ErrorCode::InvalidTrackerSetup
);
}
invest_tracker.whirlpool_id = ctx.accounts.whirlpool.key();
invest_tracker.asset_mint = asset_mint.key();
invest_tracker.amount_invested = 0;
invest_tracker.amount_withdrawn = 0;
invest_tracker.asset_amount = 0;
invest_tracker.asset_price = 0;
invest_tracker.sqrt_price = whirlpool.sqrt_price;
invest_tracker.asset_value = 0;
invest_tracker.asset_decimals = asset_mint.decimals;
invest_tracker.underlying_decimals = underlying_mint.decimals;
invest_tracker.a_to_b_for_purchase = a_to_b_for_purchase;
require!(assigned_weight <= MAX_ASSIGNED_WEIGHT, ErrorCode::InvalidTrackerSetup);
invest_tracker.assigned_weight = assigned_weight;
invest_tracker.current_weight = assigned_weight;
Ok(())
}
Loading
Loading