Skip to content

Commit

Permalink
Merge branch 'dev' into events-extention
Browse files Browse the repository at this point in the history
  • Loading branch information
codinghistorian authored Dec 20, 2024
2 parents 912191e + c20b5d4 commit afaae78
Show file tree
Hide file tree
Showing 34 changed files with 3,064 additions and 89 deletions.
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"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",
"whitelist": "npx ts-node scripts/orca/whitelist.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",
Expand All @@ -25,13 +26,16 @@
"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",
"get_tick_arrays": "npx ts-node scripts/orca/11_get_tick_arrays.ts",
"create_ALT_for_orca": "npx ts-node scripts/orca/ALT/create_ALT_for_orca.ts",
"create_multiple_ALT": "ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npx ts-node scripts/orca/ALT/create_multiple_ALT.ts || (sleep 2 && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npx ts-node scripts/orca/ALT/create_multiple_ALT.ts) || (sleep 2 && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npx ts-node scripts/orca/ALT/create_multiple_ALT.ts) || (sleep 2 && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npx ts-node scripts/orca/ALT/create_multiple_ALT.ts) || (sleep 2 && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npx ts-node scripts/orca/ALT/create_multiple_ALT.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",
"deploy-for-orca": "anchor deploy --program-name tokenized_vault && anchor deploy --program-name access_control && anchor deploy --program-name strategy && anchor deploy --program-name accountant",
"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",
"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 && npm run create_multiple_ALT && 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 && ANCHOR_PROVIDER_URL=\"https://api.devnet.solana.com\" ANCHOR_WALLET=~/.config/solana/id.json npm run update_invest_tracker",
"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"
Expand All @@ -52,6 +56,9 @@
"prettier": "^2.6.2",
"@solana/spl-token": "0.4.8",
"@solana/spl-token-metadata": "^0.1.5",
"@orca-so/whirlpool-client-sdk": "0.0.7",
"tiny-invariant": "^1.2.0",
"decimal.js": "^10.3.1",
"ts-mocha": "^10.0.0",
"typescript": "^4.3.5"
}
Expand Down
50 changes: 39 additions & 11 deletions programs/strategy/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,6 @@ pub struct SetPerformanceFeeEvent {
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 HarvestAndReportDTFEvent {
pub account_key: Pubkey,
Expand All @@ -58,6 +47,45 @@ pub struct InvestTrackerSwapEvent {
pub asset_mint: Pubkey,
pub invested_underlying_amount: u64,
pub asset_amount: u64,
pub effective_invested_amount: u64,
pub unrealized_profit: u64,
pub unrealized_loss: u64,
pub timestamp: i64,
}

#[event]
pub struct InvestTrackerUpdateEvent {
pub account_key: Pubkey,
pub invest_tracker_account_key: Pubkey,
pub whirlpool_id: Pubkey,
pub asset_mint: Pubkey,
pub amount_invested: u64,
pub amount_withdrawn: u64,
pub asset_amount: u64,
pub asset_price: u64,
pub sqrt_price: u64,
pub asset_value: u64,
pub asset_decimals: u32,
pub underlying_decimals: u32,
pub a_to_b_for_purchase: bool,
pub assigned_weight: u32,
pub current_weight: u32,
pub effective_invested_amount: u64,
pub unrealized_profit: u64,
pub unrealized_loss: u64,
pub timestamp: i64,
}

#[event]
pub struct StrategyDeployFundsEvent {
pub account_key: Pubkey,
pub amount: u64,
pub timestamp: i64,
}

#[event]
pub struct StrategyFreeFundsEvent {
pub account_key: Pubkey,
pub amount: u64,
pub timestamp: i64,
}
3 changes: 3 additions & 0 deletions programs/strategy/src/instructions/init_invest_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,8 @@ pub fn handle_init_invest_tracker(ctx: Context<InitInvestTracker>, a_to_b_for_pu
require!(assigned_weight <= MAX_ASSIGNED_WEIGHT, ErrorCode::InvalidTrackerSetup);
invest_tracker.assigned_weight = assigned_weight;
invest_tracker.current_weight = assigned_weight;
invest_tracker.effective_invested_amount = 0;
invest_tracker.unrealized_profit = 0;
invest_tracker.unrealized_loss = 0;
Ok(())
}
19 changes: 18 additions & 1 deletion programs/strategy/src/instructions/report_profit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use anchor_lang::prelude::*;
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
use access_control::{
constants::USER_ROLE_SEED,
program::AccessControl,
state::{UserRole, Role}
};

use crate::utils::unchecked_strategy::UncheckedStrategy;
use crate::error::ErrorCode;
Expand All @@ -17,10 +22,22 @@ pub struct ReportProfit<'info> {
#[account(mut, constraint = underlying_mint.key() == strategy.underlying_mint())]
pub underlying_mint: InterfaceAccount<'info, Mint>,

#[account(mut, constraint = signer.key() == strategy.manager() @ErrorCode::AccessDenied)]
#[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: Interface<'info, TokenInterface>,
pub access_control: Program<'info, AccessControl>,
}

pub fn handle_report_profit<'info>(ctx: Context<'_, '_, '_, 'info, ReportProfit<'info>>, profit: u64) -> Result<()> {
Expand Down
44 changes: 44 additions & 0 deletions programs/strategy/src/instructions/update_invest_trackers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ use crate::state::invest_tracker::*;
use crate::state::whirlpool::*;
use crate::error::ErrorCode;
use crate::utils::orca_utils::{compute_asset_value, get_price_in_underlying_decimals};
use crate::events::InvestTrackerUpdateEvent;
use crate::utils::unchecked_strategy::UncheckedStrategy;

//This instruction initializes an invest tracker for the strategy
#[derive(Accounts)]
#[instruction()]
pub struct UpdateInvestTrackers<'info> {
/// CHECK: can be any strategy
#[account(mut)]
pub strategy: UncheckedAccount<'info>,

#[account(
seeds = [
USER_ROLE_SEED.as_bytes(),
Expand All @@ -39,6 +45,8 @@ pub struct UpdateInvestTrackers<'info> {
}

pub fn handle_update_invest_trackers(ctx: Context<UpdateInvestTrackers>) -> Result<()> {
let mut strategy = ctx.accounts.strategy.from_unchecked()?;

msg!("Updating invest trackers");
//so there would be a pair of accounts for each invest tracker
//remaining accounts[0] = invest_tracker
Expand Down Expand Up @@ -109,12 +117,47 @@ pub fn handle_update_invest_trackers(ctx: Context<UpdateInvestTrackers>) -> Resu
.checked_div(FEE_BPS as u128)
.ok_or(ErrorCode::MathOverflow)?;

// Calculate unrealized profit/loss
let effective_invested = current_data.effective_invested_amount as u128;
let asset_value = current_data.asset_value;

if asset_value > effective_invested {
current_data.unrealized_profit = (asset_value - effective_invested) as u64;
current_data.unrealized_loss = 0;
} else {
current_data.unrealized_profit = 0;
current_data.unrealized_loss = (effective_invested - asset_value) as u64;
}

// Add to totals
total_weight += current_data.assigned_weight as u16;
total_asset_value = total_asset_value
.checked_add(current_data.asset_value)
.ok_or(ErrorCode::MathOverflow)?;

// Emit the update event
emit!(InvestTrackerUpdateEvent {
account_key: strategy.key(),
invest_tracker_account_key: invest_tracker_info.key(),
whirlpool_id: current_data.whirlpool_id,
asset_mint: current_data.asset_mint,
amount_invested: current_data.amount_invested,
amount_withdrawn: current_data.amount_withdrawn,
asset_amount: current_data.asset_amount,
asset_price: current_data.asset_price as u64,
sqrt_price: current_data.sqrt_price as u64,
asset_value: current_data.asset_value as u64,
asset_decimals: current_data.asset_decimals as u32,
underlying_decimals: current_data.underlying_decimals as u32,
a_to_b_for_purchase: current_data.a_to_b_for_purchase,
assigned_weight: current_data.assigned_weight as u32,
current_weight: current_data.current_weight as u32,
effective_invested_amount: current_data.effective_invested_amount as u64,
unrealized_profit: current_data.unrealized_profit as u64,
unrealized_loss: current_data.unrealized_loss as u64,
timestamp: Clock::get()?.unix_timestamp,
});

// Serialize the updated data
let serialized = current_data.try_to_vec()?;

Expand Down Expand Up @@ -153,5 +196,6 @@ pub fn handle_update_invest_trackers(ctx: Context<UpdateInvestTrackers>) -> Resu
require!(total_current_weight <= MAX_ASSIGNED_WEIGHT as u16, ErrorCode::InvalidTrackerSetup);
}

strategy.save_changes(&mut &mut ctx.accounts.strategy.try_borrow_mut_data()?[8..])?;
Ok(())
}
4 changes: 3 additions & 1 deletion programs/strategy/src/state/invest_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ pub struct InvestTracker {
pub a_to_b_for_purchase: bool,
pub assigned_weight: u16,
pub current_weight: u16,
//later add last_updated_timestamp so that the actions happen when the price is fresh
pub effective_invested_amount: u64,
pub unrealized_profit: u64,
pub unrealized_loss: u64,
}
Loading

0 comments on commit afaae78

Please sign in to comment.