Skip to content

Commit

Permalink
Pass proposals on mento gov (#200)
Browse files Browse the repository at this point in the history
* feat: mento gov utils scripts

* fix: interfaces uses correct pragma

* feat: pass and queue proposals

* feat: remove --no-cache from script calls

* fix: typo on a revert message

* feat: improve logging

* fix: remove tree that is pushed

* fix: remove merge artifacts

* feat: update readme
  • Loading branch information
baroooo authored and bowd committed Aug 15, 2024
1 parent 34bec4b commit 020cc6b
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 14 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ yarn-error.log*
!/broadcast
/broadcast/Dev-*
!/broadcast/ExecuteProposal*
/broadcast/PassProposal*
/broadcast/QueueProposal*

node_modules
.env
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mento Deployment

This repo contains scripts for deploying & proposing upgrades to the Mento protocol.
This repo contains scripts for deploying & proposing upgrades to the Mento protocol. It can be used for both Mento and Celo governance proposals.
Deployments for the core contracts are done using [Foundry solidity scripting](https://book.getfoundry.sh/tutorials/solidity-scripting).

## Getting Started
Expand Down Expand Up @@ -34,7 +34,8 @@ The deployment scripts are organized in the following structure:
- `script/upgrades/`: Contains all the upgrade scripts, which serve as a migration from one version of mento to another
- `script/upgrades/MU01/`: Contains all the upgrade scripts to migrate from version v1.0.0. to v2.0.0
- `script/dev/`: Contains dev scripts that are used in the deployment process, especially on testnets, but aren't central to the upgrade.
- `script/utils/`: Contains helpers and utilities used in the deployment process.
- `script/utils/`: Contains helpers and utilities used in the deployment and governance operations using Celo Governance.
- `script/utils/mento`: Contains helpers and utilities used in the deployment and governance operations using Mento Governance.
- `bin/`: Contains bash/typescript scripts that are used to execute the deployment process.
- `broadcast/`: Contains the broadcasted transactions for the deployment process.

Expand All @@ -46,6 +47,7 @@ General options will include:

- `-n`: The network to run on, e.g. `baklava` or `alfajores`
- `-u`: The upgrade number, e.g. `MU01`
- `-g`: The governance that will be used, e.g. `celo` or `mento`

Check the script file for more details on usage but here's a quick overview:

Expand Down Expand Up @@ -89,9 +91,9 @@ Check the script file for more details on usage but here's a quick overview:
# Run an upgrade deployment, will run all deploy scripts in an upgrade
> yarn deploy -n baklava -u MU01

# Submit an upgrade CGP, will output the proposal ID
> yarn cgp -n baklava -u MU01
# Submit an upgrade proposal, will output the proposal ID
> yarn cgp -n baklava -u MU01 -g celo

# Pass a CGP on testnets
> yarn cgp:pass -n baklava -p <proposal-id>
> yarn cgp:pass -n baklava -g celo -p <proposal-id>
```
2 changes: 1 addition & 1 deletion bin/cgp-execute.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if [ -z "$PROPOSAL_ID" ]; then
fi

if [ "$SIMULATE" = true ] ; then
echo "🥸 Simulating execution of proposal $PROPOSAL_ID on $NETWORK"
echo "🥸 Simulating execution of proposal $PROPOSAL_ID on $NETWORK"
forge script --rpc-url $RPC_URL --sig "run(uint256)" $UTILS_DIR/ExecuteProposal.sol:ExecuteProposal $PROPOSAL_ID -vvvv
else
echo "🔥 Executing proposal $PROPOSAL_ID on $NETWORK"
Expand Down
16 changes: 11 additions & 5 deletions bin/cgp-pass.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,19 @@ if [ "$GOVERNANCE" = "celo" ]; then
echo "🗳️ Voting proposal $PROPOSAL_ID"
echo "=========================================="
celocli governance:vote --value=Yes --from=$SIGNER --proposalID=$PROPOSAL_ID $SIGNER_PK_PARAM
echo "😴 301s"
echo -e "\a" && sleep 301
countdown 301 # 5 minutes
# celocli governance:execute --from=$SIGNER --proposalID=$PROPOSAL_ID $SIGNER_PK_PARAM
elif [ "$GOVERNANCE" = "mento" ]; then
# TODO: implement proposal passing for mento governance
echo "❌ Mento Governance proposal passing not implemented"
exit 1
echo "🗳️ Voting proposal: $PROPOSAL_ID"
echo "=========================================="
forge script --rpc-url $RPC_URL --sig "run(uint256)" $UTILS_DIR/PassProposal.sol:PassProposal $PROPOSAL_ID --broadcast
echo "⏳ Waiting for voting period to end"
countdown 301 # 5 minutes
echo "🚶🚶🚶 Queuing proposal: $PROPOSAL_ID"
echo "=========================================="
forge script --rpc-url $RPC_URL --sig "run(uint256)" $UTILS_DIR/QueueProposal.sol:QueueProposal $PROPOSAL_ID --broadcast
echo "⏳ Proposal queued, waiting for queue period to end"
countdown 601 # 10 minutes
else
echo "❌ Unknown governance: $GOVERNANCE"
exit 1
Expand Down
11 changes: 10 additions & 1 deletion bin/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ parse_gov () { # $1: governance
echo "🚨 Invalid governance: '$1' (celo|mento)"
exit 1
esac
echo "🗳️ Governance in use: $1"
echo "🗳️ Governance in use is $1 governance"
}

forge_skip () { # $1: target
Expand Down Expand Up @@ -101,3 +101,12 @@ confirm_if_celo () { # $1: network
done
fi
}

countdown() { # $1: seconds
local seconds=$1
echo "😴 Sleeping for $seconds seconds"
for ((i=seconds; i>0; i--)); do
echo -ne "$i seconds remaining...\033[0K\r"
sleep 1
done
}
31 changes: 29 additions & 2 deletions script/interfaces/IGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,35 @@ interface IGovernor {

/**
* @dev Cast a vote
*
* Emits a {VoteCast} event.
*/
function castVote(uint256 proposalId, uint8 support) external returns (uint256 balance);

/**
* @dev Returns information about a proposal
*/
function proposals(
uint256 proposalId
)
external
returns (
uint256 id,
address proposer,
uint256 eta,
uint256 startBlock,
uint256 endBlock,
uint256 forVotes,
uint256 againstVotes,
bool canceled,
bool executed
);

/**
* @dev Returns the quorum required for a block number
*/
function quorum(uint256 blockNumber) external view returns (uint256);

/**
* @dev Returns the state of a proposal
*/
function state(uint256 proposalId) external view returns (uint8);
}
4 changes: 4 additions & 0 deletions script/utils/mento/ExecuteProposal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ contract ExecuteProposal is Script {
function run(uint256 proposalId) public {
address governance = IGovernanceFactory(Chain.governanceFactory()).mentoGovernor();

if (IGovernor(governance).state(proposalId) != 5) {
revert(unicode"❌ Proposal is not queued, cannot be executed");
}

vm.startBroadcast(vm.envUint("MENTO_DEPLOYER_PK"));
{
IGovernor(governance).execute(proposalId);
Expand Down
39 changes: 39 additions & 0 deletions script/utils/mento/PassProposal.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.18;

import { Script } from "./Script.sol";
import { IGovernanceFactory } from "../../interfaces/IGovernanceFactory.sol";
import { IGovernor } from "../../interfaces/IGovernor.sol";
import { console2 } from "forge-std/Script.sol";
import { Chain } from "./Chain.sol";

contract PassProposal is Script {
function run(uint256 proposalId) public {
IGovernor governance = IGovernor(IGovernanceFactory(Chain.governanceFactory()).mentoGovernor());

if (governance.state(proposalId) != 1) {
revert(unicode"❌ Proposal is not active");
}

(, , , uint256 startBlock, , , , , ) = governance.proposals(proposalId);
uint256 quorumRequired = governance.quorum(startBlock);
console2.log("Quorum required: ", quorumRequired);

vm.startBroadcast(vm.envUint("MENTO_DEPLOYER_PK"));
{
governance.castVote(proposalId, 1);
}
vm.stopBroadcast();

(, , , , , uint256 forVotes, uint256 againstVotes, , ) = governance.proposals(proposalId);

console2.log("For votes: ", forVotes);
console2.log("Against votes: ", againstVotes);

if (forVotes >= quorumRequired && forVotes > againstVotes) {
console2.log(unicode"✅ Proposal has enough votes to pass");
} else {
revert(unicode"❌ Proposal needs more votes to pass");
}
}
}
26 changes: 26 additions & 0 deletions script/utils/mento/QueueProposal.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.18;

import { Script } from "./Script.sol";
import { IGovernanceFactory } from "../../interfaces/IGovernanceFactory.sol";
import { IGovernor } from "../../interfaces/IGovernor.sol";
import { console2 } from "forge-std/Script.sol";
import { Chain } from "./Chain.sol";

contract QueueProposal is Script {
function run(uint256 proposalId) public {
IGovernor governance = IGovernor(IGovernanceFactory(Chain.governanceFactory()).mentoGovernor());

if (governance.state(proposalId) != 4) {
revert(unicode"❌ Proposal is not successful, cannot be queued");
}

vm.startBroadcast(vm.envUint("MENTO_DEPLOYER_PK"));
{
governance.queue(proposalId);
}
vm.stopBroadcast();

console2.log(unicode"✅ Proposal has been queued");
}
}

0 comments on commit 020cc6b

Please sign in to comment.