-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #57 from ametel01/governance
Compound like Governance Contracts
- Loading branch information
Showing
27 changed files
with
2,069 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ members = [ | |
"examples/matchmaker", | ||
"examples/projectile", | ||
"token", | ||
"governance" | ||
] | ||
|
||
[workspace.package] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
Oops, something went wrong.