Skip to content

Commit

Permalink
Merge pull request #57 from ametel01/governance
Browse files Browse the repository at this point in the history
Compound like Governance Contracts
  • Loading branch information
ponderingdemocritus authored May 30, 2024
2 parents 4b87d23 + 84f9b24 commit 95972da
Show file tree
Hide file tree
Showing 27 changed files with 2,069 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,14 @@ jobs:
- name: Test
run: sozo test -f hex_map
shell: bash

governance:
needs: [check, build]
runs-on: ubuntu-latest
name: Test example hex map
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
- name: Test
run: sozo test -f governance
shell: bash
7 changes: 7 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ name = "dojo_plugin"
version = "0.3.11"
source = "git+https://github.com/dojoengine/dojo?tag=v0.3.11#1e651b5d4d3b79b14a7d8aa29a92062fcb9e6659"

[[package]]
name = "governance"
version = "0.0.0"
dependencies = [
"dojo",
]

[[package]]
name = "hex_map"
version = "0.0.0"
Expand Down
1 change: 1 addition & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"examples/matchmaker",
"examples/projectile",
"token",
"governance"
]

[workspace.package]
Expand Down
106 changes: 106 additions & 0 deletions governance/EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
## Introduction:
To set up a governance protocol, three main systems need to be deployed: the Governance Token, the Timelock, and the Governor.

1. Governance Token:
The Governance Token is an ERC20-compatible token that represents voting power within the governance system. It is used to determine the weight of each user's vote and to ensure that only token holders can participate in the governance process. The Governance Token contract manages the token supply, balances, and delegation of voting power.

2. Timelock:
The Timelock contract acts as a safety mechanism to prevent immediate execution of sensitive actions. It introduces a delay between the moment a proposal is approved and when it can be executed. This delay provides an opportunity for users to exit the system if they disagree with a decision, and it helps protect against malicious proposals. The Timelock contract is controlled by the Governor and ensures that approved proposals are executed only after a specified time period has passed.

3. Governor:
The Governor contract is the central component of the governance system. It manages the proposal lifecycle, including proposal creation, voting, queuing, and execution. Users with sufficient Governance Tokens can create proposals, which can be voted on by other token holders. The Governor contract tracks the voting process, determines the outcome based on predefined rules, and interacts with the Timelock contract to schedule and execute approved proposals.

To set up a governance protocol, you need to deploy these three contracts in the following order:

1. Deploy the Governance Token contract, specifying the token's name, symbol, and initial distribution.
2. Deploy the Timelock contract, providing the address of the Governor contract as the admin and setting the desired delay for executing proposals.
3. Deploy the Governor contract, specifying the addresses of the Governance Token and Timelock contracts, and setting the initial governance parameters such as quorum, threshold, voting delay, and voting period.

Once these contracts are deployed, users can start participating in the governance process by acquiring Governance Tokens, creating proposals, voting on proposals, and executing approved proposals through the Governor contract.

## 1. Upgrading a Contract:
```rust
// Create a new proposal to upgrade a contract
let proposal_id = governor.propose(target_contract_address, new_implementation_class_hash);

// Users can vote on the proposal
governor.cast_vote(proposal_id, Support::For);

// After the voting period, if the proposal succeeds, it can be queued for execution
governor.queue(proposal_id);

// After the timelock delay, the proposal can be executed to upgrade the contract
governor.execute(proposal_id);
```

## 2. Changing Governance Parameters With a New Proposal:
```rust
// Assume a proposal has been created and voted on, and has succeeded
let proposal_id = 1;

// Queue the proposal for execution
governor.queue(proposal_id);

// Wait for the timelock delay to pass
// ...

// Execute the proposal
governor.execute(proposal_id);
```

In this example, we assume that a proposal with `proposal_id` equal to 1 has been created, voted on, and has succeeded. The proposal is now ready to be executed.

1. Queuing the Proposal:
- The `queue` function is called on the Governor contract, passing the `proposal_id` as an argument.
- This function checks if the proposal has succeeded and if it is ready to be queued for execution.
- If the checks pass, the proposal is marked as queued, and the `ProposalQueued` event is emitted.
- The proposal's execution timestamp (`eta`) is set to the current timestamp plus the timelock delay.

2. Waiting for the Timelock Delay:
- After the proposal is queued, it enters a timelock period defined by the Timelock contract.
- During this period, the proposal cannot be executed immediately. It must wait until the specified timelock delay has passed.
- The purpose of the timelock delay is to provide a safety mechanism and allow stakeholders to review and potentially cancel the proposal if necessary.

3. Executing the Proposal:
- Once the timelock delay has passed, the `execute` function can be called on the Governor contract, passing the `proposal_id` as an argument.
- The function checks if the proposal is in the "Queued" state and if the current timestamp is greater than or equal to the proposal's execution timestamp (`eta`).
- If the checks pass, the proposal is executed by calling the target contract with the specified function and parameters defined in the proposal.
- The `ProposalExecuted` event is emitted to indicate that the proposal has been executed.

After the proposal is executed, the following occurs:

1. Contract Upgrade:
- If the proposal was for upgrading a contract, the target contract's implementation is updated to the new class hash specified in the proposal.
- The contract's state and storage are preserved, but the contract's behavior is updated to reflect the new implementation.

2. Governance Parameter Changes:
- If the proposal was for changing governance parameters (e.g., quorum votes, threshold, voting delay, voting period), the new parameter values take effect immediately after the proposal is executed.
- The Governor contract's state is updated to reflect the new parameter values.

3. Other Actions:
- Depending on the specific proposal and its defined actions, other changes or actions may occur after the proposal is executed.
- These actions could include transferring funds, modifying contract state, or triggering external interactions with other contracts or systems.

It's important to note that the execution of a proposal is a critical step in the governance process. It allows the approved changes to take effect and modifies the state of the system according to the proposal's specifications. The timelock delay provides an additional layer of security and allows for a final review period before the changes are irreversibly applied.


## 3. Canceling a Proposal:
```rust
// The guardian or the proposer (if their votes are below the threshold) can cancel a proposal
let proposal_id = 1;
governor.cancel(proposal_id);
```

## 4. Retrieving Proposal Information:
```rust
// Get the target contract address and class hash of a proposal
let proposal_id = 1;
let (target_contract_address, class_hash) = governor.get_action(proposal_id);

// Get the current state of a proposal
let proposal_state = governor.state(proposal_id);
```

These examples demonstrate how the Governor contract can be used to manage upgrades, change governance parameters, cancel proposals, and retrieve proposal information. The contract provides a decentralized way for stakeholders to participate in the decision-making process of a system.

Note: The code examples assume that the necessary imports and contract instances are available, and the contract addresses and class hashes are replaced with actual values.
Loading

0 comments on commit 95972da

Please sign in to comment.