Skip to content

Commit

Permalink
fix(interchain-token-service): add destination validation checks (#150)
Browse files Browse the repository at this point in the history
  • Loading branch information
AttissNgo authored Jan 17, 2025
1 parent 8239e41 commit 1b77756
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 1 deletion.
14 changes: 14 additions & 0 deletions contracts/interchain-token-service/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,15 @@ impl InterchainTokenServiceInterface for InterchainTokenService {
) -> Result<(), ContractError> {
ensure!(amount > 0, ContractError::InvalidAmount);

ensure!(
!destination_address.is_empty(),
ContractError::InvalidDestinationAddress
);

if let Some(ref data) = data {
ensure!(!data.is_empty(), ContractError::InvalidData);
}

caller.require_auth();

token_handler::take_token(
Expand Down Expand Up @@ -729,6 +738,11 @@ impl InterchainTokenService {
destination_chain: String,
gas_token: Token,
) -> Result<BytesN<32>, ContractError> {
ensure!(
destination_chain != Self::chain_name(env),
ContractError::InvalidDestinationChain
);

let token_id = Self::interchain_token_id(env, Address::zero(env), deploy_salt);
let token_address = Self::token_id_config(env, token_id.clone())?.token_address;
let token = token::Client::new(env, &token_address);
Expand Down
2 changes: 2 additions & 0 deletions contracts/interchain-token-service/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum ContractError {
FlowLimitExceeded = 20,
FlowAmountOverflow = 21,
NotApproved = 22,
InvalidDestinationChain = 23,
InvalidData = 24,
}

impl_not_approved_error!(ContractError);
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,23 @@ fn deploy_remote_interchain_token_fails_with_invalid_token_id() {
ContractError::InvalidTokenId
);
}

#[test]
fn deploy_remote_token_fails_local_deployment() {
let (env, client, _, _, _) = setup_env();

let spender = Address::generate(&env);
let gas_token = setup_gas_token(&env, &spender);
let salt = BytesN::<32>::from_array(&env, &[1; 32]);
let destination_chain = client.chain_name();

assert_contract_err!(
client.mock_all_auths().try_deploy_remote_interchain_token(
&spender,
&salt,
&destination_chain,
&gas_token
),
ContractError::InvalidDestinationChain
);
}
87 changes: 86 additions & 1 deletion contracts/interchain-token-service/tests/interchain_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ mod utils;

use soroban_sdk::testutils::Address as _;
use soroban_sdk::{Address, Bytes, String};
use stellar_axelar_std::events;
use stellar_axelar_std::traits::BytesExt;
use stellar_axelar_std::{assert_contract_err, events};
use stellar_interchain_token_service::error::ContractError;
use stellar_interchain_token_service::event::InterchainTransferSentEvent;
use utils::{register_chains, setup_env, setup_gas_token, setup_its_token};

Expand Down Expand Up @@ -64,3 +65,87 @@ fn interchain_transfer_send_fails_on_insufficient_balance() {
&gas_token,
);
}

#[test]
fn interchain_transfer_fails_on_zero_amount() {
let (env, client, _, _, _) = setup_env();
register_chains(&env, &client);

let sender: Address = Address::generate(&env);
let gas_token = setup_gas_token(&env, &sender);
let amount = 0;
let token_id = setup_its_token(&env, &client, &sender, amount);

let destination_chain = client.its_hub_chain_name();
let destination_address = Bytes::from_hex(&env, "4F4495243837681061C4743b74B3eEdf548D56A5");
let data = Some(Bytes::from_hex(&env, "abcd"));

assert_contract_err!(
client.mock_all_auths().try_interchain_transfer(
&sender,
&token_id,
&destination_chain,
&destination_address,
&amount,
&data,
&gas_token
),
ContractError::InvalidAmount
);
}

#[test]
fn interchain_transfer_fails_on_empty_destination_address() {
let (env, client, _, _, _) = setup_env();
register_chains(&env, &client);

let sender: Address = Address::generate(&env);
let gas_token = setup_gas_token(&env, &sender);
let amount = 1000;
let token_id = setup_its_token(&env, &client, &sender, amount);

let destination_chain = client.its_hub_chain_name();
let destination_address = Bytes::new(&env);
let data = Some(Bytes::from_hex(&env, "abcd"));

assert_contract_err!(
client.mock_all_auths().try_interchain_transfer(
&sender,
&token_id,
&destination_chain,
&destination_address,
&amount,
&data,
&gas_token
),
ContractError::InvalidDestinationAddress
);
}

#[test]
fn interchain_transfer_fails_on_empty_data() {
let (env, client, _, _, _) = setup_env();
register_chains(&env, &client);

let sender: Address = Address::generate(&env);
let gas_token = setup_gas_token(&env, &sender);
let amount = 1000;
let token_id = setup_its_token(&env, &client, &sender, amount);

let destination_chain = client.its_hub_chain_name();
let destination_address = Bytes::from_hex(&env, "4F4495243837681061C4743b74B3eEdf548D56A5");
let empty_data = Some(Bytes::new(&env));

assert_contract_err!(
client.mock_all_auths().try_interchain_transfer(
&sender,
&token_id,
&destination_chain,
&destination_address,
&amount,
&empty_data,
&gas_token
),
ContractError::InvalidData
);
}

0 comments on commit 1b77756

Please sign in to comment.