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}