diff --git a/contracts/smart-wallet/Cargo.toml b/contracts/smart-wallet/Cargo.toml index 4245e8b..651fe25 100644 --- a/contracts/smart-wallet/Cargo.toml +++ b/contracts/smart-wallet/Cargo.toml @@ -17,6 +17,7 @@ upgradeable = { workspace = true } [dev-dependencies] soroban-sdk = { workspace = true, features = ["testutils"] } +contract-factory = { workspace = true } ed25519-dalek = { version = "1" } stellar-strkey = { version = "0.0.13" } rand = "0.7.3" diff --git a/contracts/smart-wallet/src/lib.rs b/contracts/smart-wallet/src/lib.rs index 86f0442..7593617 100644 --- a/contracts/smart-wallet/src/lib.rs +++ b/contracts/smart-wallet/src/lib.rs @@ -13,3 +13,6 @@ pub use error::Error; #[cfg(test)] mod tests; + +#[cfg(test)] +mod test_constants; diff --git a/contracts/smart-wallet/src/test_constants.rs b/contracts/smart-wallet/src/test_constants.rs new file mode 100644 index 0000000..d0729bc --- /dev/null +++ b/contracts/smart-wallet/src/test_constants.rs @@ -0,0 +1,79 @@ +pub const SMART_WALLET_WASM: &[u8] = &[ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x34, 0x09, 0x60, 0x03, 0x7e, 0x7e, 0x7e, + 0x01, 0x7e, 0x60, 0x01, 0x7e, 0x01, 0x7e, 0x60, 0x03, 0x7f, 0x7f, 0x7f, 0x00, 0x60, 0x02, 0x7f, + 0x7f, 0x01, 0x7e, 0x60, 0x02, 0x7f, 0x7e, 0x00, 0x60, 0x00, 0x00, 0x60, 0x04, 0x7f, 0x7e, 0x7f, + 0x7f, 0x01, 0x7e, 0x60, 0x02, 0x7f, 0x7e, 0x01, 0x7e, 0x60, 0x01, 0x7e, 0x01, 0x7f, 0x02, 0x0d, + 0x02, 0x01, 0x76, 0x01, 0x68, 0x00, 0x00, 0x01, 0x62, 0x01, 0x38, 0x00, 0x01, 0x03, 0x0d, 0x0c, + 0x02, 0x02, 0x03, 0x00, 0x00, 0x04, 0x02, 0x05, 0x06, 0x06, 0x07, 0x08, 0x04, 0x05, 0x01, 0x70, + 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x11, 0x06, 0x19, 0x03, 0x7f, 0x01, 0x41, 0x80, 0x80, + 0xc0, 0x00, 0x0b, 0x7f, 0x00, 0x41, 0xd0, 0x80, 0xc0, 0x00, 0x0b, 0x7f, 0x00, 0x41, 0xd0, 0x80, + 0xc0, 0x00, 0x0b, 0x07, 0x38, 0x05, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x0c, + 0x5f, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x00, 0x06, 0x01, 0x5f, + 0x00, 0x09, 0x0a, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x6e, 0x64, 0x03, 0x01, 0x0b, + 0x5f, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x0a, 0xea, 0x04, + 0x0c, 0x86, 0x01, 0x02, 0x01, 0x7f, 0x01, 0x7e, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x10, + 0x6b, 0x22, 0x03, 0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x29, + 0x03, 0x00, 0x22, 0x04, 0x42, 0xff, 0x01, 0x83, 0x42, 0xcb, 0x00, 0x51, 0x0d, 0x00, 0x20, 0x00, + 0x42, 0x01, 0x37, 0x03, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x42, 0x02, 0x37, 0x03, 0x08, 0x20, + 0x01, 0x20, 0x04, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x41, 0x01, 0x10, 0x8a, 0x80, 0x80, 0x80, 0x00, + 0x1a, 0x02, 0x40, 0x20, 0x03, 0x29, 0x03, 0x08, 0x22, 0x04, 0x42, 0xff, 0x01, 0x83, 0x42, 0xcc, + 0x00, 0x51, 0x0d, 0x00, 0x20, 0x00, 0x42, 0x01, 0x37, 0x03, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, + 0x42, 0x00, 0x37, 0x03, 0x00, 0x20, 0x00, 0x20, 0x04, 0x37, 0x03, 0x08, 0x0b, 0x20, 0x03, 0x41, + 0x10, 0x6a, 0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x51, 0x02, 0x01, 0x7f, 0x01, 0x7e, 0x23, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x03, 0x24, 0x80, 0x80, 0x80, 0x80, 0x00, + 0x20, 0x03, 0x20, 0x01, 0x20, 0x02, 0x10, 0x88, 0x80, 0x80, 0x80, 0x00, 0x42, 0x01, 0x21, 0x04, + 0x02, 0x40, 0x20, 0x03, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x29, 0x03, 0x08, + 0x37, 0x03, 0x08, 0x42, 0x00, 0x21, 0x04, 0x0b, 0x20, 0x00, 0x20, 0x04, 0x37, 0x03, 0x00, 0x20, + 0x03, 0x41, 0x10, 0x6a, 0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x14, 0x00, 0x20, 0x01, 0x28, + 0x02, 0x00, 0x41, 0x03, 0x74, 0x41, 0x80, 0x80, 0xc0, 0x80, 0x00, 0x6a, 0x29, 0x03, 0x00, 0x0b, + 0x95, 0x01, 0x01, 0x01, 0x7f, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x30, 0x6b, 0x22, 0x03, + 0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x03, 0x20, 0x01, 0x37, 0x03, 0x10, 0x20, 0x03, 0x20, + 0x00, 0x37, 0x03, 0x08, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x20, 0x03, 0x41, 0x2f, 0x6a, 0x20, 0x03, + 0x41, 0x08, 0x6a, 0x10, 0x83, 0x80, 0x80, 0x80, 0x00, 0x02, 0x40, 0x20, 0x03, 0x28, 0x02, 0x18, + 0x41, 0x01, 0x46, 0x0d, 0x00, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x20, 0x03, 0x41, 0x2f, 0x6a, 0x20, + 0x03, 0x41, 0x10, 0x6a, 0x10, 0x82, 0x80, 0x80, 0x80, 0x00, 0x20, 0x03, 0x28, 0x02, 0x18, 0x41, + 0x01, 0x46, 0x0d, 0x00, 0x20, 0x02, 0x42, 0xff, 0x01, 0x83, 0x42, 0xcb, 0x00, 0x52, 0x0d, 0x00, + 0x20, 0x03, 0x41, 0x00, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x10, 0x84, + 0x80, 0x80, 0x80, 0x00, 0x21, 0x01, 0x20, 0x03, 0x41, 0x30, 0x6a, 0x24, 0x80, 0x80, 0x80, 0x80, + 0x00, 0x20, 0x01, 0x0f, 0x0b, 0x00, 0x0b, 0x14, 0x00, 0x10, 0x89, 0x80, 0x80, 0x80, 0x00, 0x20, + 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x85, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x5d, 0x02, 0x01, 0x7f, + 0x01, 0x7e, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x02, 0x24, 0x80, 0x80, + 0x80, 0x80, 0x00, 0x20, 0x02, 0x20, 0x01, 0x37, 0x03, 0x08, 0x42, 0x01, 0x21, 0x03, 0x02, 0x40, + 0x20, 0x02, 0x41, 0x10, 0x6a, 0x20, 0x01, 0x10, 0x8c, 0x80, 0x80, 0x80, 0x00, 0x10, 0x8d, 0x80, + 0x80, 0x80, 0x00, 0x41, 0x20, 0x47, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x02, 0x29, 0x03, 0x08, 0x37, + 0x03, 0x08, 0x42, 0x00, 0x21, 0x03, 0x0b, 0x20, 0x00, 0x20, 0x03, 0x37, 0x03, 0x00, 0x20, 0x02, + 0x41, 0x10, 0x6a, 0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x2a, 0x01, 0x01, 0x7e, 0x02, 0x40, + 0x20, 0x02, 0x29, 0x03, 0x00, 0x22, 0x03, 0x42, 0xff, 0x01, 0x83, 0x42, 0xc8, 0x00, 0x51, 0x0d, + 0x00, 0x20, 0x00, 0x42, 0x01, 0x37, 0x03, 0x00, 0x0f, 0x0b, 0x20, 0x00, 0x20, 0x03, 0x10, 0x87, + 0x80, 0x80, 0x80, 0x00, 0x0b, 0x02, 0x00, 0x0b, 0x10, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, + 0x20, 0x03, 0x10, 0x8b, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x1c, 0x00, 0x20, 0x01, 0x20, 0x02, 0xad, + 0x42, 0x20, 0x86, 0x42, 0x04, 0x84, 0x20, 0x03, 0xad, 0x42, 0x20, 0x86, 0x42, 0x04, 0x84, 0x10, + 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x0a, 0x00, 0x20, 0x01, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, + 0x0b, 0x08, 0x00, 0x20, 0x00, 0x42, 0x20, 0x88, 0xa7, 0x0b, 0x0b, 0x59, 0x01, 0x00, 0x41, 0x80, + 0x80, 0xc0, 0x00, 0x0b, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x01, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x73, 0x70, 0x65, 0x63, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x5f, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x5f, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xee, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x07, 0xd0, 0x00, + 0x00, 0x00, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x03, 0xea, 0x00, 0x00, 0x07, 0xd0, 0x00, + 0x00, 0x00, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x03, 0xe9, 0x00, 0x00, 0x03, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x1e, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x65, 0x6e, 0x76, 0x6d, 0x65, 0x74, + 0x61, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6f, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x76, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x72, 0x73, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x31, 0x2e, 0x38, 0x38, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x72, 0x73, 0x73, 0x64, 0x6b, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x2f, + 0x32, 0x32, 0x2e, 0x30, 0x2e, 0x38, 0x23, 0x66, 0x34, 0x36, 0x65, 0x39, 0x65, 0x30, 0x36, 0x31, + 0x30, 0x32, 0x31, 0x33, 0x62, 0x62, 0x62, 0x37, 0x32, 0x32, 0x38, 0x35, 0x35, 0x36, 0x36, 0x66, + 0x39, 0x64, 0x64, 0x39, 0x36, 0x30, 0x66, 0x66, 0x39, 0x36, 0x64, 0x30, 0x33, 0x64, 0x38, 0x00, +]; diff --git a/contracts/smart-wallet/src/tests/integration.rs b/contracts/smart-wallet/src/tests/integration.rs new file mode 100644 index 0000000..3d189b4 --- /dev/null +++ b/contracts/smart-wallet/src/tests/integration.rs @@ -0,0 +1,274 @@ +#![cfg(test)] + +extern crate std; + +use soroban_sdk::{ + map, symbol_short, testutils::Address as _, testutils::BytesN as _, vec, Address, BytesN, Env, + IntoVal, Val, Vec, +}; + +use crate::{ + auth::{ + permissions::{SignerPolicy, SignerRole}, + policy::{ContractAllowListPolicy, TimeBasedPolicy}, + proof::SignatureProofs, + }, + error::Error, + interface::SmartWalletInterface, + tests::test_utils::{get_token_auth_context, setup, Ed25519TestSigner, TestSignerTrait as _}, + wallet::SmartWallet, +}; + +use contract_factory::{ContractFactory, ContractFactoryClient}; +use upgradeable::SmartWalletUpgradeable; + +fn create_factory_client<'a>(e: &Env, admin: &Address) -> ContractFactoryClient<'a> { + let address = e.register(ContractFactory, (admin,)); + ContractFactoryClient::new(e, &address) +} + +fn create_mock_salt(e: &Env, value: u8) -> BytesN<32> { + let mut bytes = [0u8; 32]; + bytes[0] = value; + BytesN::from_array(e, &bytes) +} + +fn setup_factory_roles(e: &Env, client: &ContractFactoryClient, admin: &Address) -> Address { + let deployer = Address::generate(e); + + // Set role admin for deployer role + client.set_role_admin(&symbol_short!("deployer"), &symbol_short!("dep_admin")); + + // Grant deployer admin role + let deployer_admin = Address::generate(e); + client.grant_role(admin, &deployer_admin, &symbol_short!("dep_admin")); + + // Deployer admin grants deployer role + client.grant_role(&deployer_admin, &deployer, &symbol_short!("deployer")); + + deployer +} + +#[test] +fn test_factory_deployment() { + let env = setup(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let client = create_factory_client(&env, &admin); + + let new_deployer = Address::generate(&env); + client.grant_role(&admin, &new_deployer, &symbol_short!("deployer")); + + // Verify the role was granted + assert!(client + .has_role(&new_deployer, &symbol_short!("deployer")) + .is_some()); +} + +#[test] +fn test_smart_wallet_deployment_through_factory() { + let env = setup(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let client = create_factory_client(&env, &admin); + let deployer = setup_factory_roles(&env, &client, &admin); + + let admin_signer = Ed25519TestSigner::generate(SignerRole::Admin); + + let salt = create_mock_salt(&env, 1); + let predicted_address = client.get_deployed_address(&salt); + assert!(!predicted_address.to_string().is_empty()); + + let wallet_address = env.register_at( + &predicted_address, + SmartWallet, + (vec![&env, admin_signer.into_signer(&env)],), + ); + + assert_eq!(wallet_address, predicted_address); + + // Verify the wallet is properly initialized with the admin signer + let payload = BytesN::random(&env); + let (signer_key, proof) = admin_signer.sign(&env, &payload); + let auth_payloads = SignatureProofs(map![&env, (signer_key, proof)]); + + env.try_invoke_contract_check_auth::( + &wallet_address, + &payload, + auth_payloads.into_val(&env), + &vec![&env, get_token_auth_context(&env)], + ) + .unwrap(); +} + +#[test] +fn test_add_standard_signer() { + let env = setup(); + env.mock_all_auths(); + + let admin_signer = Ed25519TestSigner::generate(SignerRole::Admin); + let contract_id = env.register(SmartWallet, (vec![&env, admin_signer.into_signer(&env)],)); + + let standard_signer = Ed25519TestSigner::generate(SignerRole::Standard); + + let result = env.as_contract(&contract_id, || { + SmartWallet::add_signer(&env, standard_signer.into_signer(&env)) + }); + + assert!(result.is_ok()); +} + +#[test] +fn test_add_restricted_signer() { + let env = setup(); + env.mock_all_auths(); + + let admin_signer = Ed25519TestSigner::generate(SignerRole::Admin); + let contract_id = env.register(SmartWallet, (vec![&env, admin_signer.into_signer(&env)],)); + + let current_time = env.ledger().timestamp(); + let time_policy = SignerPolicy::TimeBased(TimeBasedPolicy { + not_before: current_time, + not_after: current_time + 1000, + }); + + let restricted_signer = + Ed25519TestSigner::generate(SignerRole::Restricted(vec![&env, time_policy])); + + let result = env.as_contract(&contract_id, || { + SmartWallet::add_signer(&env, restricted_signer.into_signer(&env)) + }); + + assert!(result.is_ok()); +} + +#[test] +fn test_wallet_upgrade() { + let env = setup(); + env.mock_all_auths(); + + let admin_signer = Ed25519TestSigner::generate(SignerRole::Admin); + let contract_id = env.register(SmartWallet, (vec![&env, admin_signer.into_signer(&env)],)); + + let new_wasm_bytes = + soroban_sdk::Bytes::from_slice(&env, crate::test_constants::SMART_WALLET_WASM); + let new_wasm_hash = env.deployer().upload_contract_wasm(new_wasm_bytes); + + env.as_contract(&contract_id, || SmartWallet::upgrade(&env, new_wasm_hash)); +} + +#[test] +fn test_external_contract_authorization() { + let env = setup(); + env.mock_all_auths(); + + let admin_signer = Ed25519TestSigner::generate(SignerRole::Admin); + let standard_signer = Ed25519TestSigner::generate(SignerRole::Standard); + + let contract_id = env.register( + SmartWallet, + (vec![ + &env, + admin_signer.into_signer(&env), + standard_signer.into_signer(&env), + ],), + ); + + let payload = BytesN::random(&env); + let (signer_key, proof) = standard_signer.sign(&env, &payload); + let auth_payloads = SignatureProofs(map![&env, (signer_key.clone(), proof.clone())]); + + env.try_invoke_contract_check_auth::( + &contract_id, + &payload, + auth_payloads.into_val(&env), + &vec![&env, get_token_auth_context(&env)], + ) + .unwrap(); +} + +#[test] +fn test_comprehensive_smart_wallet_lifecycle() { + let env = setup(); + env.mock_all_auths(); + + let factory_admin = Address::generate(&env); + let factory_client = create_factory_client(&env, &factory_admin); + let deployer = setup_factory_roles(&env, &factory_client, &factory_admin); + + let admin_signer = Ed25519TestSigner::generate(SignerRole::Admin); + let wasm_bytes = soroban_sdk::Bytes::from_slice(&env, crate::test_constants::SMART_WALLET_WASM); + let salt = create_mock_salt(&env, 42); + let constructor_args: Vec = vec![ + &env, + vec![&env, admin_signer.into_signer(&env)].into_val(&env), + ]; + + let predicted_address = factory_client.get_deployed_address(&salt); + + // with the predicted address and verifying it works with the admin signer + let wallet_address = env.register_at( + &predicted_address, + SmartWallet, + (vec![&env, admin_signer.into_signer(&env)],), + ); + + let standard_signer = Ed25519TestSigner::generate(SignerRole::Standard); + let add_standard_result = env.as_contract(&wallet_address, || { + SmartWallet::add_signer(&env, standard_signer.into_signer(&env)) + }); + assert!(add_standard_result.is_ok()); + + let allowed_contract = Address::generate(&env); + let allowlist_policy = SignerPolicy::ContractAllowList(ContractAllowListPolicy { + allowed_contracts: vec![&env, allowed_contract.clone()], + }); + let restricted_signer = + Ed25519TestSigner::generate(SignerRole::Restricted(vec![&env, allowlist_policy])); + + let add_restricted_result = env.as_contract(&wallet_address, || { + SmartWallet::add_signer(&env, restricted_signer.into_signer(&env)) + }); + assert!(add_restricted_result.is_ok()); + + let new_wasm_bytes = + soroban_sdk::Bytes::from_slice(&env, crate::test_constants::SMART_WALLET_WASM); + let new_wasm_hash = env.deployer().upload_contract_wasm(new_wasm_bytes); + + env.as_contract(&wallet_address, || { + SmartWallet::upgrade(&env, new_wasm_hash) + }); + + let payload = BytesN::random(&env); + + let (standard_key, standard_proof) = standard_signer.sign(&env, &payload); + let standard_auth = SignatureProofs(map![&env, (standard_key, standard_proof)]); + + env.try_invoke_contract_check_auth::( + &wallet_address, + &payload, + standard_auth.into_val(&env), + &vec![&env, get_token_auth_context(&env)], + ) + .unwrap(); + + let (restricted_key, restricted_proof) = restricted_signer.sign(&env, &payload); + let restricted_auth = SignatureProofs(map![&env, (restricted_key, restricted_proof)]); + + let allowed_context = + soroban_sdk::auth::Context::Contract(soroban_sdk::auth::ContractContext { + contract: allowed_contract, + fn_name: "transfer".into_val(&env), + args: ((), (), 1000).into_val(&env), + }); + + env.try_invoke_contract_check_auth::( + &wallet_address, + &payload, + restricted_auth.into_val(&env), + &vec![&env, allowed_context], + ) + .unwrap(); +} diff --git a/contracts/smart-wallet/src/tests/mod.rs b/contracts/smart-wallet/src/tests/mod.rs index 1285c08..0bcb7a9 100644 --- a/contracts/smart-wallet/src/tests/mod.rs +++ b/contracts/smart-wallet/src/tests/mod.rs @@ -1,5 +1,6 @@ #[cfg(test)] mod auth; +mod integration; mod policy_tests; mod signer_management; mod test_utils;