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

[Solana][NONEVM-1034] Error improvements, ccip_router edition. #580

Merged
merged 3 commits into from
Feb 10, 2025
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
34 changes: 17 additions & 17 deletions chains/solana/contracts/programs/ccip-router/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub mod seed {
#[derive(Accounts)]
pub struct WithdrawBilledFunds<'info> {
#[account(
owner = token_program.key() @ CcipRouterError::InvalidInputs,
owner = token_program.key() @ CcipRouterError::InvalidInputsMint,
)]
pub fee_token_mint: InterfaceAccount<'info, Mint>,

Expand All @@ -62,7 +62,7 @@ pub struct WithdrawBilledFunds<'info> {
mut,
constraint = recipient.key() == get_associated_token_address_with_program_id(
&config.load()?.fee_aggregator.key(), &fee_token_mint.key(), &token_program.key()
) @ CcipRouterError::InvalidInputs,
) @ CcipRouterError::InvalidInputsAtaAddress,
)]
pub recipient: InterfaceAccount<'info, TokenAccount>,

Expand All @@ -78,7 +78,7 @@ pub struct WithdrawBilledFunds<'info> {
#[account(
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand Down Expand Up @@ -124,7 +124,7 @@ pub struct TransferOwnership<'info> {
mut,
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand All @@ -138,7 +138,7 @@ pub struct AcceptOwnership<'info> {
mut,
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand All @@ -162,7 +162,7 @@ pub struct AddChainSelector<'info> {
#[account(
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand All @@ -178,7 +178,7 @@ pub struct UpdateDestChainSelectorConfig<'info> {
mut,
seeds = [seed::DEST_CHAIN_STATE, new_chain_selector.to_le_bytes().as_ref()],
bump,
constraint = valid_version(dest_chain_state.version, MAX_CHAINSTATE_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(dest_chain_state.version, MAX_CHAINSTATE_V) @ CcipRouterError::InvalidVersion,
realloc = ANCHOR_DISCRIMINATOR + DestChain::INIT_SPACE + dest_chain_config.dynamic_space(),
realloc::payer = authority,
// `realloc::zero = true` is only necessary in cases where an instruction is capable of reallocating
Expand All @@ -191,7 +191,7 @@ pub struct UpdateDestChainSelectorConfig<'info> {
#[account(
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand All @@ -206,7 +206,7 @@ pub struct UpdateConfigCCIPRouter<'info> {
mut,
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand All @@ -230,7 +230,7 @@ pub struct AddOfframp<'info> {
#[account(
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand All @@ -254,7 +254,7 @@ pub struct RemoveOfframp<'info> {
#[account(
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

Expand All @@ -274,15 +274,15 @@ pub struct CcipSend<'info> {
#[account(
seeds = [seed::CONFIG],
bump,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(config.load()?.version, MAX_CONFIG_V) @ CcipRouterError::InvalidVersion,
)]
pub config: AccountLoader<'info, Config>,

#[account(
mut,
seeds = [seed::DEST_CHAIN_STATE, destination_chain_selector.to_le_bytes().as_ref()],
bump,
constraint = valid_version(dest_chain_state.version, MAX_CHAINSTATE_V) @ CcipRouterError::InvalidInputs,
constraint = valid_version(dest_chain_state.version, MAX_CHAINSTATE_V) @ CcipRouterError::InvalidVersion,
)]
pub dest_chain_state: Account<'info, DestChain>,

Expand All @@ -292,7 +292,7 @@ pub struct CcipSend<'info> {
bump,
payer = authority,
space = ANCHOR_DISCRIMINATOR + Nonce::INIT_SPACE,
constraint = uninitialized(nonce.version) || valid_version(nonce.version, MAX_NONCE_V) @ CcipRouterError::InvalidInputs,
constraint = uninitialized(nonce.version) || valid_version(nonce.version, MAX_NONCE_V) @ CcipRouterError::InvalidVersion,
)]
pub nonce: Account<'info, Nonce>,

Expand All @@ -306,9 +306,9 @@ pub struct CcipSend<'info> {
pub fee_token_program: Interface<'info, TokenInterface>,

#[account(
owner = fee_token_program.key() @ CcipRouterError::InvalidInputs,
owner = fee_token_program.key() @ CcipRouterError::InvalidInputsMint,
constraint = (message.fee_token == Pubkey::default() && fee_token_mint.key() == native_mint::ID)
|| message.fee_token.key() == fee_token_mint.key() @ CcipRouterError::InvalidInputs,
|| message.fee_token.key() == fee_token_mint.key() @ CcipRouterError::InvalidInputsMint,
)]
pub fee_token_mint: InterfaceAccount<'info, Mint>, // pass pre-2022 wSOL if using native SOL

Expand Down Expand Up @@ -349,7 +349,7 @@ pub struct CcipSend<'info> {
////////////////////
/// CHECK: This is the account for the Fee Quoter program
#[account(
address = config.load()?.fee_quoter @ CcipRouterError::InvalidInputs,
address = config.load()?.fee_quoter @ CcipRouterError::InvalidVersion,
)]
pub fee_quoter: UncheckedAccount<'info>,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn transfer_ownership(ctx: Context<TransferOwnership>, proposed_owner: Pubke
let mut config = ctx.accounts.config.load_mut()?;
require!(
proposed_owner != config.owner,
CcipRouterError::InvalidInputs
CcipRouterError::RedundantOwnerProposal
);
emit!(events::OwnershipTransferRequested {
from: config.owner,
Expand Down Expand Up @@ -129,14 +129,20 @@ pub fn withdraw_billed_funds(
};

let amount = if transfer_all {
require!(desired_amount == 0, CcipRouterError::InvalidInputs);
require!(
desired_amount == 0,
CcipRouterError::InvalidInputsTransferAllAmount
);
require!(
ctx.accounts.fee_token_accum.amount > 0,
CcipRouterError::InsufficientFunds
);
ctx.accounts.fee_token_accum.amount
} else {
require!(desired_amount > 0, CcipRouterError::InvalidInputs);
require!(
desired_amount > 0,
CcipRouterError::InvalidInputsTokenAmount
);
require!(
desired_amount <= ctx.accounts.fee_token_accum.amount,
CcipRouterError::InsufficientFunds
Expand All @@ -160,7 +166,9 @@ pub fn withdraw_billed_funds(
fn validate_dest_chain_config(dest_chain_selector: u64, _config: &DestChainConfig) -> Result<()> {
// As of now, the config has very few properties and there is very little to validate yet.
// This is mainly a placeholder to add validations as that config object grows.
// TODO improve errors
require!(dest_chain_selector != 0, CcipRouterError::InvalidInputs);
require!(
dest_chain_selector != 0,
CcipRouterError::InvalidInputsChainSelector
);
Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ pub fn transfer_fee<'info>(
) -> Result<()> {
require!(
fee.token == transfer.mint.key(),
CcipRouterError::InvalidInputs
); // TODO use more specific error
CcipRouterError::FeeTokenMismatch
);

do_billing_transfer(token_program, transfer, fee.amount, decimals, signer_bump)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ pub fn ccip_send<'info>(
let token_count = message.token_amounts.len();
require!(
token_indexes.len() == token_count,
CcipRouterError::InvalidInputs,
CcipRouterError::InvalidInputsTokenIndices,
);

let mut new_message: SVM2AnyRampMessage = SVM2AnyRampMessage {
Expand Down
76 changes: 13 additions & 63 deletions chains/solana/contracts/programs/ccip-router/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub mod ccip_router {
link_token_mint: Pubkey,
) -> Result<()> {
let mut config = ctx.accounts.config.load_init()?;
require!(config.version == 0, CcipRouterError::InvalidInputs); // assert uninitialized state - AccountLoader doesn't work with constraint
require!(config.version == 0, CcipRouterError::InvalidVersion); // assert uninitialized state - AccountLoader doesn't work with constraint
config.version = 1;
config.svm_chain_selector = svm_chain_selector;
config.link_token_mint = link_token_mint;
Expand Down Expand Up @@ -372,28 +372,18 @@ pub enum AnchorErrorHack {

#[error_code]
pub enum CcipRouterError {
#[msg("The given sequence interval is invalid")]
InvalidSequenceInterval,
#[msg("The given Merkle Root is missing")]
RootNotCommitted,
#[msg("The given Merkle Root is already committed")]
ExistingMerkleRoot,
#[msg("The signer is unauthorized")]
Unauthorized,
#[msg("Invalid inputs")]
InvalidInputs,
#[msg("Source chain selector not supported")]
UnsupportedSourceChainSelector,
#[msg("Destination chain selector not supported")]
UnsupportedDestinationChainSelector,
#[msg("Invalid Proof for Merkle Root")]
InvalidProof,
#[msg("Invalid message format")]
InvalidMessage,
#[msg("Mint account input is invalid")]
InvalidInputsMint,
#[msg("Invalid version of the onchain state")]
InvalidVersion,
#[msg("Fee token doesn't match transfer token")]
FeeTokenMismatch,
#[msg("Proposed owner is the current owner")]
RedundantOwnerProposal,
#[msg("Reached max sequence number")]
ReachedMaxSequenceNumber,
#[msg("Manual execution not allowed")]
ManualExecutionNotAllowed,
#[msg("Invalid pool account account indices")]
InvalidInputsTokenIndices,
#[msg("Invalid pool accounts")]
Expand All @@ -410,64 +400,24 @@ pub enum CcipRouterError {
InvalidInputsLookupTableAccountWritable,
#[msg("Cannot send zero tokens")]
InvalidInputsTokenAmount,
#[msg("Release or mint balance mismatch")]
OfframpReleaseMintBalanceMismatch,
#[msg("Invalid data length")]
OfframpInvalidDataLength,
#[msg("Stale commit report")]
StaleCommitReport,
#[msg("Destination chain disabled")]
DestinationChainDisabled,
#[msg("Fee token disabled")]
FeeTokenDisabled,
#[msg("Message exceeds maximum data size")]
MessageTooLarge,
#[msg("Message contains an unsupported number of tokens")]
UnsupportedNumberOfTokens,
#[msg("Chain family selector not supported")]
UnsupportedChainFamilySelector,
#[msg("Invalid EVM address")]
InvalidEVMAddress,
#[msg("Invalid encoding")]
InvalidEncoding,
#[msg("Must specify zero amount to send alongside transfer_all")]
InvalidInputsTransferAllAmount,
#[msg("Invalid Associated Token Account address")]
InvalidInputsAtaAddress,
#[msg("Invalid Associated Token Account writable flag")]
InvalidInputsAtaWritable,
#[msg("Invalid token price")]
InvalidTokenPrice,
#[msg("Stale gas price")]
StaleGasPrice,
#[msg("Chain selector is invalid")]
InvalidInputsChainSelector,
#[msg("Insufficient lamports")]
InsufficientLamports,
#[msg("Insufficient funds")]
InsufficientFunds,
#[msg("Unsupported token")]
UnsupportedToken,
#[msg("Inputs are missing token configuration")]
InvalidInputsMissingTokenConfig,
#[msg("Message fee is too high")]
MessageFeeTooHigh,
#[msg("Source token data is too large")]
SourceTokenDataTooLarge,
#[msg("Message gas limit too high")]
MessageGasLimitTooHigh,
#[msg("Extra arg out of order execution must be true")]
ExtraArgOutOfOrderExecutionMustBeTrue,
#[msg("New Admin can not be zero address")]
InvalidTokenAdminRegistryInputsZeroAddress,
#[msg("An already owned registry can not be proposed")]
InvalidTokenAdminRegistryProposedAdmin,
#[msg("Invalid writability bitmap")]
InvalidWritabilityBitmap,
#[msg("Invalid extra args tag")]
InvalidExtraArgsTag,
#[msg("Invalid chain family selector")]
InvalidChainFamilySelector,
#[msg("Invalid token receiver")]
InvalidTokenReceiver,
#[msg("Invalid SVM address")]
InvalidSVMAddress,
#[msg("Sender not allowed for that destination chain")]
SenderNotAllowed,
}
Loading
Loading