A simple DAO for managing 'items'. Items consist of a name and some contents. One might use items to store pages on a website or dictionary definitions for a conlang group.
Item DAO implements the base CW20
spec
providing a token called IDAO
which is used for voting.
A schema which provides information about the format of messages that
can be sent to Item DAO can be generated by running cargo schema
and
browsing schmea/
.
Say we want to create an item dao that holds contact information about our group.
First, we instantiate a version of itemdao. Here we use code_id
94
as that is the most recent version of item dao listed below in the
"Addresses" section. During the instantiation we'll send some tokens
to some of our friends who are part of the DAO. Here's the command:
junod tx wasm instantiate 94 '{"quorum":"100","proposal_cost":"1","token_info":{"name":"Item DAO","symbol":"IDAO","decimals":0,"initial_balances":[{"address":"juno1m7a7nva00p82xr0tssye052r8sxsxvcy2v5qz6","amount":"1000000"},{"address":"juno1754qkhjmpx79swk445zgg5vge2sh33ejzgc28z","amount":"1000000"}]}}' --label 'v0.5' --from ocax101 --chain-id uni --gas auto --fees 5000ujunox
This is a big command. You'll want to replace the --from
line with
the name of a key you have on your local machine. You'll also want to
replace the addresses above with the address of your friends who you
would like to send tokens to.
Here's a better look at the initialization message that we're sending to the contract:
{
"quorum": "100",
"proposal_cost": "1",
"token_info": {
"name": "Item DAO",
"symbol": "IDAO",
"decimals": 0,
"initial_balances": [
{
"address": "juno1m7a7nva00p82xr0tssye052r8sxsxvcy2v5qz6",
"amount": "1000000"
},
{
"address": "juno1754qkhjmpx79swk445zgg5vge2sh33ejzgc28z",
"amount": "1000000"
}
]
}
}
As you can see in the initial_balances
section we are sending a
million tokens to our friends who will be part of the DAO. You need
these tokens to vote.
Having instantiated the DAO lets submit a proposal that will add a contact for ourselves. Our proposal will look like this:
{
"propose": {
"title": "add zeke to the address book",
"body": "zeke is a good friend and we should keep their email around",
"action": {
"add_item": {
"name": "zeke",
"contents": "zekemedley@gmail.com"
}
}
}
}
Our command to submit the proposal will look like this:
junod tx wasm execute juno15ah47zrj2qdcfa3ane6psv0xnylsdjuj3ccxlqprun4ymzsh8kkqzjhxv0 '{"propose":{"title":"add zeke to the address book","body":"zeke is a good friend and we should keep their email around","action":{"add_item":{"name":"zeke","contents":"zekemedley@gmail.com"}}}}' --from ocax101 --output json --yes --fees 6000ujunox --gas auto
Having done that we can query the DAO to see what the status of our proposal is. Because this is the first proposal to be submitted to the DAO it has ID 0.
junod query wasm contract-state smart juno1eu70kcgh0d2rlm0n88dgtry9wpqnerf5n2fdzt5sxm6d3vrqq3xqa5e9x8 '{"get_proposal":{"proposal_id":0}}' --output json | jq
Cool! This will show us output like this:
{
"data": {
"title": "add zeke to the address book",
"body": "zeke is a good friend and we should keep their email around",
"action": {
"add_item": {
"name": "zeke",
"contents": "zekemedley@gmail.com"
}
},
"status": "Pending",
"yes": [],
"no": [],
"abstain": [],
"proposer": "juno1754qkhjmpx79swk445zgg5vge2sh33ejzgc28z",
"proposal_cost": "1"
}
}
Now lets vote on the proposal. In this case we have enough tokens to pass it ourselves. In a world where your DAO is managed by your friends you'd probably want to set the quorum to be high enough that this is less easy.
junod tx wasm execute juno1eu70kcgh0d2rlm0n88dgtry9wpqnerf5n2fdzt5sxm6d3vrqq3xqa5e9x8 '{"vote":{"proposal_id":0,"position":"yes","amount":"100"}}' --from ocax101 --output json --yes --fees 6000ujunox --gas auto
Now if we query the proposal state again we can see that the proposal has passed!
{
"data": {
"title": "add zeke to the address book",
"body": "zeke is a good friend and we should keep their email around",
"action": {
"add_item": {
"name": "zeke",
"contents": "zekemedley@gmail.com"
}
},
"status": "Passed",
"yes": [
[
"juno1754qkhjmpx79swk445zgg5vge2sh33ejzgc28z",
"100"
]
],
"no": [],
"abstain": [],
"proposer": "juno1754qkhjmpx79swk445zgg5vge2sh33ejzgc28z",
"proposal_cost": "1"
}
}
The output of this proposal was a new item. In the yes
section we
can see that our vote and the amount of tokens we staked was
recorded. We can also query the contract to see that new item as
follows:
junod query wasm contract-state smart juno1eu70kcgh0d2rlm0n88dgtry9wpqnerf5n2fdzt5sxm6d3vrqq3xqa5e9x8 '{"get_item":{"item_id":0}}' --output json | jq
{
"data": {
"name": "zeke",
"contents": "zekemedley@gmail.com"
}
}
Finally, we can verify that the tokens that we used to vote were sent back to us when the vote completed by running:
junod query wasm contract-state smart juno1eu70kcgh0d2rlm0n88dgtry9wpqnerf5n2fdzt5sxm6d3vrqq3xqa5e9x8 '{"balance":{"address":"juno1754qkhjmpx79swk445zgg5vge2sh33ejzgc28z"}}'
This is just a sample of the commands avaliable to interact with the
DAO. For a complete reference see src/msg.rs
Item DAO was initially designed as two contracts: a CW20 token and a DAO which used that token for voting. After some consideration I opted to implement the CW20 interface inside of the DAO. Doing so meant that there was no longer a need to pay gas fees for the return of tokens to voters after the completion of a proposal.
Item DAO has two parameters: quorum
and proposal_cost
. The quorum
that is set determines how many tokens must be staked to a vote before
that vote can pass. The proposal cost determines how many tokens must
be staked to create a proposal. Upon the completion of a vote all
staked tokens are returned.
src/message.rs
contains the types that Item DAO uses to send and
receive messages as well as the test suite.src/contract.rs
contains the central logic for the DAO.src/actions.rs
contains logic related to processing new proposals
,votes, and withdrawals.src/tokens.rs
contains logic related to the implementation of the
CW20 interface.Item DAO is deployed on the uni testnet. The most recent version which
completes the DAO is not yet published as I am out of ujunox
until
the faucet comes back online.
token program: Initial mint of 100,000 tokens. Unmodified cw20-base contract. This is DAO prehistory from when the DAO was two contracts.
juno1slz6c85kxp4ek5ufmcakfhnscv9r2snlemxgwz6cjhklgh7v2hmsnwzy2k
23
dao program v0.1
Does nothing. Just tests that I understand how passing arguments into
queries and executions work.
28
juno14q5elxj4ghktt7d7d0uw0cs0gqyeay25h5fkree897gjm38gevxqexk8fn
dao program v0.2
Allows creation of proposals and voting on those proposals. All coins
sent to contract are burned. Features a bug where enums were not
converted to snake case during serialization.
59
juno1cxnmukp9tjxksduey6wkgqmwzuvhvqqcwqq54pfh45xt7ze9kmjsjhng0u
dao program v0.3
Same as v0.2 but with the snake case bug fixed.
60
juno10wmp4czgnww9tvwg7xu239k88vx4ksyqwah245nsaj7lz6r9v6uqdepwc2
dao program v0.4
The DAO now implements the cw20 interface.
71
juno1aj4khuq9descgr3r9ejs2t7gdqa83f3ufl8s8gwfeza8mgl238zsj5fzpv
dao program v0.5
Deployment pending. Implements all of the functionality described in
src/msg.rs
.
94
juno1eu70kcgh0d2rlm0n88dgtry9wpqnerf5n2fdzt5sxm6d3vrqq3xqa5e9x8
dao program v0.6
Bugfixes
179
juno1skuakpnx8gec0avqdr00nl5339k5nc6rplsnr4gtv3ge3q8e2l2qwayda3