diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index d3cb8f47..a5ea5bc1 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -3,6 +3,7 @@ on: pull_request: branches: - main + - genesis_dao jobs: build-and-test: diff --git a/build/StarcoinFramework/BuildInfo.yaml b/build/StarcoinFramework/BuildInfo.yaml index 9c75150e..42d78ef9 100644 --- a/build/StarcoinFramework/BuildInfo.yaml +++ b/build/StarcoinFramework/BuildInfo.yaml @@ -45,6 +45,9 @@ compiled_package_info: ? address: "0x00000000000000000000000000000001" name: Config : StarcoinFramework + ? address: "0x00000000000000000000000000000001" + name: ConfigProposalPlugin + : StarcoinFramework ? address: "0x00000000000000000000000000000001" name: ConsensusConfig : StarcoinFramework @@ -207,6 +210,9 @@ compiled_package_info: ? address: "0x00000000000000000000000000000001" name: STCUSDOracle : StarcoinFramework + ? address: "0x00000000000000000000000000000001" + name: SalaryGovPlugin + : StarcoinFramework ? address: "0x00000000000000000000000000000001" name: SharedEd25519PublicKey : StarcoinFramework @@ -291,7 +297,7 @@ compiled_package_info: ? address: "0x00000000000000000000000000000001" name: YieldFarmingV2 : StarcoinFramework - source_digest: 37973FE3F7BCD58FFE2521CE3319C0ED239522F2B0DDE5A5F32751C9C324DFF2 + source_digest: 7F51997501DC9F3AFC1EA8C06C8025E33EA666DF2E3F15C374AF7C7555F061D5 build_flags: dev_mode: false test_mode: false diff --git a/build/StarcoinFramework/bytecode_modules/DaoAccount.mv b/build/StarcoinFramework/bytecode_modules/DaoAccount.mv index 5c9c0f46..12f1b495 100644 Binary files a/build/StarcoinFramework/bytecode_modules/DaoAccount.mv and b/build/StarcoinFramework/bytecode_modules/DaoAccount.mv differ diff --git a/build/StarcoinFramework/bytecode_modules/GenesisDao.mv b/build/StarcoinFramework/bytecode_modules/GenesisDao.mv index 74ed0653..77fcdc3b 100644 Binary files a/build/StarcoinFramework/bytecode_modules/GenesisDao.mv and b/build/StarcoinFramework/bytecode_modules/GenesisDao.mv differ diff --git a/build/StarcoinFramework/docs/DaoAccount.md b/build/StarcoinFramework/docs/DaoAccount.md index 98cdef61..e0e96aed 100644 --- a/build/StarcoinFramework/docs/DaoAccount.md +++ b/build/StarcoinFramework/docs/DaoAccount.md @@ -11,7 +11,9 @@ - [Function `create_account`](#0x1_DaoAccount_create_account) - [Function `create_account_entry`](#0x1_DaoAccount_create_account_entry) - [Function `extract_dao_account_cap`](#0x1_DaoAccount_extract_dao_account_cap) +- [Function `restore_dao_account_cap`](#0x1_DaoAccount_restore_dao_account_cap) - [Function `upgrade_to_dao`](#0x1_DaoAccount_upgrade_to_dao) +- [Function `upgrade_to_dao_with_signer_cap`](#0x1_DaoAccount_upgrade_to_dao_with_signer_cap) - [Function `dao_signer`](#0x1_DaoAccount_dao_signer) - [Function `submit_upgrade_plan`](#0x1_DaoAccount_submit_upgrade_plan) - [Function `submit_upgrade_plan_entry`](#0x1_DaoAccount_submit_upgrade_plan_entry) @@ -19,10 +21,12 @@
use 0x1::Account;
+use 0x1::Config;
use 0x1::Errors;
use 0x1::Option;
use 0x1::PackageTxnManager;
use 0x1::Signer;
+use 0x1::Version;
@@ -55,6 +59,12 @@ DaoAccount
upgrade_plan_cap: PackageTxnManager::UpgradePlanCapability
+creator
has the public fun create_account(creator: &signer): DaoAccountCap {
- let (dao_address, signer_cap) = Account::create_delegate_account(creator);
- let dao_signer = Account::create_signer_with_cap(&signer_cap);
-
- PackageTxnManager::update_module_upgrade_strategy(&dao_signer, PackageTxnManager::get_strategy_two_phase(), Option::some(0));
- move_to(&dao_signer, DaoAccount{
- dao_address,
- signer_cap: signer_cap,
- });
- DaoAccountCap{
- dao_address
- }
+ let (_dao_address, signer_cap) = Account::create_delegate_account(creator);
+ upgrade_to_dao_with_signer_cap(signer_cap)
}
@@ -169,6 +170,7 @@ Entry function for create dao account, the extract_dao_account_cap(sender: &signer): DaoAccount::DaoAccountCap
@@ -189,6 +191,31 @@ Entry function for create dao account, the
+
+## Function `restore_dao_account_cap`
+
+Restore the DaoAccountCap to the sender
+
+
+public fun restore_dao_account_cap(sender: &signer, cap: DaoAccount::DaoAccountCap)
+
+
+
+
+
+Implementation
+
+
+public fun restore_dao_account_cap(sender: &signer, cap: DaoAccountCap) {
+ move_to(sender, cap)
+}
+
+
+
+
@@ -208,16 +235,49 @@ Upgrade sender
account to Dao account
public fun upgrade_to_dao(sender: signer): DaoAccountCap {
- //TODO assert sender not Dao
let signer_cap = Account::remove_signer_capability(&sender);
- //TODO check the account upgrade_strategy
- PackageTxnManager::update_module_upgrade_strategy(&sender, PackageTxnManager::get_strategy_two_phase(), Option::some(0));
- let dao_address = Signer::address_of(&sender);
- move_to(&sender, DaoAccount{
+ upgrade_to_dao_with_signer_cap(signer_cap)
+}
+
+
+
+
+
+
+
+
+## Function `upgrade_to_dao_with_signer_cap`
+
+Upgrade the account which have the signer_cap
to a Dao Account
+
+
+public fun upgrade_to_dao_with_signer_cap(signer_cap: Account::SignerCapability): DaoAccount::DaoAccountCap
+
+
+
+
+
+Implementation
+
+
+public fun upgrade_to_dao_with_signer_cap(signer_cap: SignerCapability): DaoAccountCap {
+ let dao_signer = Account::create_signer_with_cap(&signer_cap);
+ let dao_address = Signer::address_of(&dao_signer);
+
+ let upgrade_plan_cap = if(Config::config_exist_by_address<Version::Version>(dao_address)){
+ //TODO if the account has extract the upgrade plan cap
+ PackageTxnManager::extract_submit_upgrade_plan_cap(&dao_signer)
+ }else{
+ Config::publish_new_config<Version::Version>(&dao_signer, Version::new_version(1));
+ PackageTxnManager::update_module_upgrade_strategy(&dao_signer, PackageTxnManager::get_strategy_two_phase(), Option::some(1));
+ PackageTxnManager::extract_submit_upgrade_plan_cap(&dao_signer)
+ };
+ move_to(&dao_signer, DaoAccount{
dao_address,
- signer_cap: signer_cap,
+ signer_cap,
+ upgrade_plan_cap,
});
- DaoAccountCap{
+ DaoAccountCap{
dao_address
}
}
@@ -271,8 +331,8 @@ This function is a shortcut for create signer with DaoAccountCap and invoke public fun submit_upgrade_plan(cap: &DaoAccountCap, package_hash: vector<u8>, version:u64, enforced: bool) acquires DaoAccount{
- let dao_signer = dao_signer(cap);
- PackageTxnManager::submit_upgrade_plan_v2(&dao_signer, package_hash, version, enforced);
+ let upgrade_plan_cap = &borrow_global<DaoAccount>(cap.dao_address).upgrade_plan_cap;
+ PackageTxnManager::submit_upgrade_plan_with_cap_v2(upgrade_plan_cap, package_hash, version, enforced);
}
diff --git a/build/StarcoinFramework/docs/GenesisDao.md b/build/StarcoinFramework/docs/GenesisDao.md
index f4b4a59f..6a274960 100644
--- a/build/StarcoinFramework/docs/GenesisDao.md
+++ b/build/StarcoinFramework/docs/GenesisDao.md
@@ -8,6 +8,7 @@
- [Resource `Dao`](#0x1_GenesisDao_Dao)
- [Resource `DaoExt`](#0x1_GenesisDao_DaoExt)
- [Struct `DaoConfig`](#0x1_GenesisDao_DaoConfig)
+- [Struct `DaoCustomConfig`](#0x1_GenesisDao_DaoCustomConfig)
- [Resource `DaoAccountCapHolder`](#0x1_GenesisDao_DaoAccountCapHolder)
- [Resource `DaoTokenMintCapHolder`](#0x1_GenesisDao_DaoTokenMintCapHolder)
- [Resource `DaoTokenBurnCapHolder`](#0x1_GenesisDao_DaoTokenBurnCapHolder)
@@ -15,6 +16,7 @@
- [Resource `DaoNFTBurnCapHolder`](#0x1_GenesisDao_DaoNFTBurnCapHolder)
- [Resource `DaoNFTUpdateCapHolder`](#0x1_GenesisDao_DaoNFTUpdateCapHolder)
- [Resource `DaoConfigModifyCapHolder`](#0x1_GenesisDao_DaoConfigModifyCapHolder)
+- [Resource `DaoCustomConfigModifyCapHolder`](#0x1_GenesisDao_DaoCustomConfigModifyCapHolder)
- [Struct `CapType`](#0x1_GenesisDao_CapType)
- [Struct `DaoRootCap`](#0x1_GenesisDao_DaoRootCap)
- [Struct `DaoInstallPluginCap`](#0x1_GenesisDao_DaoInstallPluginCap)
@@ -65,6 +67,7 @@
- [Function `do_remove_member`](#0x1_GenesisDao_do_remove_member)
- [Function `increase_member_sbt`](#0x1_GenesisDao_increase_member_sbt)
- [Function `decrease_member_sbt`](#0x1_GenesisDao_decrease_member_sbt)
+- [Function `query_sbt`](#0x1_GenesisDao_query_sbt)
- [Function `is_member`](#0x1_GenesisDao_is_member)
- [Function `validate_cap`](#0x1_GenesisDao_validate_cap)
- [Function `acquire_install_plugin_cap`](#0x1_GenesisDao_acquire_install_plugin_cap)
@@ -104,6 +107,7 @@
- [Function `min_proposal_deposit`](#0x1_GenesisDao_min_proposal_deposit)
- [Function `get_config`](#0x1_GenesisDao_get_config)
- [Function `modify_dao_config`](#0x1_GenesisDao_modify_dao_config)
+- [Function `set_custom_config`](#0x1_GenesisDao_set_custom_config)
- [Function `set_voting_delay`](#0x1_GenesisDao_set_voting_delay)
- [Function `set_voting_period`](#0x1_GenesisDao_set_voting_period)
- [Function `set_voting_quorum_rate`](#0x1_GenesisDao_set_voting_quorum_rate)
@@ -260,6 +264,33 @@ Configuration of the DAO.
+
+
+
+
+## Struct `DaoCustomConfig`
+
+
+
+struct DaoCustomConfig<ConfigT> has copy, drop, store
+
+
+
+
+
+Fields
+
+
+
+-
+
config: ConfigT
+
+-
+
+
+
+
+
@@ -449,6 +480,33 @@ Configuration of the DAO.
+
+
+
+
+## Resource `DaoCustomConfigModifyCapHolder`
+
+
+
+struct DaoCustomConfigModifyCapHolder<DaoT, ConfigT: copy, drop, store> has key
+
+
+
+
+
+Fields
+
+
+
+-
+
cap: Config::ModifyConfigCapability<ConfigT>
+
+-
+
+
+
+
+
@@ -1440,7 +1498,7 @@ Creates a install plugin capability type.
Implementation
-public fun install_plugin_cap_type(): CapType { CapType{ code : 0 } }
+public fun install_plugin_cap_type(): CapType { CapType{ code: 0 } }
@@ -1463,7 +1521,7 @@ Creates a upgrade module capability type.
Implementation
-public fun upgrade_module_cap_type(): CapType { CapType{ code : 1 } }
+public fun upgrade_module_cap_type(): CapType { CapType{ code: 1 } }
@@ -1486,7 +1544,7 @@ Creates a modify dao config capability type.
Implementation
-public fun modify_config_cap_type(): CapType { CapType{ code : 2 } }
+public fun modify_config_cap_type(): CapType { CapType{ code: 2 } }
@@ -1509,7 +1567,7 @@ Creates a withdraw Token capability type.
Implementation
-public fun withdraw_token_cap_type(): CapType { CapType{ code : 3 } }
+public fun withdraw_token_cap_type(): CapType { CapType{ code: 3 } }
@@ -1532,7 +1590,7 @@ Creates a withdraw NFT capability type.
Implementation
-public fun withdraw_nft_cap_type(): CapType { CapType{ code : 4 } }
+public fun withdraw_nft_cap_type(): CapType { CapType{ code: 4 } }
@@ -1555,7 +1613,7 @@ Creates a write data to Dao account capability type.
Implementation
-public fun storage_cap_type(): CapType { CapType{ code : 5 } }
+public fun storage_cap_type(): CapType { CapType{ code: 5 } }
@@ -1579,7 +1637,7 @@ This cap can issue Dao member NFT or update member's SBT
Implementation
-public fun member_cap_type(): CapType { CapType{ code : 6 } }
+public fun member_cap_type(): CapType { CapType{ code: 6 } }
@@ -1602,7 +1660,7 @@ Creates a vote capability type.
Implementation
-public fun proposal_cap_type(): CapType { CapType{ code : 7 } }
+public fun proposal_cap_type(): CapType { CapType{ code: 7 } }
@@ -1625,7 +1683,7 @@ Creates all capability types.
Implementation
-public fun all_caps(): vector<CapType>{
+public fun all_caps(): vector<CapType> {
let caps = Vector::singleton(install_plugin_cap_type());
Vector::push_back(&mut caps, upgrade_module_cap_type());
Vector::push_back(&mut caps, modify_config_cap_type());
@@ -1738,7 +1796,7 @@ Create a dao with a exists Dao account
Implementation
-public fun upgrade_to_dao<DaoT: store>(sender:signer, name: vector<u8>, ext: DaoT, config: DaoConfig): DaoRootCap<DaoT> {
+public fun upgrade_to_dao<DaoT: store>(sender: signer, name: vector<u8>, ext: DaoT, config: DaoConfig): DaoRootCap<DaoT> {
let cap = DaoAccount::upgrade_to_dao(sender);
create_dao<DaoT>(cap, name, ext, config)
}
@@ -1764,7 +1822,7 @@ Burn the root cap after init the Dao
Implementation
-public fun burn_root_cap<DaoT>(cap: DaoRootCap<DaoT>){
+public fun burn_root_cap<DaoT>(cap: DaoRootCap<DaoT>) {
let DaoRootCap{} = cap;
}
@@ -1789,7 +1847,7 @@ Install ToInstallPluginT to Dao and grant the capabilites
Implementation
-public fun install_plugin_with_root_cap<DaoT:store, ToInstallPluginT>(_cap: &DaoRootCap<DaoT>, granted_caps: vector<CapType>) acquires DaoAccountCapHolder{
+public fun install_plugin_with_root_cap<DaoT: store, ToInstallPluginT>(_cap: &DaoRootCap<DaoT>, granted_caps: vector<CapType>) acquires DaoAccountCapHolder {
do_install_plugin<DaoT, ToInstallPluginT>(granted_caps);
}
@@ -1814,7 +1872,7 @@ Install plugin with DaoInstallPluginCap
Implementation
-public fun install_plugin<DaoT:store, PluginT, ToInstallPluginT>(_cap: &DaoInstallPluginCap<DaoT, PluginT>, granted_caps: vector<CapType>) acquires DaoAccountCapHolder{
+public fun install_plugin<DaoT: store, PluginT, ToInstallPluginT>(_cap: &DaoInstallPluginCap<DaoT, PluginT>, granted_caps: vector<CapType>) acquires DaoAccountCapHolder {
do_install_plugin<DaoT, ToInstallPluginT>(granted_caps);
}
@@ -1838,7 +1896,7 @@ Install plugin with DaoInstallPluginCap
Implementation
-fun do_install_plugin<DaoT:store, ToInstallPluginT>(granted_caps: vector<CapType>) acquires DaoAccountCapHolder{
+fun do_install_plugin<DaoT: store, ToInstallPluginT>(granted_caps: vector<CapType>) acquires DaoAccountCapHolder {
assert_no_repeat(&granted_caps);
let dao_signer = dao_signer<DaoT>();
assert!(!exists<InstalledPluginInfo<ToInstallPluginT>>(Signer::address_of(&dao_signer)), Errors::already_published(ERR_PLUGIN_HAS_INSTALLED));
@@ -1868,9 +1926,9 @@ Submit upgrade module plan
Implementation
-public fun submit_upgrade_plan<DaoT: store, PluginT>(_cap: &DaoUpgradeModuleCap<DaoT, PluginT>, package_hash: vector<u8>, version:u64, enforced: bool) acquires DaoAccountCapHolder{
- let dao_account_cap = &mut borrow_global_mut<DaoAccountCapHolder>(dao_address<DaoT>()).cap;
- DaoAccount::submit_upgrade_plan(dao_account_cap, package_hash, version, enforced);
+public fun submit_upgrade_plan<DaoT: store, PluginT>(_cap: &DaoUpgradeModuleCap<DaoT, PluginT>, package_hash: vector<u8>, version: u64, enforced: bool) acquires DaoAccountCapHolder {
+ let dao_account_cap = &mut borrow_global_mut<DaoAccountCapHolder>(dao_address<DaoT>()).cap;
+ DaoAccount::submit_upgrade_plan(dao_account_cap, package_hash, version, enforced);
}
@@ -1894,10 +1952,10 @@ Save the item to the storage
Implementation
-public fun save<DaoT:store, PluginT, V: store>(_cap: &DaoStorageCap<DaoT, PluginT>, item: V) acquires DaoAccountCapHolder{
+public fun save<DaoT: store, PluginT, V: store>(_cap: &DaoStorageCap<DaoT, PluginT>, item: V) acquires DaoAccountCapHolder {
let dao_signer = dao_signer<DaoT>();
assert!(!exists<StorageItem<PluginT, V>>(Signer::address_of(&dao_signer)), Errors::already_published(ERR_STORAGE_ERROR));
- move_to(&dao_signer, StorageItem<PluginT,V>{
+ move_to(&dao_signer, StorageItem<PluginT, V>{
item
});
}
@@ -1923,10 +1981,10 @@ Get the item from the storage
Implementation
-public fun take<DaoT:store, PluginT, V: store>(_cap: &DaoStorageCap<DaoT, PluginT>): V acquires StorageItem{
+public fun take<DaoT: store, PluginT, V: store>(_cap: &DaoStorageCap<DaoT, PluginT>): V acquires StorageItem {
let dao_address = dao_address<DaoT>();
- assert!(exists<StorageItem<PluginT, V>>(dao_address), Errors::not_published(ERR_STORAGE_ERROR));
- let StorageItem{item} = move_from<StorageItem<PluginT, V>>(dao_address);
+ assert!(exists<StorageItem<PluginT, V>>(dao_address), Errors::not_published(ERR_STORAGE_ERROR));
+ let StorageItem{ item } = move_from<StorageItem<PluginT, V>>(dao_address);
item
}
@@ -1951,7 +2009,7 @@ Withdraw the token from the Dao account
Implementation
-public fun withdraw_token<DaoT:store, PluginT, TokenT:store>(_cap: &DaoWithdrawTokenCap<DaoT, PluginT>, amount: u128): Token<TokenT> acquires DaoAccountCapHolder{
+public fun withdraw_token<DaoT: store, PluginT, TokenT: store>(_cap: &DaoWithdrawTokenCap<DaoT, PluginT>, amount: u128): Token<TokenT> acquires DaoAccountCapHolder {
let dao_signer = dao_signer<DaoT>();
//we should extract the WithdrawCapability from account, and invoke the withdraw_with_cap ?
Account::withdraw<TokenT>(&dao_signer, amount)
@@ -1978,7 +2036,7 @@ Withdraw the NFT from the Dao account
Implementation
-public fun withdraw_nft<DaoT:store, PluginT, NFTMeta: store + copy + drop, NFTBody: store>(_cap: &DaoWithdrawNFTCap<DaoT, PluginT>, id: u64): NFT<NFTMeta, NFTBody> acquires DaoAccountCapHolder{
+public fun withdraw_nft<DaoT: store, PluginT, NFTMeta: store + copy + drop, NFTBody: store>(_cap: &DaoWithdrawNFTCap<DaoT, PluginT>, id: u64): NFT<NFTMeta, NFTBody> acquires DaoAccountCapHolder {
let dao_signer = dao_signer<DaoT>();
let nft = NFTGallery::withdraw<NFTMeta, NFTBody>(&dao_signer, id);
assert!(Option::is_some(&nft), Errors::not_published(ERR_NFT_ERROR));
@@ -2006,8 +2064,7 @@ Join Dao and get a membership
Implementation
-public fun join_member<DaoT:store, PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, to_address: address, init_sbt: u128) acquires DaoNFTMintCapHolder, DaoTokenMintCapHolder, Dao{
-
+public fun join_member<DaoT: store, PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, to_address: address, init_sbt: u128) acquires DaoNFTMintCapHolder, DaoTokenMintCapHolder, Dao {
assert!(!is_member<DaoT>(to_address), Errors::already_published(ERR_NOT_ALREADY_MEMBER));
let member_id = next_member_id<DaoT>();
@@ -2056,7 +2113,7 @@ Member quit Dao by self
Implementation
-public fun quit_member<DaoT: store>(sender: &signer) acquires DaoNFTBurnCapHolder, DaoTokenBurnCapHolder{
+public fun quit_member<DaoT: store>(sender: &signer) acquires DaoNFTBurnCapHolder, DaoTokenBurnCapHolder {
let member_addr = Signer::address_of(sender);
do_remove_member<DaoT>(member_addr);
}
@@ -2082,7 +2139,7 @@ Revoke membership with cap
Implementation
-public fun revoke_member<DaoT:store,PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, member_addr: address) acquires DaoNFTBurnCapHolder, DaoTokenBurnCapHolder{
+public fun revoke_member<DaoT: store, PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, member_addr: address) acquires DaoNFTBurnCapHolder, DaoTokenBurnCapHolder {
do_remove_member<DaoT>(member_addr);
}
@@ -2106,7 +2163,7 @@ Revoke membership with cap
Implementation
-fun do_remove_member<DaoT:store>(member_addr: address) acquires DaoNFTBurnCapHolder, DaoTokenBurnCapHolder{
+fun do_remove_member<DaoT: store>(member_addr: address) acquires DaoNFTBurnCapHolder, DaoTokenBurnCapHolder {
assert!(is_member<DaoT>(member_addr), Errors::already_published(ERR_NOT_MEMBER));
let dao_address = dao_address<DaoT>();
@@ -2139,7 +2196,7 @@ Increment the member SBT
Implementation
-public fun increase_member_sbt<DaoT:store, PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, member_addr: address, amount: u128) acquires DaoNFTUpdateCapHolder, DaoTokenMintCapHolder {
+public fun increase_member_sbt<DaoT: store, PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, member_addr: address, amount: u128) acquires DaoNFTUpdateCapHolder, DaoTokenMintCapHolder {
assert!(is_member<DaoT>(member_addr), Errors::already_published(ERR_NOT_MEMBER));
let dao_address = dao_address<DaoT>();
@@ -2175,7 +2232,7 @@ Decrement the member SBT
Implementation
-public fun decrease_member_sbt<DaoT:store, PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, member_addr: address, amount: u128) acquires DaoNFTUpdateCapHolder, DaoTokenBurnCapHolder {
+public fun decrease_member_sbt<DaoT: store, PluginT>(_cap: &DaoMemberCap<DaoT, PluginT>, member_addr: address, amount: u128) acquires DaoNFTUpdateCapHolder, DaoTokenBurnCapHolder {
assert!(is_member<DaoT>(member_addr), Errors::already_published(ERR_NOT_MEMBER));
let dao_address = dao_address<DaoT>();
@@ -2193,6 +2250,44 @@ Decrement the member SBT
+
+
+
+
+## Function `query_sbt`
+
+Query amount of the member SBT
+
+
+public fun query_sbt<DaoT: store, PluginT>(member_addr: address): u128
+
+
+
+
+
+Implementation
+
+
+public fun query_sbt<DaoT: store, PluginT>(member_addr: address)
+: u128 acquires DaoNFTUpdateCapHolder {
+ assert!(is_member<DaoT>(member_addr), Errors::already_published(ERR_NOT_MEMBER));
+ let dao_address = dao_address<DaoT>();
+
+ let nft_update_cap =
+ &mut borrow_global_mut<DaoNFTUpdateCapHolder<DaoT>>(dao_address).cap;
+ let borrow_nft =
+ IdentifierNFT::borrow_out<DaoMember<DaoT>, DaoMemberBody<DaoT>>(nft_update_cap, member_addr);
+ let nft = IdentifierNFT::borrow_nft(&mut borrow_nft);
+ let body = NFT::borrow_body(nft);
+
+ let result = Token::value(&body.sbt);
+ IdentifierNFT::return_back(borrow_nft);
+ result
+}
+
+
+
+
@@ -2211,7 +2306,7 @@ Check the member_addr
account is a member of DaoT
Implementation
-public fun is_member<DaoT: store>(member_addr: address): bool{
+public fun is_member<DaoT: store>(member_addr: address): bool {
IdentifierNFT::owns<DaoMember<DaoT>, DaoMemberBody<DaoT>>(member_addr)
}
@@ -2235,13 +2330,13 @@ Check the member_addr
account is a member of DaoT
Implementation
-fun validate_cap<DaoT: store, PluginT>(cap: CapType) acquires InstalledPluginInfo{
+fun validate_cap<DaoT: store, PluginT>(cap: CapType) acquires InstalledPluginInfo {
let addr = dao_address<DaoT>();
if (exists<InstalledPluginInfo<PluginT>>(addr)) {
let plugin_info = borrow_global<InstalledPluginInfo<PluginT>>(addr);
assert!(Vector::contains(&plugin_info.granted_caps, &cap), Errors::requires_capability(E_NO_GRANTED));
} else {
- abort(Errors::requires_capability(E_NO_GRANTED))
+ abort (Errors::requires_capability(E_NO_GRANTED))
}
}
@@ -2267,7 +2362,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_install_plugin_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoInstallPluginCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_install_plugin_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoInstallPluginCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(install_plugin_cap_type());
DaoInstallPluginCap<DaoT, PluginT>{}
}
@@ -2294,7 +2389,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_upgrade_module_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoUpgradeModuleCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_upgrade_module_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoUpgradeModuleCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(upgrade_module_cap_type());
DaoUpgradeModuleCap<DaoT, PluginT>{}
}
@@ -2321,7 +2416,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_modify_config_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoModifyConfigCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_modify_config_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoModifyConfigCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(modify_config_cap_type());
DaoModifyConfigCap<DaoT, PluginT>{}
}
@@ -2348,7 +2443,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_withdraw_token_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoWithdrawTokenCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_withdraw_token_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoWithdrawTokenCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(withdraw_token_cap_type());
DaoWithdrawTokenCap<DaoT, PluginT>{}
}
@@ -2375,7 +2470,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_withdraw_nft_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoWithdrawNFTCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_withdraw_nft_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoWithdrawNFTCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(withdraw_nft_cap_type());
DaoWithdrawNFTCap<DaoT, PluginT>{}
}
@@ -2402,7 +2497,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_storage_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoStorageCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_storage_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoStorageCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(storage_cap_type());
DaoStorageCap<DaoT, PluginT>{}
}
@@ -2429,7 +2524,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_member_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoMemberCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_member_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoMemberCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(member_cap_type());
DaoMemberCap<DaoT, PluginT>{}
}
@@ -2456,7 +2551,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun acquire_proposal_cap<DaoT:store, PluginT>(_witness: &PluginT): DaoProposalCap<DaoT, PluginT> acquires InstalledPluginInfo{
+public fun acquire_proposal_cap<DaoT: store, PluginT>(_witness: &PluginT): DaoProposalCap<DaoT, PluginT> acquires InstalledPluginInfo {
validate_cap<DaoT, PluginT>(proposal_cap_type());
DaoProposalCap<DaoT, PluginT>{}
}
@@ -2481,7 +2576,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun choice_yes(): VotingChoice{VotingChoice{choice: VOTING_CHOICE_YES}}
+public fun choice_yes(): VotingChoice { VotingChoice{ choice: VOTING_CHOICE_YES } }
@@ -2503,7 +2598,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun choice_no(): VotingChoice{VotingChoice{choice: VOTING_CHOICE_NO}}
+public fun choice_no(): VotingChoice { VotingChoice{ choice: VOTING_CHOICE_NO } }
@@ -2525,7 +2620,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun choice_no_with_veto(): VotingChoice{VotingChoice{choice: VOTING_CHOICE_NO_WITH_VETO}}
+public fun choice_no_with_veto(): VotingChoice { VotingChoice{ choice: VOTING_CHOICE_NO_WITH_VETO } }
@@ -2547,7 +2642,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-public fun choice_abstain(): VotingChoice{VotingChoice{choice: VOTING_CHOICE_ABSTAIN}}
+public fun choice_abstain(): VotingChoice { VotingChoice{ choice: VOTING_CHOICE_ABSTAIN } }
@@ -2575,7 +2670,6 @@ _witness parameter ensures that the caller is the module which define PluginT
action: ActionT,
action_delay: u64,
): u64 acquires GlobalProposals, DaoAccountCapHolder, ProposalActions {
-
if (action_delay == 0) {
action_delay = min_action_delay<DaoT>();
} else {
@@ -2591,7 +2685,7 @@ _witness parameter ensures that the caller is the module which define PluginT
let start_time = Timestamp::now_milliseconds() + voting_delay<DaoT>();
let quorum_votes = quorum_votes<DaoT>();
- let (block_number,state_root) = block_number_and_state_root();
+ let (block_number, state_root) = block_number_and_state_root();
//four choise, so init four length vector.
let votes = Vector::singleton(0u128);
@@ -2599,7 +2693,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Vector::push_back(&mut votes, 0u128);
Vector::push_back(&mut votes, 0u128);
- let proposal = Proposal {
+ let proposal = Proposal{
id: proposal_id,
proposer,
start_time,
@@ -2622,11 +2716,11 @@ _witness parameter ensures that the caller is the module which define PluginT
let actions = Vector::singleton(proposal_action);
//TODO check ProposalActions is exists
- if(exists<ProposalActions<ActionT>>(dao_address)){
+ if (exists<ProposalActions<ActionT>>(dao_address)) {
//TODO add limit to max action before support Table.
let current_actions = borrow_global_mut<ProposalActions<ActionT>>(dao_address);
Vector::append(&mut current_actions.actions, actions);
- }else{
+ }else {
move_to(&dao_signer, ProposalActions<ActionT>{
actions,
});
@@ -2658,7 +2752,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-fun block_number_and_state_root():(u64, vector<u8>){
+fun block_number_and_state_root(): (u64, vector<u8>) {
//TODO how to get state root
(0, Vector::empty())
}
@@ -2683,7 +2777,7 @@ _witness parameter ensures that the caller is the module which define PluginT
Implementation
-fun generate_next_proposal_id<DaoT>(): u64{
+fun generate_next_proposal_id<DaoT>(): u64 {
//TODO
0
}
@@ -2713,17 +2807,17 @@ _witness parameter ensures that the caller is the module which define PluginT
proposal_id: u64,
sbt_proof: vector<u8>,
choice: VotingChoice,
-) acquires GlobalProposals, MyVotes{
+) acquires GlobalProposals, MyVotes {
let dao_address = dao_address<DaoT>();
let proposals = borrow_global_mut<GlobalProposals>(dao_address);
let proposal = borrow_proposal_mut(proposals, proposal_id);
- {
- let state = proposal_state(proposal);
- // only when proposal is active, use can cast vote.
- //TODO
- assert!(state == ACTIVE, Errors::invalid_state(ERR_PROPOSAL_STATE_INVALID));
- };
+ {
+ let state = proposal_state(proposal);
+ // only when proposal is active, use can cast vote.
+ //TODO
+ assert!(state == ACTIVE, Errors::invalid_state(ERR_PROPOSAL_STATE_INVALID));
+ };
let sender_addr = Signer::address_of(sender);
@@ -2752,7 +2846,6 @@ _witness parameter ensures that the caller is the module which define PluginT
votes: Vector::singleton(vote),
});
};
-
}
@@ -2780,7 +2873,7 @@ Just change vote choice, the weight do not change.
_sender: &signer,
_proposal_id: u64,
_choice: VotingChoice,
-){
+) {
//TODO
}
@@ -2807,7 +2900,7 @@ Just change vote choice, the weight do not change.
public fun revoke_vote<DaoT>(
_sender: &signer,
_proposal_id: u64,
-){
+) {
//TODO
}
@@ -2868,7 +2961,7 @@ Just change vote choice, the weight do not change.
Implementation
-fun take_proposal_action<ActionT: store>(dao_address: address, proposal_id: u64): ActionT acquires ProposalActions, GlobalProposals{
+fun take_proposal_action<ActionT: store>(dao_address: address, proposal_id: u64): ActionT acquires ProposalActions, GlobalProposals {
let actions = borrow_global_mut<ProposalActions<ActionT>>(dao_address);
let index_opt = find_action(&actions.actions, proposal_id);
//TODO error code.
@@ -2878,7 +2971,7 @@ Just change vote choice, the weight do not change.
let proposal = borrow_proposal(global_proposals, proposal_id);
let index = Option::extract(&mut index_opt);
- let ProposalAction{ proposal_id:_, deposit, action} = Vector::remove(&mut actions.actions, index);
+ let ProposalAction{ proposal_id: _, deposit, action } = Vector::remove(&mut actions.actions, index);
//TODO check the proposal state and do deposit or burn.
Account::deposit(proposal.proposer, deposit);
action
@@ -2904,12 +2997,12 @@ Just change vote choice, the weight do not change.
Implementation
-fun find_action<ActionT: store>(actions: &vector<ProposalAction<ActionT>>, proposal_id: u64): Option<u64>{
+fun find_action<ActionT: store>(actions: &vector<ProposalAction<ActionT>>, proposal_id: u64): Option<u64> {
let i = 0;
let len = Vector::length(actions);
- while(i < len){
+ while (i < len) {
let action = Vector::borrow(actions, i);
- if(action.proposal_id == proposal_id){
+ if (action.proposal_id == proposal_id) {
return Option::some(i)
};
i = i + 1;
@@ -2937,12 +3030,12 @@ Just change vote choice, the weight do not change.
Implementation
-fun has_voted<DaoT>(sender: address, proposal_id: u64): bool acquires MyVotes{
- if(exists<MyVotes<DaoT>>(sender)){
+fun has_voted<DaoT>(sender: address, proposal_id: u64): bool acquires MyVotes {
+ if (exists<MyVotes<DaoT>>(sender)) {
let my_votes = borrow_global<MyVotes<DaoT>>(sender);
let vote = get_vote<DaoT>(my_votes, proposal_id);
Option::is_some(vote)
- }else{
+ }else {
false
}
}
@@ -2967,7 +3060,7 @@ Just change vote choice, the weight do not change.
Implementation
-fun do_cast_vote(proposal: &mut Proposal, vote: &mut Vote){
+fun do_cast_vote(proposal: &mut Proposal, vote: &mut Vote) {
let weight = *Vector::borrow(&proposal.votes, (vote.choice as u64));
let total_weight = Vector::borrow_mut(&mut proposal.votes, (vote.choice as u64));
*total_weight = weight + vote.weight;
@@ -2993,7 +3086,7 @@ Just change vote choice, the weight do not change.
Implementation
-fun get_vote<DaoT>(_my_votes: &MyVotes<DaoT>, _proposal_id: u64):&Option<Vote>{
+fun get_vote<DaoT>(_my_votes: &MyVotes<DaoT>, _proposal_id: u64): &Option<Vote> {
//TODO
abort 0
}
@@ -3018,7 +3111,7 @@ Just change vote choice, the weight do not change.
Implementation
-public fun proposal_state(_proposal: &Proposal):u8 {
+public fun proposal_state(_proposal: &Proposal): u8 {
//TOOD
0
}
@@ -3043,7 +3136,7 @@ Just change vote choice, the weight do not change.
Implementation
-fun borrow_proposal_mut(_proposals: &mut GlobalProposals, _proposal_id: u64): &mut Proposal{
+fun borrow_proposal_mut(_proposals: &mut GlobalProposals, _proposal_id: u64): &mut Proposal {
//TODO
abort 0
}
@@ -3071,9 +3164,9 @@ Just change vote choice, the weight do not change.
fun borrow_proposal(proposals: &GlobalProposals, proposal_id: u64): &Proposal {
let i = 0;
let len = Vector::length(&proposals.proposals);
- while(i < len){
+ while (i < len) {
let proposal = Vector::borrow(&proposals.proposals, i);
- if(proposal.id == proposal_id){
+ if (proposal.id == proposal_id) {
return proposal
};
i = i + 1;
@@ -3103,7 +3196,7 @@ Return a copy of Proposal
Implementation
-public fun proposal<DaoT>(proposal_id: u64): Proposal acquires GlobalProposals{
+public fun proposal<DaoT>(proposal_id: u64): Proposal acquires GlobalProposals {
let dao_address = dao_address<DaoT>();
let global_proposals = borrow_global<GlobalProposals>(dao_address);
*borrow_proposal(global_proposals, proposal_id)
@@ -3138,7 +3231,7 @@ create a dao config
voting_quorum_rate: u8,
min_action_delay: u64,
min_proposal_deposit: u128,
-): DaoConfig{
+): DaoConfig {
assert!(voting_delay > 0, Errors::invalid_argument(ERR_CONFIG_PARAM_INVALID));
assert!(voting_period > 0, Errors::invalid_argument(ERR_CONFIG_PARAM_INVALID));
assert!(
@@ -3146,7 +3239,7 @@ create a dao config
Errors::invalid_argument(ERR_CONFIG_PARAM_INVALID),
);
assert!(min_action_delay > 0, Errors::invalid_argument(ERR_CONFIG_PARAM_INVALID));
- DaoConfig { voting_delay, voting_period, voting_quorum_rate, min_action_delay, min_proposal_deposit }
+ DaoConfig{ voting_delay, voting_period, voting_quorum_rate, min_action_delay, min_proposal_deposit }
}
@@ -3298,7 +3391,7 @@ Get the min proposal deposit of the DAO.
Implementation
-fun min_proposal_deposit<DaoT: store>(): u128{
+fun min_proposal_deposit<DaoT: store>(): u128 {
get_config<DaoT>().min_proposal_deposit
}
@@ -3323,7 +3416,7 @@ Get the min proposal deposit of the DAO.
fun get_config<DaoT: store>(): DaoConfig {
- let dao_address= dao_address<DaoT>();
+ let dao_address = dao_address<DaoT>();
Config::get_by_address<DaoConfig>(dao_address)
}
@@ -3362,6 +3455,44 @@ Update function, modify dao config.
+
+
+
+
+## Function `set_custom_config`
+
+Update, save function of custom plugin configuration
+
+
+public fun set_custom_config<DaoT: store, PluginT: drop, ConfigT: copy, drop, store>(_cap: &mut GenesisDao::DaoModifyConfigCap<DaoT, PluginT>, config: ConfigT)
+
+
+
+
+
+Implementation
+
+
+public fun set_custom_config<DaoT: store,
+ PluginT: drop,
+ ConfigT: copy + store + drop>(
+ _cap: &mut DaoModifyConfigCap<DaoT, PluginT>,
+ config: ConfigT)
+acquires DaoCustomConfigModifyCapHolder, DaoAccountCapHolder {
+ let dao_address = dao_address<DaoT>();
+ if (Config::config_exist_by_address<ConfigT>(dao_address)) {
+ let modify_config_cap =
+ &mut borrow_global_mut<DaoCustomConfigModifyCapHolder<DaoT, ConfigT>>(dao_address).cap;
+ Config::set_with_capability(modify_config_cap, config);
+ } else {
+ let signer = dao_signer<DaoT>();
+ Config::publish_new_config<ConfigT>(&signer, config);
+ }
+}
+
+
+
+
@@ -3526,11 +3657,11 @@ Helpers
fun next_member_id<DaoT>(): u64 acquires Dao {
- let dao_address = dao_address<DaoT>();
- let dao = borrow_global_mut<Dao>(dao_address);
- let member_id = dao.next_member_id;
- dao.next_member_id = member_id + 1;
- member_id
+ let dao_address = dao_address<DaoT>();
+ let dao = borrow_global_mut<Dao>(dao_address);
+ let member_id = dao.next_member_id;
+ dao.next_member_id = member_id + 1;
+ member_id
}
@@ -3556,9 +3687,9 @@ Helpers
fun assert_no_repeat<E>(v: &vector<E>) {
let i = 0;
let len = Vector::length(v);
- while(i < len){
+ while (i < len) {
let e = Vector::borrow(v, i);
- if(Vector::contains(v, e)){
+ if (Vector::contains(v, e)) {
abort Errors::invalid_argument(ERR_REPEAT_ELEMENT)
};
i = i + 1;
@@ -3640,7 +3771,7 @@ Helper to add an element to a vector.
Implementation
-fun dao_signer<DaoT>(): signer acquires DaoAccountCapHolder{
+fun dao_signer<DaoT>(): signer acquires DaoAccountCapHolder {
let cap = &borrow_global<DaoAccountCapHolder>(dao_address<DaoT>()).cap;
DaoAccount::dao_signer(cap)
}
diff --git a/build/StarcoinFramework/docs/README.md b/build/StarcoinFramework/docs/README.md
index c28a332a..87a8d456 100644
--- a/build/StarcoinFramework/docs/README.md
+++ b/build/StarcoinFramework/docs/README.md
@@ -25,6 +25,7 @@ This is the root document for the Move StarcoinFramework module documentation. T
- [`0x1::Collection2`](Collection2.md#0x1_Collection2)
- [`0x1::Compare`](Compare.md#0x1_Compare)
- [`0x1::Config`](Config.md#0x1_Config)
+- [`0x1::ConfigProposalPlugin`](ConfigProposalPlugin.md#0x1_ConfigProposalPlugin)
- [`0x1::ConsensusConfig`](ConsensusConfig.md#0x1_ConsensusConfig)
- [`0x1::ConsensusStrategy`](ConsensusStrategy.md#0x1_ConsensusStrategy)
- [`0x1::CoreAddresses`](CoreAddresses.md#0x1_CoreAddresses)
@@ -79,6 +80,7 @@ This is the root document for the Move StarcoinFramework module documentation. T
- [`0x1::SIP_3`](SIPs.md#0x1_SIP_3)
- [`0x1::STC`](STC.md#0x1_STC)
- [`0x1::STCUSDOracle`](Oracle.md#0x1_STCUSDOracle)
+- [`0x1::SalaryGovPlugin`](SalaryGovPlugin.md#0x1_SalaryGovPlugin)
- [`0x1::SharedEd25519PublicKey`](SharedEd25519PublicKey.md#0x1_SharedEd25519PublicKey)
- [`0x1::Signature`](Signature.md#0x1_Signature)
- [`0x1::SignedInteger64`](SignedInteger64.md#0x1_SignedInteger64)
diff --git a/build/StarcoinFramework/source_maps/DaoAccount.mvsm b/build/StarcoinFramework/source_maps/DaoAccount.mvsm
index 25867c36..da9c47a5 100644
Binary files a/build/StarcoinFramework/source_maps/DaoAccount.mvsm and b/build/StarcoinFramework/source_maps/DaoAccount.mvsm differ
diff --git a/build/StarcoinFramework/source_maps/GenesisDao.mvsm b/build/StarcoinFramework/source_maps/GenesisDao.mvsm
index 6367905e..dc480906 100644
Binary files a/build/StarcoinFramework/source_maps/GenesisDao.mvsm and b/build/StarcoinFramework/source_maps/GenesisDao.mvsm differ
diff --git a/build/StarcoinFramework/source_maps/XDao.mvsm b/build/StarcoinFramework/source_maps/XDao.mvsm
index 0a001cec..5c205f58 100644
Binary files a/build/StarcoinFramework/source_maps/XDao.mvsm and b/build/StarcoinFramework/source_maps/XDao.mvsm differ
diff --git a/integration-tests/dao_account/dao_account.exp b/integration-tests/dao_account/dao_account.exp
new file mode 100644
index 00000000..bdc5da32
--- /dev/null
+++ b/integration-tests/dao_account/dao_account.exp
@@ -0,0 +1,17 @@
+processed 4 tasks
+
+task 2 'run'. lines 6-23:
+{
+ "gas_used": 827652,
+ "status": {
+ "Keep": "Executed"
+ }
+}
+
+task 3 'run'. lines 28-40:
+{
+ "gas_used": 74662,
+ "status": {
+ "Keep": "Executed"
+ }
+}
diff --git a/integration-tests/dao_account/dao_account.move b/integration-tests/dao_account/dao_account.move
new file mode 100644
index 00000000..dc3c21b5
--- /dev/null
+++ b/integration-tests/dao_account/dao_account.move
@@ -0,0 +1,40 @@
+//# init -n dev
+
+//# faucet --addr alice --amount 1000000
+
+
+//# run --signers alice
+script {
+ use StarcoinFramework::STC::STC;
+ use StarcoinFramework::Account;
+ use StarcoinFramework::DaoAccount;
+ use StarcoinFramework::Signer;
+
+ fun main(sender: signer) {
+ let dao_cap = DaoAccount::create_account(&sender);
+ let dao_signer = DaoAccount::dao_signer(&dao_cap);
+ let dao_address= Signer::address_of(&dao_signer);
+ Account::pay_from(&sender, dao_address, 10000);
+ let dao_balance = Account::balance(dao_address);
+ assert!(dao_balance == 10000, 1001);
+ DaoAccount::restore_dao_account_cap(&sender, dao_cap);
+ }
+}
+// check: EXECUTED
+
+
+
+
+//# run --signers alice
+script {
+ use StarcoinFramework::DaoAccount;
+ use StarcoinFramework::Vector;
+
+ fun main(sender: signer) {
+ let dao_cap = DaoAccount::extract_dao_account_cap(&sender);
+ let package_hash = Vector::empty();
+ DaoAccount::submit_upgrade_plan(&dao_cap, package_hash, 2, false);
+ DaoAccount::restore_dao_account_cap(&sender, dao_cap);
+ }
+}
+// check: EXECUTED
\ No newline at end of file
diff --git a/sources/genesis_dao/DaoAccount.move b/sources/genesis_dao/DaoAccount.move
index a7d8f6bf..2a79557c 100644
--- a/sources/genesis_dao/DaoAccount.move
+++ b/sources/genesis_dao/DaoAccount.move
@@ -1,9 +1,11 @@
module StarcoinFramework::DaoAccount{
use StarcoinFramework::Account::{Self, SignerCapability};
- use StarcoinFramework::PackageTxnManager;
+ use StarcoinFramework::PackageTxnManager::{Self, UpgradePlanCapability};
use StarcoinFramework::Option;
use StarcoinFramework::Signer;
use StarcoinFramework::Errors;
+ use StarcoinFramework::Version;
+ use StarcoinFramework::Config;
spec module {
pragma verify = false;
@@ -16,6 +18,7 @@ module StarcoinFramework::DaoAccount{
struct DaoAccount has key{
dao_address: address,
signer_cap: SignerCapability,
+ upgrade_plan_cap: UpgradePlanCapability,
}
/// This capability can control the Dao account
@@ -26,17 +29,8 @@ module StarcoinFramework::DaoAccount{
/// Create a new Dao Account and return DaoAccountCap
/// Dao Account is a delegate account, the `creator` has the `DaoAccountCap`
public fun create_account(creator: &signer): DaoAccountCap {
- let (dao_address, signer_cap) = Account::create_delegate_account(creator);
- let dao_signer = Account::create_signer_with_cap(&signer_cap);
-
- PackageTxnManager::update_module_upgrade_strategy(&dao_signer, PackageTxnManager::get_strategy_two_phase(), Option::some(0));
- move_to(&dao_signer, DaoAccount{
- dao_address,
- signer_cap: signer_cap,
- });
- DaoAccountCap{
- dao_address
- }
+ let (_dao_address, signer_cap) = Account::create_delegate_account(creator);
+ upgrade_to_dao_with_signer_cap(signer_cap)
}
/// Entry function for create dao account, the `DaoAccountCap` save to the `creator` account
@@ -45,27 +39,47 @@ module StarcoinFramework::DaoAccount{
move_to(&sender, cap);
}
+ /// Extract the DaoAccountCap from the `sender`
public fun extract_dao_account_cap(sender: &signer): DaoAccountCap acquires DaoAccountCap {
let sender_addr = Signer::address_of(sender);
assert!(exists(sender_addr), Errors::not_published(ERR_ACCOUNT_CAP_NOT_EXISTS));
move_from(sender_addr)
}
+ /// Restore the DaoAccountCap to the `sender`
+ public fun restore_dao_account_cap(sender: &signer, cap: DaoAccountCap) {
+ move_to(sender, cap)
+ }
+
/// Upgrade `sender` account to Dao account
public fun upgrade_to_dao(sender: signer): DaoAccountCap {
- //TODO assert sender not Dao
let signer_cap = Account::remove_signer_capability(&sender);
- //TODO check the account upgrade_strategy
- PackageTxnManager::update_module_upgrade_strategy(&sender, PackageTxnManager::get_strategy_two_phase(), Option::some(0));
- let dao_address = Signer::address_of(&sender);
- move_to(&sender, DaoAccount{
+ upgrade_to_dao_with_signer_cap(signer_cap)
+ }
+
+ /// Upgrade the account which have the `signer_cap` to a Dao Account
+ public fun upgrade_to_dao_with_signer_cap(signer_cap: SignerCapability): DaoAccountCap {
+ let dao_signer = Account::create_signer_with_cap(&signer_cap);
+ let dao_address = Signer::address_of(&dao_signer);
+
+ let upgrade_plan_cap = if(Config::config_exist_by_address(dao_address)){
+ //TODO if the account has extract the upgrade plan cap
+ PackageTxnManager::extract_submit_upgrade_plan_cap(&dao_signer)
+ }else{
+ Config::publish_new_config(&dao_signer, Version::new_version(1));
+ PackageTxnManager::update_module_upgrade_strategy(&dao_signer, PackageTxnManager::get_strategy_two_phase(), Option::some(1));
+ PackageTxnManager::extract_submit_upgrade_plan_cap(&dao_signer)
+ };
+ move_to(&dao_signer, DaoAccount{
dao_address,
- signer_cap: signer_cap,
+ signer_cap,
+ upgrade_plan_cap,
});
- DaoAccountCap{
+ DaoAccountCap{
dao_address
}
}
+
/// Provide a function to create signer with `DaoAccountCap`
public fun dao_signer(cap: &DaoAccountCap): signer acquires DaoAccount {
@@ -76,8 +90,8 @@ module StarcoinFramework::DaoAccount{
/// Sumbit upgrade plan for the Dao account
/// This function is a shortcut for create signer with DaoAccountCap and invoke `PackageTxnManager::submit_upgrade_plan_v2`
public fun submit_upgrade_plan(cap: &DaoAccountCap, package_hash: vector, version:u64, enforced: bool) acquires DaoAccount{
- let dao_signer = dao_signer(cap);
- PackageTxnManager::submit_upgrade_plan_v2(&dao_signer, package_hash, version, enforced);
+ let upgrade_plan_cap = &borrow_global(cap.dao_address).upgrade_plan_cap;
+ PackageTxnManager::submit_upgrade_plan_with_cap_v2(upgrade_plan_cap, package_hash, version, enforced);
}
/// Sumbit upgrade plan for the Dao account, sender must hold the `DaoAccountCap`