Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin Event #97

Merged
merged 4 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/StarcoinFramework/BuildInfo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ compiled_package_info:
? address: "0x00000000000000000000000000000001"
name: YieldFarmingV2
: StarcoinFramework
source_digest: FD04C9A39DFAD60C3FA7B7566327BD66B28ABC554C15691EFA399D36AA8EAE4B
source_digest: FD22ADD0AC2FCAA5A3918D285615A4E0512A53741F05CC7711158F468064CDC3
build_flags:
dev_mode: false
test_mode: false
Expand Down
51 changes: 49 additions & 2 deletions sources/daospace/DAOSpace.move
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ module StarcoinFramework::DAOSpace {
/// Creates a grant capability type.
public fun grant_cap_type(): CapType { CapType{ code: 8 } }

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

/// Creates all capability types.
public fun all_caps(): vector<CapType> {
let caps = Vector::singleton(install_plugin_cap_type());
Expand All @@ -174,6 +177,7 @@ module StarcoinFramework::DAOSpace {
Vector::push_back(&mut caps, member_cap_type());
Vector::push_back(&mut caps, proposal_cap_type());
Vector::push_back(&mut caps, grant_cap_type());
Vector::push_back(&mut caps, plugin_event_cap_type());
jolestar marked this conversation as resolved.
Show resolved Hide resolved
caps
}

Expand All @@ -198,6 +202,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 @@ -456,6 +462,13 @@ module StarcoinFramework::DAOSpace {
item
}

/// Check the item has exists in storage
public fun exists_storage<DAOT: store, PluginT, V: store>(): bool {
let dao_address = dao_address<DAOT>();
assert!(exists<StorageItem<PluginT, V>>(dao_address), Errors::not_published(ERR_STORAGE_ERROR));
exists<StorageItem<PluginT, V>>(dao_address)
jolestar marked this conversation as resolved.
Show resolved Hide resolved
}

// Withdraw Token capability function

/// Withdraw the token from the DAO account
Expand Down Expand Up @@ -652,6 +665,33 @@ 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>();
if (!exists<PluginEvent<DAOT, PluginT, EventT>>(dao_address<DAOT>())) {
jolestar marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -999,6 +1039,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> {}
}

/// Proposal
/// --------------------------------------------------
/// Proposal state
Expand Down Expand Up @@ -1971,11 +2018,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);
}
}