Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial tests and architecture #5

Merged
merged 15 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DEPLOYER_PRIVATE_KEY=
PROPOSER_PRIVATE_KEY=
MAINNET_RPC_URL=
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:

env:
FOUNDRY_PROFILE: ci
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}

jobs:
build:
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
[submodule "lib/solmate"]
path = lib/solmate
url = https://github.com/transmissions11/solmate
8 changes: 7 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
evm_version = "paris"
optimizer = true
optimizer_runs = 10_000_000
remappings = ["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts"]
remappings = [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts",
"@solmate/utils/=lib/solmate/src/utils",
]
solc_version = "0.8.20"
verbosity = 3

Expand All @@ -16,6 +19,9 @@
# Speed up compilation and tests during development.
optimizer = false

[rpc_endpoints]
mainnet = "${MAINNET_RPC_URL}"

[fmt]
bracket_spacing = false
int_types = "long"
Expand Down
1 change: 1 addition & 0 deletions lib/solmate
Submodule solmate added at e0e9ff
30 changes: 20 additions & 10 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
// SPDX-License-Identifier: UNLICENSED
// slither-disable-start reentrancy-benign

pragma solidity 0.8.20;
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.20;

import {Script} from "forge-std/Script.sol";
import {Counter} from "src/Counter.sol";
import {DeployInput} from "script/DeployInput.sol";
import {RadworksGovernor} from "src/RadworksGovernor.sol";

contract Deploy is DeployInput, Script {
uint256 deployerPrivateKey;

function setUp() public {
deployerPrivateKey = vm.envOr(
"DEPLOYER_PRIVATE_KEY",
uint256(0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80)
);
}

contract Deploy is Script {
Counter counter;
function run() public returns (RadworksGovernor) {
vm.startBroadcast(deployerPrivateKey);
RadworksGovernor _governor =
new RadworksGovernor(INITIAL_VOTING_DELAY, INITIAL_VOTING_PERIOD, INITIAL_PROPOSAL_THRESHOLD);
vm.stopBroadcast();

function run() public {
vm.broadcast();
counter = new Counter();
return _governor;
}
}
8 changes: 8 additions & 0 deletions script/DeployInput.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.20;

contract DeployInput {
uint256 constant INITIAL_VOTING_DELAY = 7200; // 24 hours
alexkeating marked this conversation as resolved.
Show resolved Hide resolved
uint256 constant INITIAL_VOTING_PERIOD = 17_280; // matches existing config
uint256 constant INITIAL_PROPOSAL_THRESHOLD = 1_000_000e18; // matches existing config
}
54 changes: 54 additions & 0 deletions script/Propose.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.20;

import {Script} from "forge-std/Script.sol";
import {ICompoundTimelock} from
"@openzeppelin/contracts/governance/extensions/GovernorTimelockCompound.sol";

import {RadworksGovernor} from "src/RadworksGovernor.sol";
import {IGovernorAlpha} from "src/interfaces/IGovernorAlpha.sol";

contract Propose is Script {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to include some natspec on what purpose this script serves. It seems though that it'll be used to make 1 proposal specifically: the upgrade proposal. is that true? Further nitting, perhaps we should change the name to something like ProposeNewGovernor.s.sol. anyway, this shouldn't block merge, so i'll track in an issue, and from there we could ignore or PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added natspec: ce8bc2a

IGovernorAlpha constant GOVERNOR_ALPHA =
wildmolasses marked this conversation as resolved.
Show resolved Hide resolved
IGovernorAlpha(0x690e775361AD66D1c4A25d89da9fCd639F5198eD);

// TODO: resolve the list of large delegates with tally
wildmolasses marked this conversation as resolved.
Show resolved Hide resolved
address PROPOSER = 0x464D78a5C97A2E2E9839C353ee9B6d4204c90B0b; // cloudhead.eth

function propose(RadworksGovernor _newGovernor) internal returns (uint256 _proposalId) {
address[] memory _targets = new address[](2);
uint256[] memory _values = new uint256[](2);
string[] memory _signatures = new string [](2);
wildmolasses marked this conversation as resolved.
Show resolved Hide resolved
bytes[] memory _calldatas = new bytes[](2);

_targets[0] = GOVERNOR_ALPHA.timelock();
_values[0] = 0;
_signatures[0] = "setPendingAdmin(address)";
_calldatas[0] = abi.encode(address(_newGovernor));

_targets[1] = address(_newGovernor);
_values[1] = 0;
_signatures[1] = "__acceptAdmin()";
_calldatas[1] = "";

return GOVERNOR_ALPHA.propose(
_targets, _values, _signatures, _calldatas, "Upgrade to Governor Bravo"
);
}

/// @dev After the new Governor is deployed on mainnet, this can move from a parameter to a const
wildmolasses marked this conversation as resolved.
Show resolved Hide resolved
function run(RadworksGovernor _newGovernor) public returns (uint256 _proposalId) {
// The expectation is the key loaded here corresponds to the address of the `proposer` above.
// When running as a script, broadcast will fail if the key is not correct.
uint256 _proposerKey = vm.envOr(
"PROPOSER_PRIVATE_KEY",
uint256(0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d)
);
vm.rememberKey(_proposerKey);

vm.startBroadcast(PROPOSER);
_proposalId = propose(_newGovernor);
vm.stopBroadcast();
return _proposalId;
}
}
14 changes: 0 additions & 14 deletions src/Counter.sol

This file was deleted.

9 changes: 3 additions & 6 deletions src/RadworksGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,8 @@ contract RadworksGovernor is
/// @notice Human readable name of this Governor.
string private constant GOVERNOR_NAME = "Radworks Governor Bravo";

/// @notice The number of RAD (in "wei") that must participate in a vote for it to meet quorum
/// threshold.
///
/// TODO: placeholder
uint256 private constant QUORUM = 100_000e18; // 100,000 RAD
/// @notice The number of RAD (in "wei") that must participate in a vote to meet quorum threshold.
uint256 private constant QUORUM = 4_000_000e18; // 4,000,000 RAD

/// @param _initialVotingDelay The initial voting delay this Governor will enforce.
/// @param _initialVotingPeriod The initial voting period this Governor will enforce.
Expand Down Expand Up @@ -113,7 +110,7 @@ contract RadworksGovernor is

/// @inheritdoc Governor
function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
ProposalVote storage proposalVote = _proposalVotes[proposalId];
ProposalVote memory proposalVote = _proposalVotes[proposalId];

return proposalVote.forVotes > proposalVote.againstVotes;
}
Expand Down
74 changes: 74 additions & 0 deletions src/interfaces/IGovernorAlpha.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

interface IGovernorAlpha {
event ProposalCanceled(uint256 id);
event ProposalCreated(
uint256 id,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 startBlock,
uint256 endBlock,
string description
);
event ProposalExecuted(uint256 id);
event ProposalQueued(uint256 id, uint256 eta);
event VoteCast(address voter, uint256 proposalId, bool support, uint256 votes);

struct Receipt {
bool hasVoted;
bool support;
uint96 votes;
}

function BALLOT_TYPEHASH() external view returns (bytes32);
function DOMAIN_TYPEHASH() external view returns (bytes32);
function cancel(uint256 proposalId) external;
function castVote(uint256 proposalId, bool support) external;
function castVoteBySig(uint256 proposalId, bool support, uint8 v, bytes32 r, bytes32 s) external;
function execute(uint256 proposalId) external payable;
function getActions(uint256 proposalId)
external
view
returns (
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
);
function getReceipt(uint256 proposalId, address voter) external view returns (Receipt memory);
function latestProposalIds(address) external view returns (uint256);
function name() external view returns (string memory);
function proposalCount() external view returns (uint256);
function proposalMaxOperations() external pure returns (uint256);
function proposalThreshold() external pure returns (uint256);
function proposals(uint256)
external
view
returns (
address proposer,
uint256 eta,
uint256 startBlock,
uint256 endBlock,
uint256 forVotes,
uint256 againstVotes,
bool canceled,
bool executed
);
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) external returns (uint256);
function queue(uint256 proposalId) external;
function quorumVotes() external pure returns (uint256);
function state(uint256 proposalId) external view returns (uint8);
function timelock() external view returns (address);
function votingDelay() external pure returns (uint256);
function votingPeriod() external pure returns (uint256);
}
22 changes: 22 additions & 0 deletions test/Constants.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.20;

contract Constants {
address constant GOVERNOR_ALPHA = 0x690e775361AD66D1c4A25d89da9fCd639F5198eD;
address payable constant RAD_TOKEN = payable(0x31c8EAcBFFdD875c74b94b077895Bd78CF1E64A3);
address constant TIMELOCK = 0x8dA8f82d2BbDd896822de723F55D6EdF416130ba;

// TODO: resolve the list of large delegates with tallyaddress
address constant PROPOSER = 0x464D78a5C97A2E2E9839C353ee9B6d4204c90B0b;

address constant USDC_ADDRESS = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address constant GTC_ADDRESS = 0xDe30da39c46104798bB5aA3fe8B9e0e1F348163F;
address constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address constant MTV_ADDRESS = 0x6226e00bCAc68b0Fe55583B90A1d727C14fAB77f;
uint256 constant MAX_REASONABLE_TIME_PERIOD = 302_400; // 6 weeks assume a 12 sec block time

// we have not yet deployed the Radworks Bravo Governor
address constant DEPLOYED_BRAVO_GOVERNOR = 0x1111111111111111111111111111111111111111;

uint256 constant QUORUM = 4_000_000e18;
}
26 changes: 0 additions & 26 deletions test/Counter.t.sol

This file was deleted.

Loading
Loading