From 63beb53f1832b866c184122d8d15f7d70d84e2f7 Mon Sep 17 00:00:00 2001 From: Foivos Date: Mon, 20 Jan 2025 18:56:07 +0200 Subject: [PATCH] changed from trusted addresses to trusted chains --- .../sources/events.move | 9 +- .../sources/interchain_token_service.move | 164 ++++--- .../sources/types/address_tracker.move | 181 -------- .../sources/types/chain_tracker.move | 146 ++++++ .../sources/types/trusted_addresses.move | 69 --- .../interchain_token_service_v0.move | 430 +++++++----------- 6 files changed, 418 insertions(+), 581 deletions(-) delete mode 100644 move/interchain_token_service/sources/types/address_tracker.move create mode 100644 move/interchain_token_service/sources/types/chain_tracker.move delete mode 100644 move/interchain_token_service/sources/types/trusted_addresses.move diff --git a/move/interchain_token_service/sources/events.move b/move/interchain_token_service/sources/events.move index 7d2ce0d3..9382d5b0 100644 --- a/move/interchain_token_service/sources/events.move +++ b/move/interchain_token_service/sources/events.move @@ -48,9 +48,8 @@ public struct UnregisteredCoinReceived has copy, drop { decimals: u8, } -public struct TrustedAddressSet has copy, drop { +public struct TrustedAddressAdded has copy, drop { chain_name: String, - trusted_address: String, } public struct TrustedAddressRemoved has copy, drop { @@ -143,13 +142,11 @@ public(package) fun unregistered_coin_received( }); } -public(package) fun trusted_address_set( +public(package) fun trusted_address_added( chain_name: String, - trusted_address: String, ) { - event::emit(TrustedAddressSet { + event::emit(TrustedAddressAdded { chain_name, - trusted_address, }); } diff --git a/move/interchain_token_service/sources/interchain_token_service.move b/move/interchain_token_service/sources/interchain_token_service.move index efa73f95..db385bf0 100644 --- a/move/interchain_token_service/sources/interchain_token_service.move +++ b/move/interchain_token_service/sources/interchain_token_service.move @@ -4,12 +4,11 @@ use axelar_gateway::channel::{ApprovedMessage, Channel}; use axelar_gateway::message_ticket::MessageTicket; use interchain_token_service::coin_info::CoinInfo; use interchain_token_service::coin_management::CoinManagement; -use interchain_token_service::interchain_transfer_ticket::{Self, InterchainTransferTicket}; use interchain_token_service::interchain_token_service_v0::{Self, InterchainTokenService_v0}; -use interchain_token_service::owner_cap::{Self, OwnerCap}; +use interchain_token_service::interchain_transfer_ticket::{Self, InterchainTransferTicket}; use interchain_token_service::operator_cap::{Self, OperatorCap}; +use interchain_token_service::owner_cap::{Self, OwnerCap}; use interchain_token_service::token_id::TokenId; -use interchain_token_service::trusted_addresses::TrustedAddresses; use relayer_discovery::discovery::RelayerDiscovery; use relayer_discovery::transaction::Transaction; use std::ascii::{Self, String}; @@ -67,7 +66,10 @@ fun init(ctx: &mut TxContext) { // Macros // ------ /// This macro also uses version control to sinplify things a bit. -macro fun value($self: &InterchainTokenService, $function_name: vector): &InterchainTokenService_v0 { +macro fun value( + $self: &InterchainTokenService, + $function_name: vector, +): &InterchainTokenService_v0 { let its = $self; let value = its.inner.load_value(); value.version_control().check(VERSION, ascii::string($function_name)); @@ -75,7 +77,10 @@ macro fun value($self: &InterchainTokenService, $function_name: vector): &In } /// This macro also uses version control to sinplify things a bit. -macro fun value_mut($self: &mut InterchainTokenService, $function_name: vector): &mut InterchainTokenService_v0 { +macro fun value_mut( + $self: &mut InterchainTokenService, + $function_name: vector, +): &mut InterchainTokenService_v0 { let its = $self; let value = its.inner.load_value_mut(); value.version_control().check(VERSION, ascii::string($function_name)); @@ -100,9 +105,7 @@ entry fun disallow_function( version: u64, function_name: String, ) { - self - .value_mut!(b"disallow_function") - .disallow_function(version, function_name); + self.value_mut!(b"disallow_function").disallow_function(version, function_name); } // ---------------- @@ -297,24 +300,24 @@ public fun set_flow_limit( // --------------- // Owner Functions // --------------- -public fun set_trusted_addresses( +public fun add_trusted_chains( self: &mut InterchainTokenService, _owner_cap: &OwnerCap, - trusted_addresses: TrustedAddresses, + chain_names: vector, ) { - let value = self.value_mut!(b"set_trusted_addresses"); + let value = self.value_mut!(b"add_trusted_chains"); - value.set_trusted_addresses(trusted_addresses); + value.add_trusted_chains(chain_names); } -public fun remove_trusted_addresses( +public fun remove_trusted_chains( self: &mut InterchainTokenService, _owner_cap: &OwnerCap, chain_names: vector, ) { - let value = self.value_mut!(b"remove_trusted_addresses"); + let value = self.value_mut!(b"remove_trusted_chains"); - value.remove_trusted_addresses(chain_names); + value.remove_trusted_chains(chain_names); } // === Getters === @@ -367,8 +370,8 @@ fun version_control(): VersionControl { b"mint_as_distributor", b"mint_to_as_distributor", b"burn_as_distributor", - b"set_trusted_addresses", - b"remove_trusted_addresses", + b"add_trusted_chains", + b"remove_trusted_chains", b"register_transaction", b"set_flow_limit", b"set_flow_limit_as_token_operator", @@ -397,13 +400,16 @@ use utils::utils; const MESSAGE_TYPE_INTERCHAIN_TRANSFER: u256 = 0; #[test_only] const MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN: u256 = 1; -// onst MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER: u256 = 2; +// const MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER: u256 = 2; +#[test_only] +const MESSAGE_TYPE_RECEIVE_FROM_HUB: u256 = 4; // === HUB CONSTANTS === -// Identifier to be used as destination address for chains that route to hub. -// For Sui this will probably be every supported chain. +// Axelar. +const ITS_HUB_CHAIN_NAME: vector = b"axelar"; #[test_only] -const ITS_HUB_ROUTING_IDENTIFIER: vector = b"hub"; +// The address of the ITS HUB. +const ITS_HUB_ADDRESS: vector = b"hub_address"; #[test_only] public fun create_for_testing(ctx: &mut TxContext): InterchainTokenService { @@ -414,9 +420,8 @@ public fun create_for_testing(ctx: &mut TxContext): InterchainTokenService { version_control, ctx, ); - value.set_trusted_address( + value.add_trusted_chain( std::ascii::string(b"Chain Name"), - std::ascii::string(b"Address"), ); let inner = versioned::create( @@ -437,9 +442,7 @@ public(package) fun add_unregistered_coin_type_for_testing( token_id: interchain_token_service::token_id::UnregisteredTokenId, type_name: std::type_name::TypeName, ) { - self - .value_mut!(b"") - .add_unregistered_coin_type_for_testing(token_id, type_name); + self.value_mut!(b"").add_unregistered_coin_type_for_testing(token_id, type_name); } #[test_only] @@ -456,9 +459,7 @@ public(package) fun add_registered_coin_type_for_testing( token_id: TokenId, type_name: std::type_name::TypeName, ) { - self - .value_mut!(b"") - .add_registered_coin_type_for_testing(token_id, type_name); + self.value_mut!(b"").add_registered_coin_type_for_testing(token_id, type_name); } #[test_only] @@ -524,15 +525,13 @@ fun test_deploy_remote_interchain_token() { .write_bytes(*token_symbol.as_bytes()) .write_u256((token_decimals as u256)) .write_bytes(vector::empty()); + let mut payload = writer.into_bytes(); + its.value!(b"").wrap_payload_for_testing(&mut payload, destination_chain); - assert!( - message_ticket.source_id() == its.value!(b"").channel().to_address(), - ); - assert!(message_ticket.destination_chain() == destination_chain); - assert!( - message_ticket.destination_address() == its.value!(b"").trusted_address_for_testing(destination_chain), - ); - assert!(message_ticket.payload() == writer.into_bytes()); + assert!(message_ticket.source_id() == its.value!(b"").channel().to_address()); + assert!(message_ticket.destination_chain() == ITS_HUB_CHAIN_NAME.to_ascii_string()); + assert!(message_ticket.destination_address() == ITS_HUB_ADDRESS.to_ascii_string()); + assert!(message_ticket.payload() == payload); assert!(message_ticket.version() == 0); sui::test_utils::destroy(its); @@ -588,15 +587,15 @@ fun test_deploy_interchain_token() { .write_bytes(destination_address) .write_u256((amount as u256)) .write_bytes(b""); + let mut payload = writer.into_bytes(); + its.value!(b"").wrap_payload_for_testing(&mut payload, destination_chain); + assert!(message_ticket.source_id() == its.value!(b"").channel().to_address()); + assert!(message_ticket.destination_chain() == ITS_HUB_CHAIN_NAME.to_ascii_string()); assert!( - message_ticket.source_id() == its.value!(b"").channel().to_address(), + message_ticket.destination_address() == ITS_HUB_ADDRESS.to_ascii_string(), ); - assert!(message_ticket.destination_chain() == destination_chain); - assert!( - message_ticket.destination_address() == its.value!(b"").trusted_address_for_testing(destination_chain), - ); - assert!(message_ticket.payload() == writer.into_bytes()); + assert!(message_ticket.payload() == payload); assert!(message_ticket.version() == 0); clock.destroy_for_testing(); @@ -625,7 +624,6 @@ fun test_receive_interchain_transfer() { let token_id = register_coin(&mut its, coin_info, coin_management); let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let message_source_address = ascii::string(b"Address"); let its_source_address = b"Source Address"; let destination_address = @0x1; @@ -637,12 +635,18 @@ fun test_receive_interchain_transfer() { .write_bytes(destination_address.to_bytes()) .write_u256((amount as u256)) .write_bytes(b""); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - message_source_address, + ITS_HUB_ADDRESS.to_ascii_string(), its.value!(b"").channel().to_address(), payload, ); @@ -676,7 +680,6 @@ fun test_receive_interchain_transfer_with_data() { let token_id = its.register_coin(coin_info, coin_management); let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let message_source_address = ascii::string(b"Address"); let its_source_address = b"Source Address"; let channel = channel::new(ctx); let destination_address = channel.to_address(); @@ -689,12 +692,18 @@ fun test_receive_interchain_transfer_with_data() { .write_bytes(destination_address.to_bytes()) .write_u256((amount as u256)) .write_bytes(data); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - message_source_address, + ITS_HUB_ADDRESS.to_ascii_string(), its.value!(b"").channel().to_address(), payload, ); @@ -732,7 +741,6 @@ fun test_receive_deploy_interchain_token() { let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let source_address = ascii::string(b"Address"); let name = b"Token Name"; let symbol = b"Symbol"; let decimals = 9; @@ -748,12 +756,18 @@ fun test_receive_deploy_interchain_token() { .write_bytes(symbol) .write_u256((decimals as u256)) .write_bytes(vector::empty()); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - source_address, + ITS_HUB_ADDRESS.to_ascii_string(), its.value!(b"").channel().to_address(), payload, ); @@ -773,7 +787,10 @@ fun test_give_unregistered_coin() { let ctx = &mut tx_context::dummy(); let mut its = create_for_testing(ctx); - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -791,7 +808,10 @@ fun test_mint_as_distributor() { let symbol = b"COIN"; let decimals = 9; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -828,7 +848,10 @@ fun test_mint_to_as_distributor() { let symbol = b"COIN"; let decimals = 9; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -885,7 +908,7 @@ fun test_burn_as_distributor() { } #[test] -fun test_set_trusted_address() { +fun test_add_trusted_chain() { let ctx = &mut tx_context::dummy(); let mut its = create_for_testing(ctx); @@ -896,18 +919,9 @@ fun test_set_trusted_address() { let trusted_chains = vector[b"Ethereum", b"Avalance", b"Axelar"].map!( |chain| chain.to_ascii_string(), ); - let trusted_addresses = vector[ - b"ethereum address", - ITS_HUB_ROUTING_IDENTIFIER, - b"hub address", - ].map!(|chain| chain.to_ascii_string()); - let trusted_addresses = interchain_token_service::trusted_addresses::new( - trusted_chains, - trusted_addresses, - ); - its.set_trusted_addresses(&owner_cap, trusted_addresses); - its.remove_trusted_addresses(&owner_cap, trusted_chains); + its.add_trusted_chains(&owner_cap, trusted_chains); + its.remove_trusted_chains(&owner_cap, trusted_chains); sui::test_utils::destroy(its); sui::test_utils::destroy(owner_cap); @@ -921,7 +935,10 @@ fun test_set_flow_limit_as_token_operator() { let decimals = 9; let limit = 1234; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -949,7 +966,10 @@ fun test_set_flow_limit() { let decimals = 9; let limit = 1234; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, diff --git a/move/interchain_token_service/sources/types/address_tracker.move b/move/interchain_token_service/sources/types/address_tracker.move deleted file mode 100644 index a90b7ab4..00000000 --- a/move/interchain_token_service/sources/types/address_tracker.move +++ /dev/null @@ -1,181 +0,0 @@ -/// Q: why addresses are stored as Strings? -/// Q: why chains are Strings? -module interchain_token_service::address_tracker; - -use interchain_token_service::events; -use std::ascii::String; -use sui::table::{Self, Table}; - -// ------ -// Errors -// ------ -#[error] -const ENoAddress: vector = - b"attempt to borrow a trusted address but it's not registered"; -#[error] -const EEmptyChainName: vector = b"empty trusted chain name is unsupported"; -#[error] -const EEmptyTrustedAddress: vector = - b"empty trusted address is unsupported"; - -/// The interchain address tracker stores the trusted addresses for each chain. -public struct InterchainAddressTracker has store { - trusted_addresses: Table, -} - -// ----------------- -// Package Functions -// ----------------- -/// Get the trusted address for a chain. -public(package) fun trusted_address( - self: &InterchainAddressTracker, - chain_name: String, -): &String { - assert!(self.trusted_addresses.contains(chain_name), ENoAddress); - &self.trusted_addresses[chain_name] -} - -/// Check if the given address is trusted for the given chain. -public(package) fun is_trusted_address( - self: &InterchainAddressTracker, - chain_name: String, - addr: String, -): bool { - self.trusted_addresses.contains(chain_name) && self.trusted_addresses[chain_name] == addr -} - -/// Create a new interchain address tracker. -public(package) fun new(ctx: &mut TxContext): InterchainAddressTracker { - InterchainAddressTracker { - trusted_addresses: table::new(ctx), - } -} - -/// Set the trusted address for a chain or adds it if it doesn't exist. -public(package) fun set_trusted_address( - self: &mut InterchainAddressTracker, - chain_name: String, - trusted_address: String, -) { - assert!(chain_name.length() > 0, EEmptyChainName); - assert!(trusted_address.length() > 0, EEmptyTrustedAddress); - - if (self.trusted_addresses.contains(chain_name)) { - *&mut self.trusted_addresses[chain_name] = trusted_address; - } else { - self.trusted_addresses.add(chain_name, trusted_address); - }; - events::trusted_address_set(chain_name, trusted_address); -} - -public(package) fun remove_trusted_address( - self: &mut InterchainAddressTracker, - chain_name: String, -) { - assert!(chain_name.length() > 0, EEmptyChainName); - self.trusted_addresses.remove(chain_name); - events::trusted_address_removed(chain_name); -} - -// ----- -// Tests -// ----- -#[test] -fun test_address_tracker() { - let ctx = &mut sui::tx_context::dummy(); - let mut self = new(ctx); - let chain1 = std::ascii::string(b"chain1"); - let chain2 = std::ascii::string(b"chain2"); - let address1 = std::ascii::string(b"address1"); - let address2 = std::ascii::string(b"address2"); - - self.set_trusted_address(chain1, address1); - self.set_trusted_address(chain2, address2); - - assert!(self.trusted_address(chain1) == &address1); - assert!(self.trusted_address(chain2) == &address2); - - assert!(self.is_trusted_address(chain1, address1) == true); - assert!(self.is_trusted_address(chain1, address2) == false); - assert!(self.is_trusted_address(chain2, address1) == false); - assert!(self.is_trusted_address(chain2, address2) == true); - - self.set_trusted_address(chain1, address2); - self.set_trusted_address(chain2, address1); - - assert!(self.trusted_address(chain1) == &address2); - assert!(self.trusted_address(chain2) == &address1); - - assert!(self.is_trusted_address(chain1, address1) == false); - assert!(self.is_trusted_address(chain1, address2) == true); - assert!(self.is_trusted_address(chain2, address1) == true); - assert!(self.is_trusted_address(chain2, address2) == false); - - assert!(self.trusted_addresses.contains(chain1)); - assert!(self.trusted_addresses.contains(chain2)); - - sui::test_utils::destroy(self); -} - -#[test] -#[expected_failure(abort_code = EEmptyChainName)] -fun test_set_trusted_address_empty_chain_name() { - let ctx = &mut sui::tx_context::dummy(); - let mut self = new(ctx); - let chain = std::ascii::string(b""); - let address = std::ascii::string(b"address"); - - self.set_trusted_address(chain, address); - - sui::test_utils::destroy(self); -} - -#[test] -#[expected_failure(abort_code = EEmptyTrustedAddress)] -fun test_set_trusted_address_empty_trusted_address() { - let ctx = &mut sui::tx_context::dummy(); - let mut self = new(ctx); - let chain = std::ascii::string(b"chain"); - let address = std::ascii::string(b""); - - self.set_trusted_address(chain, address); - - sui::test_utils::destroy(self); -} - -#[test] -fun test_remove_trusted_address() { - let ctx = &mut sui::tx_context::dummy(); - let mut self = new(ctx); - let chain = std::ascii::string(b"chain"); - let address = std::ascii::string(b"address"); - - self.set_trusted_address(chain, address); - self.remove_trusted_address(chain); - - sui::test_utils::destroy(self); -} - -#[test] -#[expected_failure(abort_code = EEmptyChainName)] -fun test_remove_trusted_address_empty_chain_name() { - let ctx = &mut sui::tx_context::dummy(); - let mut self = new(ctx); - let chain = std::ascii::string(b""); - - self.remove_trusted_address(chain); - - sui::test_utils::destroy(self); -} - -#[test] -#[expected_failure(abort_code = ENoAddress)] -fun test_trusted_address_no_address() { - let ctx = &mut sui::tx_context::dummy(); - let self = new(ctx); - let chain = std::ascii::string(b""); - - self.trusted_address(chain); - - sui::test_utils::destroy(self); -} diff --git a/move/interchain_token_service/sources/types/chain_tracker.move b/move/interchain_token_service/sources/types/chain_tracker.move new file mode 100644 index 00000000..e2ec3b1b --- /dev/null +++ b/move/interchain_token_service/sources/types/chain_tracker.move @@ -0,0 +1,146 @@ +/// Q: why addresses are stored as Strings? +/// Q: why chains are Strings? +module interchain_token_service::chain_tracker; + +use interchain_token_service::events; +use std::ascii::String; +use sui::table::{Self, Table}; + +// ------ +// Errors +// ------ +#[error] +const EEmptyChainName: vector = b"empty trusted chain name is unsupported"; +#[error] +const EAlreadyTrusted: vector = + b"chain is already trusted"; + +public struct TrustedChain has store, drop {} + +/// The interchain address tracker stores the trusted addresses for each chain. +public struct InterchainChainTracker has store { + trusted_addresses: Table, +} + +// ----------------- +// Package Functions +// ----------------- +/// Check if the given address is trusted for the given chain. +public(package) fun is_trusted_chain( + self: &InterchainChainTracker, + chain_name: String, +): bool { + self.trusted_addresses.contains(chain_name) +} + +/// Create a new interchain address tracker. +public(package) fun new(ctx: &mut TxContext): InterchainChainTracker { + InterchainChainTracker { + trusted_addresses: table::new(ctx), + } +} + +/// Set the trusted address for a chain or adds it if it doesn't exist. +public(package) fun add_trusted_chain( + self: &mut InterchainChainTracker, + chain_name: String, +) { + assert!(chain_name.length() > 0, EEmptyChainName); + + if (self.trusted_addresses.contains(chain_name)) { + abort EAlreadyTrusted + } else { + self.trusted_addresses.add(chain_name, TrustedChain{}); + }; + events::trusted_address_added(chain_name); +} + +public(package) fun remove_trusted_chain( + self: &mut InterchainChainTracker, + chain_name: String, +) { + assert!(chain_name.length() > 0, EEmptyChainName); + self.trusted_addresses.remove(chain_name); + events::trusted_address_removed(chain_name); +} + +// ----- +// Tests +// ----- +#[test] +fun test_chain_tracker() { + let ctx = &mut sui::tx_context::dummy(); + let mut self = new(ctx); + let chain1 = std::ascii::string(b"chain1"); + let chain2 = std::ascii::string(b"chain2"); + + self.add_trusted_chain(chain1); + self.add_trusted_chain(chain2); + + assert!(self.is_trusted_chain(chain1) == true); + assert!(self.is_trusted_chain(chain2) == true); + + assert!(self.trusted_addresses.contains(chain1)); + assert!(self.trusted_addresses.contains(chain2)); + + self.remove_trusted_chain(chain1); + self.remove_trusted_chain(chain2); + + + assert!(self.is_trusted_chain(chain1) == false); + assert!(self.is_trusted_chain(chain2) == false); + + assert!(!self.trusted_addresses.contains(chain1)); + assert!(!self.trusted_addresses.contains(chain2)); + + sui::test_utils::destroy(self); +} + +#[test] +#[expected_failure(abort_code = EEmptyChainName)] +fun test_add_trusted_chain_empty_chain_name() { + let ctx = &mut sui::tx_context::dummy(); + let mut self = new(ctx); + let chain = std::ascii::string(b""); + + self.add_trusted_chain(chain); + + sui::test_utils::destroy(self); +} + +#[test] +#[expected_failure(abort_code = EAlreadyTrusted)] +fun test_add_trusted_chain_already_trusted() { + let ctx = &mut sui::tx_context::dummy(); + let mut self = new(ctx); + let chain = std::ascii::string(b"chain"); + + self.add_trusted_chain(chain); + self.add_trusted_chain(chain); + + sui::test_utils::destroy(self); +} + +#[test] +fun test_remove_trusted_chain() { + let ctx = &mut sui::tx_context::dummy(); + let mut self = new(ctx); + let chain = std::ascii::string(b"chain"); + + self.add_trusted_chain(chain); + self.remove_trusted_chain(chain); + + sui::test_utils::destroy(self); +} + +#[test] +#[expected_failure(abort_code = EEmptyChainName)] +fun test_remove_trusted_chain_empty_chain_name() { + let ctx = &mut sui::tx_context::dummy(); + let mut self = new(ctx); + let chain = std::ascii::string(b""); + + self.remove_trusted_chain(chain); + + sui::test_utils::destroy(self); +} diff --git a/move/interchain_token_service/sources/types/trusted_addresses.move b/move/interchain_token_service/sources/types/trusted_addresses.move deleted file mode 100644 index 5cf5a461..00000000 --- a/move/interchain_token_service/sources/types/trusted_addresses.move +++ /dev/null @@ -1,69 +0,0 @@ -module interchain_token_service::trusted_addresses; - -use std::ascii::String; - -/// ------ -/// Errors -/// ------ -#[error] -const EMalformedTrustedAddresses: vector = - b"trusted chains and addresses have mismatching length"; - -/// ----- -/// Types -/// ----- -public struct TrustedAddresses has copy, drop { - trusted_chains: vector, - trusted_addresses: vector, -} - -/// ---------------- -/// Public Functions -/// ---------------- -public fun new( - trusted_chains: vector, - trusted_addresses: vector, -): TrustedAddresses { - let length = trusted_chains.length(); - - assert!(length == trusted_addresses.length(), EMalformedTrustedAddresses); - - TrustedAddresses { - trusted_chains, - trusted_addresses, - } -} - -/// ----------------- -/// Package Functions -/// ----------------- -public(package) fun destroy( - self: TrustedAddresses, -): (vector, vector) { - let TrustedAddresses { trusted_chains, trusted_addresses } = self; - (trusted_chains, trusted_addresses) -} - -/// --------- -/// Test Only -/// --------- -// This does not preform sanity checks on the params -#[test_only] -public(package) fun new_for_testing( - trusted_chains: vector, - trusted_addresses: vector, -): TrustedAddresses { - TrustedAddresses { - trusted_chains, - trusted_addresses, - } -} - -/// ---- -/// Test -/// ---- -#[test] -#[expected_failure(abort_code = EMalformedTrustedAddresses)] -fun test_new_malformed() { - new(vector[], vector[b"address".to_ascii_string()]); -} diff --git a/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move b/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move index 96581440..76757da4 100644 --- a/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move +++ b/move/interchain_token_service/sources/versioned/interchain_token_service_v0.move @@ -4,14 +4,13 @@ use abi::abi::{Self, AbiReader}; use axelar_gateway::channel::{Channel, ApprovedMessage}; use axelar_gateway::gateway; use axelar_gateway::message_ticket::MessageTicket; -use interchain_token_service::address_tracker::{Self, InterchainAddressTracker}; +use interchain_token_service::chain_tracker::{Self, InterchainChainTracker}; use interchain_token_service::coin_data::{Self, CoinData}; use interchain_token_service::coin_info::{Self, CoinInfo}; use interchain_token_service::coin_management::{Self, CoinManagement}; use interchain_token_service::events; use interchain_token_service::interchain_transfer_ticket::InterchainTransferTicket; use interchain_token_service::token_id::{Self, TokenId, UnregisteredTokenId}; -use interchain_token_service::trusted_addresses::TrustedAddresses; use interchain_token_service::unregistered_coin_data::{Self, UnregisteredCoinData}; use interchain_token_service::utils as its_utils; use relayer_discovery::discovery::RelayerDiscovery; @@ -29,14 +28,11 @@ use version_control::version_control::VersionControl; // Errors // ------ #[error] -const EUnregisteredCoin: vector = - b"trying to find a coin that doesn't exist"; +const EUnregisteredCoin: vector = b"trying to find a coin that doesn't exist"; #[error] -const EUntrustedAddress: vector = - b"the sender that sent this message is not trusted"; +const EUntrustedAddress: vector = b"the sender that sent this message is not trusted"; #[error] -const EInvalidMessageType: vector = - b"the message type received is not supported"; +const EInvalidMessageType: vector = b"the message type received is not supported"; #[error] const EWrongDestination: vector = b"the channel trying to receive this call is not the destination"; @@ -47,8 +43,7 @@ const EInterchainTransferHasData: vector = const EInterchainTransferHasNoData: vector = b"interchain transfer trying to be proccessed as an interchain transfer"; #[error] -const EModuleNameDoesNotMatchSymbol: vector = - b"the module name does not match the symbol"; +const EModuleNameDoesNotMatchSymbol: vector = b"the module name does not match the symbol"; #[error] const ENotDistributor: vector = b"only the distributor can mint"; #[error] @@ -75,16 +70,15 @@ const MESSAGE_TYPE_RECEIVE_FROM_HUB: u256 = 4; // Chain name for Axelar. This is used for routing InterchainTokenService calls via InterchainTokenService hub on // Axelar. const ITS_HUB_CHAIN_NAME: vector = b"axelar"; -// Identifier to be used as destination address for chains that route to hub. -// For Sui this will probably be every supported chain. -const ITS_HUB_ROUTING_IDENTIFIER: vector = b"hub"; +// The address of the ITS HUB. +const ITS_HUB_ADDRESS: vector = b"hub_address"; // ----- // Types // ----- public struct InterchainTokenService_v0 has store { channel: Channel, - address_tracker: InterchainAddressTracker, + chain_tracker: InterchainChainTracker, unregistered_coin_types: Table, unregistered_coins: Bag, registered_coin_types: Table, @@ -102,7 +96,7 @@ public(package) fun new( ): InterchainTokenService_v0 { InterchainTokenService_v0 { channel: axelar_gateway::channel::new(ctx), - address_tracker: address_tracker::new( + chain_tracker: chain_tracker::new( ctx, ), registered_coins: bag::new(ctx), @@ -148,42 +142,31 @@ public(package) fun relayer_discovery_id(self: &InterchainTokenService_v0): ID { self.relayer_discovery_id } -public(package) fun set_trusted_address( - self: &mut InterchainTokenService_v0, - chain_name: String, - trusted_address: String, -) { - self.address_tracker.set_trusted_address(chain_name, trusted_address); +public(package) fun add_trusted_chain(self: &mut InterchainTokenService_v0, chain_name: String) { + self.chain_tracker.add_trusted_chain(chain_name); } -public(package) fun remove_trusted_address( - self: &mut InterchainTokenService_v0, - chain_name: String, -) { - self.address_tracker.remove_trusted_address(chain_name); +public(package) fun remove_trusted_chain(self: &mut InterchainTokenService_v0, chain_name: String) { + self.chain_tracker.remove_trusted_chain(chain_name); } -public(package) fun set_trusted_addresses( +public(package) fun add_trusted_chains( self: &mut InterchainTokenService_v0, - trusted_addresses: TrustedAddresses, + chain_names: vector, ) { - let (chain_names, trusted_addresses) = trusted_addresses.destroy(); - - chain_names.zip_do!( - trusted_addresses, - |chain_name, trusted_address| self.set_trusted_address( + chain_names.do!( + |chain_name| self.add_trusted_chain( chain_name, - trusted_address, ), ); } -public(package) fun remove_trusted_addresses( +public(package) fun remove_trusted_chains( self: &mut InterchainTokenService_v0, chain_names: vector, ) { chain_names.do!( - |chain_name| self.remove_trusted_address( + |chain_name| self.remove_trusted_chain( chain_name, ), ); @@ -238,7 +221,9 @@ public(package) fun deploy_remote_interchain_token( destination_chain, ); - prepare_message(self, destination_chain, writer.into_bytes()) + let mut payload = writer.into_bytes(); + self.wrap_payload(&mut payload, destination_chain); + prepare_message(self, payload) } public(package) fun send_interchain_transfer( @@ -258,9 +243,7 @@ public(package) fun send_interchain_transfer( ) = ticket.destroy(); assert!(version <= current_version, ENewerTicket); - let amount = self - .coin_management_mut(token_id) - .take_balance(balance, clock); + let amount = self.coin_management_mut(token_id).take_balance(balance, clock); let (_version, data) = its_utils::decode_metadata(metadata); let mut writer = abi::new_writer(6); @@ -281,7 +264,9 @@ public(package) fun send_interchain_transfer( &data, ); - self.prepare_message(destination_chain, writer.into_bytes()) + let mut payload = writer.into_bytes(); + self.wrap_payload(&mut payload, destination_chain); + prepare_message(self, payload) } public(package) fun receive_interchain_transfer( @@ -294,10 +279,7 @@ public(package) fun receive_interchain_transfer( approved_message, ); let mut reader = abi::new_reader(payload); - assert!( - reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, - EInvalidMessageType, - ); + assert!(reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, EInvalidMessageType); let token_id = token_id::from_u256(reader.read_u256()); let source_address = reader.read_bytes(); @@ -307,9 +289,7 @@ public(package) fun receive_interchain_transfer( assert!(data.is_empty(), EInterchainTransferHasData); - let coin = self - .coin_management_mut(token_id) - .give_coin(amount, clock, ctx); + let coin = self.coin_management_mut(token_id).give_coin(amount, clock, ctx); transfer::public_transfer(coin, destination_address); @@ -335,10 +315,7 @@ public(package) fun receive_interchain_transfer_with_data( approved_message, ); let mut reader = abi::new_reader(payload); - assert!( - reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, - EInvalidMessageType, - ); + assert!(reader.read_u256() == MESSAGE_TYPE_INTERCHAIN_TRANSFER, EInvalidMessageType); let token_id = token_id::from_u256(reader.read_u256()); @@ -371,10 +348,7 @@ public(package) fun receive_deploy_interchain_token( ) { let (_, payload, _) = self.decode_approved_message(approved_message); let mut reader = abi::new_reader(payload); - assert!( - reader.read_u256() == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, - EInvalidMessageType, - ); + assert!(reader.read_u256() == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, EInvalidMessageType); let token_id = token_id::from_u256(reader.read_u256()); let name = string::utf8(reader.read_bytes()); @@ -404,10 +378,7 @@ public(package) fun give_unregistered_coin( mut coin_metadata: CoinMetadata, ) { assert!(treasury_cap.total_supply() == 0, ENonZeroTotalSupply); - assert!( - coin::get_icon_url(&coin_metadata).is_none(), - EUnregisteredCoinHasUrl, - ); + assert!(coin::get_icon_url(&coin_metadata).is_none(), EUnregisteredCoinHasUrl); treasury_cap.update_description(&mut coin_metadata, string::utf8(b"")); @@ -415,10 +386,7 @@ public(package) fun give_unregistered_coin( let symbol = coin_metadata.get_symbol(); let module_name = type_name::get_module(&type_name::get()); - assert!( - &module_name == &its_utils::module_from_symbol(&symbol), - EModuleNameDoesNotMatchSymbol, - ); + assert!(&module_name == &its_utils::module_from_symbol(&symbol), EModuleNameDoesNotMatchSymbol); let token_id = token_id::unregistered_token_id(&symbol, decimals); @@ -525,12 +493,12 @@ fun coin_info(self: &InterchainTokenService_v0, token_id: TokenId): &CoinInfo coin_data(self, token_id).coin_info() } -fun is_trusted_address( - self: &InterchainTokenService_v0, - source_chain: String, - source_address: String, -): bool { - self.address_tracker.is_trusted_address(source_chain, source_address) +fun is_trusted_address(source_chain: String, source_address: String): bool { + source_chain.into_bytes() == ITS_HUB_CHAIN_NAME && source_address.into_bytes() == ITS_HUB_ADDRESS +} + +fun is_trusted_chain(self: &InterchainTokenService_v0, source_chain: String): bool { + self.chain_tracker.is_trusted_chain(source_chain) } fun coin_management_mut( @@ -565,9 +533,7 @@ fun remove_unregistered_coin( self: &mut InterchainTokenService_v0, token_id: UnregisteredTokenId, ): (TreasuryCap, CoinMetadata) { - let unregistered_coins: UnregisteredCoinData = self - .unregistered_coins - .remove(token_id); + let unregistered_coins: UnregisteredCoinData = self.unregistered_coins.remove(token_id); let (treasury_cap, coin_metadata) = unregistered_coins.destroy(); remove_unregistered_coin_type(self, token_id); @@ -575,10 +541,6 @@ fun remove_unregistered_coin( (treasury_cap, coin_metadata) } -fun trusted_address(self: &InterchainTokenService_v0, chain_name: String): String { - *self.address_tracker.trusted_address(chain_name) -} - fun add_unregistered_coin_type( self: &mut InterchainTokenService_v0, token_id: UnregisteredTokenId, @@ -626,38 +588,23 @@ fun add_registered_coin( ); } -/// Send a payload to a destination chain. The destination chain needs to have a -/// trusted address. -fun prepare_message( - self: &InterchainTokenService_v0, - mut destination_chain: String, - mut payload: vector, -): MessageTicket { - let mut destination_address = self.trusted_address(destination_chain); - - // Prevent sending directly to the InterchainTokenService Hub chain. This is not supported yet, - // so fail early to prevent the user from having their funds stuck. - assert!( - destination_chain.into_bytes() != ITS_HUB_CHAIN_NAME, - EUntrustedChain, - ); +fun wrap_payload(self: &InterchainTokenService_v0, payload: &mut vector, destination_chain: String) { + assert!(self.is_trusted_chain(destination_chain), EUntrustedChain); - // Check whether the InterchainTokenService call should be routed via InterchainTokenService hub for this - // destination chain - if (destination_address.into_bytes() == ITS_HUB_ROUTING_IDENTIFIER) { - let mut writer = abi::new_writer(3); - writer.write_u256(MESSAGE_TYPE_SEND_TO_HUB); - writer.write_bytes(destination_chain.into_bytes()); - writer.write_bytes(payload); - payload = writer.into_bytes(); - destination_chain = ascii::string(ITS_HUB_CHAIN_NAME); - destination_address = self.trusted_address(destination_chain); - }; + let mut writer = abi::new_writer(3); + writer.write_u256(MESSAGE_TYPE_SEND_TO_HUB); + writer.write_bytes(destination_chain.into_bytes()); + writer.write_bytes(*payload); + *payload = writer.into_bytes(); +} +/// Send a payload to a destination chain. The destination chain needs to have a +/// trusted address. +fun prepare_message(self: &InterchainTokenService_v0, payload: vector): MessageTicket { gateway::prepare_message( &self.channel, - destination_chain, - destination_address, + ITS_HUB_CHAIN_NAME.to_ascii_string(), + ITS_HUB_ADDRESS.to_ascii_string(), payload, ) } @@ -667,35 +614,19 @@ fun decode_approved_message( self: &InterchainTokenService_v0, approved_message: ApprovedMessage, ): (String, vector, String) { - let (mut source_chain, message_id, source_address, mut payload) = self + let (source_chain, message_id, source_address, payload) = self .channel .consume_approved_message(approved_message); - assert!( - self.is_trusted_address(source_chain, source_address), - EUntrustedAddress, - ); + assert!(is_trusted_address(source_chain, source_address), EUntrustedAddress); let mut reader = abi::new_reader(payload); - if (reader.read_u256() == MESSAGE_TYPE_RECEIVE_FROM_HUB) { - assert!( - source_chain.into_bytes() == ITS_HUB_CHAIN_NAME, - EUntrustedChain, - ); + assert!(reader.read_u256() == MESSAGE_TYPE_RECEIVE_FROM_HUB, EInvalidMessageType); - source_chain = ascii::string(reader.read_bytes()); - payload = reader.read_bytes(); + let source_chain = ascii::string(reader.read_bytes()); + let payload = reader.read_bytes(); - assert!( - self.trusted_address(source_chain).into_bytes() == ITS_HUB_ROUTING_IDENTIFIER, - EUntrustedChain, - ); - } else { - assert!( - source_chain.into_bytes() != ITS_HUB_CHAIN_NAME, - EUntrustedChain, - ); - }; + assert!(self.is_trusted_chain(source_chain), EUntrustedChain); (source_chain, payload, message_id) } @@ -718,9 +649,8 @@ use interchain_token_service::coin::COIN; fun create_for_testing(ctx: &mut TxContext): InterchainTokenService_v0 { let mut self = new(version_control::version_control::new(vector[]), ctx); - self.set_trusted_address( + self.add_trusted_chain( std::ascii::string(b"Chain Name"), - std::ascii::string(b"Address"), ); self @@ -733,7 +663,10 @@ public fun create_unregistered_coin( decimals: u8, ctx: &mut TxContext, ) { - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -781,11 +714,8 @@ public(package) fun remove_registered_coin_type_for_testing( } #[test_only] -public(package) fun trusted_address_for_testing( - self: &InterchainTokenService_v0, - chain_name: String, -): String { - *self.address_tracker.trusted_address(chain_name) +public(package) fun wrap_payload_for_testing(self: &InterchainTokenService_v0, payload: &mut vector, destination_chain: String) { + self.wrap_payload(payload, destination_chain); } // ----- @@ -797,21 +727,19 @@ fun test_decode_approved_message_axelar_hub_sender() { let mut self = create_for_testing(ctx); let source_chain = ascii::string(ITS_HUB_CHAIN_NAME); - let source_address = ascii::string(b"Address"); + let source_address = ascii::string(ITS_HUB_ADDRESS); let message_id = ascii::string(b"message_id"); let origin_chain = ascii::string(b"Source Chain"); let payload = b"payload"; let mut writer = abi::new_writer(3); - writer.write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB); - writer.write_bytes(origin_chain.into_bytes()); - writer.write_bytes(payload); + writer.write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB); + writer.write_bytes(origin_chain.into_bytes()); + writer.write_bytes(payload); let payload = writer.into_bytes(); - self.set_trusted_address(source_chain, source_address); - self.set_trusted_address( + self.add_trusted_chain( origin_chain, - ascii::string(ITS_HUB_ROUTING_IDENTIFIER), ); let approved_message = channel::new_approved_message( @@ -828,7 +756,7 @@ fun test_decode_approved_message_axelar_hub_sender() { } #[test] -#[expected_failure(abort_code = EUntrustedChain)] +#[expected_failure(abort_code = EUntrustedAddress)] fun test_decode_approved_message_sender_not_hub() { let ctx = &mut tx_context::dummy(); let self = create_for_testing(ctx); @@ -860,24 +788,20 @@ fun test_decode_approved_message_sender_not_hub() { #[expected_failure(abort_code = EUntrustedChain)] fun test_decode_approved_message_origin_not_hub_routed() { let ctx = &mut tx_context::dummy(); - let mut self = create_for_testing(ctx); + let self = create_for_testing(ctx); let source_chain = ascii::string(ITS_HUB_CHAIN_NAME); - let source_address = ascii::string(b"Address"); + let source_address = ascii::string(ITS_HUB_ADDRESS); let message_id = ascii::string(b"message_id"); let origin_chain = ascii::string(b"Source Chain"); - let origin_trusted_address = ascii::string(b"Origin Trusted Address"); let payload = b"payload"; let mut writer = abi::new_writer(3); - writer.write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB); - writer.write_bytes(origin_chain.into_bytes()); - writer.write_bytes(payload); + writer.write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB); + writer.write_bytes(origin_chain.into_bytes()); + writer.write_bytes(payload); let payload = writer.into_bytes(); - self.set_trusted_address(source_chain, source_address); - self.set_trusted_address(origin_chain, origin_trusted_address); - let approved_message = channel::new_approved_message( source_chain, message_id, @@ -893,19 +817,17 @@ fun test_decode_approved_message_origin_not_hub_routed() { #[test] #[expected_failure(abort_code = EUntrustedChain)] -fun test_decode_approved_message_not_hub_message_from_hub() { +fun test_decode_approved_message_untrusted_chain() { let ctx = &mut tx_context::dummy(); - let mut self = create_for_testing(ctx); + let self = create_for_testing(ctx); let source_chain = ascii::string(ITS_HUB_CHAIN_NAME); - let source_address = ascii::string(b"Address"); + let source_address = ascii::string(ITS_HUB_ADDRESS); let message_id = ascii::string(b"message_id"); let mut writer = abi::new_writer(3); - writer.write_u256(MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN); + writer.write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB); let payload = writer.into_bytes(); - self.set_trusted_address(source_chain, source_address); - let approved_message = channel::new_approved_message( source_chain, message_id, @@ -920,21 +842,16 @@ fun test_decode_approved_message_not_hub_message_from_hub() { } #[test] -#[expected_failure(abort_code = EUntrustedAddress)] -fun test_decode_approved_message_untrusted_address() { +#[expected_failure(abort_code = EInvalidMessageType)] +fun test_decode_approved_message_invalid_message_type() { let ctx = &mut tx_context::dummy(); let self = create_for_testing(ctx); let source_chain = ascii::string(ITS_HUB_CHAIN_NAME); - let source_address = ascii::string(b"Address"); + let source_address = ascii::string(ITS_HUB_ADDRESS); let message_id = ascii::string(b"message_id"); - let origin_chain = ascii::string(b"Source Chain"); - let payload = b"payload"; - let mut writer = abi::new_writer(3); - writer.write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB); - writer.write_bytes(origin_chain.into_bytes()); - writer.write_bytes(payload); + writer.write_u256(MESSAGE_TYPE_INTERCHAIN_TRANSFER); let payload = writer.into_bytes(); let approved_message = channel::new_approved_message( @@ -956,46 +873,17 @@ fun test_prepare_message_to_hub() { let mut self = create_for_testing(ctx); let destination_chain = ascii::string(b"Destination Chain"); - let hub_address = ascii::string(b"Address"); - - let payload = b"payload"; - self.set_trusted_address(ascii::string(ITS_HUB_CHAIN_NAME), hub_address); - self.set_trusted_address( - destination_chain, - ascii::string(ITS_HUB_ROUTING_IDENTIFIER), - ); + let mut payload = b"payload"; - let message_ticket = self.prepare_message(destination_chain, payload); + self.add_trusted_chain(destination_chain); - assert!( - message_ticket.destination_chain() == ascii::string(ITS_HUB_CHAIN_NAME), - ); - assert!(message_ticket.destination_address() == hub_address); + self.wrap_payload(&mut payload, destination_chain); - sui::test_utils::destroy(self); - sui::test_utils::destroy(message_ticket); -} + let message_ticket = self.prepare_message(payload); -#[test] -#[expected_failure(abort_code = EUntrustedChain)] -fun test_prepare_message_to_hub_direct() { - let ctx = &mut tx_context::dummy(); - let mut self = create_for_testing(ctx); - - let destination_chain = ascii::string(ITS_HUB_CHAIN_NAME); - let hub_address = ascii::string(b"Address"); - - let payload = b"payload"; - - self.set_trusted_address(destination_chain, hub_address); - - let message_ticket = self.prepare_message(destination_chain, payload); - - assert!( - message_ticket.destination_chain() == ascii::string(ITS_HUB_CHAIN_NAME), - ); - assert!(message_ticket.destination_address() == hub_address); + assert!(message_ticket.destination_chain() == ITS_HUB_CHAIN_NAME.to_ascii_string()); + assert!(message_ticket.destination_address() == ITS_HUB_ADDRESS.to_ascii_string()); sui::test_utils::destroy(self); sui::test_utils::destroy(message_ticket); @@ -1022,7 +910,6 @@ fun test_receive_interchain_transfer_invalid_message_type() { let token_id = self.register_coin(coin_info, coin_management); let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let message_source_address = ascii::string(b"Address"); let its_source_address = b"Source Address"; let destination_address = @0x1; @@ -1034,12 +921,18 @@ fun test_receive_interchain_transfer_invalid_message_type() { .write_bytes(destination_address.to_bytes()) .write_u256((amount as u256)) .write_bytes(b""); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - message_source_address, + ITS_HUB_ADDRESS.to_ascii_string(), self.channel.to_address(), payload, ); @@ -1071,7 +964,6 @@ fun test_receive_interchain_transfer_passed_data() { let token_id = self.register_coin(coin_info, coin_management); let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let message_source_address = ascii::string(b"Address"); let its_source_address = b"Source Address"; let destination_address = @0x1; @@ -1083,12 +975,18 @@ fun test_receive_interchain_transfer_passed_data() { .write_bytes(destination_address.to_bytes()) .write_u256((amount as u256)) .write_bytes(b"some data"); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - message_source_address, + ITS_HUB_ADDRESS.to_ascii_string(), self.channel.to_address(), payload, ); @@ -1119,7 +1017,6 @@ fun test_receive_interchain_transfer_with_data_invalid_message_type() { let token_id = self.register_coin(coin_info, coin_management); let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let message_source_address = ascii::string(b"Address"); let its_source_address = b"Source Address"; let channel = channel::new(ctx); let destination_address = channel.to_address(); @@ -1132,19 +1029,23 @@ fun test_receive_interchain_transfer_with_data_invalid_message_type() { .write_bytes(destination_address.to_bytes()) .write_u256((amount as u256)) .write_bytes(b"some_data"); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - message_source_address, + ITS_HUB_ADDRESS.to_ascii_string(), self.channel.to_address(), payload, ); - let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data< - COIN, - >( + let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data( approved_message, &channel, &clock, @@ -1178,7 +1079,6 @@ fun test_receive_interchain_transfer_with_data_wrong_destination() { let token_id = self.register_coin(coin_info, coin_management); let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let message_source_address = ascii::string(b"Address"); let its_source_address = b"Source Address"; let channel = channel::new(ctx); let destination_address = @0x1; @@ -1191,19 +1091,23 @@ fun test_receive_interchain_transfer_with_data_wrong_destination() { .write_bytes(destination_address.to_bytes()) .write_u256((amount as u256)) .write_bytes(b"some_data"); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - message_source_address, + ITS_HUB_ADDRESS.to_ascii_string(), self.channel.to_address(), payload, ); - let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data< - COIN, - >( + let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data( approved_message, &channel, &clock, @@ -1237,7 +1141,6 @@ fun test_receive_interchain_transfer_with_data_no_data() { let token_id = self.register_coin(coin_info, coin_management); let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let message_source_address = ascii::string(b"Address"); let its_source_address = b"Source Address"; let channel = channel::new(ctx); let destination_address = channel.to_address(); @@ -1250,19 +1153,23 @@ fun test_receive_interchain_transfer_with_data_no_data() { .write_bytes(destination_address.to_bytes()) .write_u256((amount as u256)) .write_bytes(b""); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - message_source_address, + ITS_HUB_ADDRESS.to_ascii_string(), self.channel.to_address(), payload, ); - let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data< - COIN, - >( + let (_, _, _, received_coin) = self.receive_interchain_transfer_with_data( approved_message, &channel, &clock, @@ -1283,7 +1190,6 @@ fun test_receive_deploy_interchain_token_with_distributor() { let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let source_address = ascii::string(b"Address"); let name = b"Token Name"; let symbol = b"Symbol"; let decimals = 9; @@ -1300,12 +1206,18 @@ fun test_receive_deploy_interchain_token_with_distributor() { .write_bytes(symbol) .write_u256((decimals as u256)) .write_bytes(distributor.to_bytes()); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - source_address, + ITS_HUB_ADDRESS.to_ascii_string(), self.channel.to_address(), payload, ); @@ -1325,7 +1237,6 @@ fun test_receive_deploy_interchain_token_invalid_message_type() { let source_chain = ascii::string(b"Chain Name"); let message_id = ascii::string(b"Message Id"); - let source_address = ascii::string(b"Address"); let name = b"Token Name"; let symbol = b"Symbol"; let decimals = 9; @@ -1341,12 +1252,18 @@ fun test_receive_deploy_interchain_token_invalid_message_type() { .write_bytes(symbol) .write_u256((decimals as u256)) .write_bytes(b""); - let payload = writer.into_bytes(); + let mut payload = writer.into_bytes(); + writer = abi::new_writer(3); + writer + .write_u256(MESSAGE_TYPE_RECEIVE_FROM_HUB) + .write_bytes(source_chain.into_bytes()) + .write_bytes(payload); + payload = writer.into_bytes(); let approved_message = channel::new_approved_message( - source_chain, + ITS_HUB_CHAIN_NAME.to_ascii_string(), message_id, - source_address, + ITS_HUB_ADDRESS.to_ascii_string(), self.channel.to_address(), payload, ); @@ -1440,7 +1357,10 @@ fun test_give_unregistered_coin_module_name_missmatch() { let ctx = &mut tx_context::dummy(); let mut self = create_for_testing(ctx); - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -1459,7 +1379,10 @@ fun test_mint_as_distributor_not_distributor() { let symbol = b"COIN"; let decimals = 9; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -1508,7 +1431,10 @@ fun test_mint_to_as_distributor_not_distributor() { let symbol = b"COIN"; let decimals = 9; - let (treasury_cap, coin_metadata) = interchain_token_service::coin::create_treasury_and_metadata( + let ( + treasury_cap, + coin_metadata, + ) = interchain_token_service::coin::create_treasury_and_metadata( symbol, decimals, ctx, @@ -1589,7 +1515,9 @@ fun test_send_interchain_transfer_newer_ticket() { let current_version = 0; let invalid_version = 1; - let interchain_transfer_ticket = interchain_token_service::interchain_transfer_ticket::new( + let interchain_transfer_ticket = interchain_token_service::interchain_transfer_ticket::new< + COIN, + >( token_id, coin.into_balance(), source_channel.to_address(), @@ -1610,19 +1538,15 @@ fun test_send_interchain_transfer_newer_ticket() { sui::test_utils::destroy(clock); } -// no error code becaues this aborts in a macro #[test] -#[expected_failure] -fun test_set_trusted_addresses_mismatch_lengths() { +#[expected_failure(abort_code = EUntrustedChain)] +fun test_wrap_payload_untrusted_chain() { let ctx = &mut tx_context::dummy(); - let mut its = create_for_testing(ctx); + let its = create_for_testing(ctx); + let mut payload = b"payload"; + let destination_chain = b"destination_chain".to_ascii_string(); - its.set_trusted_addresses( - interchain_token_service::trusted_addresses::new_for_testing( - vector[], - vector[b"trusted address".to_ascii_string()], - ), - ); + its.wrap_payload(&mut payload, destination_chain); sui::test_utils::destroy(its); }