Skip to main content

vault_crate/
lib.rs

1use anchor_lang::prelude::*;
2use primitivo_macro::Ownership;
3
4include!(concat!(env!("OUT_DIR"), "/primitivo_vault_program_id.rs"));
5
6#[account]
7#[derive(InitSpace)]
8pub struct VaultConfig {
9    pub ownership: Ownership,
10    pub seed_authority: Pubkey,
11    pub underlying_mint: Pubkey,
12    pub derivative_mint: Pubkey,
13    pub underlying_vault: Pubkey,
14    pub id: u64,
15    pub underlying_assets: u64,
16    pub derivative_decimals: u8,
17    pub bump: u8,
18    pub underlying_vault_bump: u8,
19    pub derivative_mint_bump: u8,
20}
21
22#[error_code]
23pub enum VaultError {
24    #[msg("Amount must be greater than 0")]
25    InvalidAmount,
26    #[msg("Arithmetic overflow")]
27    ArithmeticOverflow,
28    #[msg("Invalid state")]
29    InvalidState,
30    #[msg("Computed amount is zero")]
31    ZeroAmountOut,
32}
33
34pub fn quote_deposit_shares(
35    amount_in: u64,
36    underlying_assets: u64,
37    derivative_supply: u64,
38) -> Result<u64> {
39    require!(amount_in > 0, VaultError::InvalidAmount);
40
41    if derivative_supply == 0 || underlying_assets == 0 {
42        return Ok(amount_in);
43    }
44
45    let shares = (amount_in as u128)
46        .checked_mul(derivative_supply as u128)
47        .ok_or(VaultError::ArithmeticOverflow)?
48        .checked_div(underlying_assets as u128)
49        .ok_or(VaultError::ArithmeticOverflow)?;
50
51    let shares = u64::try_from(shares).map_err(|_| error!(VaultError::ArithmeticOverflow))?;
52    require!(shares > 0, VaultError::ZeroAmountOut);
53    Ok(shares)
54}
55
56pub fn quote_redeem_underlying(
57    derivative_in: u64,
58    underlying_assets: u64,
59    derivative_supply: u64,
60) -> Result<u64> {
61    require!(derivative_in > 0, VaultError::InvalidAmount);
62    require!(derivative_supply > 0, VaultError::InvalidState);
63    require!(underlying_assets > 0, VaultError::InvalidState);
64
65    let underlying_out = (derivative_in as u128)
66        .checked_mul(underlying_assets as u128)
67        .ok_or(VaultError::ArithmeticOverflow)?
68        .checked_div(derivative_supply as u128)
69        .ok_or(VaultError::ArithmeticOverflow)?;
70
71    let underlying_out =
72        u64::try_from(underlying_out).map_err(|_| error!(VaultError::ArithmeticOverflow))?;
73    require!(underlying_out > 0, VaultError::ZeroAmountOut);
74    Ok(underlying_out)
75}
76
77pub fn increase_underlying_assets(underlying_assets: &mut u64, amount: u64) -> Result<()> {
78    *underlying_assets = underlying_assets
79        .checked_add(amount)
80        .ok_or(VaultError::ArithmeticOverflow)?;
81    Ok(())
82}
83
84pub fn decrease_underlying_assets(underlying_assets: &mut u64, amount: u64) -> Result<()> {
85    *underlying_assets = underlying_assets
86        .checked_sub(amount)
87        .ok_or(VaultError::ArithmeticOverflow)?;
88    Ok(())
89}