From 028fb6131d941bfff99dd90be2207420fb3dc715 Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 12:24:30 -0800 Subject: [PATCH 01/13] feat(stellar): add auth for deploy remote canonical token --- .../tests/deploy_remote_canonical_token.rs | 75 +++++++++++++++++-- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index f8b9b427..753bf22c 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -5,15 +5,20 @@ use interchain_token_service::{ event::InterchainTokenDeploymentStartedEvent, types::{DeployInterchainToken, HubMessage, Message, TokenManagerType}, }; -use soroban_sdk::testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation}; -use soroban_sdk::token::{self, StellarAssetClient}; +use soroban_sdk::testutils::{ + Address as _, AuthorizedFunction, AuthorizedInvocation, MockAuth, MockAuthInvoke, +}; +use soroban_sdk::{ + token::{self, StellarAssetClient}, + TryIntoVal, +}; use soroban_sdk::{Address, Bytes, IntoVal, String, Symbol}; use soroban_token_sdk::metadata::TokenMetadata; use utils::{setup_env, setup_gas_token}; #[test] fn deploy_remote_canonical_token_succeeds() { - let (env, client, _, gas_service, _) = setup_env(); + let (env, client, gateway, gas_service, _) = setup_env(); let spender = Address::generate(&env); let gas_token = setup_gas_token(&env, &spender); let asset = &env.register_stellar_asset_contract_v2(Address::generate(&env)); @@ -62,9 +67,67 @@ fn deploy_remote_canonical_token_succeeds() { } .abi_encode(&env); - let deployed_token_id = client - .mock_all_auths_allowing_non_root_auth() - .deploy_remote_canonical_token(&token_address, &destination_chain, &spender, &gas_token); + let payload_val = payload.clone().expect("").to_val(); + let gas_token_val = gas_token.try_into_val(&env).expect(""); + + let transfer_token_auth = MockAuthInvoke { + contract: &gas_token.address, + fn_name: "transfer", + args: soroban_sdk::vec![ + &env, + spender.to_val(), + gas_service.address.to_val(), + gas_token.amount.into_val(&env), + ], + sub_invokes: &[], + }; + + let pay_gas_auth = MockAuthInvoke { + contract: &gas_service.address, + fn_name: "pay_gas", + args: soroban_sdk::vec![ + &env, + client.address.to_val(), + its_hub_chain.to_val(), + its_hub_address.to_val(), + payload_val, + spender.to_val(), + gas_token_val, + Bytes::new(&env).into(), + ], + sub_invokes: &[transfer_token_auth], + }; + + let call_contract_auth = MockAuthInvoke { + contract: &gateway.address, + fn_name: "call_contract", + args: soroban_sdk::vec![ + &env, + client.address.to_val(), + its_hub_chain.to_val(), + its_hub_address.to_val(), + payload_val, + ], + sub_invokes: &[], + }; + + env.mock_auths(&[ + MockAuth { + address: &spender, + invoke: &pay_gas_auth, + }, + MockAuth { + address: &spender, + invoke: &call_contract_auth, + }, + ]); + + let deployed_token_id = client.deploy_remote_canonical_token( + &token_address, + &destination_chain, + &spender, + &gas_token, + ); assert_eq!(expected_id, deployed_token_id); goldie::assert!(events::fmt_emitted_event_at_idx::< From cfaf6ee0310d2281bb1b56312cab6718be93f15b Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 14:52:14 -0800 Subject: [PATCH 02/13] update --- .../tests/deploy_remote_canonical_token.rs | 91 +++++++------------ packages/axelar-soroban-std/src/testutils.rs | 31 +++++++ 2 files changed, 63 insertions(+), 59 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index 753bf22c..f9388477 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -1,17 +1,15 @@ mod utils; -use axelar_soroban_std::{address::AddressExt, auth_invocation, events}; +use axelar_soroban_std::{ + address::AddressExt, auth_invocation, build_mock_auth, build_mock_invoke, events, +}; use interchain_token_service::{ event::InterchainTokenDeploymentStartedEvent, types::{DeployInterchainToken, HubMessage, Message, TokenManagerType}, }; -use soroban_sdk::testutils::{ - Address as _, AuthorizedFunction, AuthorizedInvocation, MockAuth, MockAuthInvoke, -}; -use soroban_sdk::{ - token::{self, StellarAssetClient}, - TryIntoVal, -}; +use soroban_sdk::testutils::MockAuthInvoke; +use soroban_sdk::testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation}; +use soroban_sdk::token::{self, StellarAssetClient}; use soroban_sdk::{Address, Bytes, IntoVal, String, Symbol}; use soroban_token_sdk::metadata::TokenMetadata; use utils::{setup_env, setup_gas_token}; @@ -67,60 +65,35 @@ fn deploy_remote_canonical_token_succeeds() { } .abi_encode(&env); - let payload_val = payload.clone().expect("").to_val(); - let gas_token_val = gas_token.try_into_val(&env).expect(""); - - let transfer_token_auth = MockAuthInvoke { - contract: &gas_token.address, - fn_name: "transfer", - args: soroban_sdk::vec![ - &env, - spender.to_val(), - gas_service.address.to_val(), - gas_token.amount.into_val(&env), - ], - sub_invokes: &[], - }; + let transfer_token_auth = build_mock_invoke!( + env, + gas_token.transfer(spender, gas_service.address, gas_token.amount), + &[] + ); - let pay_gas_auth = MockAuthInvoke { - contract: &gas_service.address, - fn_name: "pay_gas", - args: soroban_sdk::vec![ - &env, - client.address.to_val(), - its_hub_chain.to_val(), - its_hub_address.to_val(), - payload_val, - spender.to_val(), - gas_token_val, - Bytes::new(&env).into(), - ], - sub_invokes: &[transfer_token_auth], - }; + let pay_gas_auth = build_mock_auth!( + env, + spender, + gas_service.pay_gas( + client.address, + its_hub_chain, + its_hub_address, + payload, + spender, + gas_token, + Bytes::new(&env) + ), + &[transfer_token_auth] + ); - let call_contract_auth = MockAuthInvoke { - contract: &gateway.address, - fn_name: "call_contract", - args: soroban_sdk::vec![ - &env, - client.address.to_val(), - its_hub_chain.to_val(), - its_hub_address.to_val(), - payload_val, - ], - sub_invokes: &[], - }; + let call_contract_auth = build_mock_auth!( + env, + spender, + gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload), + &[] + ); - env.mock_auths(&[ - MockAuth { - address: &spender, - invoke: &pay_gas_auth, - }, - MockAuth { - address: &spender, - invoke: &call_contract_auth, - }, - ]); + env.mock_auths(&[pay_gas_auth, call_contract_auth]); let deployed_token_id = client.deploy_remote_canonical_token( &token_address, diff --git a/packages/axelar-soroban-std/src/testutils.rs b/packages/axelar-soroban-std/src/testutils.rs index f94bdbec..93e9afb5 100644 --- a/packages/axelar-soroban-std/src/testutils.rs +++ b/packages/axelar-soroban-std/src/testutils.rs @@ -140,3 +140,34 @@ macro_rules! auth_invocation { )] }}; } + +#[macro_export] +macro_rules! build_mock_invoke { + ( + $env:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ), + $sub_invokes:expr + ) => {{ + soroban_sdk::testutils::MockAuthInvoke { + contract: &$client.address, + fn_name: &stringify!($method), + args: ($($arg.clone(),)*).into_val(&$env), + sub_invokes: $sub_invokes, + } + }}; +} + +#[macro_export] +macro_rules! build_mock_auth { + ( + $env:expr, + $caller:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ), + $sub_invokes:expr + ) => {{ + soroban_sdk::testutils::MockAuth { + address: &$caller, + invoke: &build_mock_invoke!($env, $client . $method ( $($arg),* ), $sub_invokes), + } + }}; +} From bf26e27699d3d06486274ea20a95ed014eff7173 Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 14:54:52 -0800 Subject: [PATCH 03/13] Update deploy_remote_canonical_token.rs --- .../tests/deploy_remote_canonical_token.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index f9388477..23a54358 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -7,7 +7,6 @@ use interchain_token_service::{ event::InterchainTokenDeploymentStartedEvent, types::{DeployInterchainToken, HubMessage, Message, TokenManagerType}, }; -use soroban_sdk::testutils::MockAuthInvoke; use soroban_sdk::testutils::{Address as _, AuthorizedFunction, AuthorizedInvocation}; use soroban_sdk::token::{self, StellarAssetClient}; use soroban_sdk::{Address, Bytes, IntoVal, String, Symbol}; From 72e29b47842864f7f383b7af2426fa4aa381683e Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 15:47:00 -0800 Subject: [PATCH 04/13] updated --- .../tests/deploy_remote_canonical_token.rs | 13 +++--- packages/axelar-soroban-std/src/error.rs | 41 +++++++++++++------ packages/axelar-soroban-std/src/testutils.rs | 31 -------------- 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index 23a54358..85ecf60b 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -1,8 +1,6 @@ mod utils; -use axelar_soroban_std::{ - address::AddressExt, auth_invocation, build_mock_auth, build_mock_invoke, events, -}; +use axelar_soroban_std::{address::AddressExt, auth_invocation, events, mock_auth}; use interchain_token_service::{ event::InterchainTokenDeploymentStartedEvent, types::{DeployInterchainToken, HubMessage, Message, TokenManagerType}, @@ -64,13 +62,14 @@ fn deploy_remote_canonical_token_succeeds() { } .abi_encode(&env); - let transfer_token_auth = build_mock_invoke!( + let transfer_token_auth = mock_auth!( env, + spender, gas_token.transfer(spender, gas_service.address, gas_token.amount), &[] ); - let pay_gas_auth = build_mock_auth!( + let pay_gas_auth = mock_auth!( env, spender, gas_service.pay_gas( @@ -82,10 +81,10 @@ fn deploy_remote_canonical_token_succeeds() { gas_token, Bytes::new(&env) ), - &[transfer_token_auth] + &[(transfer_token_auth.invoke).clone()] ); - let call_contract_auth = build_mock_auth!( + let call_contract_auth = mock_auth!( env, spender, gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload), diff --git a/packages/axelar-soroban-std/src/error.rs b/packages/axelar-soroban-std/src/error.rs index 23cb45b5..467fb0e6 100644 --- a/packages/axelar-soroban-std/src/error.rs +++ b/packages/axelar-soroban-std/src/error.rs @@ -111,7 +111,12 @@ macro_rules! assert_invoke_auth_ok { use soroban_sdk::IntoVal; let call_result = $client - .mock_auths($crate::mock_auth!($caller, $client, $method, $($arg),*)) + .mock_auths(&[$crate::mock_auth!( + $client.env, + $caller, + $client.$method($($arg),*), + &[] + )]) .$method($($arg),*); match call_result { @@ -132,7 +137,12 @@ macro_rules! assert_invoke_auth_err { use soroban_sdk::{IntoVal, xdr::{ScError, ScErrorCode, ScVal}}; let call_result = $client - .mock_auths($crate::mock_auth!($caller, $client, $method, $($arg),*)) + .mock_auths(&[$crate::mock_auth!( + $client.env, + $caller, + $client.$method($($arg),*), + &[] + )]) .$method($($arg),*); match call_result { @@ -150,15 +160,20 @@ macro_rules! assert_invoke_auth_err { #[macro_export] macro_rules! mock_auth { - ($caller:expr, $client:ident, $method:ident, $($arg:expr),*) => { - &[soroban_sdk::testutils::MockAuth { - address: &$caller, - invoke: &soroban_sdk::testutils::MockAuthInvoke { - contract: &$client.address, - fn_name: &stringify!($method).replace("try_", ""), - args: ($($arg.clone(),)*).into_val(&$client.env), - sub_invokes: &[], - }, - }] - }; + ( + $env:expr, + $caller:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ), + $sub_invokes:expr + ) => {{ + soroban_sdk::testutils::MockAuth { + address: &$caller, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &$client.address, + fn_name: &stringify!($method).replace("try_", ""), + args: ($($arg.clone(),)*).into_val(&$env), + sub_invokes: $sub_invokes, + }, + } + }}; } diff --git a/packages/axelar-soroban-std/src/testutils.rs b/packages/axelar-soroban-std/src/testutils.rs index 93e9afb5..f94bdbec 100644 --- a/packages/axelar-soroban-std/src/testutils.rs +++ b/packages/axelar-soroban-std/src/testutils.rs @@ -140,34 +140,3 @@ macro_rules! auth_invocation { )] }}; } - -#[macro_export] -macro_rules! build_mock_invoke { - ( - $env:expr, - $client:ident . $method:ident ( $($arg:expr),* $(,)? ), - $sub_invokes:expr - ) => {{ - soroban_sdk::testutils::MockAuthInvoke { - contract: &$client.address, - fn_name: &stringify!($method), - args: ($($arg.clone(),)*).into_val(&$env), - sub_invokes: $sub_invokes, - } - }}; -} - -#[macro_export] -macro_rules! build_mock_auth { - ( - $env:expr, - $caller:expr, - $client:ident . $method:ident ( $($arg:expr),* $(,)? ), - $sub_invokes:expr - ) => {{ - soroban_sdk::testutils::MockAuth { - address: &$caller, - invoke: &build_mock_invoke!($env, $client . $method ( $($arg),* ), $sub_invokes), - } - }}; -} From 9f83a3fd41cdd432dbf268ba875f09c627a24fb2 Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 23:44:50 -0800 Subject: [PATCH 05/13] update --- .../tests/deploy_remote_canonical_token.rs | 17 +++++------------ packages/axelar-soroban-std/src/error.rs | 7 +++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index 85ecf60b..b69538d4 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -65,8 +65,7 @@ fn deploy_remote_canonical_token_succeeds() { let transfer_token_auth = mock_auth!( env, spender, - gas_token.transfer(spender, gas_service.address, gas_token.amount), - &[] + gas_token.transfer(spender, gas_service.address, gas_token.amount) ); let pay_gas_auth = mock_auth!( @@ -87,18 +86,12 @@ fn deploy_remote_canonical_token_succeeds() { let call_contract_auth = mock_auth!( env, spender, - gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload), - &[] + gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload) ); - env.mock_auths(&[pay_gas_auth, call_contract_auth]); - - let deployed_token_id = client.deploy_remote_canonical_token( - &token_address, - &destination_chain, - &spender, - &gas_token, - ); + let deployed_token_id = client + .mock_auths(&[pay_gas_auth, call_contract_auth]) + .deploy_remote_canonical_token(&token_address, &destination_chain, &spender, &gas_token); assert_eq!(expected_id, deployed_token_id); goldie::assert!(events::fmt_emitted_event_at_idx::< diff --git a/packages/axelar-soroban-std/src/error.rs b/packages/axelar-soroban-std/src/error.rs index 467fb0e6..158b397b 100644 --- a/packages/axelar-soroban-std/src/error.rs +++ b/packages/axelar-soroban-std/src/error.rs @@ -176,4 +176,11 @@ macro_rules! mock_auth { }, } }}; + ( + $env:expr, + $caller:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ) + ) => {{ + mock_auth!($env, $caller, $client.$method($($arg),*), &[]) + }}; } From ac33aaf378d01d43d9904b724c350010f169937b Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 12:24:30 -0800 Subject: [PATCH 06/13] feat(stellar): add auth for deploy remote canonical token --- .../tests/deploy_remote_canonical_token.rs | 66 +++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index 648e1964..01e1b162 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -14,7 +14,7 @@ use utils::{setup_env, setup_gas_token}; #[test] fn deploy_remote_canonical_token_succeeds() { - let (env, client, _, gas_service, _) = setup_env(); + let (env, client, gateway, gas_service, _) = setup_env(); let spender = Address::generate(&env); let gas_token = setup_gas_token(&env, &spender); let asset = &env.register_stellar_asset_contract_v2(Address::generate(&env)); @@ -63,9 +63,67 @@ fn deploy_remote_canonical_token_succeeds() { } .abi_encode(&env); - let deployed_token_id = client - .mock_all_auths_allowing_non_root_auth() - .deploy_remote_canonical_token(&token_address, &destination_chain, &spender, &gas_token); + let payload_val = payload.clone().expect("").to_val(); + let gas_token_val = gas_token.try_into_val(&env).expect(""); + + let transfer_token_auth = MockAuthInvoke { + contract: &gas_token.address, + fn_name: "transfer", + args: soroban_sdk::vec![ + &env, + spender.to_val(), + gas_service.address.to_val(), + gas_token.amount.into_val(&env), + ], + sub_invokes: &[], + }; + + let pay_gas_auth = MockAuthInvoke { + contract: &gas_service.address, + fn_name: "pay_gas", + args: soroban_sdk::vec![ + &env, + client.address.to_val(), + its_hub_chain.to_val(), + its_hub_address.to_val(), + payload_val, + spender.to_val(), + gas_token_val, + Bytes::new(&env).into(), + ], + sub_invokes: &[transfer_token_auth], + }; + + let call_contract_auth = MockAuthInvoke { + contract: &gateway.address, + fn_name: "call_contract", + args: soroban_sdk::vec![ + &env, + client.address.to_val(), + its_hub_chain.to_val(), + its_hub_address.to_val(), + payload_val, + ], + sub_invokes: &[], + }; + + env.mock_auths(&[ + MockAuth { + address: &spender, + invoke: &pay_gas_auth, + }, + MockAuth { + address: &spender, + invoke: &call_contract_auth, + }, + ]); + + let deployed_token_id = client.deploy_remote_canonical_token( + &token_address, + &destination_chain, + &spender, + &gas_token, + ); assert_eq!(expected_id, deployed_token_id); goldie::assert!(events::fmt_emitted_event_at_idx::< From 33ecbb80ae337848141499e5dd00d70ae8db1e69 Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 14:52:14 -0800 Subject: [PATCH 07/13] update --- .../tests/deploy_remote_canonical_token.rs | 77 +++++++------------ packages/axelar-std/src/testutils.rs | 31 ++++++++ 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index 01e1b162..512f6989 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -63,60 +63,35 @@ fn deploy_remote_canonical_token_succeeds() { } .abi_encode(&env); - let payload_val = payload.clone().expect("").to_val(); - let gas_token_val = gas_token.try_into_val(&env).expect(""); - - let transfer_token_auth = MockAuthInvoke { - contract: &gas_token.address, - fn_name: "transfer", - args: soroban_sdk::vec![ - &env, - spender.to_val(), - gas_service.address.to_val(), - gas_token.amount.into_val(&env), - ], - sub_invokes: &[], - }; + let transfer_token_auth = build_mock_invoke!( + env, + gas_token.transfer(spender, gas_service.address, gas_token.amount), + &[] + ); - let pay_gas_auth = MockAuthInvoke { - contract: &gas_service.address, - fn_name: "pay_gas", - args: soroban_sdk::vec![ - &env, - client.address.to_val(), - its_hub_chain.to_val(), - its_hub_address.to_val(), - payload_val, - spender.to_val(), - gas_token_val, - Bytes::new(&env).into(), - ], - sub_invokes: &[transfer_token_auth], - }; + let pay_gas_auth = build_mock_auth!( + env, + spender, + gas_service.pay_gas( + client.address, + its_hub_chain, + its_hub_address, + payload, + spender, + gas_token, + Bytes::new(&env) + ), + &[transfer_token_auth] + ); - let call_contract_auth = MockAuthInvoke { - contract: &gateway.address, - fn_name: "call_contract", - args: soroban_sdk::vec![ - &env, - client.address.to_val(), - its_hub_chain.to_val(), - its_hub_address.to_val(), - payload_val, - ], - sub_invokes: &[], - }; + let call_contract_auth = build_mock_auth!( + env, + spender, + gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload), + &[] + ); - env.mock_auths(&[ - MockAuth { - address: &spender, - invoke: &pay_gas_auth, - }, - MockAuth { - address: &spender, - invoke: &call_contract_auth, - }, - ]); + env.mock_auths(&[pay_gas_auth, call_contract_auth]); let deployed_token_id = client.deploy_remote_canonical_token( &token_address, diff --git a/packages/axelar-std/src/testutils.rs b/packages/axelar-std/src/testutils.rs index 52496777..b7b5655c 100644 --- a/packages/axelar-std/src/testutils.rs +++ b/packages/axelar-std/src/testutils.rs @@ -139,3 +139,34 @@ macro_rules! auth_invocation { )] }}; } + +#[macro_export] +macro_rules! build_mock_invoke { + ( + $env:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ), + $sub_invokes:expr + ) => {{ + soroban_sdk::testutils::MockAuthInvoke { + contract: &$client.address, + fn_name: &stringify!($method), + args: ($($arg.clone(),)*).into_val(&$env), + sub_invokes: $sub_invokes, + } + }}; +} + +#[macro_export] +macro_rules! build_mock_auth { + ( + $env:expr, + $caller:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ), + $sub_invokes:expr + ) => {{ + soroban_sdk::testutils::MockAuth { + address: &$caller, + invoke: &build_mock_invoke!($env, $client . $method ( $($arg),* ), $sub_invokes), + } + }}; +} From 62bbb584111a12ac12e41417a682ad19f04e4d7e Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 15:47:00 -0800 Subject: [PATCH 08/13] updated --- .../tests/deploy_remote_canonical_token.rs | 9 +++--- packages/axelar-std/src/testutils.rs | 31 ------------------- 2 files changed, 5 insertions(+), 35 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index 512f6989..afc0d36a 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -63,13 +63,14 @@ fn deploy_remote_canonical_token_succeeds() { } .abi_encode(&env); - let transfer_token_auth = build_mock_invoke!( + let transfer_token_auth = mock_auth!( env, + spender, gas_token.transfer(spender, gas_service.address, gas_token.amount), &[] ); - let pay_gas_auth = build_mock_auth!( + let pay_gas_auth = mock_auth!( env, spender, gas_service.pay_gas( @@ -81,10 +82,10 @@ fn deploy_remote_canonical_token_succeeds() { gas_token, Bytes::new(&env) ), - &[transfer_token_auth] + &[(transfer_token_auth.invoke).clone()] ); - let call_contract_auth = build_mock_auth!( + let call_contract_auth = mock_auth!( env, spender, gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload), diff --git a/packages/axelar-std/src/testutils.rs b/packages/axelar-std/src/testutils.rs index b7b5655c..52496777 100644 --- a/packages/axelar-std/src/testutils.rs +++ b/packages/axelar-std/src/testutils.rs @@ -139,34 +139,3 @@ macro_rules! auth_invocation { )] }}; } - -#[macro_export] -macro_rules! build_mock_invoke { - ( - $env:expr, - $client:ident . $method:ident ( $($arg:expr),* $(,)? ), - $sub_invokes:expr - ) => {{ - soroban_sdk::testutils::MockAuthInvoke { - contract: &$client.address, - fn_name: &stringify!($method), - args: ($($arg.clone(),)*).into_val(&$env), - sub_invokes: $sub_invokes, - } - }}; -} - -#[macro_export] -macro_rules! build_mock_auth { - ( - $env:expr, - $caller:expr, - $client:ident . $method:ident ( $($arg:expr),* $(,)? ), - $sub_invokes:expr - ) => {{ - soroban_sdk::testutils::MockAuth { - address: &$caller, - invoke: &build_mock_invoke!($env, $client . $method ( $($arg),* ), $sub_invokes), - } - }}; -} From 0b125020ebf26c96419d077c44c37494c023b5c6 Mon Sep 17 00:00:00 2001 From: ahramy Date: Mon, 13 Jan 2025 23:44:50 -0800 Subject: [PATCH 09/13] update --- .../tests/deploy_remote_canonical_token.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index afc0d36a..f5fbd1a5 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -66,8 +66,7 @@ fn deploy_remote_canonical_token_succeeds() { let transfer_token_auth = mock_auth!( env, spender, - gas_token.transfer(spender, gas_service.address, gas_token.amount), - &[] + gas_token.transfer(spender, gas_service.address, gas_token.amount) ); let pay_gas_auth = mock_auth!( @@ -88,18 +87,12 @@ fn deploy_remote_canonical_token_succeeds() { let call_contract_auth = mock_auth!( env, spender, - gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload), - &[] + gateway.call_contract(client.address, its_hub_chain, its_hub_address, payload) ); - env.mock_auths(&[pay_gas_auth, call_contract_auth]); - - let deployed_token_id = client.deploy_remote_canonical_token( - &token_address, - &destination_chain, - &spender, - &gas_token, - ); + let deployed_token_id = client + .mock_auths(&[pay_gas_auth, call_contract_auth]) + .deploy_remote_canonical_token(&token_address, &destination_chain, &spender, &gas_token); assert_eq!(expected_id, deployed_token_id); goldie::assert!(events::fmt_emitted_event_at_idx::< From 8487b23ae9713c6adf49dfe9fbb433c73c617e9b Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 16 Jan 2025 23:19:23 -0800 Subject: [PATCH 10/13] updated auth test in upgrader --- .../tests/deploy_remote_canonical_token.rs | 2 +- contracts/upgrader/tests/atomic_upgrades.rs | 113 ++++++++---------- packages/axelar-std/src/error.rs | 54 ++++++--- 3 files changed, 87 insertions(+), 82 deletions(-) diff --git a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs index f5fbd1a5..53a6d45c 100644 --- a/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs +++ b/contracts/interchain-token-service/tests/deploy_remote_canonical_token.rs @@ -5,7 +5,7 @@ use soroban_sdk::token::{self, StellarAssetClient}; use soroban_sdk::{Address, Bytes, IntoVal, String, Symbol}; use soroban_token_sdk::metadata::TokenMetadata; use stellar_axelar_std::address::AddressExt; -use stellar_axelar_std::{auth_invocation, events}; +use stellar_axelar_std::{auth_invocation, events, mock_auth}; use stellar_interchain_token_service::event::InterchainTokenDeploymentStartedEvent; use stellar_interchain_token_service::types::{ DeployInterchainToken, HubMessage, Message, TokenManagerType, diff --git a/contracts/upgrader/tests/atomic_upgrades.rs b/contracts/upgrader/tests/atomic_upgrades.rs index dd897ef9..dc202bd9 100644 --- a/contracts/upgrader/tests/atomic_upgrades.rs +++ b/contracts/upgrader/tests/atomic_upgrades.rs @@ -1,7 +1,8 @@ mod utils; -use soroban_sdk::testutils::{Address as _, MockAuth, MockAuthInvoke}; +use soroban_sdk::testutils::Address as _; use soroban_sdk::{Address, BytesN, Env, String}; +use stellar_axelar_std::mock_auth; use stellar_upgrader::{Upgrader, UpgraderClient}; use utils::{DataKey, DummyContract, DummyContractClient}; @@ -23,22 +24,21 @@ fn upgrade_and_migrate_are_atomic() { let original_version: String = dummy_client.version(); assert_eq!(original_version, String::from_str(&env, "0.1.0")); - let (upgrade_auth, migrate_auth) = - build_invocation_auths(&env, &contract_address, &hash_after_upgrade, &expected_data); - - // add the owner to the set of authenticated addresses - env.mock_auths(&[ - MockAuth { - address: &owner, - invoke: &upgrade_auth, - }, - MockAuth { - address: &owner, - invoke: &migrate_auth, - }, - ]); + let upgrader = UpgraderClient::new(&env, &upgrader_address); - UpgraderClient::new(&env, &upgrader_address).upgrade( + let upgrade_auth = mock_auth! { + env, + owner, + dummy_client.upgrade(hash_after_upgrade) + }; + + let migrate_auth = mock_auth! { + env, + owner, + dummy_client.migrate(expected_data) + }; + + upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( &contract_address, &expected_version, &hash_after_upgrade, @@ -69,24 +69,26 @@ fn upgrade_fails_if_caller_is_authenticated_but_not_owner() { .. } = setup_contracts_and_call_args(); - let (upgrade_auth, migrate_auth) = - build_invocation_auths(&env, &contract_address, &hash_after_upgrade, &expected_data); + let dummy_client = DummyContractClient::new(&env, &contract_address); + let upgrader = UpgraderClient::new(&env, &upgrader_address); // add the caller to the set of authenticated addresses let caller = Address::generate(&env); - env.mock_auths(&[ - MockAuth { - address: &caller, - invoke: &upgrade_auth, - }, - MockAuth { - address: &caller, - invoke: &migrate_auth, - }, - ]); + + let upgrade_auth = mock_auth! { + env, + caller, + dummy_client.upgrade(hash_after_upgrade) + }; + + let migrate_auth = mock_auth! { + env, + caller, + dummy_client.migrate(expected_data) + }; // should panic: caller is authenticated, but not the owner - UpgraderClient::new(&env, &upgrader_address).upgrade( + upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( &contract_address, &expected_version, &hash_after_upgrade, @@ -106,24 +108,26 @@ fn upgrade_fails_if_correct_owner_is_not_authenticated_for_full_invocation_tree( expected_data, expected_version, } = setup_contracts_and_call_args(); + let dummy_client = DummyContractClient::new(&env, &contract_address); + let upgrader = UpgraderClient::new(&env, &upgrader_address); - let (upgrade_auth, migrate_auth) = - build_invocation_auths(&env, &contract_address, &hash_after_upgrade, &expected_data); - - // only add the owner to the set of authenticated addresses for the upgrade function, and the caller for the migrate function + // add the caller to the set of authenticated addresses let caller = Address::generate(&env); - env.mock_auths(&[ - MockAuth { - address: &owner, - invoke: &upgrade_auth, - }, - MockAuth { - address: &caller, - invoke: &migrate_auth, - }, - ]); - UpgraderClient::new(&env, &upgrader_address).upgrade( + let upgrade_auth = mock_auth! { + env, + owner, + dummy_client.upgrade(hash_after_upgrade) + }; + + let migrate_auth = mock_auth! { + env, + caller, + dummy_client.migrate(expected_data) + }; + + // only add the owner to the set of authenticated addresses for the upgrade function, and the caller for the migrate function + upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( &contract_address, &expected_version, &hash_after_upgrade, @@ -184,24 +188,3 @@ fn setup_contracts_and_call_args() -> TestFixture { expected_version, } } - -fn build_invocation_auths<'a>( - env: &Env, - contract_address: &'a Address, - hash_after_upgrade: &'a BytesN<32>, - expected_data: &'a String, -) -> (MockAuthInvoke<'a>, MockAuthInvoke<'a>) { - let upgrade = MockAuthInvoke { - contract: contract_address, - fn_name: "upgrade", - args: soroban_sdk::vec![&env, hash_after_upgrade.to_val()], - sub_invokes: &[], - }; - let migrate = MockAuthInvoke { - contract: contract_address, - fn_name: "migrate", - args: soroban_sdk::vec![&env, expected_data.to_val()], - sub_invokes: &[], - }; - (upgrade, migrate) -} diff --git a/packages/axelar-std/src/error.rs b/packages/axelar-std/src/error.rs index 9a8037ce..1d5b1fde 100644 --- a/packages/axelar-std/src/error.rs +++ b/packages/axelar-std/src/error.rs @@ -108,12 +108,15 @@ macro_rules! assert_some { #[macro_export] macro_rules! assert_auth { ($caller:expr, $client:ident . $method:ident ( $($arg:expr),* $(,)? )) => {{ - use soroban_sdk::IntoVal; - // Paste is used to concatenate the method name with the `try_` prefix paste::paste! { let call_result = $client - .mock_auths($crate::mock_auth!($caller, $client, $method, $($arg),*)) + .mock_auths(&[$crate::mock_auth!( + $client.env, + $caller, + $client.$method($($arg),*), + &[] + )]) .[]($($arg),*); } @@ -132,11 +135,16 @@ macro_rules! assert_auth { #[macro_export] macro_rules! assert_auth_err { ($caller:expr, $client:ident . $method:ident ( $($arg:expr),* $(,)? )) => {{ - use soroban_sdk::{IntoVal, xdr::{ScError, ScErrorCode, ScVal}}; + use soroban_sdk::xdr::{ScError, ScErrorCode, ScVal}; paste::paste! { let call_result = $client - .mock_auths($crate::mock_auth!($caller, $client, $method, $($arg),*)) + .mock_auths(&[$crate::mock_auth!( + $client.env, + $caller, + $client.$method($($arg),*), + &[] + )]) .[]($($arg),*); } match call_result { @@ -154,15 +162,29 @@ macro_rules! assert_auth_err { #[macro_export] macro_rules! mock_auth { - ($caller:expr, $client:ident, $method:ident, $($arg:expr),*) => { - &[soroban_sdk::testutils::MockAuth { - address: &$caller, - invoke: &soroban_sdk::testutils::MockAuthInvoke { - contract: &$client.address, - fn_name: &stringify!($method), - args: ($($arg.clone(),)*).into_val(&$client.env), - sub_invokes: &[], - }, - }] - }; + ( + $env:expr, + $caller:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ), + $sub_invokes:expr + ) => {{ + use soroban_sdk::IntoVal; + + soroban_sdk::testutils::MockAuth { + address: &$caller, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &$client.address, + fn_name: &stringify!($method).replace("try_", ""), + args: ($($arg.clone(),)*).into_val(&$env), + sub_invokes: $sub_invokes, + }, + } + }}; + ( + $env:expr, + $caller:expr, + $client:ident . $method:ident ( $($arg:expr),* $(,)? ) + ) => {{ + mock_auth!($env, $caller, $client.$method($($arg),*), &[]) + }}; } From 25fce6b1acde54eaeea320334a7b3ecd3b22eb27 Mon Sep 17 00:00:00 2001 From: ahramy Date: Thu, 16 Jan 2025 23:22:07 -0800 Subject: [PATCH 11/13] Update error.rs --- packages/axelar-std/src/error.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/axelar-std/src/error.rs b/packages/axelar-std/src/error.rs index c6402760..1d5b1fde 100644 --- a/packages/axelar-std/src/error.rs +++ b/packages/axelar-std/src/error.rs @@ -168,6 +168,8 @@ macro_rules! mock_auth { $client:ident . $method:ident ( $($arg:expr),* $(,)? ), $sub_invokes:expr ) => {{ + use soroban_sdk::IntoVal; + soroban_sdk::testutils::MockAuth { address: &$caller, invoke: &soroban_sdk::testutils::MockAuthInvoke { From f0e0cdda84050f66d32fc626d07f94bed554e339 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 17 Jan 2025 02:30:38 -0500 Subject: [PATCH 12/13] Apply suggestions from code review --- contracts/upgrader/tests/atomic_upgrades.rs | 27 +++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/contracts/upgrader/tests/atomic_upgrades.rs b/contracts/upgrader/tests/atomic_upgrades.rs index dc202bd9..f3f02470 100644 --- a/contracts/upgrader/tests/atomic_upgrades.rs +++ b/contracts/upgrader/tests/atomic_upgrades.rs @@ -26,17 +26,16 @@ fn upgrade_and_migrate_are_atomic() { let upgrader = UpgraderClient::new(&env, &upgrader_address); - let upgrade_auth = mock_auth! { + let upgrade_auth = mock_auth!( env, owner, dummy_client.upgrade(hash_after_upgrade) - }; - - let migrate_auth = mock_auth! { + ); + let migrate_auth = mock_auth!( env, owner, dummy_client.migrate(expected_data) - }; + ); upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( &contract_address, @@ -75,17 +74,16 @@ fn upgrade_fails_if_caller_is_authenticated_but_not_owner() { // add the caller to the set of authenticated addresses let caller = Address::generate(&env); - let upgrade_auth = mock_auth! { + let upgrade_auth = mock_auth!( env, caller, dummy_client.upgrade(hash_after_upgrade) - }; - - let migrate_auth = mock_auth! { + ); + let migrate_auth = mock_auth!( env, caller, dummy_client.migrate(expected_data) - }; + ); // should panic: caller is authenticated, but not the owner upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( @@ -114,17 +112,16 @@ fn upgrade_fails_if_correct_owner_is_not_authenticated_for_full_invocation_tree( // add the caller to the set of authenticated addresses let caller = Address::generate(&env); - let upgrade_auth = mock_auth! { + let upgrade_auth = mock_auth!( env, owner, dummy_client.upgrade(hash_after_upgrade) - }; - - let migrate_auth = mock_auth! { + ); + let migrate_auth = mock_auth!( env, caller, dummy_client.migrate(expected_data) - }; + ); // only add the owner to the set of authenticated addresses for the upgrade function, and the caller for the migrate function upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( From 964a195dc7c97436fff9640630073eb4bac59c66 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 17 Jan 2025 02:31:59 -0500 Subject: [PATCH 13/13] fmt --- contracts/upgrader/tests/atomic_upgrades.rs | 36 ++++----------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/contracts/upgrader/tests/atomic_upgrades.rs b/contracts/upgrader/tests/atomic_upgrades.rs index f3f02470..7bb9959a 100644 --- a/contracts/upgrader/tests/atomic_upgrades.rs +++ b/contracts/upgrader/tests/atomic_upgrades.rs @@ -26,16 +26,8 @@ fn upgrade_and_migrate_are_atomic() { let upgrader = UpgraderClient::new(&env, &upgrader_address); - let upgrade_auth = mock_auth!( - env, - owner, - dummy_client.upgrade(hash_after_upgrade) - ); - let migrate_auth = mock_auth!( - env, - owner, - dummy_client.migrate(expected_data) - ); + let upgrade_auth = mock_auth!(env, owner, dummy_client.upgrade(hash_after_upgrade)); + let migrate_auth = mock_auth!(env, owner, dummy_client.migrate(expected_data)); upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( &contract_address, @@ -74,16 +66,8 @@ fn upgrade_fails_if_caller_is_authenticated_but_not_owner() { // add the caller to the set of authenticated addresses let caller = Address::generate(&env); - let upgrade_auth = mock_auth!( - env, - caller, - dummy_client.upgrade(hash_after_upgrade) - ); - let migrate_auth = mock_auth!( - env, - caller, - dummy_client.migrate(expected_data) - ); + let upgrade_auth = mock_auth!(env, caller, dummy_client.upgrade(hash_after_upgrade)); + let migrate_auth = mock_auth!(env, caller, dummy_client.migrate(expected_data)); // should panic: caller is authenticated, but not the owner upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade( @@ -112,16 +96,8 @@ fn upgrade_fails_if_correct_owner_is_not_authenticated_for_full_invocation_tree( // add the caller to the set of authenticated addresses let caller = Address::generate(&env); - let upgrade_auth = mock_auth!( - env, - owner, - dummy_client.upgrade(hash_after_upgrade) - ); - let migrate_auth = mock_auth!( - env, - caller, - dummy_client.migrate(expected_data) - ); + let upgrade_auth = mock_auth!(env, owner, dummy_client.upgrade(hash_after_upgrade)); + let migrate_auth = mock_auth!(env, caller, dummy_client.migrate(expected_data)); // only add the owner to the set of authenticated addresses for the upgrade function, and the caller for the migrate function upgrader.mock_auths(&[upgrade_auth, migrate_auth]).upgrade(