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

Proposal Incentives & Voting Incentives #797

Open
wants to merge 49 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
fb60e86
Smart contract skeleton for voting incentives
JakeHartnell Jan 9, 2024
16bfaee
More comments
JakeHartnell Jan 23, 2024
bd79371
dao-proposal-incentives initial commit
JakeHartnell Jan 24, 2024
97e2472
Add more design notes and TODOs
JakeHartnell Jan 24, 2024
c1ef0bf
Proposal incentives fixups and notes
JakeHartnell Jan 25, 2024
a7bb852
Voting incentives checks and notes
JakeHartnell Jan 25, 2024
21c488b
More notes
JakeHartnell Jan 25, 2024
b7b01cb
Proposal Incentives
ismellike Jan 31, 2024
834e16e
Fix clippy errors
ismellike Jan 31, 2024
34c7474
More clippy
ismellike Jan 31, 2024
41b15fe
Schema + clippy fix
ismellike Feb 1, 2024
ed344a4
Progress on voting incentives
ismellike Feb 7, 2024
f0c494b
Handle revoting and update readme's
ismellike Feb 7, 2024
1c3d428
Update README.md
ismellike Feb 7, 2024
86c85f5
Work on voting tests
ismellike Feb 8, 2024
01eedd6
Fix for simultaneous hook error handling
ismellike Feb 9, 2024
e4477df
Wrap up tests for voting incentives
ismellike Feb 10, 2024
30bfeab
Combine rewards queries
ismellike Feb 13, 2024
2816beb
Add is_claimable flag to reward response
ismellike Feb 14, 2024
a86f0dc
Merge branch 'development' into gov-incentives
ismellike May 7, 2024
a76127f
Schemas and clippy fixes
ismellike May 8, 2024
064f353
Update contracts/external/dao-proposal-incentives/Cargo.toml
ismellike Jun 13, 2024
8849221
Smart contract skeleton for voting incentives
JakeHartnell Jan 9, 2024
55b9665
More comments
JakeHartnell Jan 23, 2024
aa3dd76
dao-proposal-incentives initial commit
JakeHartnell Jan 24, 2024
e219dea
Add more design notes and TODOs
JakeHartnell Jan 24, 2024
76f5ca1
Proposal incentives fixups and notes
JakeHartnell Jan 25, 2024
40dd5fe
Voting incentives checks and notes
JakeHartnell Jan 25, 2024
632bfe4
More notes
JakeHartnell Jan 25, 2024
d2c39be
Proposal Incentives
ismellike Jan 31, 2024
dbab201
Fix clippy errors
ismellike Jan 31, 2024
3597697
More clippy
ismellike Jan 31, 2024
012f8c3
Schema + clippy fix
ismellike Feb 1, 2024
2bf1ec1
Progress on voting incentives
ismellike Feb 7, 2024
5c9383f
Handle revoting and update readme's
ismellike Feb 7, 2024
22a13d1
Update README.md
ismellike Feb 7, 2024
65fa0de
Work on voting tests
ismellike Feb 8, 2024
9419658
Fix for simultaneous hook error handling
ismellike Feb 9, 2024
6961ce6
Wrap up tests for voting incentives
ismellike Feb 10, 2024
809ba2c
Combine rewards queries
ismellike Feb 13, 2024
1d5bd35
Add is_claimable flag to reward response
ismellike Feb 14, 2024
21eb271
Schemas and clippy fixes
ismellike May 8, 2024
4a9a9e1
Update contracts/external/dao-proposal-incentives/Cargo.toml
ismellike Jun 13, 2024
778a361
Improve proposal & voting incentives readme's + add not audited warnings
ismellike Aug 16, 2024
2fb9ec5
Merge branch 'gov-incentives' of https://github.com/ismellike/dao-con…
ismellike Aug 16, 2024
7cce5b3
gen schema
ismellike Aug 16, 2024
754442d
Disable doctests on gov-incentives
ismellike Aug 16, 2024
ffe92b1
Bump integration_tests to nightly toolchain
ismellike Aug 16, 2024
c3b6321
Free up space for test_tube.yml
ismellike Aug 16, 2024
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
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ dao-voting-cw20-staked = { path = "./contracts/voting/dao-voting-cw20-staked", v
dao-voting-cw4 = { path = "./contracts/voting/dao-voting-cw4", version = "2.4.0" }
dao-voting-cw721-roles = { path = "./contracts/voting/dao-voting-cw721-roles", version = "2.4.0" }
dao-voting-cw721-staked = { path = "./contracts/voting/dao-voting-cw721-staked", version = "2.4.0" }
dao-voting-incentives = { path = "./contracts/external/dao-voting-incentives", version = "2.4.0" }
dao-voting-token-staked = { path = "./contracts/voting/dao-voting-token-staked", version = "2.4.0" }

# v1 dependencies. used for state migrations.
Expand Down
8 changes: 3 additions & 5 deletions contracts/external/dao-proposal-incentives/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ To instantiate the contract, provide the following parameters:
- `owner`: The DAO sending this contract proposal hooks.
- `proposal_incentives`: Configuration for the incentives to be awarded for successful proposals. This should be specified using the `ProposalIncentivesUnchecked` structure.

## Setup
## Configuration

- This contract should be added as a `ProposalHook` to either the `dao-voting-single` or `dao-voting-multiple` proposal modules.
- The DAO must be set as the `owner` of this contract to manage incentives and ownership.

The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources.

## Execute

- **ProposalHook(ProposalHookMsg)**: Triggered when a proposal's status changes. This is used to evaluate and potentially reward successful proposals.
Expand All @@ -27,7 +29,3 @@ To instantiate the contract, provide the following parameters:
## Query

- **ProposalIncentives { height: Option<u64> }**: Returns the current configuration of the proposal incentives. The `height` parameter is optional and can be used to query the incentives at a specific blockchain height, providing a snapshot of the incentives at that point in time.

## Configuration

The incentives can be adjusted at any time by the owner of the contract. The rewards are determined based on the configuration at the proposal's `start_time`. This allows for dynamic adjustment of incentives to reflect the DAO's evolving priorities and resources.
59 changes: 23 additions & 36 deletions contracts/external/dao-proposal-incentives/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ use std::vec;

use cosmwasm_std::{
testing::{mock_dependencies, mock_env},
to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, Uint128, WasmMsg,
to_json_binary, Addr, Binary, Coin, CosmosMsg, Uint128, WasmMsg,
};

use cw20::Cw20Coin;
use cw_denom::{CheckedDenom, UncheckedDenom};
use cw_multi_test::{
error::AnyResult, App, AppBuilder, AppResponse, Contract, ContractWrapper, Executor,
};
use cw_multi_test::{error::AnyResult, App, AppBuilder, AppResponse, Executor};
use cw_ownable::Ownership;
use dao_testing::{
contracts::{dao_proposal_incentives_contract, proposal_single_contract},
contracts::{cw20_base_contract, dao_proposal_incentives_contract, proposal_single_contract},
helpers::instantiate_with_cw4_groups_governance,
};
use dao_voting::{proposal::SingleChoiceProposeMsg, threshold::Threshold};
Expand All @@ -35,15 +33,6 @@ struct Context {
dao_proposal_incentives_code_id: u64,
}

fn cw20_base_contract() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new(
cw20_base::contract::execute,
cw20_base::contract::instantiate,
cw20_base::contract::query,
);
Box::new(contract)
}

fn get_context() -> Context {
// Set up app with native balances
let mut app = AppBuilder::default().build(|router, _, storage| {
Expand Down Expand Up @@ -352,28 +341,26 @@ pub fn test_hook() {
assert!(result.is_ok());

// Propose adding a hook
context
.app
.execute_contract(
Addr::unchecked(ADDR1),
context.proposal_single_addr.clone(),
&dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg {
title: "Add proposal hook".to_string(),
description: "Adding a proposal hook to test the dao_proposal_incentives contract"
.to_string(),
msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: context.proposal_single_addr.to_string(),
msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook {
address: dao_proposal_incentives_addr.to_string(),
})
.unwrap(),
funds: vec![],
})],
proposer: None,
}),
&[],
)
.unwrap();
let result = context.app.execute_contract(
Addr::unchecked(ADDR1),
context.proposal_single_addr.clone(),
&dao_proposal_single::msg::ExecuteMsg::Propose(SingleChoiceProposeMsg {
title: "Add proposal hook".to_string(),
description: "Adding a proposal hook to test the dao_proposal_incentives contract"
.to_string(),
msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: context.proposal_single_addr.to_string(),
msg: to_json_binary(&dao_proposal_single::msg::ExecuteMsg::AddProposalHook {
address: dao_proposal_incentives_addr.to_string(),
})
.unwrap(),
funds: vec![],
})],
proposer: None,
}),
&[],
);
assert!(result.is_ok());

// Vote and execute the proposal to add the proposal hook
vote_yes_on_proposal(&mut context, 1u64).unwrap();
Expand Down
3 changes: 3 additions & 0 deletions contracts/external/dao-voting-incentives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ cw-multi-test = { workspace = true }
dao-dao-core = { workspace = true, features = ["library"] }
cw20-base = { workspace = true, features = ["library"] }
cw-hooks = { workspace = true }
dao-testing = { workspace = true }
dao-hooks = { workspace = true }
dao-proposal-single = { workspace = true, features = ["library"] }
7 changes: 7 additions & 0 deletions contracts/external/dao-voting-incentives/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use cosmwasm_std::{
};
use cw2::set_contract_version;
use cw_ownable::get_ownership;
use cw_utils::Expiration;

use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
Expand Down Expand Up @@ -33,6 +34,11 @@ pub fn instantiate(
if msg.expiration.is_expired(&env.block) {
return Err(ContractError::AlreadyExpired {});
}
if let Expiration::Never {} = msg.expiration {
return Err(ContractError::NotExpired {
expiration: Expiration::Never {},
});
}

// Save voting incentives config
CONFIG.save(
Expand Down Expand Up @@ -81,6 +87,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
}
QueryMsg::Config {} => to_json_binary(&query::config(deps)?),
QueryMsg::Ownership {} => to_json_binary(&get_ownership(deps.storage)?),
QueryMsg::Votes { address } => to_json_binary(&query::votes(deps, address)?),
}
}

Expand Down
3 changes: 3 additions & 0 deletions contracts/external/dao-voting-incentives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ pub mod msg;
pub mod query;
pub mod state;

#[cfg(test)]
mod tests;

pub use crate::error::ContractError;
3 changes: 3 additions & 0 deletions contracts/external/dao-voting-incentives/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub enum QueryMsg {
/// Returns the expected rewards for the given address
#[returns(RewardResponse)]
ExpectedRewards { address: String },
/// Returns the votes count for the given address
#[returns(Uint128)]
Votes { address: String },
}

#[cw_serde]
Expand Down
12 changes: 10 additions & 2 deletions contracts/external/dao-voting-incentives/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use cosmwasm_std::{Deps, Env, StdError, StdResult};
use cosmwasm_std::{Deps, Env, StdError, StdResult, Uint128};

use crate::{
msg::RewardResponse,
state::{self, Config, CONFIG},
state::{self, Config, CONFIG, USER_VOTE_COUNT},
};

pub fn rewards(deps: Deps, address: String) -> StdResult<RewardResponse> {
Expand All @@ -21,3 +21,11 @@ pub fn expected_rewards(deps: Deps, env: Env, address: String) -> StdResult<Rewa
pub fn config(deps: Deps) -> StdResult<Config> {
CONFIG.load(deps.storage)
}

pub fn votes(deps: Deps, address: String) -> StdResult<Uint128> {
let address = deps.api.addr_validate(&address)?;

Ok(USER_VOTE_COUNT
.may_load(deps.storage, &address)?
.unwrap_or_default())
}
Loading
Loading