diff --git a/contracts/soroban/contracts/centralized-connection/src/contract.rs b/contracts/soroban/contracts/centralized-connection/src/contract.rs index 5dcd9913..507f5451 100644 --- a/contracts/soroban/contracts/centralized-connection/src/contract.rs +++ b/contracts/soroban/contracts/centralized-connection/src/contract.rs @@ -14,6 +14,7 @@ impl CentralizedConnection { storage::store_conn_sn(&env, 0); storage::store_admin(&env, msg.relayer); storage::store_xcall(&env, msg.xcall_address); + storage::store_upgrade_authority(&env, msg.upgrade_authority); Ok(()) } @@ -29,6 +30,18 @@ impl CentralizedConnection { Ok(()) } + pub fn get_upgrade_authority(env: Env) -> Result
{ + let address = storage::get_upgrade_authority(&env)?; + Ok(address) + } + + pub fn set_upgrade_authority(env: &Env, address: Address) -> Result<(), ContractError> { + helpers::ensure_upgrade_authority(&env)?; + storage::store_upgrade_authority(&env, address); + + Ok(()) + } + pub fn send_message( env: Env, tx_origin: Address, @@ -109,7 +122,7 @@ impl CentralizedConnection { } pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) -> Result<(), ContractError> { - helpers::ensure_admin(&env)?; + helpers::ensure_upgrade_authority(&env)?; env.deployer().update_current_contract_wasm(new_wasm_hash); Ok(()) diff --git a/contracts/soroban/contracts/centralized-connection/src/helpers.rs b/contracts/soroban/contracts/centralized-connection/src/helpers.rs index f702898e..d43fe65a 100644 --- a/contracts/soroban/contracts/centralized-connection/src/helpers.rs +++ b/contracts/soroban/contracts/centralized-connection/src/helpers.rs @@ -9,6 +9,13 @@ pub fn ensure_admin(e: &Env) -> Result { Ok(admin) } +pub fn ensure_upgrade_authority(e: &Env) -> Result { + let authority = storage::get_upgrade_authority(&e)?; + authority.require_auth(); + + Ok(authority) +} + pub fn ensure_xcall(e: &Env) -> Result { let xcall = storage::get_xcall(&e)?; xcall.require_auth(); diff --git a/contracts/soroban/contracts/centralized-connection/src/storage.rs b/contracts/soroban/contracts/centralized-connection/src/storage.rs index 3bed6670..4a410aa0 100644 --- a/contracts/soroban/contracts/centralized-connection/src/storage.rs +++ b/contracts/soroban/contracts/centralized-connection/src/storage.rs @@ -29,6 +29,13 @@ pub fn admin(e: &Env) -> Result { .ok_or(ContractError::Uninitialized) } +pub fn get_upgrade_authority(e: &Env) -> Result { + e.storage() + .instance() + .get(&StorageKey::UpgradeAuthority) + .ok_or(ContractError::Uninitialized) +} + pub fn get_xcall(e: &Env) -> Result { e.storage() .instance() @@ -106,6 +113,12 @@ pub fn store_admin(e: &Env, admin: Address) { e.storage().instance().set(&StorageKey::Admin, &admin); } +pub fn store_upgrade_authority(e: &Env, address: Address) { + e.storage() + .instance() + .set(&StorageKey::UpgradeAuthority, &address); +} + pub fn store_xcall(e: &Env, xcall: Address) { e.storage().instance().set(&StorageKey::Xcall, &xcall); } diff --git a/contracts/soroban/contracts/centralized-connection/src/test.rs b/contracts/soroban/contracts/centralized-connection/src/test.rs index 7d732f8c..a44bd217 100644 --- a/contracts/soroban/contracts/centralized-connection/src/test.rs +++ b/contracts/soroban/contracts/centralized-connection/src/test.rs @@ -26,6 +26,7 @@ pub struct TestContext { native_token: Address, token_admin: Address, nid: String, + upgrade_authority: Address, } impl TestContext { @@ -38,6 +39,7 @@ impl TestContext { relayer: Address::generate(&env), native_token: env.register_stellar_asset_contract(token_admin.clone()), nid: String::from_str(&env, "icon"), + upgrade_authority: Address::generate(&env), env, token_admin, } @@ -50,6 +52,7 @@ impl TestContext { relayer: self.relayer.clone(), native_token: self.native_token.clone(), xcall_address: self.xcall.clone(), + upgrade_authority: self.upgrade_authority.clone(), }); } @@ -66,6 +69,7 @@ fn get_dummy_initialize_msg(env: &Env) -> InitializeMsg { relayer: Address::generate(&env), native_token: env.register_stellar_asset_contract(Address::generate(&env)), xcall_address: Address::generate(&env), + upgrade_authority: Address::generate(&env), } } @@ -143,6 +147,34 @@ fn test_set_admin_fail() { ) } +#[test] +fn test_set_upgrade_authority() { + let ctx = TestContext::default(); + let client = CentralizedConnectionClient::new(&ctx.env, &ctx.contract); + ctx.init_context(&client); + + let new_upgrade_authority = Address::generate(&ctx.env); + client.set_upgrade_authority(&new_upgrade_authority); + + assert_eq!( + ctx.env.auths(), + std::vec![( + ctx.upgrade_authority.clone(), + AuthorizedInvocation { + function: AuthorizedFunction::Contract(( + ctx.contract.clone(), + Symbol::new(&ctx.env, "set_upgrade_authority"), + (&new_upgrade_authority,).into_val(&ctx.env) + )), + sub_invocations: std::vec![] + } + )] + ); + + let autorhity = client.get_upgrade_authority(); + assert_eq!(autorhity, new_upgrade_authority); +} + #[test] fn test_set_fee() { let ctx = TestContext::default(); diff --git a/contracts/soroban/contracts/centralized-connection/src/types.rs b/contracts/soroban/contracts/centralized-connection/src/types.rs index fb275b75..e3f08bdb 100644 --- a/contracts/soroban/contracts/centralized-connection/src/types.rs +++ b/contracts/soroban/contracts/centralized-connection/src/types.rs @@ -5,6 +5,7 @@ use soroban_sdk::{contracttype, Address, String}; pub enum StorageKey { Xcall, Admin, + UpgradeAuthority, Xlm, ConnSn, NetworkFee(String), @@ -16,6 +17,7 @@ pub struct InitializeMsg { pub relayer: Address, pub native_token: Address, pub xcall_address: Address, + pub upgrade_authority: Address, } #[contracttype] diff --git a/contracts/soroban/contracts/xcall/src/contract.rs b/contracts/soroban/contracts/xcall/src/contract.rs index 49ab319b..47c2eec9 100644 --- a/contracts/soroban/contracts/xcall/src/contract.rs +++ b/contracts/soroban/contracts/xcall/src/contract.rs @@ -17,6 +17,7 @@ impl Xcall { storage::store_admin(&env, &msg.sender); storage::store_fee_handler(&env, &msg.sender); + storage::store_upgrade_authority(&env, &msg.upgrade_authority); storage::store_config( &env, Config { @@ -35,6 +36,13 @@ impl Xcall { Ok(()) } + pub fn set_upgrade_authority(env: &Env, address: Address) -> Result<(), ContractError> { + helpers::ensure_upgrade_authority(&env)?; + storage::store_upgrade_authority(&env, &address); + + Ok(()) + } + pub fn set_protocol_fee(env: &Env, fee: u128) -> Result<(), ContractError> { helpers::ensure_admin(&env)?; storage::store_protocol_fee(&env, fee); @@ -101,6 +109,11 @@ impl Xcall { Ok(admin) } + pub fn get_upgrade_authority(env: Env) -> Result { + let address = storage::get_upgrade_authority(&env)?; + Ok(address) + } + pub fn get_network_address(env: Env) -> Result