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

feat(interchain-token-service): encode source/recipient addresses as strings instead of XDR #147

Merged
merged 14 commits into from
Jan 20, 2025
Merged
11 changes: 3 additions & 8 deletions contracts/interchain-token-service/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use interchain_token::InterchainTokenClient;
use soroban_sdk::{
contract, contractimpl, panic_with_error,
token::{self, StellarAssetClient},
xdr::{FromXdr, ToXdr},
xdr::ToXdr,
Address, Bytes, BytesN, Env, String,
};
use soroban_token_sdk::metadata::TokenMetadata;
Expand Down Expand Up @@ -532,9 +532,7 @@ impl InterchainTokenService {
amount,
data,
}) => {
let destination_address = Address::from_xdr(env, &destination_address)
.map_err(|_| ContractError::InvalidDestinationAddress)?;

let destination_address = Address::from_string_bytes(&destination_address);
TanvirDeol marked this conversation as resolved.
Show resolved Hide resolved
let token_config_value =
Self::token_id_config_with_extended_ttl(env, token_id.clone())?;

Expand Down Expand Up @@ -597,10 +595,7 @@ impl InterchainTokenService {
);

// Note: attempt to convert a byte string which doesn't represent a valid Soroban address fails at the Host level
let minter = minter
.map(|m| Address::from_xdr(env, &m))
.transpose()
.map_err(|_| ContractError::InvalidMinter)?;
let minter = minter.map(|m| Address::from_string_bytes(&m));

TanvirDeol marked this conversation as resolved.
Show resolved Hide resolved
let deployed_address = Self::deploy_interchain_token_contract(
env,
Expand Down
1 change: 1 addition & 0 deletions contracts/interchain-token-service/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub enum HubMessage {
}

/// The type of token manager used for the tokenId.
///
/// Only the variants supported by Stellar ITS are defined here.
/// The variant values need to match the [ITS spec](https://github.com/axelarnetwork/interchain-token-service/blob/v2.0.0/contracts/interfaces/ITokenManagerType.sol#L9).
#[contracttype]
Expand Down
6 changes: 4 additions & 2 deletions contracts/interchain-token-service/tests/executable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod utils;

use axelar_gateway::testutils::{generate_proof, get_approve_hash};
use axelar_gateway::types::Message as GatewayMessage;
use axelar_soroban_std::testutils::address_to_bytes;
use axelar_soroban_std::traits::BytesExt;
use axelar_soroban_std::{assert_invoke_auth_err, events};
use interchain_token_service::types::{HubMessage, InterchainTransfer, Message};
Expand Down Expand Up @@ -131,13 +132,14 @@ fn interchain_transfer_execute_succeeds() {
let deployer = Address::generate(&env);
let token_id = setup_its_token(&env, &client, &deployer, amount);
let data = Bytes::from_hex(&env, "dead");
let destination_address = address_to_bytes(&env, &executable_id);

let msg = HubMessage::ReceiveFromHub {
source_chain: String::from_str(&env, HUB_CHAIN),
message: Message::InterchainTransfer(InterchainTransfer {
token_id: token_id.clone(),
source_address: sender,
destination_address: executable_id.clone().to_xdr(&env),
destination_address,
amount,
data: Some(data.clone()),
}),
Expand Down Expand Up @@ -181,7 +183,7 @@ fn executable_fails_if_not_executed_from_its() {
let executable_client = test::ExecutableContractClient::new(&env, &executable_id);

let source_chain = client.its_hub_chain_name();
let source_address = Address::generate(&env).to_xdr(&env);
let source_address = address_to_bytes(&env, &Address::generate(&env));
let amount = 1000;
let token_id = BytesN::<32>::from_array(&env, &[1; 32]);
let token_address = Address::generate(&env);
Expand Down
7 changes: 4 additions & 3 deletions contracts/interchain-token-service/tests/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod utils;

use axelar_gateway::types::Message as GatewayMessage;
use axelar_soroban_std::events;
use axelar_soroban_std::testutils::address_to_bytes;
use interchain_token_service::event::{
InterchainTokenDeployedEvent, InterchainTransferReceivedEvent,
};
Expand Down Expand Up @@ -67,7 +68,7 @@ fn interchain_transfer_message_execute_succeeds() {
register_chains(&env, &client);

let sender = Address::generate(&env).to_xdr(&env);
let recipient = Address::generate(&env).to_xdr(&env);
let recipient = address_to_bytes(&env, &Address::generate(&env));
let source_chain = client.its_hub_chain_name();
let source_address = Address::generate(&env).to_string();

Expand Down Expand Up @@ -116,7 +117,7 @@ fn deploy_interchain_token_message_execute_succeeds() {
register_chains(&env, &client);

let sender = Address::generate(&env);
let sender_bytes = sender.clone().to_xdr(&env);
let sender_bytes = address_to_bytes(&env, &sender);
let source_chain = client.its_hub_chain_name();
let source_address = Address::generate(&env).to_string();

Expand Down Expand Up @@ -319,7 +320,7 @@ fn deploy_interchain_token_message_execute_fails_token_already_deployed() {
let (env, client, gateway_client, _, signers) = setup_env();
register_chains(&env, &client);

let sender = Address::generate(&env).to_xdr(&env);
let sender = address_to_bytes(&env, &Address::generate(&env));
let source_chain = client.its_hub_chain_name();
let source_address = Address::generate(&env).to_string();

Expand Down
7 changes: 4 additions & 3 deletions contracts/interchain-token-service/tests/flow_limit.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod utils;

use axelar_gateway::types::Message as GatewayMessage;
use axelar_soroban_std::testutils::address_to_bytes;
use axelar_soroban_std::{assert_contract_err, assert_invoke_auth_ok, events, traits::BytesExt};
use interchain_token_service::{
error::ContractError,
Expand All @@ -9,7 +10,7 @@ use interchain_token_service::{
InterchainTokenServiceClient,
};
use soroban_sdk::testutils::{Address as _, Ledger as _};
use soroban_sdk::{vec, xdr::ToXdr, Address, Bytes, BytesN, Env, String, Vec};
use soroban_sdk::{vec, Address, Bytes, BytesN, Env, String, Vec};
use utils::{
approve_gateway_messages, register_chains, setup_env, setup_gas_token, setup_its_token,
HUB_CHAIN,
Expand All @@ -36,8 +37,8 @@ fn create_interchain_transfer_message(
token_id: &BytesN<32>,
amount: i128,
) -> (String, String, String, Bytes, Vec<GatewayMessage>) {
let sender = Address::generate(env).to_xdr(env);
let recipient = Address::generate(env).to_xdr(env);
let sender = address_to_bytes(env, &Address::generate(env));
let recipient = address_to_bytes(env, &Address::generate(env));
let source_chain = client.its_hub_chain_name();
let source_address = Address::generate(env).to_string();

Expand Down
5 changes: 3 additions & 2 deletions contracts/interchain-token-service/tests/message_routing.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
mod utils;
use axelar_soroban_std::testutils::address_to_bytes;
use axelar_soroban_std::{assert_contract_err, traits::BytesExt};
use interchain_token_service::error::ContractError;
use soroban_sdk::{testutils::Address as _, xdr::ToXdr, Address, Bytes, String};
use soroban_sdk::{testutils::Address as _, Address, Bytes, String};
use utils::{register_chains, setup_env, setup_gas_token, setup_its_token};

#[test]
Expand Down Expand Up @@ -42,7 +43,7 @@ fn send_to_untrusted_chain_fails() {
&sender,
&token_id,
&String::from_str(&env, "untrusted_chain"),
&Address::generate(&env).to_xdr(&env),
&address_to_bytes(&env, &Address::generate(&env)),
&amount,
&None,
&gas_token,
Expand Down
12 changes: 11 additions & 1 deletion packages/axelar-soroban-std/src/testutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ extern crate std;

use soroban_sdk::{
testutils::{AuthorizedFunction, AuthorizedInvocation, Events},
vec, Address, Env, IntoVal, Symbol, Val, Vec,
vec, Address, Bytes, Env, IntoVal, Symbol, Val, Vec,
};

/// Asserts invocation auth of a contract from a single caller.
Expand Down Expand Up @@ -33,6 +33,7 @@ pub fn assert_invocation<T>(
}

/// Asserts that the event at `event_index` in the environment's emitted events is the expected event.
///
/// If `event_index` is negative, the length of events will be added to it, i.e it'll be indexed from the end.
pub fn assert_emitted_event<U, V>(
env: &Env,
Expand Down Expand Up @@ -71,6 +72,15 @@ where
assert_emitted_event(env, -1, contract_id, topics, data);
}

// Converts Stellar address (soroban_sdk::Address) to soroban_sdk::Bytes
pub fn address_to_bytes(env: &Env, address: &Address) -> Bytes {
TanvirDeol marked this conversation as resolved.
Show resolved Hide resolved
let address_str = address.to_string();
let mut str_bytes = [0u8; 56];
address_str.copy_into_slice(&mut str_bytes);
let address_bytes: Bytes = Bytes::from_slice(env, &str_bytes);
address_bytes
}

/// Helper macro for building and verifying authorization chains in Soroban contract tests.
///
/// Used to verify that contract calls require the correct sequence of authorizations.
Expand Down