Skip to content

Commit

Permalink
Plugin Event (#97)
Browse files Browse the repository at this point in the history
* Add plugin event

* Rename for script functions

* Fixed PR comments in #97
  • Loading branch information
welbon committed Sep 12, 2022
1 parent 3e95aef commit 31b9a9c
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 20 deletions.
50 changes: 47 additions & 3 deletions sources/daospace/DAOSpace.move
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ module StarcoinFramework::DAOSpace {

/// Create a token burning capability type.
public fun token_burn_cap_type(): CapType { CapType{code: 10 } }

/// Creates a grant capability type.
public fun plugin_event_cap_type(): CapType { CapType{ code: 11 } }

/// Create all capability types.
public fun all_caps(): vector<CapType> {
Expand All @@ -197,6 +200,7 @@ module StarcoinFramework::DAOSpace {
Vector::push_back(&mut caps, grant_cap_type());
Vector::push_back(&mut caps, token_mint_cap_type());
Vector::push_back(&mut caps, token_burn_cap_type());
Vector::push_back(&mut caps, plugin_event_cap_type());
caps
}

Expand All @@ -221,6 +225,8 @@ module StarcoinFramework::DAOSpace {

struct DAOGrantCap<phantom DAOT, phantom PluginT> has drop {}

struct DAOPluginEventCap<phantom DAOT, phantom PluginT> has drop {}

struct DAOGrantWithdrawTokenKey<phantom DAOT, phantom PluginT ,phantom TokenT> has key, store{
/// The total amount of tokens that can be withdrawn by this capability
total: u128,
Expand Down Expand Up @@ -503,6 +509,11 @@ module StarcoinFramework::DAOSpace {
item
}

/// Check the item has exists in storage
public fun exists_storage<DAOT: store, PluginT, V: store>(): bool {
exists<StorageItem<PluginT, V>>(dao_address<DAOT>())
}

// Withdraw Token capability function

/// Withdraw the token from the DAO account
Expand Down Expand Up @@ -725,6 +736,32 @@ module StarcoinFramework::DAOSpace {
IdentifierNFT::owns<DAOMember<DAOT>, DAOMemberBody<DAOT>>(member_addr)
}

struct PluginEvent<phantom DAOT, phantom PluginT, phantom EventT> has key, store {
event_handle: Event::EventHandle<EventT>,
}

/// Plugin event
public fun init_plugin_event<DAOT: store,
PluginT: store,
EventT: store + drop>(_cap: &DAOPluginEventCap<DAOT, PluginT>)
acquires DAOAccountCapHolder {
let dao_signer = dao_signer<DAOT>();
assert!(!exists<PluginEvent<DAOT, PluginT, EventT>>(dao_address<DAOT>()), Errors::invalid_state(ERR_ALREADY_INIT));
move_to(&dao_signer, PluginEvent<DAOT, PluginT, EventT> {
event_handle: Event::new_event_handle<EventT>(&dao_signer)
});
}

public fun emit_plugin_event<DAOT: store,
PluginT: store,
EventT: store + drop>(_cap: &DAOPluginEventCap<DAOT, PluginT>,
event: EventT) acquires PluginEvent {
let dao_address = dao_address<DAOT>();
let plugin_event = borrow_global_mut<PluginEvent<DAOT, PluginT, EventT>>(dao_address);
Event::emit_event(&mut plugin_event.event_handle, event);
}


/// Grant Event

struct GrantEvent<phantom PluginT> has key, store{
Expand Down Expand Up @@ -1072,6 +1109,13 @@ module StarcoinFramework::DAOSpace {
DAOGrantCap<DAOT, PluginT>{}
}


/// Acquire the plugin event capability
/// _witness parameter ensures that the caller is the module which define PluginT
public fun acquire_plugin_event_cap<DAOT: store, PluginT>(_witness: &PluginT): DAOPluginEventCap<DAOT, PluginT> acquires InstalledPluginInfo {
validate_cap<DAOT, PluginT>(plugin_event_cap_type());
DAOPluginEventCap<DAOT, PluginT> {}

/// Delegate the token mint capability to DAO
/// _witness parameter ensures that the caller is the module which define PluginT
public fun delegate_token_mint_cap<DAOT: store, PluginT, TokenT: store>(cap: Token::MintCapability<TokenT>, _witness: &PluginT)
Expand Down Expand Up @@ -1119,7 +1163,7 @@ module StarcoinFramework::DAOSpace {

/// Proposal
/// --------------------------------------------------
/// Proposal state
/// Proposal state
const PENDING: u8 = 1;
const ACTIVE: u8 = 2;
const DEFEATED: u8 = 3;
Expand Down Expand Up @@ -2126,11 +2170,11 @@ module StarcoinFramework::DAOSpace {
DAOAccount::dao_signer(cap)
}

fun dao_address<DAOT>(): address {
public fun dao_address<DAOT>(): address {
DAORegistry::dao_address<DAOT>()
}

fun dao_id(dao_address: address): u64 acquires DAO {
public fun dao_id(dao_address: address): u64 acquires DAO {
if (exists<DAO>(dao_address)){
let dao = borrow_global<DAO>(dao_address);
dao.id
Expand Down
158 changes: 141 additions & 17 deletions sources/daospaceplugin/StakeToSBTPlugin.move
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,7 @@ module StarcoinFramework::StakeToSBTPlugin {
const ERR_PLUGIN_CONFIG_INIT_REPEATE: u64 = 1005;
const ERR_PLUGIN_ITEM_CANT_FOUND: u64 = 1006;

struct StakeToSBTPlugin has store, drop{}

public fun required_caps(): vector<DAOSpace::CapType> {
let caps = Vector::singleton(DAOSpace::proposal_cap_type());
Vector::push_back(&mut caps, DAOSpace::member_cap_type());
Vector::push_back(&mut caps, DAOSpace::modify_config_cap_type());
caps
}
struct StakeToSBTPlugin has store, drop {}

struct Stake<phantom DAOT, phantom TokenT> has key, store {
id: u64,
Expand Down Expand Up @@ -56,14 +49,74 @@ module StarcoinFramework::StakeToSBTPlugin {

struct AcceptTokenCap<phantom DAOT, phantom TokenT> has store {}

/// Events
///
struct SBTTokenAcceptedEvent has copy, drop, store {
dao_id: u64,
token_code: Token::TokenCode
}

struct SBTWeightChangedEvent has copy, drop, store {
dao_id: u64,
token_code: Token::TokenCode,
lock_time: u64,
weight: u64,
}

struct SBTStakeEvent has copy, drop, store {
dao_id: u64,
stake_id: u64,
token_code: Token::TokenCode,
amount: u128,
lock_time: u64,
weight: u64,
sbt_amount: u128,
member: address,
}

struct SBTUnstakeEvent has copy, drop, store {
dao_id: u64,
stake_id: u64,
token_code: Token::TokenCode,
amount: u128,
lock_time: u64,
weight: u64,
sbt_amount: u128,
member: address,
}

public fun required_caps(): vector<DAOSpace::CapType> {
let caps = Vector::singleton(DAOSpace::proposal_cap_type());
Vector::push_back(&mut caps, DAOSpace::member_cap_type());
Vector::push_back(&mut caps, DAOSpace::modify_config_cap_type());
Vector::push_back(&mut caps, DAOSpace::plugin_event_cap_type());
caps
}

/// Accept token with token type by given DAO root capability
public fun accept_token_with_root_cap<DAOT: store, TokenT: store>(_cap: &DAOSpace::DAORootCap<DAOT>) {
accept_token(AcceptTokenCap<DAOT, TokenT> {})
accept_token(AcceptTokenCap<DAOT, TokenT> {});
install_event<DAOT>();
}

public fun install_event<DAOT: store>() {
let witness = StakeToSBTPlugin {};
let plugin_event_cap =
DAOSpace::acquire_plugin_event_cap<DAOT, StakeToSBTPlugin>(&witness);

DAOSpace::init_plugin_event<DAOT, StakeToSBTPlugin, SBTTokenAcceptedEvent>(&plugin_event_cap);
DAOSpace::init_plugin_event<DAOT, StakeToSBTPlugin, SBTWeightChangedEvent>(&plugin_event_cap);
DAOSpace::init_plugin_event<DAOT, StakeToSBTPlugin, SBTStakeEvent>(&plugin_event_cap);
DAOSpace::init_plugin_event<DAOT, StakeToSBTPlugin, SBTUnstakeEvent>(&plugin_event_cap);
}

/// Set sbt weight by given DAO root capability
public fun set_sbt_weight_with_root_cap<DAOT: store,
TokenT: store>(_cap: &DAOSpace::DAORootCap<DAOT>, lock_time: u64, weight: u64) {
TokenT: store>(
_cap: &DAOSpace::DAORootCap<DAOT>,
lock_time: u64,
weight: u64
) {
set_sbt_weight<DAOT, TokenT>(lock_time, weight);
}

Expand All @@ -86,6 +139,18 @@ module StarcoinFramework::StakeToSBTPlugin {
>(&mut modify_config_cap, LockWeightConfig<DAOT, TokenT> {
weight_vec: Vector::empty<LockWeight<DAOT, TokenT>>()
});

let witness = StakeToSBTPlugin {};
let plugin_event_cap =
DAOSpace::acquire_plugin_event_cap<DAOT, StakeToSBTPlugin>(&witness);

DAOSpace::emit_plugin_event<DAOT, StakeToSBTPlugin, SBTTokenAcceptedEvent>(
&plugin_event_cap,
SBTTokenAcceptedEvent {
dao_id: DAOSpace::dao_id(DAOSpace::dao_address<DAOT>()),
token_code: Token::token_code<TokenT>(),
}
);
}

public fun stake<DAOT: store, TokenT: store>(sender: &signer,
Expand Down Expand Up @@ -115,6 +180,7 @@ module StarcoinFramework::StakeToSBTPlugin {
Option::destroy_some(weight_opt)
};

let token_amount = Token::value<TokenT>(&token);
let sbt_amount = compute_token_to_sbt(weight, &token);
DAOSpace::increase_member_sbt(&member_cap, sender_addr, sbt_amount);

Expand All @@ -132,6 +198,21 @@ module StarcoinFramework::StakeToSBTPlugin {
});
stake_list.next_id = id;

let witness = StakeToSBTPlugin {};
let plugin_event_cap = DAOSpace::acquire_plugin_event_cap<DAOT, StakeToSBTPlugin>(&witness);
DAOSpace::emit_plugin_event<DAOT, StakeToSBTPlugin, SBTStakeEvent>(
&plugin_event_cap,
SBTStakeEvent {
dao_id: DAOSpace::dao_id(DAOSpace::dao_address<DAOT>()),
stake_id: id,
token_code: Token::token_code<TokenT>(),
amount: token_amount,
lock_time,
weight,
sbt_amount,
member: sender_addr,
}
);
id
}

Expand Down Expand Up @@ -171,7 +252,28 @@ module StarcoinFramework::StakeToSBTPlugin {
let poped_item =
Vector::remove(&mut stake_list.items, Option::destroy_some(item_index));

let amount = Token::value<TokenT>(&poped_item.token);
let lock_time = poped_item.lock_time;
let weight = poped_item.weight;
let sbt_amount = poped_item.sbt_amount;

Account::deposit<TokenT>(member, unstake_item(member, poped_item));

let witness = StakeToSBTPlugin {};
let plugin_event_cap = DAOSpace::acquire_plugin_event_cap<DAOT, StakeToSBTPlugin>(&witness);
DAOSpace::emit_plugin_event<DAOT, StakeToSBTPlugin, SBTUnstakeEvent>(
&plugin_event_cap,
SBTUnstakeEvent {
dao_id: DAOSpace::dao_id(DAOSpace::dao_address<DAOT>()),
stake_id: id,
token_code: Token::token_code<TokenT>(),
amount,
lock_time,
weight,
sbt_amount,
member,
}
);
}

/// Unstake all staking items from member address,
Expand Down Expand Up @@ -276,7 +378,7 @@ module StarcoinFramework::StakeToSBTPlugin {

/// Create proposal that to specific a weight for a locktime
public(script) fun create_weight_proposal<DAOT: store, TokenT: store>(sender: signer,
description:vector<u8>,
description: vector<u8>,
lock_time: u64,
weight: u64,
action_delay: u64) {
Expand All @@ -287,9 +389,9 @@ module StarcoinFramework::StakeToSBTPlugin {
DAOSpace::create_proposal(&cap, &sender, LockWeight<DAOT, TokenT> {
lock_time,
weight,
},
description,
action_delay);
},
description,
action_delay);
}

public(script) fun execute_weight_proposal<DAOT: store, TokenT: store>(sender: signer,
Expand All @@ -312,7 +414,7 @@ module StarcoinFramework::StakeToSBTPlugin {

/// Create proposal that to accept a token type, which allow user to convert amount of token to SBT
public(script) fun create_token_accept_proposal<DAOT: store, TokenT: store>(sender: signer,
description:vector<u8>,
description: vector<u8>,
action_delay: u64) {
let witness = StakeToSBTPlugin {};

Expand All @@ -336,7 +438,29 @@ module StarcoinFramework::StakeToSBTPlugin {
accept_token(cap);
}

public(script) fun install_plugin_proposal<DAOT: store>(sender: signer, description:vector<u8>, action_delay: u64) {
InstallPluginProposalPlugin::create_proposal<DAOT, StakeToSBTPlugin>(&sender, required_caps(), description,action_delay);
/// Query all weight from config
public fun get_sbt_weights<DAOT: store, TokenT: store>(): vector<LockWeight<DAOT, TokenT>> {
let config = DAOSpace::get_custom_config<DAOT, LockWeightConfig<DAOT, TokenT>>();
let c = &mut config.weight_vec;
*c
}

/// Called by script
public(script) fun install_plugin_proposal<DAOT: store>(sender: signer, description: vector<u8>, action_delay: u64) {
InstallPluginProposalPlugin::create_proposal<DAOT, StakeToSBTPlugin>(&sender, required_caps(), description, action_delay);
}

/// Called by script
public(script) fun stake_entry<DAOT: store, TokenT: store>(sender: signer,
amount: u128,
lock_time: u64) acquires StakeList {
let token = Account::withdraw<TokenT>(&sender, amount);
stake<DAOT, TokenT>(&sender, token, lock_time);
}

/// Called by script
public(script) fun unstake_item_entry<DAOT: store, TokenT: store>(member: address,
id: u64) acquires StakeList {
unstake_by_id<DAOT, TokenT>(member, id);
}
}

0 comments on commit 31b9a9c

Please sign in to comment.