starcoin-framework

Module 0x1::OnChainConfigDao

OnChainConfigDao is a DAO proposal for modify onchain configuration.

use 0x1::Config;
use 0x1::Dao;
use 0x1::Errors;
use 0x1::Signer;
use 0x1::Token;

Resource WrappedConfigModifyCapability

A wrapper of Config::ModifyConfigCapability<ConfigT>.

struct WrappedConfigModifyCapability<TokenT, ConfigT: copy, drop, store> has key
Fields
cap: Config::ModifyConfigCapability<ConfigT>

Struct OnChainConfigUpdate

request of updating configuration.

struct OnChainConfigUpdate<ConfigT: copy, drop, store> has copy, drop, store
Fields
value: ConfigT

Constants

const ERR_NOT_AUTHORIZED: u64 = 401;

Function plugin

Plugin method of the module. Should be called by token issuer.

public fun plugin<TokenT: copy, drop, store, ConfigT: copy, drop, store>(signer: &signer)
Implementation
public fun plugin<TokenT: copy + drop + store, ConfigT: copy + drop + store>(signer: &signer) {
    let token_issuer = Token::token_address<TokenT>();
    assert!(Signer::address_of(signer) == token_issuer, Errors::requires_address(ERR_NOT_AUTHORIZED));
    let config_modify_cap = Config::extract_modify_config_capability<ConfigT>(signer);
    let cap = WrappedConfigModifyCapability<TokenT, ConfigT> { cap: config_modify_cap };
    move_to(signer, cap);
}
Specification
pragma aborts_if_is_partial = false;
let sender = Signer::address_of(signer);
aborts_if sender != Token::SPEC_TOKEN_TEST_ADDRESS();
include Config::AbortsIfCapNotExist<ConfigT>{account: sender};
aborts_if exists<WrappedConfigModifyCapability<TokenT, ConfigT>>(sender);
ensures exists<WrappedConfigModifyCapability<TokenT, ConfigT>>(sender);

Function propose_update

issue a proposal to update config of ConfigT goved by TokenT

public fun propose_update<TokenT: copy, drop, store, ConfigT: copy, drop, store>(signer: &signer, new_config: ConfigT, exec_delay: u64)
Implementation
public fun propose_update<TokenT: copy + drop + store, ConfigT: copy + drop + store>(
    signer: &signer,
    new_config: ConfigT,
    exec_delay: u64,
) {
    Dao::propose<TokenT, OnChainConfigUpdate<ConfigT>>(
        signer,
        OnChainConfigUpdate { value: new_config },
        exec_delay,
    );
}
Specification
pragma aborts_if_is_partial = false;
include Dao::AbortIfDaoConfigNotExist<TokenT>;
include Dao::AbortIfDaoInfoNotExist<TokenT>;
aborts_if !exists<Timestamp::CurrentTimeMilliseconds>(CoreAddresses::SPEC_GENESIS_ADDRESS());
aborts_if exec_delay > 0 && exec_delay < Dao::spec_dao_config<TokenT>().min_action_delay;
include Dao::CheckQuorumVotes<TokenT>;
let sender = Signer::address_of(signer);
aborts_if exists<Dao::Proposal<TokenT, OnChainConfigUpdate<ConfigT>>>(sender);

Function execute

Once the proposal is agreed, anyone can call the method to make the proposal happen. Caller need to make sure that the proposal of proposal_id under proposal_address is the kind of this proposal module.

public fun execute<TokenT: copy, drop, store, ConfigT: copy, drop, store>(proposer_address: address, proposal_id: u64)
Implementation
public fun execute<TokenT: copy + drop + store, ConfigT: copy + drop + store>(
    proposer_address: address,
    proposal_id: u64,
) acquires WrappedConfigModifyCapability {
    let OnChainConfigUpdate { value } = Dao::extract_proposal_action<
        TokenT,
        OnChainConfigUpdate<ConfigT>,
    >(proposer_address, proposal_id);
    let cap = borrow_global_mut<WrappedConfigModifyCapability<TokenT, ConfigT>>(
        Token::token_address<TokenT>(),
    );
    Config::set_with_capability(&mut cap.cap, value);
}
Specification
pragma aborts_if_is_partial = true;
let expected_states = vec<u8>(6);
include Dao::CheckProposalStates<TokenT, OnChainConfigUpdate<ConfigT>>{expected_states};
aborts_if !exists<WrappedConfigModifyCapability<TokenT, ConfigT>>(Token::SPEC_TOKEN_TEST_ADDRESS());

Module Specification

pragma verify = false;
pragma aborts_if_is_strict;
pragma aborts_if_is_partial;