Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ sdk/src/**/*.js.map
.DS_STORE
.vscode
migrations
/**/*.env
/**/*.env
vendor
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion programs/drift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ drift-rs=[]
[dependencies]
anchor-lang = "0.29.0"
solana-program = "1.16"
anchor-spl = "0.29.0"
anchor-spl = { version = "0.29.0", features = ["metadata"] }
pyth-client = "0.2.2"
pyth-lazer-solana-contract = { git = "https://github.com/drift-labs/pyth-crosschain", rev = "d790d1cb4da873a949cf33ff70349b7614b232eb", features = ["no-entrypoint"]}
pythnet-sdk = { git = "https://github.com/drift-labs/pyth-crosschain", rev = "3e8a24ecd0bcf22b787313e2020f4186bb22c729"}
Expand Down
125 changes: 123 additions & 2 deletions programs/drift/src/instructions/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ use std::convert::identity;
use std::mem::size_of;

use crate::msg;
use crate::signer::get_signer_seeds;
use crate::state::lp_pool::LPPool;
use anchor_lang::prelude::*;
use anchor_spl::{
metadata::{
create_metadata_accounts_v3, mpl_token_metadata::types::DataV2, CreateMetadataAccountsV3,
Metadata,
},
};
use anchor_spl::token::Token;
use anchor_spl::token_2022::Token2022;
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
Expand Down Expand Up @@ -4359,6 +4367,67 @@ pub fn handle_initialize_high_leverage_mode_config(
Ok(())
}

pub fn handle_initialize_lp_pool(
ctx: Context<InitializeLpPool>,
name: [u8; 32],
token_name: String,
token_symbol: String,
token_uri: String,
_token_decimals: u8,
max_aum: u64,
) -> Result<()> {
let mut lp_pool = ctx.accounts.lp_pool.load_init()?;
let state = &mut ctx.accounts.state;

*lp_pool = LPPool {
name,
pubkey: ctx.accounts.lp_pool.key(),
mint: ctx.accounts.mint.key(),
// token_vault: ctx.accounts.token_vault.key(),
constituents: 0,
max_aum,
last_aum: 0,
last_aum_slot: 0,
last_aum_ts: 0,
last_revenue_rebalance_ts: 0,
total_fees_received: 0,
total_fees_paid: 0,
padding: [0; 6],
};

let signature_seeds = get_signer_seeds(&state.signer_nonce);
let signers = &[&signature_seeds[..]];

create_metadata_accounts_v3(
CpiContext::new_with_signer(
ctx.accounts.token_metadata_program.to_account_info(),
CreateMetadataAccountsV3 {
metadata: ctx.accounts.metadata_account.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
mint_authority: ctx.accounts.lp_pool.to_account_info(),
update_authority: ctx.accounts.lp_pool.to_account_info(),
payer: ctx.accounts.admin.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
},
signers,
),
DataV2 {
name: token_name,
symbol: token_symbol,
uri: token_uri,
seller_fee_basis_points: 0,
creators: None,
collection: None,
uses: None,
},
false, // Is mutable
true, // Update authority is signer
None, // Collection details
)?;

Ok(())
}
pub fn handle_update_high_leverage_mode_config(
ctx: Context<UpdateHighLeverageModeConfig>,
max_users: u32,
Expand Down Expand Up @@ -4394,8 +4463,8 @@ pub fn handle_update_protected_maker_mode_config(
) -> Result<()> {
let mut config = load_mut!(ctx.accounts.protected_maker_mode_config)?;

if current_users.is_some() {
config.current_users = current_users.unwrap();
if let Some(users) = current_users {
config.current_users = users;
}
config.max_users = max_users;
config.reduce_only = reduce_only as u8;
Expand Down Expand Up @@ -5130,3 +5199,55 @@ pub struct UpdateProtectedMakerModeConfig<'info> {
)]
pub state: Box<Account<'info, State>>,
}

#[derive(Accounts)]
#[instruction(
name: [u8; 32],
token_decimals: u8,
)]
pub struct InitializeLpPool<'info> {
#[account(mut)]
pub admin: Signer<'info>,
#[account(
init,
seeds = [b"lp_pool", name.as_ref()],
space = LPPool::SIZE,
bump,
payer = admin
)]
pub lp_pool: AccountLoader<'info, LPPool>,
#[account(
init,
seeds = [b"mint", lp_pool.key().as_ref()],
bump,
payer = admin,
mint::decimals = token_decimals,
mint::authority = lp_pool.key(),
mint::freeze_authority = lp_pool.key(),
)]
pub mint: InterfaceAccount<'info, Mint>,
// #[account(
// token::authority = lp_pool.key(),
// token::mint = mint.key()
// )]
// pub token_vault: InterfaceAccount<'info, TokenAccount>,
#[account(
mut,
seeds = [b"metadata", token_metadata_program.key().as_ref(), mint.key().as_ref()],
bump,
seeds::program = token_metadata_program.key(),
)]
/// CHECK: Validate address by deriving pda
pub metadata_account: UncheckedAccount<'info>,

#[account(
has_one = admin
)]
pub state: Box<Account<'info, State>>,

pub token_program: Program<'info, Token>,
pub token_metadata_program: Program<'info, Metadata>,

pub rent: Sysvar<'info, Rent>,
pub system_program: Program<'info, System>,
}
12 changes: 12 additions & 0 deletions programs/drift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,18 @@ pub mod drift {
handle_initialize_high_leverage_mode_config(ctx, max_users)
}

pub fn initialize_lp_pool(
ctx: Context<InitializeLpPool>,
name: [u8; 32],
token_name: String,
token_symbol: String,
token_uri: String,
token_decimals: u8,
max_aum: u64,
) -> Result<()> {
handle_initialize_lp_pool(ctx, name, token_name, token_symbol, token_uri, token_decimals, max_aum)
}

pub fn update_high_leverage_mode_config(
ctx: Context<UpdateHighLeverageModeConfig>,
max_users: u32,
Expand Down
78 changes: 47 additions & 31 deletions programs/drift/src/state/lp_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,61 @@ use crate::math::safe_math::SafeMath;
use crate::state::oracle::OracleSource;
use crate::state::spot_market::{SpotBalance, SpotBalanceType, SpotMarket};
use anchor_lang::prelude::*;
use borsh::{BorshDeserialize, BorshSerialize};
use crate::state::traits::Size;

#[cfg(test)]
mod tests;

#[account(zero_copy)]
#[derive(Default, Debug)]
#[repr(C)]
pub struct LPPool {
/// name of vault, TODO: check type + size
pub name: [u8; 32],
pub name: [u8; 32], // 32
/// address of the vault.
pub pubkey: Pubkey,
pub pubkey: Pubkey, // 32, 64
// vault token mint
pub mint: Pubkey,
pub mint: Pubkey, // 32, 96
/// LPPool's token account
pub token_vault: Pubkey,
// pub token_vault: Pubkey, // 32, 128

/// token_supply? to simplify NAV calculation, or load from mint account
/// token_total_supply: u64

/// The current number of VaultConstituents in the vault, each constituent is pda(LPPool.address, constituent_index)
pub constituents: u16,
/// which constituent is the quote, receives revenue pool distributions. (maybe this should just be implied idx 0)
/// pub quote_constituent_index: u16,

/// Max AUM. Prohibit minting new DLP beyond this
/// pub max_aum: u64,
/// QUOTE_PRECISION: Max AUM, Prohibit minting new DLP beyond this
pub max_aum: u64, // 8, 136

/// AUM of the vault in USD, updated lazily
pub last_aum: u64,
/// QUOTE_PRECISION: AUM of the vault in USD, updated lazily
pub last_aum: u64, // 8, 144

/// timestamp of last AUM slot
pub last_aum_slot: u64,
pub last_aum_slot: u64, // 8, 152
/// timestamp of last AUM update
pub last_aum_ts: u64,
pub last_aum_ts: u64, // 8, 160

/// timestamp of last vAMM revenue rebalance
pub last_revenue_rebalance_ts: u64,
pub last_revenue_rebalance_ts: u64, // 8, 168

/// all revenue settles recieved
pub total_fees_received: u128,
pub total_fees_received: u128, // 16, 176
/// all revenues paid out
pub total_fees_paid: u128,
pub total_fees_paid: u128, // 16, 192

pub constituents: u16, // 2, 194
pub padding: [u8; 6],
}

impl Size for LPPool {
const SIZE: usize = 1743;
}

#[zero_copy(unsafe)]
#[derive(Default, Eq, PartialEq, Debug)]
#[derive(Default, Eq, PartialEq, Debug, BorshDeserialize, BorshSerialize)]
#[repr(C)]
pub struct BLPosition {
/// The scaled balance of the position. To get the token amount, multiply by the cumulative deposit/borrow
Expand Down Expand Up @@ -94,22 +105,15 @@ impl SpotBalance for BLPosition {
}
}

#[account(zero_copy(unsafe))]
#[derive(Default, Debug, BorshDeserialize, BorshSerialize)]
#[repr(C)]
pub struct Constituent {
/// address of the constituent
pub pubkey: Pubkey,
/// idx in LPPool.constituents
pub constituent_index: u16,

/// how to store actual DLP spot balances:
/// option 1) token account for the constituent (use this to isolate user deposits) - does not allow borrow/lend
/// pub token_account: Pubkey,
/// option 2) spot market balance (use this to deposit constituent balance into spot market and be exposed to borrow/lend interest)
/// pub scaled_balance: u64,
/// pub balance_type: BalanceType.

/// oracle used to price the constituent
pub oracle: Pubkey,
pub oracle_source: OracleSource,
/// max deviation from target_weight allowed for the constituent
/// precision: PERCENTAGE_PRECISION
pub max_weight_deviation: u64,
Expand All @@ -129,38 +133,51 @@ pub struct Constituent {

/// spot borrow-lend balance for constituent
pub spot_balance: BLPosition, // should be in constituent base asset
pub padding: [u8; 16],
}

// pub struct PerpConstituent {
// }

#[zero_copy]
#[derive(Debug, BorshDeserialize, BorshSerialize)]
#[repr(C)]
pub struct AmmConstituentDatum {
pub perp_market_index: u16,
pub constituent_index: u16,
/// PERCENTAGE_PRECISION. The weight this constituent has on the perp market
pub padding: [u8; 4],
/// PERCENTAGE_PRECISION. The weight this constituent has on the perp market
pub data: u64,
pub last_slot: u64,
}

#[zero_copy]
#[derive(Debug, BorshDeserialize, BorshSerialize)]
#[repr(C)]
pub struct WeightDatum {
pub constituent_index: u16,
/// PERCENTAGE_PRECISION. The weights of the target weight matrix
pub padding: [u8; 6],
/// PERCENTAGE_PRECISION. The weights of the target weight matrix
pub data: u64,
pub last_slot: u64,
}

#[account]
#[derive(Debug)]
#[repr(C)]
pub struct AmmConstituentMapping {
// flattened matrix elements, PERCENTAGE_PRECISION. Keep at the end of the account to allow expansion with new constituents.
pub data: Vec<AmmConstituentDatum>,
}

#[account]
#[derive(Debug)]
#[repr(C)]
pub struct ConstituentTargetWeights {
// rows in the matrix (VaultConstituents)
pub num_rows: u16,
// columns in the matrix (0th is the weight, 1st is the last time the weight was updated)
pub num_cols: u16,
// ts of the oldest weight in data, for swaps to reference without traversing matrix
pub oldest_weight_ts: u64,
// PERCENTAGE_PRECISION. The weights of the target weight matrix. Updated async
pub data: Vec<WeightDatum>,
}
Expand All @@ -170,7 +187,6 @@ impl Default for ConstituentTargetWeights {
ConstituentTargetWeights {
num_rows: 0,
num_cols: 0,
oldest_weight_ts: 0,
data: Vec::with_capacity(0),
}
}
Expand All @@ -193,7 +209,6 @@ impl ConstituentTargetWeights {
self.data.clear();
self.num_rows = constituents.len() as u16;
self.num_cols = 2;
self.oldest_weight_ts = slot;

for (constituent_index, constituent) in constituents.iter().enumerate() {
let mut target_amount = 0u128;
Expand All @@ -217,6 +232,7 @@ impl ConstituentTargetWeights {

self.data.push(WeightDatum {
constituent_index: constituent_index as u16,
padding: [0; 6],
data: weight_datum,
last_slot: slot,
});
Expand Down
Loading