ETH Price: $3,006.75 (+3.49%)
Gas: 5 Gwei

Transaction Decoder

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 Code
0x223592a1...E771539A9
0x77FbA179...0AdA60ce0
0x8a994C6F...E3a2dA8F1
(beaverbuild)
18.908600938454414849 Eth18.908604794063213303 Eth0.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
        {"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"}}