Skip to content

Commit

Permalink
Merge pull request #82 from threshold-network/moar-dao
Browse files Browse the repository at this point in the history
Improved tests and deployment scripts for Tokenholder DAO
  • Loading branch information
cygnusv committed Feb 23, 2022
2 parents 89bcd82 + 1da7d28 commit 3a57079
Show file tree
Hide file tree
Showing 14 changed files with 1,492 additions and 691 deletions.
176 changes: 176 additions & 0 deletions contracts/governance/BaseTokenholderGovernor.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// SPDX-License-Identifier: GPL-3.0-or-later

// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ██████████████ ▐████▌ ██████████████
// ██████████████ ▐████▌ ██████████████
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌
// ▐████▌ ▐████▌

pragma solidity 0.8.9;

import "./TokenholderGovernorVotes.sol";
import "../token/T.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorPreventLateQuorum.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";

contract BaseTokenholderGovernor is
AccessControl,
GovernorCountingSimple,
TokenholderGovernorVotes,
GovernorPreventLateQuorum,
GovernorTimelockControl
{
bytes32 public constant VETO_POWER =
keccak256("Power to veto proposals in Threshold's Tokenholder DAO");

constructor(
T _token,
IVotesHistory _staking,
TimelockController _timelock,
address _vetoer,
uint256 _quorumNumerator,
uint256 _proposalThresholdNumerator,
uint256 votingDelay,
uint256 votingPeriod,
uint64 votingExtension
)
Governor("TokenholderGovernor")
GovernorParameters(
_quorumNumerator,
_proposalThresholdNumerator,
votingDelay,
votingPeriod
)
GovernorPreventLateQuorum(votingExtension)
TokenholderGovernorVotes(_token, _staking)
GovernorTimelockControl(_timelock)
{
_setupRole(VETO_POWER, _vetoer);
_setupRole(DEFAULT_ADMIN_ROLE, address(_timelock));
}

function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) external onlyRole(VETO_POWER) returns (uint256) {
return _cancel(targets, values, calldatas, descriptionHash);
}

function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(Governor, IGovernor) returns (uint256) {
return super.propose(targets, values, calldatas, description);
}

function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorParameters)
returns (uint256)
{
return super.quorum(blockNumber);
}

function proposalThreshold()
public
view
override(Governor, GovernorParameters)
returns (uint256)
{
return super.proposalThreshold();
}

function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernor, TokenholderGovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}

function state(uint256 proposalId)
public
view
override(Governor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}

function supportsInterface(bytes4 interfaceId)
public
view
override(Governor, GovernorTimelockControl, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}

function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}

function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}

function _executor()
internal
view
override(Governor, GovernorTimelockControl)
returns (address)
{
return super._executor();
}

function proposalDeadline(uint256 proposalId)
public
view
virtual
override(IGovernor, Governor, GovernorPreventLateQuorum)
returns (uint256)
{
return super.proposalDeadline(proposalId);
}

function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason
)
internal
virtual
override(Governor, GovernorPreventLateQuorum)
returns (uint256)
{
return super._castVote(proposalId, account, support, reason);
}
}
2 changes: 1 addition & 1 deletion contracts/governance/GovernorParameters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import "@openzeppelin/contracts/governance/Governor.sol";
/// GovernorVotes and GovernorSettings for reference.
abstract contract GovernorParameters is Governor {
uint256 public constant FRACTION_DENOMINATOR = 10000;
uint256 internal constant AVERAGE_BLOCK_TIME_IN_SECONDS = 13;
uint64 internal constant AVERAGE_BLOCK_TIME_IN_SECONDS = 13;

uint256 public quorumNumerator;
uint256 public proposalThresholdNumerator;
Expand Down
133 changes: 12 additions & 121 deletions contracts/governance/TokenholderGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,143 +15,34 @@

pragma solidity 0.8.9;

import "./TokenholderGovernorVotes.sol";
import "../token/T.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
import "./BaseTokenholderGovernor.sol";

contract TokenholderGovernor is
AccessControl,
GovernorCountingSimple,
TokenholderGovernorVotes,
GovernorTimelockControl
{
contract TokenholderGovernor is BaseTokenholderGovernor {
uint256 private constant INITIAL_QUORUM_NUMERATOR = 150; // Defined in basis points, i.e., 1.5%
uint256 private constant INITIAL_PROPOSAL_THRESHOLD_NUMERATOR = 25; // Defined in basis points, i.e., 0.25%
uint256 private constant INITIAL_VOTING_DELAY =
2 days / AVERAGE_BLOCK_TIME_IN_SECONDS;
uint256 private constant INITIAL_VOTING_PERIOD =
10 days / AVERAGE_BLOCK_TIME_IN_SECONDS;

bytes32 public constant VETO_POWER =
keccak256("Power to veto proposals in Threshold's Tokenholder DAO");
uint64 private constant INITIAL_VOTING_EXTENSION =
uint64(2 days) / AVERAGE_BLOCK_TIME_IN_SECONDS;

constructor(
T _token,
IVotesHistory _staking,
TimelockController _timelock,
address vetoer
)
Governor("TokenholderGovernor")
GovernorParameters(
BaseTokenholderGovernor(
_token,
_staking,
_timelock,
vetoer,
INITIAL_QUORUM_NUMERATOR,
INITIAL_PROPOSAL_THRESHOLD_NUMERATOR,
INITIAL_VOTING_DELAY,
INITIAL_VOTING_PERIOD
INITIAL_VOTING_PERIOD,
INITIAL_VOTING_EXTENSION
)
TokenholderGovernorVotes(_token, _staking)
GovernorTimelockControl(_timelock)
{
_setupRole(VETO_POWER, vetoer);
_setupRole(DEFAULT_ADMIN_ROLE, address(_timelock));
}

function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) external onlyRole(VETO_POWER) returns (uint256) {
return _cancel(targets, values, calldatas, descriptionHash);
}

function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) public override(Governor, IGovernor) returns (uint256) {
uint256 atLastBlock = block.number - 1;
require(
getVotes(msg.sender, atLastBlock) >= proposalThreshold(atLastBlock),
"Proposal below threshold"
);
return super.propose(targets, values, calldatas, description);
}

function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorParameters)
returns (uint256)
{
return super.quorum(blockNumber);
}

function proposalThreshold()
public
view
override(Governor, GovernorParameters)
returns (uint256)
{
return super.proposalThreshold();
}

function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernor, TokenholderGovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}

function state(uint256 proposalId)
public
view
override(Governor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}

function supportsInterface(bytes4 interfaceId)
public
view
override(Governor, GovernorTimelockControl, AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}

function _execute(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) {
super._execute(proposalId, targets, values, calldatas, descriptionHash);
}

function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(Governor, GovernorTimelockControl) returns (uint256) {
return super._cancel(targets, values, calldatas, descriptionHash);
}

function _executor()
internal
view
override(Governor, GovernorTimelockControl)
returns (address)
{
return super._executor();
}
{}
}
20 changes: 16 additions & 4 deletions contracts/test/TestGovernorTestSet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,29 @@ contract TestStakerGovernor is StakerGovernor {
}
}

contract TestTokenholderGovernor is TokenholderGovernor {
contract TestTokenholderGovernor is BaseTokenholderGovernor {
uint256 private constant INITIAL_QUORUM_NUMERATOR = 150; // Defined in basis points, i.e., 1.5%
uint256 private constant INITIAL_PROPOSAL_THRESHOLD_NUMERATOR = 25; // Defined in basis points, i.e., 0.25%
uint256 private constant INITIAL_VOTING_DELAY = 2;
uint256 private constant INITIAL_VOTING_PERIOD = 8;
uint64 private constant INITIAL_VOTING_EXTENSION = 4;

constructor(
T _tToken,
IVotesHistory _tStaking,
TimelockController _timelock,
address _vetoer
)
TokenholderGovernor(
BaseTokenholderGovernor(
_tToken,
_tStaking,
TimelockController(payable(0)),
_vetoer
_timelock,
_vetoer,
INITIAL_QUORUM_NUMERATOR,
INITIAL_PROPOSAL_THRESHOLD_NUMERATOR,
INITIAL_VOTING_DELAY,
INITIAL_VOTING_PERIOD,
INITIAL_VOTING_EXTENSION
)
{}
}
Expand Down
Loading

0 comments on commit 3a57079

Please sign in to comment.