diff --git a/dao/src/bid_escrow/contract.rs b/dao/src/bid_escrow/contract.rs index 6f323e97..969b8dd7 100644 --- a/dao/src/bid_escrow/contract.rs +++ b/dao/src/bid_escrow/contract.rs @@ -408,6 +408,14 @@ impl BidEscrowContract { to self.access_control { /// Changes the ownership of the contract. Transfers ownership to the `owner`. /// Only the current owner is permitted to call this method. + /// [`Read more`](AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); + + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// [`Read more`](AccessControl::accept_new_owner()) + pub fn accept_new_owner(&mut self); + + /// Changes the ownership of the contract to the new address. /// [`Read more`](AccessControl::change_ownership()) pub fn change_ownership(&mut self, owner: Address); diff --git a/dao/src/core_contracts/dao_nft.rs b/dao/src/core_contracts/dao_nft.rs index f40210db..1e07f4ac 100644 --- a/dao/src/core_contracts/dao_nft.rs +++ b/dao/src/core_contracts/dao_nft.rs @@ -35,6 +35,12 @@ impl DaoNft { to self.access_control { /// Changes the ownership of the contract. Transfers ownership to the `owner`. /// Only the current owner is permitted to call this method. + /// [`Read more`](AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// [`Read more`](AccessControl::accept_new_owner()) + pub fn accept_new_owner(&mut self); + /// Changes the ownership of the contract to the new address. /// [`Read more`](AccessControl::change_ownership()) pub fn change_ownership(&mut self, owner: Address); /// Adds a new address to the whitelist. diff --git a/dao/src/core_contracts/kyc_ntf.rs b/dao/src/core_contracts/kyc_ntf.rs index a5392dad..8dfbec4a 100644 --- a/dao/src/core_contracts/kyc_ntf.rs +++ b/dao/src/core_contracts/kyc_ntf.rs @@ -37,6 +37,15 @@ impl KycNftContract { delegate! { to self.token { + /// Changes the ownership of the contract. Transfers ownership to the `owner`. + /// Only the current owner is permitted to call this method. + /// [`Read more`](crate::modules::access_control::AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// [`Read more`](crate::modules::access_control::AccessControl::accept_new_owner()) + pub fn accept_new_owner(&mut self); + /// Changes the ownership of the contract to the new address. + /// [`Read more`](AccessControl::change_ownership()) pub fn change_ownership(&mut self, owner: Address); /// Adds a new address to the whitelist. pub fn add_to_whitelist(&mut self, address: Address); diff --git a/dao/src/core_contracts/reputation/token.rs b/dao/src/core_contracts/reputation/token.rs index 4688bc50..7e538eaf 100644 --- a/dao/src/core_contracts/reputation/token.rs +++ b/dao/src/core_contracts/reputation/token.rs @@ -34,7 +34,13 @@ impl ReputationContract { /// Changes ownership of the contract. Transfer the ownership to the `owner`. Only the current owner /// is permitted to call this method. /// - /// See [AccessControl](AccessControl::change_ownership()) + /// See [AccessControl](AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// See [AccessControl](AccessControl::accept_new_owner()) + pub fn accept_new_owner(&mut self); + /// Changes the ownership of the contract to the new address. + /// [`Read more`](AccessControl::change_ownership()) pub fn change_ownership(&mut self, owner: Address); /// Adds a new address to the whitelist. /// diff --git a/dao/src/core_contracts/va_nft.rs b/dao/src/core_contracts/va_nft.rs index 93b79302..05545669 100644 --- a/dao/src/core_contracts/va_nft.rs +++ b/dao/src/core_contracts/va_nft.rs @@ -39,7 +39,13 @@ impl VaNftContract { to self.token { /// Changes the ownership of the contract. Transfers ownership to the `owner`. /// Only the current owner is permitted to call this method. - /// [`Read more`](crate::modules::access_control::AccessControl::change_ownership()) + /// [`Read more`](crate::modules::access_control::AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// [`Read more`](crate::modules::access_control::AccessControl::accept_new_owner()) + pub fn accept_new_owner(&mut self); + /// Changes the ownership of the contract to the new address. + /// [`Read more`](AccessControl::change_ownership()) pub fn change_ownership(&mut self, owner: Address); /// Adds a new address to the whitelist. /// [`Read more`](crate::modules::access_control::AccessControl::add_to_whitelist()) diff --git a/dao/src/core_contracts/variable_repository.rs b/dao/src/core_contracts/variable_repository.rs index 972b6403..c8617498 100644 --- a/dao/src/core_contracts/variable_repository.rs +++ b/dao/src/core_contracts/variable_repository.rs @@ -61,6 +61,12 @@ impl VariableRepositoryContract { pub fn get_owner(&self) -> Option
; /// Changes the ownership of the contract. Transfers ownership to the `owner`. /// Only the current owner is permitted to call this method. + /// [`Read more`](AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// [`Read more`](AccessControl::accept_new_owner()) + pub fn accept_new_owner(&mut self); + /// Changes the ownership of the contract to the new address. /// [`Read more`](AccessControl::change_ownership()) pub fn change_ownership(&mut self, owner: Address); /// Adds a new address to the whitelist. diff --git a/dao/src/modules/access_control.rs b/dao/src/modules/access_control.rs index caf14266..2cd9d830 100644 --- a/dao/src/modules/access_control.rs +++ b/dao/src/modules/access_control.rs @@ -1,5 +1,6 @@ //! AccessControl module. use crate::modules::{Owner, Whitelist}; +use odra::contract_env::caller; use odra::types::Address; /// A AccessControl module storage definition. @@ -23,16 +24,37 @@ impl AccessControl { self.whitelist.add_to_whitelist(address); } - /// Changes ownership of the contract. Transfer the ownership to the `owner`. Only the current owner - /// is permited to call this method. + /// Proposes a change of ownership of the contract. Owner will be changed if accepted by propsed + /// new owner. Only the current owner is permited to call this method. /// /// # Errors /// Throws [`NotAnOwner`](crate::utils::Error::NotAnOwner) if caller /// is not the current owner. /// + pub fn propose_new_owner(&mut self, owner: Address) { + self.owner.ensure_owner(); + self.owner.propose_owner(owner); + } + + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// /// # Events /// Emits [`OwnerChanged`](crate::modules::owner::events::OwnerChanged), /// [`AddedToWhitelist`](crate::modules::whitelist::events::AddedToWhitelist) events. + pub fn accept_new_owner(&mut self) { + let caller = caller(); + self.owner.accept_owner(caller); + self.whitelist.add_to_whitelist(caller); + } + + /// Changes the ownership of the contract to the new address. + /// + /// # Events + /// Emits [`OwnerChanged`](crate::modules::owner::events::OwnerChanged) event. + /// + /// # Errors + /// Throws [`NotAnOwner`](crate::utils::Error::NotAnOwner) if caller + /// is not the current owner. pub fn change_ownership(&mut self, owner: Address) { self.owner.ensure_owner(); self.owner.change_ownership(owner); diff --git a/dao/src/modules/owner.rs b/dao/src/modules/owner.rs index 91047d95..d749e4a4 100644 --- a/dao/src/modules/owner.rs +++ b/dao/src/modules/owner.rs @@ -9,6 +9,7 @@ use odra::Variable; #[odra::module] pub struct Owner { pub owner: Variable
, + pub proposed_owner: Variable>, } /// Module entrypoints implementation. @@ -20,9 +21,27 @@ impl Owner { self.change_ownership(owner); } + /// Sets a new owner proposition. + pub fn propose_owner(&mut self, owner: Address) { + self.proposed_owner.set(Some(owner)); + } + + /// Accepts the new owner proposition. + pub fn accept_owner(&mut self, caller: Address) { + if let Some(proposed_owner) = self.proposed_owner.get_or_default() { + if proposed_owner != caller { + revert(Error::NotAProposedOwner); + } + self.change_ownership(proposed_owner); + } else { + revert(Error::NoProposedOwner); + } + } + /// Set the owner to the new address. pub fn change_ownership(&mut self, owner: Address) { self.owner.set(owner); + self.proposed_owner.set(None); OwnerChanged { new_owner: owner }.emit(); } diff --git a/dao/src/utils/errors.rs b/dao/src/utils/errors.rs index 9129b1e2..31aa0f80 100644 --- a/dao/src/utils/errors.rs +++ b/dao/src/utils/errors.rs @@ -69,6 +69,8 @@ execution_error! { OnboardingRequestNotFound => 3416, OnboardingConfigurationNotFound => 3417, AttachedValueMismatch => 3418, + NotAProposedOwner => 3419, + NoProposedOwner => 3420, // Bid Escrow Errors. CannotPostJobForSelf => 4000, diff --git a/dao/src/utils_contracts/ids.rs b/dao/src/utils_contracts/ids.rs index 01cfcd2a..38e39655 100644 --- a/dao/src/utils_contracts/ids.rs +++ b/dao/src/utils_contracts/ids.rs @@ -23,8 +23,8 @@ impl DaoIdsContract { /// Changes the ownership of the contract. Transfers the ownership to the `owner`. /// Only the current owner is permitted to call this method. /// - /// [`Read more`](AccessControl::change_ownership()) - pub fn change_ownership(&mut self, owner: Address); + /// [`Read more`](AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); /// Adds a new address to the whitelist. /// /// [`Read more`](AccessControl::add_to_whitelist()) diff --git a/dao/src/voting_contracts/admin.rs b/dao/src/voting_contracts/admin.rs index d83bead8..e449a838 100644 --- a/dao/src/voting_contracts/admin.rs +++ b/dao/src/voting_contracts/admin.rs @@ -46,6 +46,8 @@ impl AdminContract { } to self.access_control { + pub fn propose_new_owner(&mut self, owner: Address); + pub fn accept_new_owner(&mut self); pub fn change_ownership(&mut self, owner: Address); pub fn add_to_whitelist(&mut self, address: Address); pub fn remove_from_whitelist(&mut self, address: Address); @@ -173,7 +175,8 @@ impl AdminVotingCreated { pub enum Action { AddToWhitelist, RemoveFromWhitelist, - ChangeOwner, + ChangeOwnership, + ProposeNewOwner, } impl Action { @@ -181,7 +184,8 @@ impl Action { match self { Action::AddToWhitelist => "add_to_whitelist", Action::RemoveFromWhitelist => "remove_from_whitelist", - Action::ChangeOwner => "change_ownership", + Action::ChangeOwnership => "change_ownership", + Action::ProposeNewOwner => "propose_new_owner", } .to_string() } @@ -190,7 +194,8 @@ impl Action { match self { Action::AddToWhitelist => "address", Action::RemoveFromWhitelist => "address", - Action::ChangeOwner => "owner", + Action::ChangeOwnership => "owner", + Action::ProposeNewOwner => "owner", } } } diff --git a/dao/src/voting_contracts/kyc_voter.rs b/dao/src/voting_contracts/kyc_voter.rs index 6652f8e6..8bb2e3e6 100644 --- a/dao/src/voting_contracts/kyc_voter.rs +++ b/dao/src/voting_contracts/kyc_voter.rs @@ -70,6 +70,8 @@ impl KycVoterContract { } to self.access_control { + pub fn propose_new_owner(&mut self, owner: Address); + pub fn accept_new_owner(&mut self); pub fn change_ownership(&mut self, owner: Address); pub fn add_to_whitelist(&mut self, address: Address); pub fn remove_from_whitelist(&mut self, address: Address); diff --git a/dao/src/voting_contracts/onboarding_request.rs b/dao/src/voting_contracts/onboarding_request.rs index 6ca2ad01..c9cf5907 100644 --- a/dao/src/voting_contracts/onboarding_request.rs +++ b/dao/src/voting_contracts/onboarding_request.rs @@ -75,6 +75,12 @@ impl OnboardingRequestContract { to self.access_control { /// Changes the ownership of the contract. Transfers ownership to the `owner`. /// Only the current owner is permitted to call this method. + /// [`Read more`](AccessControl::propose_new_owner()) + pub fn propose_new_owner(&mut self, owner: Address); + /// Accepts the new owner proposition. This can be called only by the proposed owner. + /// [`Read more`](AccessControl::accept_new_owner()) + pub fn accept_new_owner(&mut self); + /// Changes the ownership of the contract. Transfers ownership to the `owner`. /// [`Read more`](AccessControl::change_ownership()) pub fn change_ownership(&mut self, owner: Address); /// Adds a new address to the whitelist. diff --git a/dao/src/voting_contracts/repo_voter.rs b/dao/src/voting_contracts/repo_voter.rs index 9d7b67eb..30d08c78 100644 --- a/dao/src/voting_contracts/repo_voter.rs +++ b/dao/src/voting_contracts/repo_voter.rs @@ -59,6 +59,8 @@ impl RepoVoterContract { } to self.access_control { + pub fn propose_new_owner(&mut self, owner: Address); + pub fn accept_new_owner(&mut self); pub fn change_ownership(&mut self, owner: Address); pub fn add_to_whitelist(&mut self, address: Address); pub fn remove_from_whitelist(&mut self, address: Address); diff --git a/dao/src/voting_contracts/reputation_voter.rs b/dao/src/voting_contracts/reputation_voter.rs index 0db07047..8529271f 100644 --- a/dao/src/voting_contracts/reputation_voter.rs +++ b/dao/src/voting_contracts/reputation_voter.rs @@ -63,6 +63,8 @@ impl ReputationVoterContract { } to self.access_control { + pub fn propose_new_owner(&mut self, owner: Address); + pub fn accept_new_owner(&mut self); pub fn change_ownership(&mut self, owner: Address); pub fn add_to_whitelist(&mut self, address: Address); pub fn remove_from_whitelist(&mut self, address: Address); diff --git a/dao/src/voting_contracts/simple_voter.rs b/dao/src/voting_contracts/simple_voter.rs index 82c2905d..ae95818f 100644 --- a/dao/src/voting_contracts/simple_voter.rs +++ b/dao/src/voting_contracts/simple_voter.rs @@ -54,6 +54,8 @@ impl SimpleVoterContract { } to self.access_control { + pub fn propose_new_owner(&mut self, owner: Address); + pub fn accept_new_owner(&mut self); pub fn change_ownership(&mut self, owner: Address); pub fn add_to_whitelist(&mut self, address: Address); pub fn remove_from_whitelist(&mut self, address: Address); diff --git a/dao/src/voting_contracts/slashing_voter.rs b/dao/src/voting_contracts/slashing_voter.rs index b8cca8ee..e0df478a 100644 --- a/dao/src/voting_contracts/slashing_voter.rs +++ b/dao/src/voting_contracts/slashing_voter.rs @@ -55,6 +55,8 @@ impl SlashingVoterContract { } to self.access_control { + pub fn propose_new_owner(&mut self, owner: Address); + pub fn accept_new_owner(&mut self); pub fn change_ownership(&mut self, owner: Address); pub fn add_to_whitelist(&mut self, address: Address); pub fn remove_from_whitelist(&mut self, address: Address); diff --git a/dao/tests/common/contracts/ownership.rs b/dao/tests/common/contracts/ownership.rs index d23e6c87..09d53aea 100644 --- a/dao/tests/common/contracts/ownership.rs +++ b/dao/tests/common/contracts/ownership.rs @@ -5,6 +5,8 @@ use crate::common::{params::Account, DaoWorld}; #[odra::external_contract] trait AccessControl { fn change_ownership(&mut self, owner: Address); + fn propose_new_owner(&mut self, owner: Address); + fn accept_new_owner(&mut self); fn is_whitelisted(&self, address: Address) -> bool; fn remove_from_whitelist(&mut self, address: Address); fn add_to_whitelist(&mut self, address: Address); @@ -39,11 +41,21 @@ impl DaoWorld { } pub fn change_ownership(&mut self, contract: &Account, caller: &Account, new_owner: &Account) { + let new_owner_address = self.get_address(new_owner); + let contract = self.get_address(contract); + self.set_caller(caller); + AccessControlRef::at(&contract).change_ownership(new_owner_address); + } + + pub fn propose_new_owner(&mut self, contract: &Account, new_owner: &Account) { let new_owner = self.get_address(new_owner); let contract = self.get_address(contract); + AccessControlRef::at(&contract).propose_new_owner(new_owner); + } - self.set_caller(caller); - AccessControlRef::at(&contract).change_ownership(new_owner); + pub fn accept_new_owner(&mut self, contract: &Account) { + let contract = self.get_address(contract); + AccessControlRef::at(&contract).accept_new_owner(); } pub fn is_whitelisted(&mut self, contract: &Account, account: &Account) -> bool { diff --git a/dao/tests/common/contracts/voting/builder.rs b/dao/tests/common/contracts/voting/builder.rs index 5c343a18..f86facaf 100644 --- a/dao/tests/common/contracts/voting/builder.rs +++ b/dao/tests/common/contracts/voting/builder.rs @@ -19,7 +19,7 @@ pub fn build(world: &DaoWorld, voting: Voting) -> VotingSetup { let action = match action.as_str() { "add_to_whitelist" => AdminAction::AddToWhitelist, "remove_from_whitelist" => AdminAction::RemoveFromWhitelist, - "change_ownership" => AdminAction::ChangeOwner, + "change_ownership" => AdminAction::ChangeOwnership, unknown => panic!("{:?} is not a valid action", unknown), }; diff --git a/dao/tests/features/voting/admin/admin_actions.feature b/dao/tests/features/voting/admin/admin_actions.feature index 576d4b0c..fa4ab684 100644 --- a/dao/tests/features/voting/admin/admin_actions.feature +++ b/dao/tests/features/voting/admin/admin_actions.feature @@ -10,8 +10,8 @@ Background: | VA2 | true | 1000 | | | VA3 | true | 1000 | | And Admin is the owner of all contracts - Then Alice is not whitelisted in ReputationToken contract - And Bob is whitelisted in ReputationToken contract + Then Alice is not whitelisted in ReputationToken contract + And Bob is whitelisted in ReputationToken contract And Bob is not the owner of ReputationToken contract Scenario Outline: Voting passed, action applied diff --git a/dao/tests/steps/ownership.rs b/dao/tests/steps/ownership.rs index 414cf3b7..c78559ea 100644 --- a/dao/tests/steps/ownership.rs +++ b/dao/tests/steps/ownership.rs @@ -43,6 +43,15 @@ fn assert_ownership(world: &mut DaoWorld, user: Account, contract: Account) { assert_eq!(owner, Some(user_address)); } +#[then(expr = "{account} is the proposed owner of {account} contract")] +fn assert_proposed_ownership(world: &mut DaoWorld, user: Account, contract: Account) { + let user_address = world.get_address(&user); + world.set_caller(&user); + world.accept_new_owner(&contract); + let owner = world.get_owner(&contract); + assert_eq!(owner, Some(user_address)); +} + #[then(expr = "{account} is not the owner of {account} contract")] fn assert_ne_ownership(world: &mut DaoWorld, user: Account, contract: Account) { let user_address = world.get_address(&user); diff --git a/resources/admin_contract_schema.json b/resources/admin_contract_schema.json index eba1e384..ac9b2639 100644 --- a/resources/admin_contract_schema.json +++ b/resources/admin_contract_schema.json @@ -173,6 +173,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/bid_escrow_contract_schema.json b/resources/bid_escrow_contract_schema.json index 23f9d7d1..28119447 100644 --- a/resources/bid_escrow_contract_schema.json +++ b/resources/bid_escrow_contract_schema.json @@ -359,6 +359,23 @@ "Option": "Any" } }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/dao_ids_contract_schema.json b/resources/dao_ids_contract_schema.json index 911e82d1..8713028e 100644 --- a/resources/dao_ids_contract_schema.json +++ b/resources/dao_ids_contract_schema.json @@ -14,7 +14,7 @@ "return_ty": "U32" }, { - "name": "change_ownership", + "name": "propose_new_owner", "is_mutable": true, "args": [ { diff --git a/resources/kyc_nft_contract_schema.json b/resources/kyc_nft_contract_schema.json index 8e278f70..7b2daa8f 100644 --- a/resources/kyc_nft_contract_schema.json +++ b/resources/kyc_nft_contract_schema.json @@ -20,6 +20,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/kyc_voter_contract_schema.json b/resources/kyc_voter_contract_schema.json index a6595949..acd9d594 100644 --- a/resources/kyc_voter_contract_schema.json +++ b/resources/kyc_voter_contract_schema.json @@ -173,6 +173,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/onboarding_request_contract_schema.json b/resources/onboarding_request_contract_schema.json index b3f00422..a317fa35 100644 --- a/resources/onboarding_request_contract_schema.json +++ b/resources/onboarding_request_contract_schema.json @@ -133,6 +133,23 @@ "Option": "Any" } }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/repo_voter_contract_schema.json b/resources/repo_voter_contract_schema.json index 7ab7574e..45ebe383 100644 --- a/resources/repo_voter_contract_schema.json +++ b/resources/repo_voter_contract_schema.json @@ -181,6 +181,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/reputation_contract_schema.json b/resources/reputation_contract_schema.json index 6da0e8fc..fa8fddad 100644 --- a/resources/reputation_contract_schema.json +++ b/resources/reputation_contract_schema.json @@ -48,6 +48,23 @@ ], "return_ty": "U512" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/reputation_voter_contract_schema.json b/resources/reputation_voter_contract_schema.json index 2cb9d531..6329807f 100644 --- a/resources/reputation_voter_contract_schema.json +++ b/resources/reputation_voter_contract_schema.json @@ -177,6 +177,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/simple_voter_contract_schema.json b/resources/simple_voter_contract_schema.json index 4e7a9adc..20aafeca 100644 --- a/resources/simple_voter_contract_schema.json +++ b/resources/simple_voter_contract_schema.json @@ -178,6 +178,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/slashing_voter_contract_schema.json b/resources/slashing_voter_contract_schema.json index da0d36b4..f11af532 100644 --- a/resources/slashing_voter_contract_schema.json +++ b/resources/slashing_voter_contract_schema.json @@ -182,6 +182,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/va_nft_contract_schema.json b/resources/va_nft_contract_schema.json index c5e25917..cb15376f 100644 --- a/resources/va_nft_contract_schema.json +++ b/resources/va_nft_contract_schema.json @@ -20,6 +20,23 @@ ], "return_ty": "Unit" }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true, diff --git a/resources/variable_repository_contract_schema.json b/resources/variable_repository_contract_schema.json index a678a2fc..2a83120d 100644 --- a/resources/variable_repository_contract_schema.json +++ b/resources/variable_repository_contract_schema.json @@ -122,6 +122,23 @@ "Option": "Key" } }, + { + "name": "propose_new_owner", + "is_mutable": true, + "args": [ + { + "name": "owner", + "ty": "Key" + } + ], + "return_ty": "Unit" + }, + { + "name": "accept_new_owner", + "is_mutable": true, + "args": [], + "return_ty": "Unit" + }, { "name": "change_ownership", "is_mutable": true,