Transaction Hash:
Block:
19420006 at Mar-12-2024 03:50:47 PM +UTC
Transaction Fee:
0.009618346719098712 ETH
$28.92
Gas Used:
125,538 Gas / 76.617014124 Gwei
Emitted Events:
317 |
Forth.Transfer( from=Timelock, to=Proxy, amount=800000000000000000000000 )
|
318 |
Timelock.ExecuteTransaction( txHash=C4A06DB68650D375A732FD5A8F0717E99EB635B0C6F96B6D6057FAFAC23CB473, target=Forth, value=0, signature=, data=0xA9059CBB000000000000000000000000C3A947372191453DD9DB02B0852D378DCCBDF27100000000000000000000000000000000000000000000A968163F0A57B4000000, eta=1710231215 )
|
319 |
GovernorBravoDelegator.ProposalExecuted( id=26 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x223592a1...E771539A9 | |||||
0x77FbA179...0AdA60ce0 | |||||
0x8a994C6F...E3a2dA8F1 | |||||
0x95222290...5CC4BAfe5
Miner
| (beaverbuild) | 18.908600938454414849 Eth | 18.908604794063213303 Eth | 0.000003855608798454 | |
0xfe2321D7...9161e7F98 | (Ampleforth Governance: Deployer) |
0.594673562635068826 Eth
Nonce: 1601
|
0.585055215915970114 Eth
Nonce: 1602
| 0.009618346719098712 |
Execution Trace
GovernorBravoDelegator.fe0d94c1( )
GovernorBravoDelegate.execute( proposalId=26 )
-
Timelock.STATICCALL( )
Timelock.executeTransaction( target=0x77FbA179C79De5B7653F68b5039Af940AdA60ce0, value=0, signature=, data=0xA9059CBB000000000000000000000000C3A947372191453DD9DB02B0852D378DCCBDF27100000000000000000000000000000000000000000000A968163F0A57B4000000, eta=1710231215 ) => ( 0x0000000000000000000000000000000000000000000000000000000000000001 )
-
Forth.transfer( dst=0xc3a947372191453Dd9dB02B0852d378dCCBDf271, rawAmount=800000000000000000000000 ) => ( True )
-
-
File 1 of 5: GovernorBravoDelegator
File 2 of 5: Timelock
File 3 of 5: Proxy
File 4 of 5: Forth
File 5 of 5: GovernorBravoDelegate
{"GovernorBravoDelegator.sol":{"content":"// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./GovernorBravoInterfaces.sol\";\n\ncontract GovernorBravoDelegator is GovernorBravoDelegatorStorage, GovernorBravoEvents {\n constructor(\n address timelock_,\n address forth_,\n address admin_,\n address implementation_,\n uint votingPeriod_,\n uint votingDelay_,\n uint proposalThreshold_) public {\n\n // Admin set to msg.sender for initialization\n admin = msg.sender;\n\n delegateTo(implementation_, abi.encodeWithSignature(\"initialize(address,address,uint256,uint256,uint256)\",\n timelock_,\n forth_,\n votingPeriod_,\n votingDelay_,\n proposalThreshold_));\n\n _setImplementation(implementation_);\n\n admin = admin_;\n }\n\n\n /**\n * @notice Called by the admin to update the implementation of the delegator\n * @param implementation_ The address of the new implementation for delegation\n */\n function _setImplementation(address implementation_) public {\n require(msg.sender == admin, \"GovernorBravoDelegator::_setImplementation: admin only\");\n require(implementation_ != address(0), \"GovernorBravoDelegator::_setImplementation: invalid implementation address\");\n\n address oldImplementation = implementation;\n implementation = implementation_;\n\n emit NewImplementation(oldImplementation, implementation);\n }\n\n /**\n * @notice Internal method to delegate execution to another contract\n * @dev It returns to the external caller whatever the implementation returns or forwards reverts\n * @param callee The contract to delegatecall\n * @param data The raw data to delegatecall\n */\n function delegateTo(address callee, bytes memory data) internal {\n (bool success, bytes memory returnData) = callee.delegatecall(data);\n assembly {\n if eq(success, 0) {\n revert(add(returnData, 0x20), returndatasize())\n }\n }\n }\n\n /**\n * @dev Delegates the current call to implementation.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal {\n // delegate all other functions to current implementation\n (bool success, ) = implementation.delegatecall(msg.data);\n\n assembly {\n let free_mem_ptr := mload(0x40)\n returndatacopy(free_mem_ptr, 0, returndatasize())\n\n switch success\n case 0 { revert(free_mem_ptr, returndatasize()) }\n default { return(free_mem_ptr, returndatasize()) }\n }\n }\n\n /**\n * @dev Delegates execution to an implementation contract.\n * It returns to the external caller whatever the implementation returns or forwards reverts.\n */\n fallback() external payable {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to implementation. Will run if call data is empty.\n */\n receive() external payable {\n _fallback();\n }\n}\n"},"GovernorBravoInterfaces.sol":{"content":"// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\n\ncontract GovernorBravoEvents {\n /// @notice An event emitted when a new proposal is created\n event ProposalCreated(uint id, address proposer, address[] targets, uint[] values, string[] signatures, bytes[] calldatas, uint startBlock, uint endBlock, string description);\n\n /// @notice An event emitted when a vote has been cast on a proposal\n /// @param voter The address which casted a vote\n /// @param proposalId The proposal id which was voted on\n /// @param support Support value for the vote. 0=against, 1=for, 2=abstain\n /// @param votes Number of votes which were cast by the voter\n /// @param reason The reason given for the vote by the voter\n event VoteCast(address indexed voter, uint proposalId, uint8 support, uint votes, string reason);\n\n /// @notice An event emitted when a proposal has been canceled\n event ProposalCanceled(uint id);\n\n /// @notice An event emitted when a proposal has been queued in the Timelock\n event ProposalQueued(uint id, uint eta);\n\n /// @notice An event emitted when a proposal has been executed in the Timelock\n event ProposalExecuted(uint id);\n\n /// @notice An event emitted when the voting delay is set\n event VotingDelaySet(uint oldVotingDelay, uint newVotingDelay);\n\n /// @notice An event emitted when the voting period is set\n event VotingPeriodSet(uint oldVotingPeriod, uint newVotingPeriod);\n\n /// @notice Emitted when implementation is changed\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /// @notice Emitted when proposal threshold is set\n event ProposalThresholdSet(uint oldProposalThreshold, uint newProposalThreshold);\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Emitted when pendingAdmin is accepted, which means admin is updated\n event NewAdmin(address oldAdmin, address newAdmin);\n}\n\ncontract GovernorBravoDelegatorStorage {\n /// @notice Administrator for this contract\n address public admin;\n\n /// @notice Pending administrator for this contract\n address public pendingAdmin;\n\n /// @notice Active brains of Governor\n address public implementation;\n}\n\n\n/**\n * @title Storage for Governor Bravo Delegate\n * @notice For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new\n * contract which implements GovernorBravoDelegateStorageV1 and following the naming convention\n * GovernorBravoDelegateStorageVX.\n */\ncontract GovernorBravoDelegateStorageV1 is GovernorBravoDelegatorStorage {\n\n /// @notice The delay before voting on a proposal may take place, once proposed, in blocks\n uint public votingDelay;\n\n /// @notice The duration of voting on a proposal, in blocks\n uint public votingPeriod;\n\n /// @notice The number of votes required in order for a voter to become a proposer\n uint public proposalThreshold;\n\n /// @notice The total number of proposals\n uint public proposalCount;\n\n /// @notice The address of the Ampleforth Protocol Timelock\n TimelockInterface public timelock;\n\n /// @notice The address of the Ampleforth governance token\n ForthInterface public forth;\n\n /// @notice The official record of all proposals ever proposed\n mapping (uint =\u003e Proposal) public proposals;\n\n /// @notice The latest proposal for each proposer\n mapping (address =\u003e uint) public latestProposalIds;\n\n\n struct Proposal {\n // Unique id for looking up a proposal\n uint id;\n\n // Creator of the proposal\n address proposer;\n\n // The timestamp that the proposal will be available for execution, set once the vote succeeds\n uint eta;\n\n // The ordered list of target addresses for calls to be made\n address[] targets;\n\n // The ordered list of values (i.e. msg.value) to be passed to the calls to be made\n uint[] values;\n\n // The ordered list of function signatures to be called\n string[] signatures;\n\n // The ordered list of calldata to be passed to each call\n bytes[] calldatas;\n\n // The block at which voting begins: holders must delegate their votes prior to this block\n uint startBlock;\n\n // The block at which voting ends: votes must be cast prior to this block\n uint endBlock;\n\n // Current number of votes in favor of this proposal\n uint forVotes;\n\n // Current number of votes in opposition to this proposal\n uint againstVotes;\n\n // Current number of votes for abstaining for this proposal\n uint abstainVotes;\n\n // Flag marking whether the proposal has been canceled\n bool canceled;\n\n // Flag marking whether the proposal has been executed\n bool executed;\n\n // Receipts of ballots for the entire set of voters\n mapping (address =\u003e Receipt) receipts;\n }\n\n /// @notice Ballot receipt record for a voter\n struct Receipt {\n // Whether or not a vote has been cast\n bool hasVoted;\n\n // Whether or not the voter supports the proposal or abstains\n uint8 support;\n\n // The number of votes the voter had, which were cast\n uint96 votes;\n }\n\n /// @notice Possible states that a proposal may be in\n enum ProposalState {\n Pending,\n Active,\n Canceled,\n Defeated,\n Succeeded,\n Queued,\n Expired,\n Executed\n }\n}\n\ninterface TimelockInterface {\n function delay() external view returns (uint);\n function GRACE_PERIOD() external view returns (uint);\n function acceptAdmin() external;\n function queuedTransactions(bytes32 hash) external view returns (bool);\n function queueTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external returns (bytes32);\n function cancelTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external;\n function executeTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external payable returns (bytes memory);\n}\n\ninterface ForthInterface {\n function getPriorVotes(address account, uint blockNumber) external view returns (uint96);\n}\n"}}
File 2 of 5: Timelock
{"SafeMath.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity \u003e=0.6.0 \u003c0.8.0;\n\n/**\n * @dev Wrappers over Solidity\u0027s arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it\u0027s recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c \u003c a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b \u003e a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c \u003e= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003c= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003e 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003e 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003c= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0, errorMessage);\n return a % b;\n }\n}\n"},"Timelock.sol":{"content":"// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.6.11;\n\nimport \"./SafeMath.sol\";\n\ncontract Timelock {\n using SafeMath for uint;\n\n event NewAdmin(address indexed newAdmin);\n event NewPendingAdmin(address indexed newPendingAdmin);\n event NewDelay(uint indexed newDelay);\n event CancelTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta);\n event ExecuteTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta);\n event QueueTransaction(bytes32 indexed txHash, address indexed target, uint value, string signature, bytes data, uint eta);\n\n uint public constant GRACE_PERIOD = 14 days;\n uint public constant MINIMUM_DELAY = 2 days;\n uint public constant MAXIMUM_DELAY = 30 days;\n\n address public admin;\n address public pendingAdmin;\n uint public delay;\n\n mapping (bytes32 =\u003e bool) public queuedTransactions;\n\n\n constructor(address admin_, uint delay_) public {\n require(delay_ \u003e= MINIMUM_DELAY, \"Timelock::constructor: Delay must exceed minimum delay.\");\n require(delay_ \u003c= MAXIMUM_DELAY, \"Timelock::setDelay: Delay must not exceed maximum delay.\");\n\n admin = admin_;\n delay = delay_;\n }\n\n receive() external payable { }\n\n function setDelay(uint delay_) public {\n require(msg.sender == address(this), \"Timelock::setDelay: Call must come from Timelock.\");\n require(delay_ \u003e= MINIMUM_DELAY, \"Timelock::setDelay: Delay must exceed minimum delay.\");\n require(delay_ \u003c= MAXIMUM_DELAY, \"Timelock::setDelay: Delay must not exceed maximum delay.\");\n delay = delay_;\n\n emit NewDelay(delay);\n }\n\n function acceptAdmin() public {\n require(msg.sender == pendingAdmin, \"Timelock::acceptAdmin: Call must come from pendingAdmin.\");\n admin = msg.sender;\n pendingAdmin = address(0);\n\n emit NewAdmin(admin);\n }\n\n function setPendingAdmin(address pendingAdmin_) public {\n require(msg.sender == address(this), \"Timelock::setPendingAdmin: Call must come from Timelock.\");\n pendingAdmin = pendingAdmin_;\n\n emit NewPendingAdmin(pendingAdmin);\n }\n\n function queueTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public returns (bytes32) {\n require(msg.sender == admin, \"Timelock::queueTransaction: Call must come from admin.\");\n require(eta \u003e= getBlockTimestamp().add(delay), \"Timelock::queueTransaction: Estimated execution block must satisfy delay.\");\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n queuedTransactions[txHash] = true;\n\n emit QueueTransaction(txHash, target, value, signature, data, eta);\n return txHash;\n }\n\n function cancelTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public {\n require(msg.sender == admin, \"Timelock::cancelTransaction: Call must come from admin.\");\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n queuedTransactions[txHash] = false;\n\n emit CancelTransaction(txHash, target, value, signature, data, eta);\n }\n\n function executeTransaction(address target, uint value, string memory signature, bytes memory data, uint eta) public payable returns (bytes memory) {\n require(msg.sender == admin, \"Timelock::executeTransaction: Call must come from admin.\");\n\n bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));\n require(queuedTransactions[txHash], \"Timelock::executeTransaction: Transaction hasn\u0027t been queued.\");\n require(getBlockTimestamp() \u003e= eta, \"Timelock::executeTransaction: Transaction hasn\u0027t surpassed time lock.\");\n require(getBlockTimestamp() \u003c= eta.add(GRACE_PERIOD), \"Timelock::executeTransaction: Transaction is stale.\");\n\n queuedTransactions[txHash] = false;\n\n bytes memory callData;\n\n if (bytes(signature).length == 0) {\n callData = data;\n } else {\n callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);\n }\n\n // solium-disable-next-line security/no-call-value\n (bool success, bytes memory returnData) = target.call{value: value}(callData);\n require(success, \"Timelock::executeTransaction: Transaction execution reverted.\");\n\n emit ExecuteTransaction(txHash, target, value, signature, data, eta);\n\n return returnData;\n }\n\n function getBlockTimestamp() internal view returns (uint) {\n // solium-disable-next-line security/no-block-members\n return block.timestamp;\n }\n}\n"}}
File 3 of 5: Proxy
pragma solidity ^0.5.3; /// @title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. /// @author Stefan George - <[email protected]> /// @author Richard Meissner - <[email protected]> contract Proxy { // masterCopy always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated. // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt` address internal masterCopy; /// @dev Constructor function sets address of master copy contract. /// @param _masterCopy Master copy address. constructor(address _masterCopy) public { require(_masterCopy != address(0), "Invalid master copy address provided"); masterCopy = _masterCopy; } /// @dev Fallback function forwards all transactions and returns all received return data. function () external payable { // solium-disable-next-line security/no-inline-assembly assembly { let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff) // 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) { mstore(0, masterCopy) return(0, 0x20) } calldatacopy(0, 0, calldatasize()) let success := delegatecall(gas, masterCopy, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) if eq(success, 0) { revert(0, returndatasize()) } return(0, returndatasize()) } } }
File 4 of 5: Forth
{"Forth.sol":{"content":"// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./SafeMath.sol\";\n\ncontract Forth {\n /// @notice EIP-20 token name for this token\n string public constant name = \"Ampleforth Governance\";\n\n /// @notice EIP-20 token symbol for this token\n string public constant symbol = \"FORTH\";\n\n /// @notice EIP-20 token decimals for this token\n uint8 public constant decimals = 18;\n\n /// @notice Total number of tokens in circulation\n uint public totalSupply = 15_000_000e18; // 15 million Forth\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint public mintingAllowedAfter;\n\n /// @notice Minimum time between mints\n uint32 public constant minimumTimeBetweenMints = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant mintCap = 2;\n\n /// @dev Allowance amounts on behalf of others\n mapping (address =\u003e mapping (address =\u003e uint96)) internal allowances;\n\n /// @dev Official record of token balances for each account\n mapping (address =\u003e uint96) internal balances;\n\n /// @notice A record of each accounts delegate\n mapping (address =\u003e address) public delegates;\n\n /// @notice A checkpoint for marking number of votes from a given block\n struct Checkpoint {\n uint32 fromBlock;\n uint96 votes;\n }\n\n /// @notice A record of votes checkpoints for each account, by index\n mapping (address =\u003e mapping (uint32 =\u003e Checkpoint)) public checkpoints;\n\n /// @notice The number of checkpoints for each account\n mapping (address =\u003e uint32) public numCheckpoints;\n\n /// @notice The EIP-712 typehash for the contract\u0027s domain\n bytes32 public constant DOMAIN_TYPEHASH = keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant DELEGATION_TYPEHASH = keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n /// @notice The EIP-712 typehash for the permit struct used by the contract\n bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n /// @notice A record of states for signing / validating signatures\n mapping (address =\u003e uint) public nonces;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account\u0027s vote balance changes\n event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice The standard EIP-20 transfer event\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /// @notice The standard EIP-20 approval event\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Construct a new Forth token\n * @param account The initial account to grant all the tokens\n * @param minter_ The account with minting ability\n * @param mintingAllowedAfter_ The timestamp after which minting may occur\n */\n constructor(address account, address minter_, uint mintingAllowedAfter_) public {\n require(mintingAllowedAfter_ \u003e= block.timestamp, \"Forth::constructor: minting can only begin after deployment\");\n\n balances[account] = uint96(totalSupply);\n emit Transfer(address(0), account, totalSupply);\n minter = minter_;\n emit MinterChanged(address(0), minter);\n mintingAllowedAfter = mintingAllowedAfter_;\n }\n\n /**\n * @notice Change the minter address\n * @param minter_ The address of the new minter\n */\n function setMinter(address minter_) external {\n require(msg.sender == minter, \"Forth::setMinter: only the minter can change the minter address\");\n emit MinterChanged(minter, minter_);\n minter = minter_;\n }\n\n /**\n * @notice Mint new tokens\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to be minted\n */\n function mint(address dst, uint rawAmount) external {\n require(msg.sender == minter, \"Forth::mint: only the minter can mint\");\n require(block.timestamp \u003e= mintingAllowedAfter, \"Forth::mint: minting not allowed yet\");\n require(dst != address(0), \"Forth::mint: cannot transfer to the zero address\");\n\n // record the mint\n mintingAllowedAfter = SafeMath.add(block.timestamp, minimumTimeBetweenMints);\n\n // mint the amount\n uint96 amount = safe96(rawAmount, \"Forth::mint: amount exceeds 96 bits\");\n require(amount \u003c= SafeMath.div(SafeMath.mul(totalSupply, mintCap), 100), \"Forth::mint: exceeded mint cap\");\n uint96 supply = safe96(totalSupply, \"Forth::mint old totalSupply exceeds 96 bits\");\n totalSupply = add96(supply, amount, \"Forth::mint: new totalSupply exceeds 96 bits\");\n\n // transfer the amount to the recipient\n balances[dst] = add96(balances[dst], amount, \"Forth::mint: transfer amount overflows\");\n emit Transfer(address(0), dst, amount);\n\n // move delegates\n _moveDelegates(address(0), delegates[dst], amount);\n }\n\n /**\n * @notice Destroys `amount` tokens from the caller\n * @param rawAmount The number of tokens to burn\n */\n function burn(uint256 rawAmount) external {\n uint96 amount = safe96(rawAmount, \"Forth::burn: rawAmount exceeds 96 bits\");\n _burn(msg.sender, amount);\n }\n\n /**\n * @notice Destroys `amount` tokens from `account`, deducting from the caller\u0027s allowance\n * @param account The address of the account to burn from\n * @param rawAmount The number of tokens to burn\n */\n function burnFrom(address account, uint256 rawAmount) external {\n uint96 amount = safe96(rawAmount, \"Forth::burnFrom: rawAmount exceeds 96 bits\");\n\n uint96 decreasedAllowance =\n sub96(allowances[account][msg.sender], amount, \"Forth::burnFrom: amount exceeds allowance\");\n allowances[account][msg.sender] = decreasedAllowance;\n emit Approval(account, msg.sender, decreasedAllowance);\n\n _burn(account, amount);\n }\n\n /**\n * @notice Destroys `amount` tokens from `account`, reducing the total supply\n * @param account The address of the account to burn from\n * @param amount The number of tokens to burn\n */\n function _burn(address account, uint96 amount) internal {\n require(account != address(0), \"Forth::_burn: burn from the zero address\");\n\n uint96 supply = safe96(totalSupply, \"Forth::_burn: old supply exceeds 96 bits\");\n totalSupply = sub96(supply, amount, \"Forth::_burn: amount exceeds totalSupply\");\n\n balances[account] = sub96(balances[account], amount, \"Forth::_burn: amount exceeds balance\");\n emit Transfer(account, address(0), amount);\n\n // move delegates\n _moveDelegates(delegates[account], address(0), amount);\n }\n\n /**\n * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`\n * @param account The address of the account holding the funds\n * @param spender The address of the account spending the funds\n * @return The number of tokens approved\n */\n function allowance(address account, address spender) external view returns (uint) {\n return allowances[account][spender];\n }\n\n /**\n * @notice Approve `spender` to transfer up to `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address spender, uint rawAmount) external returns (bool) {\n uint96 amount;\n if (rawAmount == type(uint).max) {\n amount = type(uint96).max;\n } else {\n amount = safe96(rawAmount, \"Forth::approve: amount exceeds 96 bits\");\n }\n\n allowances[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n * @notice Triggers an approval from owner to spends\n * @param owner The address to approve from\n * @param spender The address to be approved\n * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)\n * @param deadline The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function permit(address owner, address spender, uint rawAmount, uint deadline, uint8 v, bytes32 r, bytes32 s) external {\n uint96 amount;\n if (rawAmount == type(uint).max) {\n amount = type(uint96).max;\n } else {\n amount = safe96(rawAmount, \"Forth::permit: amount exceeds 96 bits\");\n }\n\n bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));\n bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, rawAmount, nonces[owner]++, deadline));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"Forth::permit: invalid signature\");\n require(signatory == owner, \"Forth::permit: unauthorized\");\n require(now \u003c= deadline, \"Forth::permit: signature expired\");\n\n allowances[owner][spender] = amount;\n\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @notice Get the number of tokens held by the `account`\n * @param account The address of the account to get the balance of\n * @return The number of tokens held\n */\n function balanceOf(address account) external view returns (uint) {\n return balances[account];\n }\n\n /**\n * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint rawAmount) external returns (bool) {\n uint96 amount = safe96(rawAmount, \"Forth::transfer: amount exceeds 96 bits\");\n _transferTokens(msg.sender, dst, amount);\n return true;\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the source account\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint rawAmount) external returns (bool) {\n address spender = msg.sender;\n uint96 spenderAllowance = allowances[src][spender];\n uint96 amount = safe96(rawAmount, \"Forth::approve: amount exceeds 96 bits\");\n\n if (spender != src \u0026\u0026 spenderAllowance != type(uint96).max) {\n uint96 newAllowance = sub96(spenderAllowance, amount, \"Forth::transferFrom: transfer amount exceeds spender allowance\");\n allowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n }\n\n _transferTokens(src, dst, amount);\n return true;\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The address to delegate votes to\n */\n function delegate(address delegatee) public {\n return _delegate(msg.sender, delegatee);\n }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public {\n bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));\n bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"Forth::delegateBySig: invalid signature\");\n require(nonce == nonces[signatory]++, \"Forth::delegateBySig: invalid nonce\");\n require(now \u003c= expiry, \"Forth::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n return nCheckpoints \u003e 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n /**\n * @notice Determine the prior number of votes for an account as of a block number\n * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.\n * @param account The address of the account to check\n * @param blockNumber The block number to get the vote balance at\n * @return The number of votes the account had as of the given block\n */\n function getPriorVotes(address account, uint blockNumber) public view returns (uint96) {\n require(blockNumber \u003c block.number, \"Forth::getPriorVotes: not yet determined\");\n\n uint32 nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent balance\n if (checkpoints[account][nCheckpoints - 1].fromBlock \u003c= blockNumber) {\n return checkpoints[account][nCheckpoints - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlock \u003e blockNumber) {\n return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper \u003e lower) {\n uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n if (cp.fromBlock == blockNumber) {\n return cp.votes;\n } else if (cp.fromBlock \u003c blockNumber) {\n lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower].votes;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator];\n uint96 delegatorBalance = balances[delegator];\n delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _transferTokens(address src, address dst, uint96 amount) internal {\n require(src != address(0), \"Forth::_transferTokens: cannot transfer from the zero address\");\n require(dst != address(0), \"Forth::_transferTokens: cannot transfer to the zero address\");\n\n balances[src] = sub96(balances[src], amount, \"Forth::_transferTokens: transfer amount exceeds balance\");\n balances[dst] = add96(balances[dst], amount, \"Forth::_transferTokens: transfer amount overflows\");\n emit Transfer(src, dst, amount);\n\n _moveDelegates(delegates[src], delegates[dst], amount);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep \u0026\u0026 amount \u003e 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n uint96 srcRepOld = srcRepNum \u003e 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld, amount, \"Forth::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld = dstRepNum \u003e 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"Forth::_moveVotes: vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumber = safe32(block.number, \"Forth::_writeCheckpoint: block number exceeds 32 bits\");\n\n if (nCheckpoints \u003e 0 \u0026\u0026 checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n } else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1;\n }\n\n emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n require(n \u003c 2**32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {\n require(n \u003c 2**96, errorMessage);\n return uint96(n);\n }\n\n function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c \u003e= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n require(b \u003c= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n uint256 chainId;\n assembly { chainId := chainid() }\n return chainId;\n }\n}\n"},"SafeMath.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity \u003e=0.6.0 \u003c0.8.0;\n\n/**\n * @dev Wrappers over Solidity\u0027s arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it\u0027s recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c \u003c a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b \u003e a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c \u003e= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003c= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003e 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003e 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003c= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0, errorMessage);\n return a % b;\n }\n}\n"}}
File 5 of 5: GovernorBravoDelegate
{"GovernorBravoDelegate.sol":{"content":"// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./GovernorBravoInterfaces.sol\";\n\ncontract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoEvents {\n\n /// @notice The name of this contract\n string public constant name = \"Ampleforth Governor Bravo\";\n\n /// @notice The minimum setable proposal threshold\n uint public constant MIN_PROPOSAL_THRESHOLD = 75000e18; // 75,000 Forth\n\n /// @notice The maximum setable proposal threshold\n uint public constant MAX_PROPOSAL_THRESHOLD = 300000e18; // 300,000 Forth\n\n /// @notice The minimum setable voting period\n uint public constant MIN_VOTING_PERIOD = 5760; // About 24 hours\n\n /// @notice The max setable voting period\n uint public constant MAX_VOTING_PERIOD = 80640; // About 2 weeks\n\n /// @notice The min setable voting delay\n uint public constant MIN_VOTING_DELAY = 1;\n\n /// @notice The max setable voting delay\n uint public constant MAX_VOTING_DELAY = 40320; // About 1 week\n\n /// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed\n uint public constant quorumVotes = 600000e18; // 600,000 = 4% of Forth\n\n /// @notice The maximum number of actions that can be included in a proposal\n uint public constant proposalMaxOperations = 10; // 10 actions\n\n /// @notice The EIP-712 typehash for the contract\u0027s domain\n bytes32 public constant DOMAIN_TYPEHASH = keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the ballot struct used by the contract\n bytes32 public constant BALLOT_TYPEHASH = keccak256(\"Ballot(uint256 proposalId,uint8 support)\");\n\n /**\n * @notice Used to initialize the contract during delegator contructor\n * @param timelock_ The address of the Timelock\n * @param forth_ The address of the FORTH token\n * @param votingPeriod_ The initial voting period\n * @param votingDelay_ The initial voting delay\n * @param proposalThreshold_ The initial proposal threshold\n */\n function initialize(address timelock_, address forth_, uint votingPeriod_, uint votingDelay_, uint proposalThreshold_) public {\n require(address(timelock) == address(0), \"GovernorBravo::initialize: can only initialize once\");\n require(msg.sender == admin, \"GovernorBravo::initialize: admin only\");\n require(timelock_ != address(0), \"GovernorBravo::initialize: invalid timelock address\");\n require(forth_ != address(0), \"GovernorBravo::initialize: invalid forth address\");\n require(votingPeriod_ \u003e= MIN_VOTING_PERIOD \u0026\u0026 votingPeriod_ \u003c= MAX_VOTING_PERIOD, \"GovernorBravo::initialize: invalid voting period\");\n require(votingDelay_ \u003e= MIN_VOTING_DELAY \u0026\u0026 votingDelay_ \u003c= MAX_VOTING_DELAY, \"GovernorBravo::initialize: invalid voting delay\");\n require(proposalThreshold_ \u003e= MIN_PROPOSAL_THRESHOLD \u0026\u0026 proposalThreshold_ \u003c= MAX_PROPOSAL_THRESHOLD, \"GovernorBravo::initialize: invalid proposal threshold\");\n\n timelock = TimelockInterface(timelock_);\n timelock.acceptAdmin();\n forth = ForthInterface(forth_);\n votingPeriod = votingPeriod_;\n votingDelay = votingDelay_;\n proposalThreshold = proposalThreshold_;\n }\n\n /**\n * @notice Function used to propose a new proposal. Sender must have delegates above the proposal threshold\n * @param targets Target addresses for proposal calls\n * @param values Eth values for proposal calls\n * @param signatures Function signatures for proposal calls\n * @param calldatas Calldatas for proposal calls\n * @param description String description of the proposal\n * @return Proposal id of new proposal\n */\n function propose(address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) public returns (uint) {\n require(forth.getPriorVotes(msg.sender, sub256(block.number, 1)) \u003e proposalThreshold, \"GovernorBravo::propose: proposer votes below proposal threshold\");\n require(targets.length == values.length \u0026\u0026 targets.length == signatures.length \u0026\u0026 targets.length == calldatas.length, \"GovernorBravo::propose: proposal function information arity mismatch\");\n require(targets.length != 0, \"GovernorBravo::propose: must provide actions\");\n require(targets.length \u003c= proposalMaxOperations, \"GovernorBravo::propose: too many actions\");\n\n uint latestProposalId = latestProposalIds[msg.sender];\n if (latestProposalId != 0) {\n ProposalState proposersLatestProposalState = state(latestProposalId);\n require(proposersLatestProposalState != ProposalState.Active, \"GovernorBravo::propose: one live proposal per proposer, found an already active proposal\");\n require(proposersLatestProposalState != ProposalState.Pending, \"GovernorBravo::propose: one live proposal per proposer, found an already pending proposal\");\n }\n\n uint startBlock = add256(block.number, votingDelay);\n uint endBlock = add256(startBlock, votingPeriod);\n\n proposalCount++;\n Proposal memory newProposal = Proposal({\n id: proposalCount,\n proposer: msg.sender,\n eta: 0,\n targets: targets,\n values: values,\n signatures: signatures,\n calldatas: calldatas,\n startBlock: startBlock,\n endBlock: endBlock,\n forVotes: 0,\n againstVotes: 0,\n abstainVotes: 0,\n canceled: false,\n executed: false\n });\n\n proposals[newProposal.id] = newProposal;\n latestProposalIds[newProposal.proposer] = newProposal.id;\n\n emit ProposalCreated(newProposal.id, msg.sender, targets, values, signatures, calldatas, startBlock, endBlock, description);\n return newProposal.id;\n }\n\n /**\n * @notice Queues a proposal of state succeeded\n * @param proposalId The id of the proposal to queue\n */\n function queue(uint proposalId) external {\n require(state(proposalId) == ProposalState.Succeeded, \"GovernorBravo::queue: proposal can only be queued if it is succeeded\");\n Proposal storage proposal = proposals[proposalId];\n uint eta = add256(block.timestamp, timelock.delay());\n for (uint i = 0; i \u003c proposal.targets.length; i++) {\n queueOrRevertInternal(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta);\n }\n proposal.eta = eta;\n emit ProposalQueued(proposalId, eta);\n }\n\n function queueOrRevertInternal(address target, uint value, string memory signature, bytes memory data, uint eta) internal {\n require(!timelock.queuedTransactions(keccak256(abi.encode(target, value, signature, data, eta))), \"GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta\");\n timelock.queueTransaction(target, value, signature, data, eta);\n }\n\n /**\n * @notice Executes a queued proposal if eta has passed\n * @param proposalId The id of the proposal to execute\n */\n function execute(uint proposalId) external payable {\n require(state(proposalId) == ProposalState.Queued, \"GovernorBravo::execute: proposal can only be executed if it is queued\");\n Proposal storage proposal = proposals[proposalId];\n proposal.executed = true;\n for (uint i = 0; i \u003c proposal.targets.length; i++) {\n timelock.executeTransaction{value: proposal.values[i]}(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta);\n }\n emit ProposalExecuted(proposalId);\n }\n\n /**\n * @notice Cancels a proposal only if sender is the proposer, or proposer delegates dropped below proposal threshold\n * @param proposalId The id of the proposal to cancel\n */\n function cancel(uint proposalId) external {\n require(state(proposalId) != ProposalState.Executed, \"GovernorBravo::cancel: cannot cancel executed proposal\");\n\n Proposal storage proposal = proposals[proposalId];\n require(msg.sender == proposal.proposer || forth.getPriorVotes(proposal.proposer, sub256(block.number, 1)) \u003c proposalThreshold, \"GovernorBravo::cancel: proposer above threshold\");\n\n proposal.canceled = true;\n for (uint i = 0; i \u003c proposal.targets.length; i++) {\n timelock.cancelTransaction(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], proposal.eta);\n }\n\n emit ProposalCanceled(proposalId);\n }\n\n /**\n * @notice Gets actions of a proposal\n * @param proposalId the id of the proposal\n * @return targets proposal targets\n * @return values proposal values\n * @return signatures proposal signatures\n * @return calldatas proposal calldatas\n */\n function getActions(uint proposalId) external view returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas) {\n Proposal storage p = proposals[proposalId];\n return (p.targets, p.values, p.signatures, p.calldatas);\n }\n\n /**\n * @notice Gets the receipt for a voter on a given proposal\n * @param proposalId the id of proposal\n * @param voter The address of the voter\n * @return The voting receipt\n */\n function getReceipt(uint proposalId, address voter) external view returns (Receipt memory) {\n return proposals[proposalId].receipts[voter];\n }\n\n /**\n * @notice Gets the state of a proposal\n * @param proposalId The id of the proposal\n * @return Proposal state\n */\n function state(uint proposalId) public view returns (ProposalState) {\n require(proposalCount \u003e= proposalId \u0026\u0026 proposalId \u003e 0, \"GovernorBravo::state: invalid proposal id\");\n Proposal storage proposal = proposals[proposalId];\n if (proposal.canceled) {\n return ProposalState.Canceled;\n } else if (block.number \u003c= proposal.startBlock) {\n return ProposalState.Pending;\n } else if (block.number \u003c= proposal.endBlock) {\n return ProposalState.Active;\n } else if (proposal.forVotes \u003c= proposal.againstVotes || proposal.forVotes \u003c quorumVotes) {\n return ProposalState.Defeated;\n } else if (proposal.eta == 0) {\n return ProposalState.Succeeded;\n } else if (proposal.executed) {\n return ProposalState.Executed;\n } else if (block.timestamp \u003e= add256(proposal.eta, timelock.GRACE_PERIOD())) {\n return ProposalState.Expired;\n } else {\n return ProposalState.Queued;\n }\n }\n\n /**\n * @notice Cast a vote for a proposal\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n */\n function castVote(uint proposalId, uint8 support) external {\n emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), \"\");\n }\n\n /**\n * @notice Cast a vote for a proposal with a reason\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @param reason The reason given for the vote by the voter\n */\n function castVoteWithReason(uint proposalId, uint8 support, string calldata reason) external {\n emit VoteCast(msg.sender, proposalId, support, castVoteInternal(msg.sender, proposalId, support), reason);\n }\n\n /**\n * @notice Cast a vote for a proposal by signature\n * @dev External function that accepts EIP-712 signatures for voting on proposals.\n */\n function castVoteBySig(uint proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external {\n bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainIdInternal(), address(this)));\n bytes32 structHash = keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"GovernorBravo::castVoteBySig: invalid signature\");\n emit VoteCast(signatory, proposalId, support, castVoteInternal(signatory, proposalId, support), \"\");\n }\n\n /**\n * @notice Internal function that caries out voting logic\n * @param voter The voter that is casting their vote\n * @param proposalId The id of the proposal to vote on\n * @param support The support value for the vote. 0=against, 1=for, 2=abstain\n * @return The number of votes cast\n */\n function castVoteInternal(address voter, uint proposalId, uint8 support) internal returns (uint96) {\n require(state(proposalId) == ProposalState.Active, \"GovernorBravo::castVoteInternal: voting is closed\");\n require(support \u003c= 2, \"GovernorBravo::castVoteInternal: invalid vote type\");\n Proposal storage proposal = proposals[proposalId];\n Receipt storage receipt = proposal.receipts[voter];\n require(receipt.hasVoted == false, \"GovernorBravo::castVoteInternal: voter already voted\");\n uint96 votes = forth.getPriorVotes(voter, proposal.startBlock);\n\n if (support == 0) {\n proposal.againstVotes = add256(proposal.againstVotes, votes);\n } else if (support == 1) {\n proposal.forVotes = add256(proposal.forVotes, votes);\n } else if (support == 2) {\n proposal.abstainVotes = add256(proposal.abstainVotes, votes);\n }\n\n receipt.hasVoted = true;\n receipt.support = support;\n receipt.votes = votes;\n\n return votes;\n }\n\n /**\n * @notice Admin function for setting the voting delay\n * @param newVotingDelay new voting delay, in blocks\n */\n function _setVotingDelay(uint newVotingDelay) external {\n require(msg.sender == admin, \"GovernorBravo::_setVotingDelay: admin only\");\n require(newVotingDelay \u003e= MIN_VOTING_DELAY \u0026\u0026 newVotingDelay \u003c= MAX_VOTING_DELAY, \"GovernorBravo::_setVotingDelay: invalid voting delay\");\n uint oldVotingDelay = votingDelay;\n votingDelay = newVotingDelay;\n\n emit VotingDelaySet(oldVotingDelay,votingDelay);\n }\n\n /**\n * @notice Admin function for setting the voting period\n * @param newVotingPeriod new voting period, in blocks\n */\n function _setVotingPeriod(uint newVotingPeriod) external {\n require(msg.sender == admin, \"GovernorBravo::_setVotingPeriod: admin only\");\n require(newVotingPeriod \u003e= MIN_VOTING_PERIOD \u0026\u0026 newVotingPeriod \u003c= MAX_VOTING_PERIOD, \"GovernorBravo::_setVotingPeriod: invalid voting period\");\n uint oldVotingPeriod = votingPeriod;\n votingPeriod = newVotingPeriod;\n\n emit VotingPeriodSet(oldVotingPeriod, votingPeriod);\n }\n\n /**\n * @notice Admin function for setting the proposal threshold\n * @dev newProposalThreshold must be greater than the hardcoded min\n * @param newProposalThreshold new proposal threshold\n */\n function _setProposalThreshold(uint newProposalThreshold) external {\n require(msg.sender == admin, \"GovernorBravo::_setProposalThreshold: admin only\");\n require(newProposalThreshold \u003e= MIN_PROPOSAL_THRESHOLD \u0026\u0026 newProposalThreshold \u003c= MAX_PROPOSAL_THRESHOLD, \"GovernorBravo::_setProposalThreshold: invalid proposal threshold\");\n uint oldProposalThreshold = proposalThreshold;\n proposalThreshold = newProposalThreshold;\n\n emit ProposalThresholdSet(oldProposalThreshold, proposalThreshold);\n }\n\n /**\n * @notice Begins transfer of admin rights. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @dev Admin function to begin change of admin. The newPendingAdmin must call `_acceptAdmin` to finalize the transfer.\n * @param newPendingAdmin New pending admin.\n */\n function _setPendingAdmin(address newPendingAdmin) external {\n // Check caller = admin\n require(msg.sender == admin, \"GovernorBravo:_setPendingAdmin: admin only\");\n\n // Save current value, if any, for inclusion in log\n address oldPendingAdmin = pendingAdmin;\n\n // Store pendingAdmin with value newPendingAdmin\n pendingAdmin = newPendingAdmin;\n\n // Emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin)\n emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin);\n }\n\n /**\n * @notice Accepts transfer of admin rights. msg.sender must be pendingAdmin\n * @dev Admin function for pending admin to accept role and update admin\n */\n function _acceptAdmin() external {\n // Check caller is pendingAdmin and pendingAdmin ≠ address(0)\n require(msg.sender == pendingAdmin \u0026\u0026 msg.sender != address(0), \"GovernorBravo:_acceptAdmin: pending admin only\");\n\n // Save current values for inclusion in log\n address oldAdmin = admin;\n address oldPendingAdmin = pendingAdmin;\n\n // Store admin with value pendingAdmin\n admin = pendingAdmin;\n\n // Clear the pending value\n pendingAdmin = address(0);\n\n emit NewAdmin(oldAdmin, admin);\n emit NewPendingAdmin(oldPendingAdmin, pendingAdmin);\n }\n\n function add256(uint256 a, uint256 b) internal pure returns (uint) {\n uint c = a + b;\n require(c \u003e= a, \"addition overflow\");\n return c;\n }\n\n function sub256(uint256 a, uint256 b) internal pure returns (uint) {\n require(b \u003c= a, \"subtraction underflow\");\n return a - b;\n }\n\n function getChainIdInternal() internal pure returns (uint) {\n uint chainId;\n assembly { chainId := chainid() }\n return chainId;\n }\n}\n"},"GovernorBravoInterfaces.sol":{"content":"// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\n\ncontract GovernorBravoEvents {\n /// @notice An event emitted when a new proposal is created\n event ProposalCreated(uint id, address proposer, address[] targets, uint[] values, string[] signatures, bytes[] calldatas, uint startBlock, uint endBlock, string description);\n\n /// @notice An event emitted when a vote has been cast on a proposal\n /// @param voter The address which casted a vote\n /// @param proposalId The proposal id which was voted on\n /// @param support Support value for the vote. 0=against, 1=for, 2=abstain\n /// @param votes Number of votes which were cast by the voter\n /// @param reason The reason given for the vote by the voter\n event VoteCast(address indexed voter, uint proposalId, uint8 support, uint votes, string reason);\n\n /// @notice An event emitted when a proposal has been canceled\n event ProposalCanceled(uint id);\n\n /// @notice An event emitted when a proposal has been queued in the Timelock\n event ProposalQueued(uint id, uint eta);\n\n /// @notice An event emitted when a proposal has been executed in the Timelock\n event ProposalExecuted(uint id);\n\n /// @notice An event emitted when the voting delay is set\n event VotingDelaySet(uint oldVotingDelay, uint newVotingDelay);\n\n /// @notice An event emitted when the voting period is set\n event VotingPeriodSet(uint oldVotingPeriod, uint newVotingPeriod);\n\n /// @notice Emitted when implementation is changed\n event NewImplementation(address oldImplementation, address newImplementation);\n\n /// @notice Emitted when proposal threshold is set\n event ProposalThresholdSet(uint oldProposalThreshold, uint newProposalThreshold);\n\n /// @notice Emitted when pendingAdmin is changed\n event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);\n\n /// @notice Emitted when pendingAdmin is accepted, which means admin is updated\n event NewAdmin(address oldAdmin, address newAdmin);\n}\n\ncontract GovernorBravoDelegatorStorage {\n /// @notice Administrator for this contract\n address public admin;\n\n /// @notice Pending administrator for this contract\n address public pendingAdmin;\n\n /// @notice Active brains of Governor\n address public implementation;\n}\n\n\n/**\n * @title Storage for Governor Bravo Delegate\n * @notice For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new\n * contract which implements GovernorBravoDelegateStorageV1 and following the naming convention\n * GovernorBravoDelegateStorageVX.\n */\ncontract GovernorBravoDelegateStorageV1 is GovernorBravoDelegatorStorage {\n\n /// @notice The delay before voting on a proposal may take place, once proposed, in blocks\n uint public votingDelay;\n\n /// @notice The duration of voting on a proposal, in blocks\n uint public votingPeriod;\n\n /// @notice The number of votes required in order for a voter to become a proposer\n uint public proposalThreshold;\n\n /// @notice The total number of proposals\n uint public proposalCount;\n\n /// @notice The address of the Ampleforth Protocol Timelock\n TimelockInterface public timelock;\n\n /// @notice The address of the Ampleforth governance token\n ForthInterface public forth;\n\n /// @notice The official record of all proposals ever proposed\n mapping (uint =\u003e Proposal) public proposals;\n\n /// @notice The latest proposal for each proposer\n mapping (address =\u003e uint) public latestProposalIds;\n\n\n struct Proposal {\n // Unique id for looking up a proposal\n uint id;\n\n // Creator of the proposal\n address proposer;\n\n // The timestamp that the proposal will be available for execution, set once the vote succeeds\n uint eta;\n\n // The ordered list of target addresses for calls to be made\n address[] targets;\n\n // The ordered list of values (i.e. msg.value) to be passed to the calls to be made\n uint[] values;\n\n // The ordered list of function signatures to be called\n string[] signatures;\n\n // The ordered list of calldata to be passed to each call\n bytes[] calldatas;\n\n // The block at which voting begins: holders must delegate their votes prior to this block\n uint startBlock;\n\n // The block at which voting ends: votes must be cast prior to this block\n uint endBlock;\n\n // Current number of votes in favor of this proposal\n uint forVotes;\n\n // Current number of votes in opposition to this proposal\n uint againstVotes;\n\n // Current number of votes for abstaining for this proposal\n uint abstainVotes;\n\n // Flag marking whether the proposal has been canceled\n bool canceled;\n\n // Flag marking whether the proposal has been executed\n bool executed;\n\n // Receipts of ballots for the entire set of voters\n mapping (address =\u003e Receipt) receipts;\n }\n\n /// @notice Ballot receipt record for a voter\n struct Receipt {\n // Whether or not a vote has been cast\n bool hasVoted;\n\n // Whether or not the voter supports the proposal or abstains\n uint8 support;\n\n // The number of votes the voter had, which were cast\n uint96 votes;\n }\n\n /// @notice Possible states that a proposal may be in\n enum ProposalState {\n Pending,\n Active,\n Canceled,\n Defeated,\n Succeeded,\n Queued,\n Expired,\n Executed\n }\n}\n\ninterface TimelockInterface {\n function delay() external view returns (uint);\n function GRACE_PERIOD() external view returns (uint);\n function acceptAdmin() external;\n function queuedTransactions(bytes32 hash) external view returns (bool);\n function queueTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external returns (bytes32);\n function cancelTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external;\n function executeTransaction(address target, uint value, string calldata signature, bytes calldata data, uint eta) external payable returns (bytes memory);\n}\n\ninterface ForthInterface {\n function getPriorVotes(address account, uint blockNumber) external view returns (uint96);\n}\n"}}