governance::permissions
Module 0xc0ded0c1::permissions
0xc0ded0c1::permissions
module governance::permissions
governance::permissions
A module needing a governance can use this module to set up basic governance permissions, which we call Phase 0 of governance.
The workflow is as follows:
The deployer of the governance sets up a new package with a
GovernanceType
struct.The deployer of
GovernanceType
deploys the module needing governance usingdeploy
<GovernanceType>()
. This step can be skipped if governance does not control upgradability of the contract code, but only parameters of the protocol.During initialization of the contract needing governance,
initialize_permissions
is called to set up permissions.Any method in the contract needing governance that should be under governance must use
assert_authority
<GovernanceType>()
.The deployer of
GovernanceType
can initialize full fledged governance, which we call Phase 1 of governance, at any point.Phase 1 governance can vote to revoke deployer permission. This uses
revoke_deployer_authorization_privilege
()
.After revocation of deployer permission, governance is in full control.
The governance can use
create_signer_for_proposal_resolution
()
to resolve successful proposals.
Note: Once the control of the contract is fully transferred to governance, it is not possible to return it to the deployer.
use 0x1::account;
use 0x1::code;
use 0x1::error;
use 0x1::signer;
use 0xc0ded0c1::utils;
Resource AuthorizationCapability
AuthorizationCapability
When a governance proposal passes, this signer capability is used to create a signer
which can execute the proposal in the main_contract
which is under governance.
struct AuthorizationCapability<GovernanceType> has key
Resource DeployerPermission
DeployerPermission
Keeps track of deployer's permission.
struct DeployerPermission<GovernanceType> has key
Resource Admins
Admins
struct Admins<GovernanceType> has key
Constants
When the petitioner is not authorized to perform an action.
const EPERMISSION_DENIED: u64 = 1;
When the governance has already been initialized.
const EALREADY_INITIALIZED: u64 = 4;
When the deployer attempts to revoke their own deployer permission.
const EDEPLOYER_REVOKE_NOT_ALLOWED: u64 = 2;
When the deployer is not authorized to perform an action.
const EDEPLOYER_UNAUTHORIZED: u64 = 0;
When the governance has not been initialized.
const EPERMISSIONS_NOT_INITIALIZED: u64 = 3;
Random seed generated using aptos-crypto crate. This is used in creating new signer capabilities.
const RANDOM_SEED: vector<u8> = [16, 255, 222, 172, 207, 31, 104, 153, 235, 236, 70, 179, 127, 42, 232, 183, 157, 58, 223, 63, 36, 34, 133, 8, 219, 195, 166, 178, 84, 108, 90, 247];
Function is_deployer_authorized
is_deployer_authorized
Returns whether governance deployer's permissions are still valid
public fun is_deployer_authorized<GovernanceType>(): bool
Function initialize_permissions
initialize_permissions
Initializes the permissions for governance and deployer
.
Phase 0 initialization must happen when the main contract needing governance is initialized, otherwise, none of the permissioned methods would work in the main contract.
public fun initialize_permissions<GovernanceType>(deployer: &signer)
Function assert_initialization
assert_initialization
Assert if permissions have been initialized.
Abort conditions
If the permissions have not been initialized.
public fun assert_initialization<GovernanceType>()
Function assert_deploy_authority
assert_deploy_authority
Assert if the petitioner
has the deploy authority. Checked upon deploy or fallback for admin.
Abort conditions
If the
petitioner
is not authorized to perform the action.
public fun assert_deploy_authority<GovernanceType>(petitioner: &signer)
Function assert_authority
assert_authority
Assert if the petitioner
has the authority to perform an action.
All methods in the main contract which need governance permissions must call this method. The main contract's methods that are not under the control of governance should not use this method.
Abort conditions
If the
petitioner
is not authorized to perform the action.
public fun assert_authority<GovernanceType>(petitioner: &signer)
Function create_signer_for_an_upgrade_or_deploy
create_signer_for_an_upgrade_or_deploy
Creates a signer
for the deployer
which can be used to perform actions on the main contract.
Abort conditions
If the
deployer
is not authorized to perform the action.
public fun create_signer_for_an_upgrade_or_deploy<GovernanceType>(deployer: &signer): signer
Function revoke_deployer_authorization_privilege
revoke_deployer_authorization_privilege
Revokes the deployer's permission to perform actions on the main.
The governance of type GovernanceType
can permanently revoke GovernanceType
's deployer's authorization privileges This cannot be reversed, so it should only be called via a successful governance proposal.
Abort conditions
If the
dao
is not authorized to perform the action.If the
dao
signer is the same as the governance deployer.
public fun revoke_deployer_authorization_privilege<GovernanceType>(dao: &signer)
Function initialize
initialize
Creates a resource account derived from the deployer
, gives the deployer
the AuthorizationCapability
to create a signer for running authorized actions on the contract and the DeployerPermission
which tracks the permissions the deployer has.
Upon initialization, the deployer
is authorized to perform all actions on the contract, and can also upgrade the contract code.
public fun initialize<GovernanceType>(deployer: &signer)
Function deploy
deploy
The governance can deploy the code using this method, which will enable governance to control upgradability of the code.
public fun deploy<GovernanceType>(deployer: &signer, metadata_serialized: vector<u8>, code: vector<vector<u8>>)
Function set_admin
set_admin
set the admin for the governance
public fun set_admin<GovernanceType>(auth_signer: &signer, new_admin: address)
Function assert_governance_permission
assert_governance_permission
Assert if the deployer_address
is the same as the governance_address()
.
Abort conditions
If the
deployer_address
is not the governance address.
fun assert_governance_permission<GovernanceType>(deployer_address: address)
Function create_signer_for_proposal_resolution
create_signer_for_proposal_resolution
This function creates a signer
in order to resolve a governance proposal.
public(friend) fun create_signer_for_proposal_resolution<GovernanceType>(): signer
Last updated