Skip to content

Commit

Permalink
Better zero handling (#92)
Browse files Browse the repository at this point in the history
- Add failure for 0 asset handling for the following methods: cooldown,
delegation, minting, burning
- Added details on specification for mint/burn/etc.
  • Loading branch information
buffalu authored Aug 30, 2024
1 parent 9051a45 commit c2beade
Show file tree
Hide file tree
Showing 12 changed files with 272 additions and 70 deletions.
20 changes: 20 additions & 0 deletions clients/js/vault_client/errors/jitoVault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ export const JITO_VAULT_ERROR__SLASHER_OVERFLOW = 0x40d; // 1037
export const JITO_VAULT_ERROR__NCN_OVERFLOW = 0x40e; // 1038
/** OperatorOverflow: OperatorOverflow */
export const JITO_VAULT_ERROR__OPERATOR_OVERFLOW = 0x40f; // 1039
/** VaultDelegationZero: VaultDelegationZero */
export const JITO_VAULT_ERROR__VAULT_DELEGATION_ZERO = 0x410; // 1040
/** VaultCooldownZero: VaultCooldownZero */
export const JITO_VAULT_ERROR__VAULT_COOLDOWN_ZERO = 0x411; // 1041
/** VaultBurnZero: VaultBurnZero */
export const JITO_VAULT_ERROR__VAULT_BURN_ZERO = 0x412; // 1042
/** VaultEnqueueWithdrawalAmountZero: VaultEnqueueWithdrawalAmountZero */
export const JITO_VAULT_ERROR__VAULT_ENQUEUE_WITHDRAWAL_AMOUNT_ZERO = 0x413; // 1043
/** VaultMintZero: VaultMintZero */
export const JITO_VAULT_ERROR__VAULT_MINT_ZERO = 0x414; // 1044

export type JitoVaultError =
| typeof JITO_VAULT_ERROR__NCN_OPERATOR_STATE_UNSLASHABLE
Expand All @@ -105,9 +115,13 @@ export type JitoVaultError =
| typeof JITO_VAULT_ERROR__SLASHER_OVERFLOW
| typeof JITO_VAULT_ERROR__SLIPPAGE_ERROR
| typeof JITO_VAULT_ERROR__VAULT_ADMIN_INVALID
| typeof JITO_VAULT_ERROR__VAULT_BURN_ZERO
| typeof JITO_VAULT_ERROR__VAULT_CAPACITY_ADMIN_INVALID
| typeof JITO_VAULT_ERROR__VAULT_CAPACITY_EXCEEDED
| typeof JITO_VAULT_ERROR__VAULT_COOLDOWN_ZERO
| typeof JITO_VAULT_ERROR__VAULT_DELEGATION_ADMIN_INVALID
| typeof JITO_VAULT_ERROR__VAULT_DELEGATION_ZERO
| typeof JITO_VAULT_ERROR__VAULT_ENQUEUE_WITHDRAWAL_AMOUNT_ZERO
| typeof JITO_VAULT_ERROR__VAULT_FEE_ADMIN_INVALID
| typeof JITO_VAULT_ERROR__VAULT_FEE_BUMP_TOO_LARGE
| typeof JITO_VAULT_ERROR__VAULT_FEE_CAP_EXCEEDED
Expand All @@ -116,6 +130,7 @@ export type JitoVaultError =
| typeof JITO_VAULT_ERROR__VAULT_IS_UPDATED
| typeof JITO_VAULT_ERROR__VAULT_MAX_SLASHED_PER_OPERATOR_EXCEEDED
| typeof JITO_VAULT_ERROR__VAULT_MINT_BURN_ADMIN_INVALID
| typeof JITO_VAULT_ERROR__VAULT_MINT_ZERO
| typeof JITO_VAULT_ERROR__VAULT_NCN_ADMIN_INVALID
| typeof JITO_VAULT_ERROR__VAULT_NCN_SLASHER_TICKET_FAILED_COOLDOWN
| typeof JITO_VAULT_ERROR__VAULT_NCN_SLASHER_TICKET_FAILED_WARMUP
Expand Down Expand Up @@ -149,9 +164,13 @@ if (process.env.NODE_ENV !== 'production') {
[JITO_VAULT_ERROR__SLASHER_OVERFLOW]: `SlasherOverflow`,
[JITO_VAULT_ERROR__SLIPPAGE_ERROR]: `SlippageError`,
[JITO_VAULT_ERROR__VAULT_ADMIN_INVALID]: `VaultAdminInvalid`,
[JITO_VAULT_ERROR__VAULT_BURN_ZERO]: `VaultBurnZero`,
[JITO_VAULT_ERROR__VAULT_CAPACITY_ADMIN_INVALID]: `VaultCapacityAdminInvalid`,
[JITO_VAULT_ERROR__VAULT_CAPACITY_EXCEEDED]: `VaultCapacityExceeded`,
[JITO_VAULT_ERROR__VAULT_COOLDOWN_ZERO]: `VaultCooldownZero`,
[JITO_VAULT_ERROR__VAULT_DELEGATION_ADMIN_INVALID]: `VaultDelegationAdminInvalid`,
[JITO_VAULT_ERROR__VAULT_DELEGATION_ZERO]: `VaultDelegationZero`,
[JITO_VAULT_ERROR__VAULT_ENQUEUE_WITHDRAWAL_AMOUNT_ZERO]: `VaultEnqueueWithdrawalAmountZero`,
[JITO_VAULT_ERROR__VAULT_FEE_ADMIN_INVALID]: `VaultFeeAdminInvalid`,
[JITO_VAULT_ERROR__VAULT_FEE_BUMP_TOO_LARGE]: `VaultFeeBumpTooLarge`,
[JITO_VAULT_ERROR__VAULT_FEE_CAP_EXCEEDED]: `VaultFeeCapExceeded`,
Expand All @@ -160,6 +179,7 @@ if (process.env.NODE_ENV !== 'production') {
[JITO_VAULT_ERROR__VAULT_IS_UPDATED]: `VaultIsUpdated`,
[JITO_VAULT_ERROR__VAULT_MAX_SLASHED_PER_OPERATOR_EXCEEDED]: `VaultMaxSlashedPerOperatorExceeded`,
[JITO_VAULT_ERROR__VAULT_MINT_BURN_ADMIN_INVALID]: `VaultMintBurnAdminInvalid`,
[JITO_VAULT_ERROR__VAULT_MINT_ZERO]: `VaultMintZero`,
[JITO_VAULT_ERROR__VAULT_NCN_ADMIN_INVALID]: `VaultNcnAdminInvalid`,
[JITO_VAULT_ERROR__VAULT_NCN_SLASHER_TICKET_FAILED_COOLDOWN]: `VaultNcnSlasherTicketFailedCooldown`,
[JITO_VAULT_ERROR__VAULT_NCN_SLASHER_TICKET_FAILED_WARMUP]: `VaultNcnSlasherTicketFailedWarmup`,
Expand Down
15 changes: 15 additions & 0 deletions clients/rust/vault_client/src/generated/errors/jito_vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,21 @@ pub enum JitoVaultError {
/// 1039 - OperatorOverflow
#[error("OperatorOverflow")]
OperatorOverflow = 0x40F,
/// 1040 - VaultDelegationZero
#[error("VaultDelegationZero")]
VaultDelegationZero = 0x410,
/// 1041 - VaultCooldownZero
#[error("VaultCooldownZero")]
VaultCooldownZero = 0x411,
/// 1042 - VaultBurnZero
#[error("VaultBurnZero")]
VaultBurnZero = 0x412,
/// 1043 - VaultEnqueueWithdrawalAmountZero
#[error("VaultEnqueueWithdrawalAmountZero")]
VaultEnqueueWithdrawalAmountZero = 0x413,
/// 1044 - VaultMintZero
#[error("VaultMintZero")]
VaultMintZero = 0x414,
}

impl solana_program::program_error::PrintProgramError for JitoVaultError {
Expand Down
25 changes: 25 additions & 0 deletions idl/jito_vault.json
Original file line number Diff line number Diff line change
Expand Up @@ -2316,6 +2316,31 @@
"code": 1039,
"name": "OperatorOverflow",
"msg": "OperatorOverflow"
},
{
"code": 1040,
"name": "VaultDelegationZero",
"msg": "VaultDelegationZero"
},
{
"code": 1041,
"name": "VaultCooldownZero",
"msg": "VaultCooldownZero"
},
{
"code": 1042,
"name": "VaultBurnZero",
"msg": "VaultBurnZero"
},
{
"code": 1043,
"name": "VaultEnqueueWithdrawalAmountZero",
"msg": "VaultEnqueueWithdrawalAmountZero"
},
{
"code": 1044,
"name": "VaultMintZero",
"msg": "VaultMintZero"
}
],
"metadata": {
Expand Down
87 changes: 66 additions & 21 deletions integration_tests/tests/vault/enqueue_withdrawal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#[cfg(test)]
mod tests {
use jito_vault_core::config::Config;
use solana_sdk::signature::{Keypair, Signer};
use jito_vault_sdk::error::VaultError;
use solana_sdk::{
instruction::InstructionError,
signature::{Keypair, Signer},
transaction::TransactionError,
};
use spl_associated_token_account::get_associated_token_address;

use crate::fixtures::{
Expand Down Expand Up @@ -45,29 +50,12 @@ mod tests {
.unwrap();

let depositor = Keypair::new();
fixture.transfer(&depositor.pubkey(), 100.0).await.unwrap();
fixture
.mint_spl_to(&vault.supported_mint, &depositor.pubkey(), MINT_AMOUNT)
.await
.unwrap();
fixture
.create_ata(&vault.vrt_mint, &depositor.pubkey())
vault_program_client
.configure_depositor(&vault_root, &depositor.pubkey(), MINT_AMOUNT)
.await
.unwrap();

vault_program_client
.mint_to(
&vault_root.vault_pubkey,
&vault.vrt_mint,
&depositor,
&get_associated_token_address(&depositor.pubkey(), &vault.supported_mint),
&get_associated_token_address(&vault_root.vault_pubkey, &vault.supported_mint),
&get_associated_token_address(&depositor.pubkey(), &vault.vrt_mint),
&get_associated_token_address(&vault.fee_wallet, &vault.vrt_mint),
None,
MINT_AMOUNT,
min_amount_out,
)
.do_mint_to(&vault_root, &depositor, MINT_AMOUNT, min_amount_out)
.await
.unwrap();

Expand Down Expand Up @@ -156,4 +144,61 @@ mod tests {
.unwrap();
assert_eq!(vault.vrt_enqueued_for_cooldown_amount(), amount_to_dequeue);
}

#[tokio::test]
async fn test_enqueue_withdraw_zero_fails() {
let mut fixture = TestBuilder::new().await;
let ConfiguredVault {
mut vault_program_client,
vault_root,
operator_roots,
..
} = fixture
.setup_vault_with_ncn_and_operators(0, 0, 0, 1, &[])
.await
.unwrap();

let depositor = Keypair::new();
vault_program_client
.configure_depositor(&vault_root, &depositor.pubkey(), 100)
.await
.unwrap();
vault_program_client
.do_mint_to(&vault_root, &depositor, 100, 100)
.await
.unwrap();

// let vault operator ticket warmup
let config = vault_program_client
.get_config(&Config::find_program_address(&jito_vault_program::id()).0)
.await
.unwrap();
fixture
.warp_slot_incremental(2 * config.epoch_length())
.await
.unwrap();

let operator_root_pubkeys: Vec<_> = operator_roots
.iter()
.map(|root| root.operator_pubkey)
.collect();
vault_program_client
.do_full_vault_update(&vault_root.vault_pubkey, &operator_root_pubkeys)
.await
.unwrap();

let err = vault_program_client
.do_enqueue_withdraw(&vault_root, &depositor, 0)
.await
.unwrap_err()
.to_transaction_error()
.unwrap();
assert_eq!(
err,
TransactionError::InstructionError(
0,
InstructionError::Custom(VaultError::VaultEnqueueWithdrawalAmountZero as u32)
)
);
}
}
29 changes: 29 additions & 0 deletions vault_core/src/delegation_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ impl DelegationState {
/// Cools down stake by subtracting it from the staked amount and adding it to the enqueued
/// cooldown amount
pub fn cooldown(&mut self, amount: u64) -> Result<(), VaultError> {
if amount == 0 {
msg!("Cooldown amount is zero");
return Err(VaultError::VaultCooldownZero);
}

let mut staked_amount: u64 = self.staked_amount.into();
staked_amount = staked_amount
.checked_sub(amount)
Expand All @@ -205,6 +210,11 @@ impl DelegationState {

/// Delegates assets to the operator
pub fn delegate(&mut self, amount: u64) -> Result<(), VaultError> {
if amount == 0 {
msg!("Delegation amount is zero");
return Err(VaultError::VaultDelegationZero);
}

let mut staked_amount: u64 = self.staked_amount.into();
staked_amount = staked_amount
.checked_add(amount)
Expand All @@ -217,6 +227,7 @@ impl DelegationState {
#[cfg(test)]
mod tests {
use jito_bytemuck::types::PodU64;
use jito_vault_sdk::error::VaultError;

use crate::delegation_state::DelegationState;

Expand Down Expand Up @@ -279,4 +290,22 @@ mod tests {
assert_eq!(delegation_state.cooling_down_amount(), 0);
assert_eq!(delegation_state.total_security().unwrap(), 50);
}

#[test]
fn test_delegate_zero() {
let mut delegation_state = DelegationState::default();
assert_eq!(
delegation_state.delegate(0),
Err(VaultError::VaultDelegationZero)
);
}

#[test]
fn test_cooldown_zero() {
let mut delegation_state = DelegationState::new(100, 0, 0);
assert_eq!(
delegation_state.cooldown(0),
Err(VaultError::VaultCooldownZero)
);
}
}
Loading

0 comments on commit c2beade

Please sign in to comment.