Skip to content

Commit

Permalink
chore(interchain-token-service): verify input validation (#208)
Browse files Browse the repository at this point in the history
  • Loading branch information
AttissNgo authored Jan 27, 2025
1 parent 03d1a48 commit f160c1d
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 49 deletions.
32 changes: 20 additions & 12 deletions contracts/stellar-interchain-token-service/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ impl InterchainTokenServiceInterface for InterchainTokenService {
) -> Result<BytesN<32>, ContractError> {
caller.require_auth();

ensure!(initial_supply >= 0, ContractError::InvalidSupply);

let initial_minter = if initial_supply > 0 {
Some(env.current_contract_address())
} else if let Some(ref minter) = minter {
Expand All @@ -239,7 +241,7 @@ impl InterchainTokenServiceInterface for InterchainTokenService {
);
Some(minter.clone())
} else {
None
return Err(ContractError::InvalidSupply);
};

let deploy_salt = Self::interchain_token_deploy_salt(env, caller.clone(), salt);
Expand Down Expand Up @@ -538,12 +540,13 @@ impl InterchainTokenService {
/// Retrieves the configuration value for the specified token ID.
///
/// # Arguments
/// - `env`: Reference to the environment.
/// - `token_id`: A 32-byte unique identifier for the token.
///
/// # Returns
/// - `Ok(TokenIdConfigValue)`: The configuration value if it exists.
/// - `Err(ContractError::InvalidTokenId)`: If the token ID does not exist in storage.
///
/// # Errors
/// - `ContractError::InvalidTokenId`: If the token ID does not exist in storage.
fn token_id_config(
env: &Env,
token_id: BytesN<32>,
Expand All @@ -557,12 +560,13 @@ impl InterchainTokenService {
/// Retrieves the configuration value for the specified token ID and extends its TTL.
///
/// # Arguments
/// - `env`: Reference to the environment.
/// - `token_id`: A 32-byte unique identifier for the token.
///
/// # Returns
/// - `Ok(TokenIdConfigValue)`: The configuration value if it exists.
/// - `Err(ContractError::InvalidTokenId)`: If the token ID does not exist in storage.
///
/// # Errors
/// - `ContractError::InvalidTokenId`: If the token ID does not exist in storage.
fn token_id_config_with_extended_ttl(
env: &Env,
token_id: BytesN<32>,
Expand All @@ -579,23 +583,27 @@ impl InterchainTokenService {

/// Deploys a remote token on a specified destination chain.
///
/// This function authorizes the caller, retrieves the token's metadata,
/// validates the metadata, and emits an event indicating the start of the
/// token deployment process. It also constructs and sends the deployment
/// message to the remote chain.
/// This function retrieves and validates the token's metadata
/// and emits an event indicating the start of the token deployment process.
/// It also constructs and sends the deployment message to the remote chain.
///
/// # Arguments
/// * `env` - Reference to the environment object.
/// * `caller` - Address of the caller initiating the deployment.
/// * `deploy_salt` - Unique salt used for token deployment.
/// * `destination_chain` - The name of the destination chain where the token will be deployed.
/// * `gas_token` - The token used to pay for gas during the deployment.
///
/// # Returns
/// Returns the token ID of the deployed token on the remote chain, or an error if the deployment fails.
/// - `Ok(BytesN<32>)`: Returns the token ID.
///
/// # Errors
/// Returns `ContractError` if the deployment fails, the token ID is invalid, or token metadata is invalid.
/// - `ContractError::InvalidDestinationChain`: If the `destination_chain` is the current chain.
/// - `ContractError::InvalidTokenId`: If the token ID is invalid.
/// - Errors propagated from `token_metadata`.
/// - Any error propagated from `pay_gas_and_call_contract`.
///
/// # Authorization
/// - The `caller` must authenticate.
fn deploy_remote_token(
env: &Env,
caller: Address,
Expand Down
1 change: 1 addition & 0 deletions contracts/stellar-interchain-token-service/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum ContractError {
InvalidTokenDecimals = 27,
TokenAlreadyRegistered = 28,
ContractPaused = 29,
InvalidSupply = 30,
}

impl_not_approved_error!(ContractError);
Original file line number Diff line number Diff line change
Expand Up @@ -191,27 +191,23 @@ fn deploy_interchain_token_fails_zero_initial_supply_and_invalid_minter() {
}

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

let (sender, salt, token_metadata) = dummy_token_params(&env);
let minter: Option<Address> = None;
let initial_supply = 0;

let token_id = assert_auth!(
&sender,
client.deploy_interchain_token(&sender, &salt, &token_metadata, &initial_supply, &minter,)
assert_contract_err!(
client.mock_all_auths().try_deploy_interchain_token(
&sender,
&salt,
&token_metadata,
&initial_supply,
&minter
),
ContractError::InvalidSupply
);

goldie::assert!(events::fmt_last_emitted_event::<InterchainTokenDeployedEvent>(&env));

let token_address = client.token_address(&token_id);
let token = InterchainTokenClient::new(&env, &token_address);

assert_eq!(token.owner(), client.address);
assert!(token.is_minter(&client.address));
assert!(!token.is_minter(&sender));
assert_eq!(token.balance(&sender), initial_supply);
}

#[test]
Expand All @@ -221,7 +217,7 @@ fn deploy_interchain_token_fails_with_invalid_token_metadata() {
let sender = Address::generate(&env);
let minter: Option<Address> = None;
let salt = BytesN::<32>::from_array(&env, &[1; 32]);
let initial_supply = 0;
let initial_supply = 1000;

let cases = [
(
Expand Down Expand Up @@ -279,3 +275,22 @@ fn deploy_interchain_token_fails_with_invalid_auth() {
client.deploy_interchain_token(&sender, &salt, &token_metadata, &initial_supply, &minter)
);
}

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

let (sender, salt, token_metadata) = dummy_token_params(&env);
let invalid_supply = -1;

assert_contract_err!(
client.mock_all_auths().try_deploy_interchain_token(
&sender,
&salt,
&token_metadata,
&invalid_supply,
&None
),
ContractError::InvalidSupply
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ fn interchain_transfer_fails_on_zero_amount() {
.mock_all_auths()
.set_trusted_chain(&client.its_hub_chain_name());

let amount = 0;
let (sender, gas_token, token_id) = setup_sender(&env, &client, amount);
let supply = 1000;
let transfer_amount = 0;
let (sender, gas_token, token_id) = setup_sender(&env, &client, supply);
let (destination_chain, destination_address, data) = dummy_transfer_params(&env);

assert_contract_err!(
Expand All @@ -118,7 +119,7 @@ fn interchain_transfer_fails_on_zero_amount() {
&token_id,
&destination_chain,
&destination_address,
&amount,
&transfer_amount,
&data,
&gas_token
),
Expand Down

This file was deleted.

0 comments on commit f160c1d

Please sign in to comment.