Skip to content

Commit 88367b8

Browse files
committed
Merge "feat: transfer fees to treasury (#78)" into dev
2 parents 06ec269 + a546134 commit 88367b8

File tree

6 files changed

+174
-38
lines changed

6 files changed

+174
-38
lines changed

pallets/governance/src/application.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
use codec::{Decode, Encode, MaxEncodedLen};
22
use polkadot_sdk::{
33
frame_election_provider_support::Get,
4-
frame_support::{
5-
dispatch::DispatchResult,
6-
traits::{Currency, WithdrawReasons},
7-
DebugNoBound,
8-
},
4+
frame_support::{dispatch::DispatchResult, traits::Currency, DebugNoBound},
95
polkadot_sdk_frame::prelude::BlockNumberFor,
106
sp_runtime::BoundedVec,
117
sp_std::vec::Vec,
@@ -86,10 +82,10 @@ pub fn submit_application<T: crate::Config>(
8682
let config = crate::GlobalGovernanceConfig::<T>::get();
8783
let cost = config.agent_application_cost;
8884

89-
let _ = <T as crate::Config>::Currency::withdraw(
85+
<T as crate::Config>::Currency::transfer(
9086
&payer,
87+
&crate::DaoTreasuryAddress::<T>::get(),
9188
cost,
92-
WithdrawReasons::except(WithdrawReasons::TIP),
9389
ExistenceRequirement::AllowDeath,
9490
)
9591
.map_err(|_| crate::Error::<T>::NotEnoughBalanceToApply)?;
@@ -161,8 +157,12 @@ pub fn accept_application<T: crate::Config>(application_id: u32) -> DispatchResu
161157
});
162158

163159
// Give the application fee back to the payer key.
164-
let _ =
165-
<T as crate::Config>::Currency::deposit_creating(&application.payer_key, application.cost);
160+
let _ = <T as crate::Config>::Currency::transfer(
161+
&crate::DaoTreasuryAddress::<T>::get(),
162+
&application.payer_key,
163+
application.cost,
164+
ExistenceRequirement::AllowDeath,
165+
);
166166

167167
crate::Pallet::<T>::deposit_event(crate::Event::<T>::ApplicationAccepted(application.id));
168168

@@ -184,8 +184,6 @@ pub fn deny_application<T: crate::Config>(application_id: u32) -> DispatchResult
184184
}
185185
});
186186

187-
// Application cost is discarded
188-
189187
crate::Pallet::<T>::deposit_event(crate::Event::<T>::ApplicationDenied(application.id));
190188

191189
Ok(())

pallets/governance/src/proposal.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ use codec::{Decode, Encode, MaxEncodedLen};
22
use polkadot_sdk::{
33
frame_election_provider_support::Get,
44
frame_support::{
5-
dispatch::DispatchResult,
6-
ensure,
7-
storage::with_storage_layer,
8-
traits::{Currency, WithdrawReasons},
5+
dispatch::DispatchResult, ensure, storage::with_storage_layer, traits::Currency,
96
},
107
polkadot_sdk_frame::{prelude::BlockNumberFor, traits::CheckedAdd},
118
sp_core::{ConstU32, U256},
@@ -89,8 +86,12 @@ impl<T: crate::Config> Proposal<T> {
8986
/// Executes the changes.
9087
fn execute_proposal(self) -> DispatchResult {
9188
// Proposal fee is given back to the proposer.
92-
let _ =
93-
<T as crate::Config>::Currency::deposit_creating(&self.proposer, self.proposal_cost);
89+
let _ = <T as crate::Config>::Currency::transfer(
90+
&crate::DaoTreasuryAddress::<T>::get(),
91+
&self.proposer,
92+
self.proposal_cost,
93+
ExistenceRequirement::AllowDeath,
94+
);
9495

9596
match self.data {
9697
ProposalData::GlobalParams(data) => {
@@ -415,13 +416,13 @@ fn add_proposal<T: crate::Config>(
415416
let config = GlobalGovernanceConfig::<T>::get();
416417

417418
let cost = config.proposal_cost;
418-
let _ = <T as crate::Config>::Currency::withdraw(
419+
<T as crate::Config>::Currency::transfer(
419420
&proposer,
421+
&crate::DaoTreasuryAddress::<T>::get(),
420422
cost,
421-
WithdrawReasons::except(WithdrawReasons::TIP),
422423
ExistenceRequirement::AllowDeath,
423424
)
424-
.map_err(|_| crate::Error::<T>::NotEnoughBalanceToPropose)?;
425+
.map_err(|_| crate::Error::<T>::NotEnoughBalanceToApply)?;
425426

426427
let proposal_id: u64 = crate::Proposals::<T>::iter()
427428
.count()

pallets/governance/tests/application.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
use pallet_emission0::PendingEmission;
12
use pallet_governance::{
23
application::ApplicationStatus, AgentApplications, GlobalGovernanceConfig, Whitelist,
34
};
5+
use pallet_governance::{DaoTreasuryAddress, TreasuryEmissionFee};
6+
use pallet_governance_api::GovernanceApi;
47
use polkadot_sdk::frame_support::assert_err;
8+
use polkadot_sdk::sp_runtime::Percent;
59
use test_utils::*;
610

711
#[test]
@@ -205,6 +209,10 @@ fn error_is_thrown_on_multiple_applications_same_key() {
205209
#[test]
206210
fn application_denied_doesnt_add_to_whitelist() {
207211
new_test_ext().execute_with(|| {
212+
PendingEmission::<Test>::set(0);
213+
TreasuryEmissionFee::<Test>::set(Percent::zero());
214+
let balance = get_balance(DaoTreasuryAddress::<Test>::get());
215+
208216
let key = 0;
209217
let adding_key = 1;
210218
pallet_governance::Curators::<Test>::insert(key, ());
@@ -251,6 +259,10 @@ fn application_denied_doesnt_add_to_whitelist() {
251259
application.status,
252260
ApplicationStatus::Resolved { accepted: false }
253261
);
262+
assert_eq!(
263+
get_balance(Governance::dao_treasury_address()),
264+
balance + crate::GlobalGovernanceConfig::<Test>::get().agent_application_cost
265+
);
254266
});
255267
}
256268

@@ -263,6 +275,10 @@ fn application_expires() {
263275
config.agent_application_expiration
264276
});
265277

278+
PendingEmission::<Test>::set(0);
279+
TreasuryEmissionFee::<Test>::set(Percent::zero());
280+
let balance = get_balance(DaoTreasuryAddress::<Test>::get());
281+
266282
let key = 0;
267283
let adding_key = 1;
268284
pallet_governance::Curators::<Test>::insert(key, ());
@@ -291,6 +307,10 @@ fn application_expires() {
291307
let application =
292308
pallet_governance::AgentApplications::<Test>::get(application_id).unwrap();
293309
assert_eq!(application.status, ApplicationStatus::Expired);
310+
assert_eq!(
311+
get_balance(Governance::dao_treasury_address()),
312+
balance + crate::GlobalGovernanceConfig::<Test>::get().agent_application_cost
313+
);
294314
});
295315
}
296316

pallets/governance/tests/voting.rs

Lines changed: 115 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
use pallet_governance::proposal::{Proposal, ProposalData};
2-
use pallet_governance::Error;
3-
use pallet_governance::{proposal::ProposalStatus, Proposals};
4-
use polkadot_sdk::frame_support::{assert_err, assert_ok};
5-
use polkadot_sdk::sp_runtime::BoundedVec;
1+
use pallet_emission0::PendingEmission;
2+
use pallet_governance::{
3+
proposal::{Proposal, ProposalData, ProposalStatus},
4+
DaoTreasuryAddress, Error, GlobalGovernanceConfig, Proposals, TreasuryEmissionFee,
5+
};
6+
use pallet_governance_api::GovernanceApi;
7+
use polkadot_sdk::frame_support::assert_err;
8+
use polkadot_sdk::{frame_support::assert_ok, sp_runtime::Percent};
9+
use polkadot_sdk::{frame_support::traits::Get, sp_runtime::BoundedVec};
610
use test_utils::{
7-
add_balance, get_balance, get_origin, new_test_ext, to_nano, zero_min_burn, AccountId, Test,
11+
add_balance, get_balance, get_origin, new_test_ext, step_block, to_nano, zero_min_burn,
12+
AccountId, Governance, Test,
813
};
914

1015
fn register(account: AccountId, _unused: u16, module: AccountId, stake: u128) {
@@ -74,7 +79,49 @@ fn removes_vote_correctly() {
7479
const FOR: u32 = 0;
7580
const AGAINST: u32 = 1;
7681

82+
let key = 0;
83+
7784
register(FOR, 0, 0, to_nano(10));
85+
register(AGAINST, 0, 1, to_nano(5));
86+
87+
config(1, 100);
88+
89+
add_balance(key, 1);
90+
assert_ok!(
91+
pallet_governance::Pallet::<Test>::add_global_custom_proposal(
92+
get_origin(key),
93+
b"metadata".to_vec()
94+
)
95+
);
96+
97+
vote(FOR, 0, true);
98+
vote(AGAINST, 0, false);
99+
100+
step_block(100);
101+
102+
assert_eq!(
103+
Proposals::<Test>::get(0).unwrap().status,
104+
ProposalStatus::Accepted {
105+
block: 100,
106+
stake_for: to_nano(10),
107+
stake_against: to_nano(5),
108+
}
109+
);
110+
});
111+
}
112+
113+
#[test]
114+
fn global_proposal_is_refused_correctly() {
115+
new_test_ext().execute_with(|| {
116+
PendingEmission::<Test>::set(0);
117+
TreasuryEmissionFee::<Test>::set(Percent::zero());
118+
let balance = get_balance(DaoTreasuryAddress::<Test>::get());
119+
120+
zero_min_burn();
121+
const FOR: u32 = 0;
122+
const AGAINST: u32 = 1;
123+
124+
register(FOR, 0, 0, to_nano(5));
78125
register(AGAINST, 0, 1, to_nano(10));
79126

80127
config(1, 100);
@@ -103,6 +150,11 @@ fn removes_vote_correctly() {
103150
}
104151
_ => unreachable!(),
105152
}
153+
154+
assert_eq!(
155+
get_balance(Governance::dao_treasury_address()),
156+
balance + crate::GlobalGovernanceConfig::<Test>::get().proposal_cost
157+
);
106158
});
107159
}
108160

@@ -149,27 +201,80 @@ fn ensures_proposal_exists() {
149201
zero_min_burn();
150202

151203
const MODULE: u32 = 0;
204+
PendingEmission::<Test>::set(0);
205+
TreasuryEmissionFee::<Test>::set(Percent::zero());
206+
let balance = get_balance(DaoTreasuryAddress::<Test>::get());
152207

153-
register(MODULE, 0, 0, to_nano(10));
208+
let min_stake: u128 = <Test as pallet_torus0::Config>::DefaultMinAllowedStake::get();
209+
let default_proposal_expiration: u64 =
210+
<Test as pallet_governance::Config>::DefaultProposalExpiration::get();
154211

155212
config(1, 100);
156213

214+
let origin = get_origin(0);
215+
add_balance(0, to_nano(2));
216+
register(0, 0, 0, to_nano(1) - min_stake);
217+
157218
if pallet_torus0::stake::sum_staked_by::<Test>(&MODULE) < 1 {
158219
stake(MODULE, MODULE, to_nano(1));
159220
}
160221

222+
let _ = pallet_governance::roles::penalize_agent::<Test>(0, 100);
223+
pallet_torus0::TotalStake::<Test>::set(to_nano(10));
224+
225+
assert_ok!(pallet_governance::Pallet::<Test>::add_emission_proposal(
226+
origin.clone(),
227+
Percent::from_parts(20),
228+
Percent::from_parts(20),
229+
Percent::from_parts(20),
230+
vec![b'0'; 64],
231+
));
232+
233+
vote(0, 0, true);
234+
235+
step_block(default_proposal_expiration);
236+
237+
assert_eq!(
238+
Proposals::<Test>::get(0).unwrap().status,
239+
ProposalStatus::Expired
240+
);
241+
assert_eq!(
242+
get_balance(Governance::dao_treasury_address()),
243+
balance + crate::GlobalGovernanceConfig::<Test>::get().proposal_cost
244+
);
245+
});
246+
}
247+
248+
#[test]
249+
fn creates_emission_proposal_with_invalid_params_and_it_fails() {
250+
new_test_ext().execute_with(|| {
251+
const MODULE: AccountId = 0;
252+
253+
zero_min_burn();
254+
255+
let default_proposal_expiration: u64 =
256+
<Test as pallet_governance::Config>::DefaultProposalExpiration::get();
257+
258+
let min_stake: u128 = <Test as pallet_torus0::Config>::DefaultMinAllowedStake::get();
259+
260+
config(1, default_proposal_expiration);
261+
262+
let origin = get_origin(MODULE);
263+
add_balance(MODULE, to_nano(2));
264+
register(MODULE, 0, MODULE, to_nano(1) - min_stake);
265+
161266
assert_err!(
162-
pallet_governance::Pallet::<Test>::vote_proposal(get_origin(MODULE), 0, true),
267+
pallet_governance::Pallet::<Test>::vote_proposal(origin.clone(), 0, true),
163268
Error::<Test>::ProposalNotFound
164269
);
165270

166271
assert_err!(
167-
pallet_governance::Pallet::<Test>::vote_proposal(get_origin(MODULE), 0, false),
272+
pallet_governance::Pallet::<Test>::vote_proposal(origin.clone(), 0, false),
168273
Error::<Test>::ProposalNotFound
169274
);
170275

171276
assert_err!(
172-
pallet_governance::Pallet::<Test>::remove_vote_proposal(get_origin(MODULE), 0),
277+
pallet_governance::Pallet::<Test>::remove_vote_proposal(origin, 0),
173278
Error::<Test>::ProposalNotFound
174279
);
175280
});

pallets/torus0/src/agent.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use polkadot_sdk::{
66
frame_support::{
77
dispatch::DispatchResult,
88
ensure,
9-
traits::{Currency, ExistenceRequirement, WithdrawReasons},
9+
traits::{Currency, ExistenceRequirement},
1010
DebugNoBound,
1111
},
1212
polkadot_sdk_frame::prelude::BlockNumberFor,
@@ -101,10 +101,11 @@ pub fn register<T: crate::Config>(
101101

102102
let burn = crate::Burn::<T>::get();
103103

104-
let _ = <T as crate::Config>::Currency::withdraw(
104+
// Registration cost is sent to treasury
105+
<T as crate::Config>::Currency::transfer(
105106
&payer,
107+
&<T as crate::Config>::Governance::dao_treasury_address(),
106108
burn,
107-
WithdrawReasons::except(WithdrawReasons::TIP),
108109
ExistenceRequirement::AllowDeath,
109110
)
110111
.map_err(|_| crate::Error::<T>::NotEnoughBalanceToRegisterAgent)?;

pallets/torus0/tests/agent.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1+
use pallet_governance_api::GovernanceApi;
12
use pallet_torus0::{
23
agent::Agent, AgentUpdateCooldown, Agents, Burn, Error, ImmunityPeriod, MaxAllowedAgents,
34
};
45
use polkadot_sdk::{frame_support::assert_err, sp_core::Get, sp_runtime::Percent};
56
use test_utils::{
6-
assert_ok, clear_cooldown, get_origin,
7-
pallet_emission0::{ConsensusMembers, WeightControlDelegation},
8-
pallet_governance::{self, Allocators},
9-
step_block, Test,
7+
assert_ok, clear_cooldown, get_balance, get_origin,
8+
pallet_emission0::{ConsensusMembers, PendingEmission, WeightControlDelegation},
9+
pallet_governance::{self, Allocators, DaoTreasuryAddress, TreasuryEmissionFee},
10+
step_block, Governance, Test,
1011
};
1112

1213
#[test]
1314
fn register_correctly() {
1415
test_utils::new_test_ext().execute_with(|| {
16+
PendingEmission::<Test>::set(0);
17+
TreasuryEmissionFee::<Test>::set(Percent::zero());
18+
let balance = get_balance(DaoTreasuryAddress::<Test>::get());
19+
1520
let agent_id = 0;
1621
let allocator_id = 1;
17-
let name = "agent".as_bytes().to_vec();
22+
23+
let name = "idk://agent".as_bytes().to_vec();
1824
let url = "idk://agent".as_bytes().to_vec();
1925
let metadata = "idk://agent".as_bytes().to_vec();
2026

@@ -67,6 +73,11 @@ fn register_correctly() {
6773
),
6874
Error::<Test>::AgentAlreadyRegistered
6975
);
76+
77+
assert_eq!(
78+
get_balance(Governance::dao_treasury_address()),
79+
balance + Burn::<Test>::get()
80+
);
7081
});
7182
}
7283

0 commit comments

Comments
 (0)