Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate assertions to Vipers #104

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
36 changes: 36 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions stable-swap-program/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ no-entrypoint = []
fuzz = ["stable-swap-client/fuzz"]

[dependencies]
anchor-lang = ">=0.17"
anchor-spl = ">=0.17"
solana-program = "^1.6.10"
spl-token = { version = "3.3.0", features = ["no-entrypoint"] }
stable-swap-client = { path = "../../stable-swap-client", version = "^1" }
stable-swap-math = { path = "../../stable-swap-math", version = "^1" }
vipers = "^1.5.5"

[dev-dependencies]
solana-sdk = "^1.9.5"
Expand Down
2 changes: 2 additions & 0 deletions stable-swap-program/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub mod processor;
pub use stable_swap_client::{error, fees, instruction, state};
pub use stable_swap_math::{curve, math, pool_converter};

pub use stable_swap_client::error::SwapError as ErrorCode;

/// Export current solana-program types for downstream users who may also be
/// building with a different solana-program version
pub use solana_program;
Expand Down
108 changes: 72 additions & 36 deletions stable-swap-program/program/src/processor/checks.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
//! Checks for processing instructions.

use anchor_lang::prelude::*;

use super::logging::log_slippage_error;
use crate::{
error::SwapError,
processor::utils,
state::{SwapInfo, SwapTokenInfo},
};

use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
pubkey::Pubkey,
};

use super::logging::log_slippage_error;
use vipers::{assert_keys_eq, assert_keys_neq, invariant};

/// Checks if the reserve of the swap is the given key.
fn check_reserves_match(token: &SwapTokenInfo, reserves_info_key: &Pubkey) -> ProgramResult {
check_token_keys_equal!(
token,
*reserves_info_key,
token.reserves,
"Reserves",
SwapError::IncorrectSwapAccount
);
if token.index == 0 {
assert_keys_eq!(
reserves_info_key,
token.reserves,
SwapError::IncorrectSwapAccount,
"Reserves A"
);
} else if token.index == 1 {
assert_keys_eq!(
reserves_info_key,
token.reserves,
SwapError::IncorrectSwapAccount,
"Reserves B"
);
} else {
assert_keys_eq!(
reserves_info_key,
token.reserves,
SwapError::IncorrectSwapAccount,
"Reserves",
);
}
Ok(())
}

Expand All @@ -30,15 +46,16 @@ pub fn check_has_admin_signer(
expected_admin_key: &Pubkey,
admin_account_info: &AccountInfo,
) -> ProgramResult {
check_keys_equal!(
*expected_admin_key,
*admin_account_info.key,
assert_keys_eq!(
expected_admin_key,
admin_account_info.key,
SwapError::Unauthorized,
"Admin signer",
SwapError::Unauthorized
);
if !admin_account_info.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
invariant!(
admin_account_info.is_signer,
ProgramError::MissingRequiredSignature
);
Ok(())
}

Expand All @@ -47,13 +64,32 @@ pub fn check_deposit_token_accounts(
source_key: &Pubkey,
reserves_info_key: &Pubkey,
) -> ProgramResult {
check_token_keys_not_equal!(
token,
*source_key,
token.reserves,
"Source account cannot be swap token account of token",
SwapError::InvalidInput
);
match token.index {
0 => {
assert_keys_neq!(
source_key,
token.reserves,
SwapError::InvalidInput,
"Source account cannot be one of swap's token accounts for token A",
);
}
1 => {
assert_keys_neq!(
source_key,
token.reserves,
SwapError::InvalidInput,
"Source account cannot be one of swap's token accounts for token B",
);
}
_ => {
assert_keys_neq!(
source_key,
token.reserves,
SwapError::InvalidInput,
"Source account cannot be one of swap's token accounts",
);
}
};
check_reserves_match(token, reserves_info_key)?;
Ok(())
}
Expand All @@ -78,11 +114,11 @@ pub fn check_withdraw_token_accounts(
admin_fee_dest_key: &Pubkey,
) -> ProgramResult {
check_reserves_match(token, reserves_info_key)?;
check_keys_equal!(
*admin_fee_dest_key,
assert_keys_eq!(
admin_fee_dest_key,
token.admin_fees,
SwapError::InvalidAdmin,
"Admin fee dest",
SwapError::InvalidAdmin
);
Ok(())
}
Expand All @@ -94,11 +130,11 @@ pub fn check_swap_authority(
swap_authority_key: &Pubkey,
) -> ProgramResult {
let swap_authority = utils::authority_id(program_id, swap_info_key, token_swap.nonce)?;
check_keys_equal!(
*swap_authority_key,
assert_keys_eq!(
swap_authority_key,
swap_authority,
SwapError::InvalidProgramAddress,
"Swap authority",
SwapError::InvalidProgramAddress
);
Ok(())
}
Expand All @@ -109,17 +145,17 @@ pub fn check_swap_token_destination_accounts(
swap_destination_info_key: &Pubkey,
admin_destination_info_key: &Pubkey,
) -> ProgramResult {
check_keys_equal!(
*swap_destination_info_key,
assert_keys_eq!(
swap_destination_info_key,
token.reserves,
SwapError::IncorrectSwapAccount,
"Incorrect destination, expected",
SwapError::IncorrectSwapAccount
);
check_keys_equal!(
*admin_destination_info_key,
assert_keys_eq!(
admin_destination_info_key,
token.admin_fees,
SwapError::InvalidAdmin,
"Admin fee",
SwapError::InvalidAdmin
);
Ok(())
}
25 changes: 0 additions & 25 deletions stable-swap-program/program/src/processor/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use solana_program::log::sol_log_64;
use solana_program::msg;
use solana_program::pubkey::Pubkey;

/// Event enum
#[derive(Debug)]
Expand Down Expand Up @@ -47,30 +46,6 @@ pub fn log_event(
);
}

pub fn log_keys_mismatch(msg: &str, left: Pubkey, right: Pubkey) {
msg!(msg);
msg!("Left:");
left.log();
msg!("Right:");
right.log();
}

pub fn log_keys_mismatch_optional(msg: &str, left: Option<Pubkey>, right: Option<Pubkey>) {
msg!(msg);
msg!("Left:");
if let Some(left_inner) = left {
left_inner.log();
} else {
msg!("left: missing");
}
msg!("Right:");
if let Some(right_inner) = right {
right_inner.log();
} else {
msg!("right: missing");
}
}

/// Log slippage error
pub fn log_slippage_error(minimum_amount: u64, computed_amount: u64) {
sol_log_64(0, 0, 0, minimum_amount, computed_amount);
Expand Down
75 changes: 0 additions & 75 deletions stable-swap-program/program/src/processor/macros.rs

This file was deleted.

5 changes: 0 additions & 5 deletions stable-swap-program/program/src/processor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
//! Program state processor

#[macro_use]
mod macros;

mod admin;
mod checks;
mod logging;
mod swap;
mod token;
mod utils;

#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod test_utils;

use crate::instruction::AdminInstruction;
Expand Down
Loading