Skip to content

An on and offchain single-contract deployment permissioned dao protocol

Notifications You must be signed in to change notification settings

voteagora/oodao

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

82 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

An On & Offchain DAO Protocol using EAS

A Python command-line tool for deploying schemas and creating attestations using the On & Offchain Attestation DAO Protocol with Ethereum Attestation Service (EAS).

The protocol works using a collection of verbs, mixed with resolvers to handle the double-spend problem and voting window of decentralized voting.

X - INSTANTIATE
X - PERMA_INSTANTIATE
X - GRANT
X - CREATE_PROPOSAL_TYPE
O - CREATE_PROPOSAL
X - CHECKED_PROPOSAL
X - SET_PROPOSAL_TYPE
X - SET_PARAM_VALUE
V - DELEGATED_SIMPLE_VOTE
V - DELEGATED_ADVANCED_VOTE
V - SIMPLE_VOTE
V - ADVANCED_VOTE
X - DELETE
X - BADGE_DEFINITION
X - IDENTITY_BADGE

Overview

This CLI wraps Foundry's forge commands to simplify interaction with the DAO governance protocol defined in protocol.md.

Deployments

Eth Mainnet

Entity Resolver Proxy:

0xf246C55a4f91f08c991F566fcF063156f67e6c03

ProxyAdmin

0x8D7512290251bd5417A00730aBFA0E5fdba1094A

Votes Resolver Proxy:

0x576c9f4C976e2E6AF9E7093F1A23Fa31B21D4cB3

ProxyAdmin

0x4Ee4b7e6eE98e0b5361dACcF9062733858c4B066

Eth Sepolia

Entity Resolver Proxy

0x7106847Cc6c99E3D730D4f2a8312A905c0ad2ad7

ProxyAdmin

0xe84969F17B2628C71B421d552450b7F131bE07A2

Votes Resolver Proxy

0xC8EA7C7651245728BE57c2d4C5638F8eF843b0E7

ProxyAdmin

0xaFb13914085154869a6770d6bbcE1Cc9B3aDE560

Base Mainnet

Entity Resolver Proxy

0xEF28EB0D4186E5795ddD25E792697abFBabceC42

ProxyAdmin

0x458fAdE53C9a7186b4f097527ee1441eBD8ecAD5

Votes Resolver Proxy

0x83e02A6b7DA88d78a90Bdf7C0B8a9dd93624801c

ProxyAdmin

0xE6fDeEfD25c6973d57AA7757BA546027625c40a4

OP Mainnet

Entity Resolver Proxy:

0x2829EE5e93cD1671140D8AE1fe7524Ba1F5AC6ad

ProxyAdmin

0xeb4Ceb297f180057CD6616d0FC5077Be795d6683

Votes Resolver Proxy

0x3d0Ee8700f3A2267a677504FfEdAE54A15ABBE7B

ProxyAdmin

0x8e1892c1Eb9a2E20df90f9d55f25e765542c6790

Schema Hashes

Mainnet Deployment

{
   'INSTANTIATE' : '0x4564d3a746bafcf78838969daaff3ba173e9f5ab73ac3023ea98dd9220953e75',
   'PERMA_INSTANTIATE' : '0xc825cf97f111a55edfb1bec7b6b624dae6ccab74a3a3a42f89891dfb0d06137b',
   'GRANT' : '0x8c6e4ae96424697731fd6aaa20b759a25684af059a23ba1b6aa48a12c21fd5d7',
   'CREATE_PROPOSAL_TYPE' : '0xab4e473a3f8a0a0a490619bcd2ecf23ad1be4720d4033fa16f2d1cbd1519caa1',
   'CREATE_PROPOSAL' : '0x38bfba767c2f41790962f09bcf52923713cfff3ad6d7604de7cc77c15fcf169a',
   'CHECK_PROPOSAL' : '0x80155c3a8c4ea17ce96e8899f7ab1ceca9e85382d7f893619a1d03947a70f844',
   'SET_PROPOSAL_TYPE' : '0x0519039455b478a51b33c82934bf28814f5755f6bb21c20fc47fd98c2a3fafa3',
   'SET_PARAM_VALUE' : '0x5c27757206150b56764617513558234fc12ab9bb64eee71afb525fa9689c4842',
   'DELEGATED_SIMPLE_VOTE' : '0x59bad5b0800beda0617b1d883711be28f8a0e619ef549310bfa6432ba64ab399',
   'DELEGATED_ADVANCED_VOTE' : '0xfcff350666dcf68a382ea5e22ac4529915312b29f3bfe5a070424dcc781e354e',
   'SIMPLE_VOTE' : '0x12cd8679de42e111a5ece9f2aee44dc8b8351024dea881cda97c2ff5b58349f6',
   'ADVANCED_VOTE' : '0xc4465af5d96b474b1c7a6418500461d3de1fc35552679bf695eb2b3124817dce',
   'DELETE' : '0x8c97e2700d9a3e52e76a4bf3c42b5a5d178f193cb14f6e2ddbc6db4ed1eae767',
}

Sepolia Deployment

{
   'INSTANTIATE' : '0xa45718ef6b8758277682e9914ed85b960e19fd8331ed75e24641d228b7efcd2d',
   'PERMA_INSTANTIATE' : '0x3921c650e5c0a565fe4e2b5dad38546999588bd18904a3354641ca6c998f6bc4',
   'GRANT' : '0xd430f8dc7a9503e92e621503eed2c716a524604be530842601d7fb0e1bb8ff15',
   'CREATE_PROPOSAL_TYPE' : '0x4147434e77680f972dcaa494427b876fa0f5ecdfde56131dd24a988ad90a6950',
   'CREATE_PROPOSAL' : '0x38bfba767c2f41790962f09bcf52923713cfff3ad6d7604de7cc77c15fcf169a',
   'CHECK_PROPOSAL' : '0x08df8e6e629077cabef4ed15cd4ff4f2359c2a60ad65b8355ac1f905b8f23a6f',
   'SET_PROPOSAL_TYPE' : '0xa6ca209ead271e33d86bf969fb5b9d5f559bf3fb22765ede70652b1faa4973b5',
   'SET_PARAM_VALUE' : '0xa1e21d322b14d3d79bd697b106b7374e19a61eb766907ef27d392dd635d9642f',
   'DELEGATED_SIMPLE_VOTE' : '0x291f9b12f6624076505cb07cc62acf79bd7403cceb435e91d279dcbe6336c94b',
   'DELEGATED_ADVANCED_VOTE' : '0xd9a51aa77ea609950350db55093af36e4c0dce621a131164cb7b410b9c2435bc',
   'SIMPLE_VOTE' : '0x19c36b80a224c4800fd6ed68901ec21f591563c8a5cb2dd95382d430603f91ff',
   'ADVANCED_VOTE' : '0x991b014c62b19364882fc89dbf3baa6104b4598ee2c4f29152be2cbcfcb4cb81',
   'DELETE' : '0x2c451b53c595d44441eb1e8242912a0446e7bfc5f745535537908bef47e6e334',
   'BADGE_DEFINITION': '0x44c0a23e342cc3b74cae094dd9be5b38447ec67045ccea4868c74d6387a52fca',
   'IDENTITY_BADGE': '0x0b9dd04e9927bd43e11ddd02c31a971859ffc23abed1a0eb226fa13bfd5046d4',
}

Base Mainnet Deployment

{
   'INSTANTIATE' : '0xbab63b7b41b5350afcf392b0f5b6031ea8990a6fee079ef523851ee28a4a7b74',
   'PERMA_INSTANTIATE' : '0x07654386b9800935560f841794e1c5a080641e75ebc6b619e4bcec0ef7b5f11a',
   'GRANT' : '0x690c13b37802f0914b28e851844e0a438aba961a9aae089a6c2a5c8a9ff0cff8',
   'CREATE_PROPOSAL_TYPE' : '0xf3f87e20caefe2aac522d0eae399b03851c32d28840979c6e47c4575be2b089a',
   'CREATE_PROPOSAL' : '0x38bfba767c2f41790962f09bcf52923713cfff3ad6d7604de7cc77c15fcf169a',
   'CHECK_PROPOSAL' : '0xe8d4638f7eb0d8d480f81365b9fe99a9826dd42a012f0ecd3e3621bfe1602b41',
   'SET_PROPOSAL_TYPE' : '0xd9a4856778d6c4ad4f692f5e498bc757f96890c101bcbf5b76b847604929fb50',
   'SET_PARAM_VALUE' : '0x8e20525ba72e66262408abc256801c048b7291e6801bd3f0612c5dd72d33f74a',
   'DELEGATED_SIMPLE_VOTE' : '0x3b3bc4228e669275d8d6abc1a4ff89272a92c1b9beef65e994d3cb7235d15094',
   'DELEGATED_ADVANCED_VOTE' : '0xf96a60e6afdf11ceb32d2a5f79c2556f35d58f925bae955acbca20b93ed81361',
   'SIMPLE_VOTE' : '0x72edbb9603b8ff8ae5310c1d33912f4a7998bea0c03afc0e06a64e41d32b78b9',
   'ADVANCED_VOTE' : '0xadeeda60a3496bacee2d9fb250dc3b2af802d2623feb31e211cfc8f210119fea',
   'DELETE' : '0x9b33510be4b823ffbaa2c55e9e5b2762c37a32361c24289655d35bef1ecd7b9b',
   'BADGE_DEFINITION' : '0x37b439c809cec771782b95da77af9d1ed1724fe5d4ce14bce55b5b8c2373fe30',
   'IDENTITY_BADGE' : '0x29283083ab37d4c00e1f2186492d9df145e9648229da70810c36da04f35c2e13',
}

Optimism Mainnet Deployment

{
   'INSTANTIATE' : '0x91b236556a1503af427e3eac950b37f19c22d4e975b72aec520212261902b102',
   'PERMA_INSTANTIATE' : '0xec89a693c93a79b17cb778fe793fa1a26f040954eb8bd4b99fe5cb5a06bf631c',
   'GRANT' : '0x98bea12de475e8ad6a74b7ccaea65ade03615da82cc6dc2fe51a9d7492986942',
   'CREATE_PROPOSAL_TYPE' : '0xd2c361729c5542fb5821b5d2e786ea961611f5483943ff705d0bbd5b8fb75712',
   'CREATE_PROPOSAL' : '0x38bfba767c2f41790962f09bcf52923713cfff3ad6d7604de7cc77c15fcf169a',
   'CHECK_PROPOSAL' : '0xfec5cd334991ff965ed91167c7542028aaedacd12e33e828097718d1616bf6d5',
   'SET_PROPOSAL_TYPE' : '0xef9cc3898fd4664f66c37158a7888fa6d43c2e701db83603c9a63be8249d72f6',
   'SET_PARAM_VALUE' : '0x481be5d3cfd5551ce60aa6c8e66b1cc2f960ee7a0700e5a6d00ab2183390b5eb',
   'DELEGATED_SIMPLE_VOTE' : '0xebdb46abcca3042ac41c8eb5c9ce67639443b0f756145fe226bf6456e008900d',
   'DELEGATED_ADVANCED_VOTE' : '0x5b439cb5cb1598b4906f69f3b48b0de0b5987ccfff0f35fbad109d349307ced0',
   'SIMPLE_VOTE' : '0xa75b4e232ed088242e7ed3ec4e2f7c05836ed48fa4859febe7e505972345abc6',
   'ADVANCED_VOTE' : '0x968d2abd9840871fc61e0f5fc267e2f16ea29b11cebc1aae33056d0cce79582d',
   'DELETE' : '0xb4916db80e2576f3b43279838d120c35cb70f933595ac1228fac97a49d58115d',
   'BADGE_DEFINITION' : '0xaa192e7d4d23ded5ce0d883324276131253880ae37f72dc5997327f9bae33d35',
   'IDENTITY_BADGE' : '0xcfa6d9f1417bdef7b4d77f2e2259da4a6356a3e445fc299a9aef3834e9f4031a',
}

Installation

Prerequisites

Setup

  1. Install Python dependencies:
pip install -r requirements.txt
  1. Configure environment variables:
cp .env.example .env

Edit .env with your values:

CHAIN_ID=11155111                                    # Network chain ID
RPC_URL=https://ethereum-sepolia-rpc.publicnode.com  # RPC endpoint
FORGE_ACCOUNT=default                                 # Forge account name
  1. Make the CLI executable (optional):
chmod +x eas_cli.py

Usage

Deploy Command

Deploy a schema for an attestation type:

./eas_cli.py deploy <ATTESTATION_COMMAND>

Examples:

./eas_cli.py deploy INSTANTIATE
./eas_cli.py deploy GRANT
./eas_cli.py deploy CREATE_PROPOSAL_TYPE

Attest Command

Create an attestation with the specified arguments:

./eas_cli.py attest <ATTESTATION_COMMAND> <args...>

Arguments must match the schema field order defined in protocol.md.

Examples

1. Instantiate a DAO

Deploy the INSTANTIATE schema:

./eas_cli.py deploy INSTANTIATE

Create an INSTANTIATE attestation:

./eas_cli.py attest INSTANTIATE \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  "v0.1.0" \
  "My DAO"

Schema: bytes32 dao_uuid, string protocol_version, string name

2. Grant Permissions

Deploy the GRANT schema:

./eas_cli.py deploy GRANT

Grant CREATE_PROPOSAL permission to an address:

./eas_cli.py attest GRANT \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xABCDEF1234567890ABCDEF1234567890ABCDEF12 \
  "CREATE_PROPOSAL" \
  7 \
  ""

Schema: bytes32 dao_uuid, address subject, string permission, uint8 level, string filter

Permission levels (bitmask):

  • Bit 0 (1): CREATE
  • Bit 1 (2): REVOKE
  • Bit 2 (4): UNDO
  • Example: 7 (binary 111) = CREATE + REVOKE + UNDO

3. Create a Proposal Type

Deploy the CREATE_PROPOSAL_TYPE schema:

./eas_cli.py deploy CREATE_PROPOSAL_TYPE

Define a gov-proposal proposal type:

./eas_cli.py attest CREATE_PROPOSAL_TYPE \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890 \
  "gov-proposal" \
  '{"quorum": "50%", "threshold": "majority"}'

Schema: bytes32 dao_uuid, bytes32 proposal_type_uuid, string class, string kwargs

Supported classes: gov-proposal, tempcheck

4. Create a Proposal

Deploy the CREATE_PROPOSAL schema:

./eas_cli.py deploy CREATE_PROPOSAL

Submit a standard proposal:

./eas_cli.py attest CREATE_PROPOSAL \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321 \
  0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890 \
  "Treasury Allocation" \
  "Allocate 100 ETH to development fund" \
  1704067200 \
  1704153600 \
  '{"voting_module": "standard"}'

Submit an approval proposal:

./eas_cli.py attest CREATE_PROPOSAL \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321 \
  0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890 \
  "Treasury Allocation" \
  "Allocate 100 ETH to development fund" \
  1704067200 \
  1704153600 \
  '{"voting_module": "approval", "choices": ["A", "B", "C"], "max_approvals": 2, "criteria": "TOP_CHOICES", "criteria_value": 2}'

Submit an optimistic proposal:

./eas_cli.py attest CREATE_PROPOSAL \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321 \
  0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890 \
  "Treasury Allocation" \
  "Allocate 100 ETH to development fund" \
  1704067200 \
  1704153600 \
  '{"voting_module": "optimistic"}'

Schema: bytes32 dao_uuid, bytes32 proposal_uuid, bytes32 proposal_type_uuid, string title, string description, uint64 startts, uint64 endts, string kwargs

kwargs: kwargs is a JSON-encoded blob that allows clients to express richer proposal configuration without changing the onchain schema. This is where you specify details needed to support different proposal classes such as approval, and optimistic voting.

Timestamps: POSIX timestamps in seconds (UTC)

5. Cast a Simple Vote

Deploy the SIMPLE_VOTE schema:

./eas_cli.py deploy SIMPLE_VOTE

Vote on a proposal:

./eas_cli.py attest SIMPLE_VOTE \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321 \
  0xVOTER_ADDRESS \
  1 \
  "I support this allocation" \
  1000000000000000000

Schema: bytes32 dao_uuid, bytes32 proposal_uuid, address voter, int8 choice, string reason, uint256 weight

Vote choices:

  • 1 = For
  • -1 = Against
  • 0 = Abstain

6. Cast an Advanced Vote

Deploy the ADVANCED_VOTE schema:

./eas_cli.py deploy ADVANCED_VOTE

Vote with complex choice data:

./eas_cli.py attest ADVANCED_VOTE \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321 \
  0xVOTER_ADDRESS \
  '{"option_a": 60, "option_b": 40}' \
  "Split vote based on priorities" \
  1000000000000000000

Schema: bytes32 dao_uuid, bytes32 proposal_uuid, address voter, string choice, string reason, uint256 weight

7. Undo an Attestation

Deploy the UNDO schema:

./eas_cli.py deploy UNDO

Retroactively nullify an attestation:

./eas_cli.py attest UNDO \
  0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef \
  0xATTESTATION_UID_TO_UNDO

Schema: bytes32 dao_uuid, bytes32 uid

Note: UNDO retroactively invalidates attestations. Requires UNDO permission (bit 2 in GRANT level).

Protocol Reference

For complete protocol specification, security considerations, and governance flow details, see protocol.md.

Key Concepts

  • dao_uuid: Unique identifier for a DAO (bytes32)
  • Permissions: Authority delegated via GRANT attestations
  • Proposal Types: Classes that define voting rules (gov-proposal, tempcheck)
  • Timestamps: POSIX seconds since epoch (UTC)

Example Governance Flow

  1. Platform issues INSTANTIATE to create DAO
  2. Initial authority grants CREATE_PROPOSAL_TYPE permission to council
  3. Council member creates proposal type via CREATE_PROPOSAL_TYPE
  4. Delegates create proposals via CREATE_PROPOSAL
  5. Members vote via SIMPLE_VOTE or ADVANCED_VOTE
  6. Results tallied offchain (or onchain with custom resolvers)
  7. If needed, authorized actors can issue UNDO to nullify attestations

License

Open source under the protocol defined in protocol.md.

About

An on and offchain single-contract deployment permissioned dao protocol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors 4

  •  
  •  
  •  
  •