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

Cwd proposal delegate #562

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6d8035d
init cwd-proposal-delegate
baoskee Nov 22, 2022
5a7afcf
Msg + Error + State design
baoskee Nov 22, 2022
3ccfe6d
Skeleton code setup
baoskee Nov 22, 2022
c0383c2
execute and state redesign for security
baoskee Nov 23, 2022
afab973
execute_delegate and execute_remove_delegation
baoskee Nov 23, 2022
9642d52
execute_execute body
baoskee Nov 23, 2022
d54df15
Reply implementation for submessage
baoskee Nov 23, 2022
0a995fc
Query functions
baoskee Nov 23, 2022
1fd25d2
Added smart contract risks section
baoskee Nov 23, 2022
a474388
Update contracts/proposal/cwd-proposal-delegate/Cargo.toml
baoskee Dec 27, 2022
4d679b0
Update contracts/proposal/cwd-proposal-delegate/Cargo.toml
baoskee Dec 27, 2022
b8c9830
Merge https://github.com/DA0-DA0/dao-contracts into cwd-proposal-dele…
baoskee Dec 27, 2022
a103eee
new cargo.toml
baoskee Dec 27, 2022
cf21c54
Removed exposure of delegation count
baoskee Dec 27, 2022
683ccd8
merged
baoskee Dec 27, 2022
2a3ea2a
test shell
baoskee Dec 27, 2022
f433008
Added testing strategy
baoskee Dec 27, 2022
d44ffb7
test unauthorized delegation
baoskee Dec 27, 2022
d3513e9
execute_authorization tests
baoskee Dec 27, 2022
b003b9a
Expiration test
baoskee Dec 27, 2022
07f2358
Revocable policy and delegation not found error path
baoskee Dec 27, 2022
b0e54d0
First try at testing submessage
baoskee Dec 28, 2022
5c1bc28
Added pagination query for delegations
baoskee Dec 28, 2022
c635cca
Reply hook testing
baoskee Dec 28, 2022
b8e34e3
refactor to policy_module_irrevocable
baoskee Dec 28, 2022
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
4 changes: 4 additions & 0 deletions contracts/proposal/cwd-proposal-delegate/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[alias]
wasm = "build --release --lib --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --bin schema"
16 changes: 16 additions & 0 deletions contracts/proposal/cwd-proposal-delegate/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Build results
/target
/schema

# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
.cargo-ok

# Text file backups
**/*.rs.bk

# macOS
.DS_Store

# IDEs
*.iml
.idea
55 changes: 55 additions & 0 deletions contracts/proposal/cwd-proposal-delegate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[package]
name = "cwd-proposal-delegate"
version = "0.1.0"
authors = ["Bao <baomai@berkeley.edu>"]
edition = "2021"

exclude = [
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"contract.wasm",
"hash.txt",
]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib", "rlib"]

[profile.release]
opt-level = 3
debug = false
rpath = false
lto = true
debug-assertions = false
codegen-units = 1
panic = 'abort'
incremental = false
overflow-checks = true

[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []

[package.metadata.scripts]
optimize = """docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/rust-optimizer:0.12.6
"""
baoskee marked this conversation as resolved.
Show resolved Hide resolved

[dependencies]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all of these can be cosmwasm-x = { workspace = true }

cosmwasm-schema = "1.1.3"
cosmwasm-std = "1.1.3"
cosmwasm-storage = "1.1.3"
baoskee marked this conversation as resolved.
Show resolved Hide resolved
cw-storage-plus = "0.15.1"
cw-utils.workspace = true
cw2 = "0.15.1"
schemars = "0.8.10"
serde = { version = "1.0.145", default-features = false, features = ["derive"] }
thiserror = { version = "1.0.31" }
cwd-core = { workspace = true, features = ["library"] }

[dev-dependencies]
cw-multi-test = "0.15.1"
95 changes: 95 additions & 0 deletions contracts/proposal/cwd-proposal-delegate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Introduction

Delegation is basically: “we trust you have the judgment, we give you the power to do this specific action within some X time frame. You have the right but not the obligation.”

## Examples
- You have the power to kick this specific member after review. Perhaps you make an investigative committee after a member is accused of something, and delegate the power to a multisig to execute the message: “Kick this member”
- You can pause one of our SubDAOs for 1 week if necessary
- You have the power to add a specific item to our DAO config at any time
- You have the power to increase Bob’s salary by 800 JUNO through DAO treasury
- Liquidate 8000 JUNO through JunoSwap at any time. Perhaps you want to delegate this to a hedge fund who promises to “time the market”

## When would it not be useful?

- **You can compose it through something other than a proposal module**. A separate option contract. However, this would not allow you to execute messages through the core module. Only proposal modules can pass messages through the core module.
- In order to control Treasury funds, you can siphon off to a SubDAO, and then SubDAO can make the decisions. However, this does not constrain the action of the SubDAO. It can totally misuse those funds. We want allowance of specific and concrete messages.
- In most cases, an escrow contract would do the job, but in certain cases, we want to be very granular with the actions we delegate

## When would it be useful?

- **For specific, constrained DAO-related actions**. For the things the DAO control and in which an escrow would give too much power over the resource. The DAO wants delegation on specific message that gives the delegate constrained power
- **Time-based actions**. Actions where the time of execution matters, and an executive decision maker needs power to execute at any time
- **Judgment-based actions**. Perhaps another DAO or oracle service specializes in identity-proving activities, and you would like to mark certain members as a real person for some sort of one person one vote thing. Or, perhaps, you want to remove a multisig member, and decide to delegate said action to a Judiciary DAO, some sort of tribunal



# Design

This is kind of a “messages escrow” module in which the execution of the proposal is wrapped into an option and execution is given to another party.


It would be a “proposal module” that allows arbitrary wrapping of messages, and would be required for the DAO to add as a Proposal Module. However, it would not use a voting module, but rather, another proposal module like `cwd-proposal-single` would pass a delegation message to the Core module, whereby the core module would execute a delegation message.

Execution messages:

```rust
// Gives back a delegation ID
Delegate { msgs: Vec<CosmosMsg<Empty>>, addr: String, expiration: Expiration }
// Authorized execution only
Execute { delegation_id: u64 }
```

State:

```rust
struct Config {
admin: Addr,
}

struct Delegation {
addr: Addr,
msgs: Vec<CosmosMsg<Empty>>,
expiration: Expiration,
}

const DELEGATIONS: Map<u64, Delegation> = Map::new("delegations");
const CONFIG: Item<Config> = Item::new("config");
```

## How could a DaoDao core module use this?

1. Add as a proposal module
2. Pass a delegation message through another proposal module (single or multiple-choice) as a Wasm message (converted into Cosmos message)

```rust
WasmMsg::Execute {
contract_addr: // address of Delegation Proposal Module
msg: to_binary(&DelegationExecuteMsg::Delegate {
msgs: // Cosmos messages to delegate,
addr: "0x2342", // Delegate with power to execute, possibly another DAO
expiration: 123123324
})?,
funds: vec![]
}
```

3. The delegate has the power to execute said proposal through the Delegate Proposal Module at any time up until expiration. Said execution would go through the DaoDao core module


# Smart Contract Risks
Proposal modules can route arbitrary messages to
the core module so we have to take special care.
I can classify risks into these domains:
* Un-authorized delegation
* Un-authorized execution
* Un-authorized revocation
* Multiple execution
* Expired execution

Policy risks:
* Forbidden revoking when policy enabled
* Does not preserve on failure when policy enabled


Of all the risks, un-authorized delegation will definitely
compromise the core module.
11 changes: 11 additions & 0 deletions contracts/proposal/cwd-proposal-delegate/src/bin/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use cosmwasm_schema::write_api;

use cwd_proposal_delegate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};

fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ExecuteMsg,
query: QueryMsg,
}
}
Loading