Contract 0x8bF05ce17B30f8C73B06e49f67076f944687c967

 
Txn Hash Method
Block
From
To
Value
0x1c76754b127aa6ddf9f1fe1d25c328fd7342372853461e3c621cdf2ffe9054830x5f348555134802172021-10-24 12:33:022 days 5 hrs ago0x8bf418c4c734f85a8d0b51c37b2d92373906feb2 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.041839509046 58.650338177
0x5cbcbfc0ada033664806dc22e0725210cd57485e0e20f32db2a37002115c66bf0x5f348555134544122021-10-20 11:43:386 days 6 hrs ago0x1555d9dd364168ce671a92493aa01f05caf68cb4 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.04305092668 60.428544511
0xa9f8021bda163fb1f8284cb8b030fa6acdc32461bf8debd58dcbb13ef668175c0x5f348555134534492021-10-20 8:07:056 days 10 hrs ago0xb010ca9be09c382a9f31b79493bb232bcc319f01 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.060881482985 52.450396457
0xd3158d8edf7c2aad510d9f340e6c752209bea0fa68ac9b74e1582aebf317346f0x5f348555134482272021-10-19 12:37:417 days 5 hrs ago0xd08d7118df080ad546cc4f1fb7c63bce39aeee2f IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.080132228449 70.252111932
0xf2e38f07cc81c4e5528f0344ee8b0ff9fbbce27a4fe2b935b68e2c4f8a94a7410x5f348555134373062021-10-17 19:26:168 days 23 hrs agoENS Name bretthenry.eth IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.079431098774 64.009382305
0xc2137998013a4a54122e8aad607cae44caf913e6548a98d82844b0c27c42c6310x5f348555133940232021-10-11 0:06:5915 days 18 hrs ago0x846e4dff3ec7a5d7f7b47dd5b681346b4096eb06 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.115510295849 101.291590171
0x61c0edfa588f9a25b6707386851de1a1ed775c5a3b6b1e562ce91a1ab02120db0x5f348555133851502021-10-09 14:46:0517 days 3 hrs ago0xf4dfea1119da0cb511e1982c5130c47bb0594b0f IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.08328734617 71.753415198
0x74887fabbdf5046f1f9fe0ab369cca1f9c1055dce17acf9c63cf62bfdd7642d50x5f348555133639272021-10-06 6:46:1220 days 11 hrs ago0x7a15f03b46b642ac9e70c30f2c80b0d257754b32 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.152580769342 133.765102495
0xcd5d2e1e6cd59ba5671315b231b14e3a6a3264b35086ad3749733910067fa2b40x5f348555133441062021-10-03 4:26:5423 days 14 hrs agoENS Name jeremyg.eth IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.062663345233 50.498588705
0x85dcf4ce1cb940ba6a1468ea6c2517db2e96721ee375c58fc6328aa75c10663f0x5f348555133393992021-10-02 10:45:3724 days 7 hrs ago0xf684885742956cb744cec7190ba888b9a9e19e5b IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.046385497206 39.986842635
0x8c9fc7d8b425f7ac70561f7c1a85018b6c131e63e6eee80045afd8889441eaea0x5f348555133277972021-09-30 15:14:1326 days 3 hrs ago0x2471a0dc634c8961719e4ad5bdb7e401f5d09bbc IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.086543035138 98.726587069
0x2ee6006925a1bba8f99c37f46a80bdb3e9c8b6f50b8668cb6a2509df5ea380be0x5f348555133206412021-09-29 12:25:0727 days 6 hrs agoENS Name hyperfunk.eth IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.06382370456
0x4a38503ecbedaade75a727ad219b03bcdf4ca2ae410394ea796f8e7f2dfe0ab10x5f348555133189242021-09-29 5:50:0427 days 12 hrs ago0xc4d8e54e89439672ecc338b4829a3143929bf738 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.050347474781 44.137427068
0x4137217cf728dbe5eb43241345f5c236377145d0d43eb8f90b0053422cfff89d0x5f348555133104332021-09-27 22:03:3728 days 20 hrs ago0xa15ca74e65bf72730811abf95163e89ad9b9dff6 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.111062953616 97.437233453
0x11d0c0d1996bcaedbb10c989e0c25ea8a4c141b828f29fcc853b8d2ca2f118240x5f348555133089112021-09-27 16:31:0929 days 1 hr ago0x93c8b165a6a097c8b8bb4bf2a59e185b3af5b08d IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.183479623532157.18830726
0x8baff316afd4bc841ed7ee5e4dd716047616607ef504751709327f6fb37f49940x5f348555133043302021-09-26 23:16:4429 days 19 hrs ago0x1584f0048e5091ae2a950a4a210ece159fdd9162 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.038432701137 51.926399046
0xe7a26312e5c652c29ad16b99277664a6b378f94120948f716f4bd81310104e390x5f348555133039622021-09-26 21:55:2929 days 20 hrs ago0x1584f0048e5091ae2a950a4a210ece159fdd9162 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.0472879056 61.653955403
0x6c676470892b2349114a6cb4ca93f41b7e7def1921e943147fd673f5040d39e40x5f348555133006552021-09-26 9:40:3230 days 8 hrs ago0x73f4c54b663f084fd68be4eed261f66a828cdafe IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.076875622753 61.942270476
0xca8f3f65eb650d0b7ac5bb54717f7914ea8c156d0449eae801d6c2c5e470d92e0x5f348555132985662021-09-26 1:42:0230 days 16 hrs agoENS Name zkpeep.eth IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.047918332486 41.28285641
0x4fd9eb6ca7cd7cb5e80121320a67488bab7b5a4eb5fe52ca76fd459993af15f40x5f348555132905212021-09-24 20:04:3731 days 22 hrs ago0xa3d8f82044a53b9daf24a718fc3631a0a48dc96f IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.08333765839 73.066932024
0x85be72835b93f732ddd72e335983c3859aeaa96fac6f2f1d0ae269406abe066c0x5f348555132849532021-09-23 23:28:3832 days 19 hrs agoChic-A-Dees: Deployer IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.047127200785 66.057125055
0xbaa98e98a346a300cf4865098e810294b703373c4f1006fa40792cd371f1f9340x5f348555132675702021-09-21 6:49:5135 days 11 hrs agoENS Name tywen.eth IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.085354731732 62.082625126
0x2aef29381f059a9f5af92a761023c2e21389def0d1c136c4e7446b67568f4ede0x5f348555132583712021-09-19 20:33:5636 days 21 hrs ago0x89ce0f71d7387a580c6c07032f74f393a65d77f4 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.087306500665 76.533761469
0x1ea2390349690d3743bf06b85ecf96514f3fef1239f9eec107bcbd14a4b689620x5f348555132551602021-09-19 8:45:0737 days 9 hrs ago0x3fb6d9b0b071e0627b1ce8aa669cdea3a337837f IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.01997567628
0x4ac16dca7317457d3ec9f6db76a6ac3f339739d2d07ab7cfe17a3c1767daa2210x5f348555132526852021-09-18 23:31:3937 days 18 hrs ago0xcd886a1cac4ba6616f0f3f8f2157feacd751fe20 IN  0x8bf05ce17b30f8c73b06e49f67076f944687c9670 Ether0.045098197674 38.850828972
[ Download CSV Export 
View more zero value Internal Transactions in Advanced View mode
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GovernBaseFactory

Compiler Version
v0.6.8+commit.0bbfe453

Optimization Enabled:
Yes with 20000 runs

Other Settings:
default evmVersion, GNU GPLv3 license
File 1 of 35 : GovernFactory.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;

import "erc3k/contracts/IERC3000.sol";
import "@aragon/govern-core/contracts/Govern.sol";
import "@aragon/govern-contract-utils/contracts/minimal-proxies/ERC1167ProxyFactory.sol";
import "@aragon/govern-contract-utils/contracts/address-utils/AddressUtils.sol";

contract GovernFactory {
    using ERC1167ProxyFactory for address;
    using AddressUtils for address;
    
    address public base;

    constructor() public {
        setupBase();
    }

    function newGovern(IERC3000 _initialExecutor, bytes32 _salt) public returns (Govern govern) {
        if (_salt != bytes32(0)) {
            return Govern(base.clone2(_salt, abi.encodeWithSelector(govern.initialize.selector, _initialExecutor)).toPayable());
        } else {
            return new Govern(address(_initialExecutor));
        }
    }

    function setupBase() private {
        base = address(new Govern(address(2)));
    }
}

File 2 of 35 : IERC3000.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;

import "./ERC3000Data.sol";

abstract contract IERC3000 {
    /**
     * @notice Schedules an action for execution, allowing for challenges and vetos on a defined time window
     * @param container A Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     * @return containerHash
     */
    function schedule(ERC3000Data.Container memory container) virtual public returns (bytes32 containerHash);
    event Scheduled(bytes32 indexed containerHash, ERC3000Data.Payload payload);

    /**
     * @notice Executes an action after its execution delay has passed and its state hasn't been altered by a challenge or veto
     * @param container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     * MUST be an ERC3000Executor call: payload.executor.exec(payload.actions)
     * @return failureMap
     * @return execResults
     */
    function execute(ERC3000Data.Container memory container) virtual public returns (bytes32 failureMap, bytes[] memory execResults);
    event Executed(bytes32 indexed containerHash, address indexed actor);

    /**
     * @notice Challenge a container in case its scheduling is illegal as per Config.rules. Pulls collateral and dispute fees from sender into contract
     * @param container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     * @param reason Hint for case reviewers as to why the scheduled container is illegal
     * @return resolverId
     */
    function challenge(ERC3000Data.Container memory container, bytes memory reason) virtual public returns (uint256 resolverId);
    event Challenged(bytes32 indexed containerHash, address indexed actor, bytes reason, uint256 resolverId, ERC3000Data.Collateral collateral);

    /**
     * @notice Apply arbitrator's ruling over a challenge once it has come to a final ruling
     * @param container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     * @param resolverId disputeId in the arbitrator in which the dispute over the container was created
     * @return failureMap
     * @return execResults
     */
    function resolve(ERC3000Data.Container memory container, uint256 resolverId) virtual public returns (bytes32 failureMap, bytes[] memory execResults);
    event Resolved(bytes32 indexed containerHash, address indexed actor, bool approved);

    /**
     * @notice Apply arbitrator's ruling over a challenge once it has come to a final ruling
     * @param container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     * @param reason Justification for the veto
     */
    function veto(ERC3000Data.Container memory container, bytes memory reason) virtual public;
    event Vetoed(bytes32 indexed containerHash, address indexed actor, bytes reason);

    /**
     * @notice Apply a new configuration for all *new* containers to be scheduled
     * @param config A ERC3000Data.Config struct holding all the new params that will control the system
     * @return configHash
     */
    function configure(ERC3000Data.Config memory config) virtual public returns (bytes32 configHash);
    event Configured(bytes32 indexed configHash, address indexed actor, ERC3000Data.Config config);
}

File 3 of 35 : Govern.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;
pragma experimental ABIEncoderV2;

import "erc3k/contracts/IERC3000Executor.sol";
import "erc3k/contracts/IERC3000.sol";

import "@aragon/govern-contract-utils/contracts/acl/ACL.sol";
import "@aragon/govern-contract-utils/contracts/adaptive-erc165/AdaptiveERC165.sol";
import "@aragon/govern-contract-utils/contracts/bitmaps/BitmapLib.sol";
import "@aragon/govern-contract-utils/contracts/address-utils/AddressUtils.sol";
import "@aragon/govern-contract-utils/contracts/erc20/ERC20.sol";
import "@aragon/govern-contract-utils/contracts/erc20/SafeERC20.sol";

import "./erc1271/ERC1271.sol";

contract Govern is IERC3000Executor, AdaptiveERC165, ERC1271, ACL {
    using BitmapLib for bytes32;
    using AddressUtils for address;
    using SafeERC20 for ERC20;

    string private constant ERROR_DEPOSIT_AMOUNT_ZERO = "GOVERN_DEPOSIT_AMOUNT_ZERO";
    string private constant ERROR_ETH_DEPOSIT_AMOUNT_MISMATCH = "GOVERN_ETH_DEPOSIT_AMOUNT_MISMATCH";
    string private constant ERROR_TOKEN_NOT_CONTRACT = "GOVERN_TOKEN_NOT_CONTRACT";
    string private constant ERROR_TOKEN_DEPOSIT_FAILED = "GOVERN_TOKEN_DEPOSIT_FAILED";
    string private constant ERROR_TOO_MANY_ACTIONS = "GOVERN_TOO_MANY_ACTIONS";
    string private constant ERROR_ACTION_CALL_FAILED = "GOVERN_ACTION_CALL_FAILED";
    string private constant ERROR_TOKEN_WITHDRAW_FAILED = "GOVERN_TOKEN_WITHDRAW_FAILED";
    string private constant ERROR_ETH_WITHDRAW_FAILED = "GOVERN_ETH_WITHDRAW_FAILED";

    bytes4 internal constant EXEC_ROLE = this.exec.selector;
    bytes4 internal constant WITHDRAW_ROLE = this.withdraw.selector;

    bytes4 internal constant REGISTER_STANDARD_ROLE = this.registerStandardAndCallback.selector;
    bytes4 internal constant SET_SIGNATURE_VALIDATOR_ROLE = this.setSignatureValidator.selector;
    uint256 internal constant MAX_ACTIONS = 256;

    ERC1271 signatureValidator;

    // ETHDeposited and Deposited are both needed. ETHDeposited makes sure that whoever sends funds
    // with `send/transfer`, receive function can still be executed without reverting due to gas cost
    // increases in EIP-2929. To still use `send/transfer`, access list is needed that has the address
    // of the contract(base contract) that is behind the proxy.
    event ETHDeposited(address sender, uint256 amount);

    event Deposited(address indexed sender, address indexed token, uint256 amount, string _reference);
    event Withdrawn(address indexed token, address indexed to, address from, uint256 amount, string _reference);

    constructor(address _initialExecutor) ACL(address(this)) public {
        initialize(_initialExecutor);
    }

    function initialize(address _initialExecutor) public initACL(address(this)) onlyInit("govern") {
        _grant(EXEC_ROLE, address(_initialExecutor));
        _grant(WITHDRAW_ROLE, address(this));

        // freeze the withdraw so that only GovernExecutor can call
        _freeze(WITHDRAW_ROLE);

        _grant(REGISTER_STANDARD_ROLE, address(this));
        _grant(SET_SIGNATURE_VALIDATOR_ROLE, address(this));

        _registerStandard(ERC3000_EXEC_INTERFACE_ID);
        _registerStandard(type(ERC1271).interfaceId);
    }

    receive () external payable {
        emit ETHDeposited(msg.sender, msg.value);
    }

    fallback () external {
        _handleCallback(msg.sig, msg.data); // WARN: does a low-level return, any code below would be unreacheable
    }

    function deposit(address _token, uint256 _amount, string calldata _reference) external payable {
        require(_amount > 0, ERROR_DEPOSIT_AMOUNT_ZERO);

        if (_token == address(0)) {
            require(msg.value == _amount, ERROR_ETH_DEPOSIT_AMOUNT_MISMATCH);
        } else {
            require(_token.isContract(), ERROR_TOKEN_NOT_CONTRACT);
            require(ERC20(_token).safeTransferFrom(msg.sender, address(this), _amount), ERROR_TOKEN_DEPOSIT_FAILED);
        }
        emit Deposited(msg.sender, _token, _amount, _reference);
    }

    function withdraw(address _token, address _from, address _to, uint256 _amount, string memory _reference) public auth(WITHDRAW_ROLE) {
        if (_token == address(0)) {
            (bool ok, ) = _to.call{value: _amount}("");
            require(ok, ERROR_ETH_WITHDRAW_FAILED);
        } else {
            require(ERC20(_token).safeTransfer(_to, _amount), ERROR_TOKEN_WITHDRAW_FAILED);
        }
        emit Withdrawn(_token, _to, _from, _amount, _reference);
    }

    function exec(ERC3000Data.Action[] memory actions, bytes32 allowFailuresMap, bytes32 memo) override public auth(EXEC_ROLE) returns (bytes32, bytes[] memory) {
        require(actions.length <= MAX_ACTIONS, ERROR_TOO_MANY_ACTIONS); // need to limit since we use 256-bit bitmaps

        bytes[] memory execResults = new bytes[](actions.length);
        bytes32 failureMap = BitmapLib.empty; // start with an empty bitmap

        for (uint256 i = 0; i < actions.length; i++) {
            // TODO: optimize with assembly
            (bool ok, bytes memory ret) = actions[i].to.call{value: actions[i].value}(actions[i].data);
            require(ok || allowFailuresMap.get(uint8(i)), ERROR_ACTION_CALL_FAILED);
            // if a call fails, flip that bit to signal failure
            failureMap = ok ? failureMap : failureMap.flip(uint8(i));
            execResults[i] = ret;
        }

        emit Executed(msg.sender, actions, memo, failureMap, execResults);

        return (failureMap, execResults);
    }

    function registerStandardAndCallback(bytes4 _interfaceId, bytes4 _callbackSig, bytes4 _magicNumber) external auth(REGISTER_STANDARD_ROLE) {
        _registerStandardAndCallback(_interfaceId, _callbackSig, _magicNumber);
    }

    function setSignatureValidator(ERC1271 _signatureValidator) external auth(SET_SIGNATURE_VALIDATOR_ROLE) {
        signatureValidator = _signatureValidator;
    }

    function isValidSignature(bytes32 _hash, bytes memory _signature) override public view returns (bytes4) {
        if (address(signatureValidator) == address(0)) return bytes4(0); // invalid magic number
        return signatureValidator.isValidSignature(_hash, _signature); // forward call to set validation contract
    }
}

File 4 of 35 : ERC1167ProxyFactory.sol
/*
 * SPDX-License-Identifier:    MIT
 */

// Inspired by: https://github.com/optionality/clone-factory

pragma solidity ^0.6.8;

library ERC1167ProxyFactory {
    function clone(address _implementation) internal returns (address cloneAddr) {
        bytes memory createData = generateCreateData(_implementation);

        assembly {
            cloneAddr := create(0, add(createData, 0x20), 55)
        }

        require(cloneAddr != address(0), "proxy-factory: bad create");
    }

    function clone(address _implementation, bytes memory _initData) internal returns (address cloneAddr) {
        cloneAddr = clone(_implementation);
        (bool ok, bytes memory ret) = cloneAddr.call(_initData);

        require(ok, _getRevertMsg(ret));
    }

    function clone2(address _implementation, bytes32 _salt) internal returns (address cloneAddr) {
        bytes memory createData = generateCreateData(_implementation);

        assembly {
            cloneAddr := create2(0, add(createData, 0x20), 55, _salt)
        }

        require(cloneAddr != address(0), "proxy-factory: bad create2");
    }

    function clone2(address _implementation, bytes32 _salt, bytes memory _initData) internal returns (address cloneAddr) {
        cloneAddr = clone2(_implementation, _salt);
        (bool ok, bytes memory ret) = cloneAddr.call(_initData);

        require(ok, _getRevertMsg(ret));
    }

    function generateCreateData(address _implementation) internal pure returns (bytes memory) {
        return abi.encodePacked(
            //---- constructor -----
            bytes10(0x3d602d80600a3d3981f3),
            //---- proxy code -----
            bytes10(0x363d3d373d3d3d363d73),
            _implementation,
            bytes15(0x5af43d82803e903d91602b57fd5bf3)
        );
    }

    // From: https://ethereum.stackexchange.com/a/83577
    function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {
        // If the _res length is less than 68, then the transaction failed silently (without a revert message)
        if (_returnData.length < 68) return '';

        assembly {
            _returnData := add(_returnData, 0x04) // Slice the sighash.
        }
        return abi.decode(_returnData, (string)); // All that remains is the revert string
    }
}

File 5 of 35 : AddressUtils.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

library AddressUtils {
    
    function toPayable(address addr) internal pure returns (address payable) {
        return address(bytes20(addr));
    }

    /**
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     */
    function isContract(address addr) internal view returns (bool result) {
        assembly {
            result := iszero(iszero(extcodesize(addr)))
        }
    }
}

File 6 of 35 : ERC3000Data.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;

import "./IERC3000Executor.sol";

library ERC3000Data {
    // TODO: come up with a non-shitty name
    struct Container {
        Payload payload;
        Config config;
    }

    // WARN: Always remember to change the 'hash' function if modifying the struct
    struct Payload {
        uint256 nonce;
        uint256 executionTime;
        address submitter;
        IERC3000Executor executor;
        Action[] actions;
        bytes32 allowFailuresMap;
        bytes proof;
    }

    struct Action {
        address to;
        uint256 value;
        bytes data;
    }

    struct Config {
        uint256 executionDelay; // how many seconds to wait before being able to call `execute`.
        Collateral scheduleDeposit; // fees for scheduling
        Collateral challengeDeposit; // fees for challenging
        address resolver;  // resolver that will rule the disputes
        bytes rules; // rules of how DAO should be managed
        uint256 maxCalldataSize; // max calldatasize for the schedule
    }

    struct Collateral {
        address token;
        uint256 amount;
    }

    function containerHash(bytes32 payloadHash, bytes32 configHash) internal view returns (bytes32) {
        uint chainId;
        assembly {
            chainId := chainid()
        }

        return keccak256(abi.encodePacked("erc3k-v1", address(this), chainId, payloadHash, configHash));
    }

    function hash(Container memory container) internal view returns (bytes32) {
        return containerHash(hash(container.payload), hash(container.config));
    }

    function hash(Payload memory payload) internal pure returns (bytes32) {
        return keccak256(
            abi.encode(
                payload.nonce,
                payload.executionTime,
                payload.submitter,
                payload.executor,
                keccak256(abi.encode(payload.actions)),
                payload.allowFailuresMap,
                keccak256(payload.proof)
            )
        );
    }

    function hash(Config memory config) internal pure returns (bytes32) {
        return keccak256(abi.encode(config));
    }
}

File 7 of 35 : IERC3000Executor.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;

import "./ERC3000Data.sol";

abstract contract IERC3000Executor {
    bytes4 internal constant ERC3000_EXEC_INTERFACE_ID = this.exec.selector;

    /**
     * @notice Executes all given actions
     * @param actions A array of ERC3000Data.Action for later executing those
     * @param allowFailuresMap A map with the allowed failures
     * @param memo The hash of the ERC3000Data.Container
     * @return failureMap
     * @return execResults
     */
    function exec(ERC3000Data.Action[] memory actions, bytes32 allowFailuresMap, bytes32 memo) virtual public returns (bytes32 failureMap, bytes[] memory execResults);
    event Executed(address indexed actor, ERC3000Data.Action[] actions, bytes32 memo, bytes32 failureMap, bytes[] execResults);
}

File 8 of 35 : ACL.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;

import "../initializable/Initializable.sol";

import "./IACLOracle.sol";

library ACLData {
    enum BulkOp { Grant, Revoke, Freeze }

    struct BulkItem {
        BulkOp op;
        bytes4 role;
        address who;
    }
}

contract ACL is Initializable {
    bytes4 public constant ROOT_ROLE =
        this.grant.selector
        ^ this.revoke.selector
        ^ this.freeze.selector
        ^ this.bulk.selector
    ;

    // "Who" constants
    address internal constant ANY_ADDR = address(-1);

    // "Access" flags
    address internal constant UNSET_ROLE = address(0);
    address internal constant FREEZE_FLAG = address(1); // Also used as "who"
    address internal constant ALLOW_FLAG = address(2);

    // Role -> Who -> Access flag (unset or allow) or ACLOracle (any other address denominates auth via ACLOracle)
    mapping (bytes4 => mapping (address => address)) public roles;

    event Granted(bytes4 indexed role, address indexed actor, address indexed who, IACLOracle oracle);
    event Revoked(bytes4 indexed role, address indexed actor, address indexed who);
    event Frozen(bytes4 indexed role, address indexed actor);

    modifier auth(bytes4 _role) {
        require(willPerform(_role, msg.sender, msg.data), "acl: auth");
        _;
    }

    modifier initACL(address _initialRoot) {
        // ACL might have been already initialized by constructors
        if (initBlocks["acl"] == 0) {
            _initializeACL(_initialRoot);
        } else {
            require(roles[ROOT_ROLE][_initialRoot] == ALLOW_FLAG, "acl: initial root misaligned");
        }
        _;
    }

    constructor(address _initialRoot) public initACL(_initialRoot) { }

    function grant(bytes4 _role, address _who) external auth(ROOT_ROLE) {
        _grant(_role, _who);
    }

    function grantWithOracle(bytes4 _role, address _who, IACLOracle _oracle) external auth(ROOT_ROLE) {
        _grantWithOracle(_role, _who, _oracle);
    }

    function revoke(bytes4 _role, address _who) external auth(ROOT_ROLE) {
        _revoke(_role, _who);
    }

    function freeze(bytes4 _role) external auth(ROOT_ROLE) {
        _freeze(_role);
    }

    function bulk(ACLData.BulkItem[] calldata items) external auth(ROOT_ROLE) {
        for (uint256 i = 0; i < items.length; i++) {
            ACLData.BulkItem memory item = items[i];

            if (item.op == ACLData.BulkOp.Grant) _grant(item.role, item.who);
            else if (item.op == ACLData.BulkOp.Revoke) _revoke(item.role, item.who);
            else if (item.op == ACLData.BulkOp.Freeze) _freeze(item.role);
        }
    }

    function willPerform(bytes4 _role, address _who, bytes memory _data) internal returns (bool) {
        // First check if the given who is auth'd, then if any address is auth'd
        return _checkRole(_role, _who, _data) || _checkRole(_role, ANY_ADDR, _data);
    }

    function isFrozen(bytes4 _role) public view returns (bool) {
        return roles[_role][FREEZE_FLAG] == FREEZE_FLAG;
    }

    function _initializeACL(address _initialRoot) internal onlyInit("acl") {
        _grant(ROOT_ROLE, _initialRoot);
    }

    function _grant(bytes4 _role, address _who) internal {
        _grantWithOracle(_role, _who, IACLOracle(ALLOW_FLAG));
    }

    function _grantWithOracle(bytes4 _role, address _who, IACLOracle _oracle) internal {
        require(!isFrozen(_role), "acl: frozen");
        require(_who != FREEZE_FLAG, "acl: bad freeze");

        roles[_role][_who] = address(_oracle);
        emit Granted(_role, msg.sender, _who, _oracle);
    }

    function _revoke(bytes4 _role, address _who) internal {
        require(!isFrozen(_role), "acl: frozen");

        roles[_role][_who] = UNSET_ROLE;
        emit Revoked(_role, msg.sender, _who);
    }

    function _freeze(bytes4 _role) internal {
        require(!isFrozen(_role), "acl: frozen");

        roles[_role][FREEZE_FLAG] = FREEZE_FLAG;
        emit Frozen(_role, msg.sender);
    }

    function _checkRole(bytes4 _role, address _who, bytes memory _data) internal returns (bool) {
        address accessFlagOrAclOracle = roles[_role][_who];
        if (accessFlagOrAclOracle != UNSET_ROLE) {
            if (accessFlagOrAclOracle == ALLOW_FLAG) return true;

            // Since it's not a flag, assume it's an ACLOracle and try-catch to skip failures
            try IACLOracle(accessFlagOrAclOracle).willPerform(_role, _who, _data) returns (bool allowed) {
                if (allowed) return true;
            } catch { }
        }

        return false;
    }
}

File 9 of 35 : AdaptiveERC165.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

import "../erc165/ERC165.sol";

contract AdaptiveERC165 is ERC165 {
    // ERC165 interface ID -> whether it is supported
    mapping (bytes4 => bool) internal standardSupported;
    // Callback function signature -> magic number to return
    mapping (bytes4 => bytes32) internal callbackMagicNumbers;

    bytes32 internal constant UNREGISTERED_CALLBACK = bytes32(0);

    event RegisteredStandard(bytes4 interfaceId);
    event RegisteredCallback(bytes4 sig, bytes4 magicNumber);
    event ReceivedCallback(bytes4 indexed sig, bytes data);

    function supportsInterface(bytes4 _interfaceId) override virtual public view returns (bool) {
        return standardSupported[_interfaceId] || super.supportsInterface(_interfaceId);
    }

    function _handleCallback(bytes4 _sig, bytes memory _data) internal {
        bytes32 magicNumber = callbackMagicNumbers[_sig];
        require(magicNumber != UNREGISTERED_CALLBACK, "adap-erc165: unknown callback");

        emit ReceivedCallback(_sig, _data);

        // low-level return magic number
        assembly {
            mstore(0x00, magicNumber)
            return(0x00, 0x20)
        }
    }

    function _registerStandardAndCallback(bytes4 _interfaceId, bytes4 _callbackSig, bytes4 _magicNumber) internal {
        _registerStandard(_interfaceId);
        _registerCallback(_callbackSig, _magicNumber);
    }

    function _registerStandard(bytes4 _interfaceId) internal {
        standardSupported[_interfaceId] = true;
        emit RegisteredStandard(_interfaceId);
    }

    function _registerCallback(bytes4 _callbackSig, bytes4 _magicNumber) internal {
        callbackMagicNumbers[_callbackSig] = _magicNumber;
        emit RegisteredCallback(_callbackSig, _magicNumber);
    }
}

File 10 of 35 : BitmapLib.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

library BitmapLib {
    bytes32 constant internal empty = bytes32(0);

    function flip(bytes32 map, uint8 index) internal pure returns (bytes32) {
        return bytes32(uint256(map) ^ uint256(1) << index);
    }

    function get(bytes32 map, uint8 index) internal pure returns (bool) {
        return (uint256(map) >> index & 1) == 1;
    }
}

File 11 of 35 : ERC20.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
interface ERC20 {
    // Optional fields 
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);


    function totalSupply() external view returns (uint256);

    function balanceOf(address _who) external view returns (uint256);

    function allowance(address _owner, address _spender) external view returns (uint256);

    function transfer(address _to, uint256 _value) external returns (bool);

    function approve(address _spender, uint256 _value) external returns (bool);

    function transferFrom(address _from, address _to, uint256 _value) external returns (bool);

    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value
    );

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

File 12 of 35 : SafeERC20.sol
/*
 * SPDX-License-Identifier:    MIT
 */

// From https://github.com/aragon/aragonOS/blob/next/contracts/common/SafeERC20.sol

// Inspired by AdEx (https://github.com/AdExNetwork/adex-protocol-eth/blob/b9df617829661a7518ee10f4cb6c4108659dd6d5/contracts/libs/SafeERC20.sol)
// and 0x (https://github.com/0xProject/0x-monorepo/blob/737d1dc54d72872e24abce5a1dbe1b66d35fa21a/contracts/protocol/contracts/protocol/AssetProxy/ERC20Proxy.sol#L143)

pragma solidity ^0.6.8;

import "../address-utils/AddressUtils.sol";

import "./ERC20.sol";

library SafeERC20 {
    using AddressUtils for address;

    function invokeAndCheckSuccess(address _addr, bytes memory _calldata)
        private
        returns (bool ret)
    {
        if (!_addr.isContract()) {
            return false;
        }

        assembly {
            let ptr := mload(0x40)    // free memory pointer

            let success := call(
                gas(),                // forward all
                _addr,                // address
                0,                    // no value
                add(_calldata, 0x20), // calldata start
                mload(_calldata),     // calldata length
                ptr,                  // write output over free memory
                0x20                  // uint256 return
            )

            if gt(success, 0) {
                // Check number of bytes returned from last function call
                switch returndatasize()

                // No bytes returned: assume success
                case 0 {
                    ret := 1
                }

                // 32 bytes returned: check if non-zero
                case 0x20 {
                    // Only return success if returned data was true
                    // Already have output in ptr
                    ret := iszero(iszero(mload(ptr)))
                }

                // Not sure what was returned: don't mark as success
                default { }
            }
        }
    }

    /**
    * @dev Same as a standards-compliant ERC20.transfer() that never reverts (returns false).
    *      Note that this makes an external call to the token.
    */
    function safeTransfer(ERC20 _token, address _to, uint256 _amount) internal returns (bool) {
        bytes memory transferCallData = abi.encodeWithSelector(
            _token.transfer.selector,
            _to,
            _amount
        );
        return invokeAndCheckSuccess(address(_token), transferCallData);
    }

    /**
    * @dev Same as a standards-compliant ERC20.transferFrom() that never reverts (returns false).
    *      Note that this makes an external call to the token.
    */
    function safeTransferFrom(ERC20 _token, address _from, address _to, uint256 _amount) internal returns (bool) {
        bytes memory transferFromCallData = abi.encodeWithSelector(
            _token.transferFrom.selector,
            _from,
            _to,
            _amount
        );
        return invokeAndCheckSuccess(address(_token), transferFromCallData);
    }

    /**
    * @dev Same as a standards-compliant ERC20.approve() that never reverts (returns false).
    *      Note that this makes an external call to the token.
    */
    function safeApprove(ERC20 _token, address _spender, uint256 _amount) internal returns (bool) {
        bytes memory approveCallData = abi.encodeWithSelector(
            _token.approve.selector,
            _spender,
            _amount
        );
        return invokeAndCheckSuccess(address(_token), approveCallData);
    }
}

File 13 of 35 : ERC1271.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

/**
* @title ERC1271 interface
* @dev see https://eips.ethereum.org/EIPS/eip-1271
*/
abstract contract ERC1271 {
    // bytes4(keccak256("isValidSignature(bytes32,bytes)")
    bytes4 constant internal MAGICVALUE = 0x1626ba7e;

    /**
    * @dev Should return whether the signature provided is valid for the provided data
    * @param _hash Keccak256 hash of arbitrary length data signed on the behalf of address(this)
    * @param _signature Signature byte array associated with _data
    *
    * MUST return the bytes4 magic value 0x1626ba7e when function passes.
    * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)
    * MUST allow external calls
    */
    function isValidSignature(bytes32 _hash, bytes memory _signature) virtual public view returns (bytes4 magicValue);
}

File 14 of 35 : Initializable.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity 0.6.8;

contract Initializable {
    mapping (string => uint256) public initBlocks;

    event Initialized(string indexed key);

    modifier onlyInit(string memory key) {
        require(initBlocks[key] == 0, "initializable: already initialized");
        initBlocks[key] = block.number;
        _;
        emit Initialized(key);
    }
}

File 15 of 35 : IACLOracle.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

interface IACLOracle {
    function willPerform(bytes4 role, address who, bytes calldata data) external returns (bool allowed);
}

File 16 of 35 : ERC165.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

abstract contract ERC165 {
    // Includes supportsInterface method:
    bytes4 internal constant ERC165_INTERFACE_ID = bytes4(0x01ffc9a7);

    /**
    * @dev Query if a contract implements a certain interface
    * @param _interfaceId The interface identifier being queried, as specified in ERC-165
    * @return True if the contract implements the requested interface and if its not 0xffffffff, false otherwise
    */
    function supportsInterface(bytes4 _interfaceId) virtual public view returns (bool) {
        return _interfaceId == ERC165_INTERFACE_ID;
    }
}

File 17 of 35 : GovernBaseFactory.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;
pragma experimental ABIEncoderV2;

import "@aragon/govern-core/contracts/GovernRegistry.sol";

import "@aragon/govern-token/contracts/GovernTokenFactory.sol";
import "@aragon/govern-token/contracts/interfaces/IERC20.sol";
import "@aragon/govern-token/contracts/GovernMinter.sol";
import "@aragon/govern-token/contracts/libraries/TokenLib.sol";

import "./core-factories/GovernFactory.sol";
import "./core-factories/GovernQueueFactory.sol";

contract GovernBaseFactory {
    address internal constant ANY_ADDR = address(-1);
    uint256 internal constant MAX_SCHEDULE_ACCESS_LIST_ALLOWED = 10;
    
    string private constant ERROR_SCHEDULE_LIST_EXCEEDED = "basefactory: schedule list exceeded";

    GovernFactory public governFactory;
    GovernQueueFactory public queueFactory;
    GovernTokenFactory public tokenFactory;
    GovernRegistry public registry;
    
    constructor(
        GovernRegistry _registry,
        GovernFactory _governFactory,
        GovernQueueFactory _queueFactory,
        GovernTokenFactory _tokenFactory
    ) public {
        governFactory = _governFactory;
        queueFactory = _queueFactory;
        tokenFactory = _tokenFactory;
        registry = _registry;
    }

    function newGovern(
        TokenLib.TokenConfig calldata _token,
        address[] calldata _scheduleAccessList,
        bool _useProxies,
        ERC3000Data.Config calldata _config,
        string calldata _name
    ) external returns (Govern govern, GovernQueue queue) {
        require(_scheduleAccessList.length <= MAX_SCHEDULE_ACCESS_LIST_ALLOWED, ERROR_SCHEDULE_LIST_EXCEEDED);

        bytes32 salt = _useProxies ? keccak256(abi.encodePacked(_name)) : bytes32(0);

        queue = queueFactory.newQueue(address(this), _config, salt);
        govern = governFactory.newGovern(queue, salt);

        IERC20 token = _token.tokenAddress;
        GovernMinter minter;

        if (address(token) == address(0)) {
            (token, minter) = tokenFactory.newToken(
                govern,
                _token,
                _useProxies
            );

            // if both(scheduleDeposit and challengeDeposit) are non-zero, 
            // they have already been set and no need for a config change.
            if (_config.scheduleDeposit.token == address(0) || _config.challengeDeposit.token == address(0)) {
                // give base factory the permission so that it can change 
                // the config with new token in the same transaction
                queue.grant(queue.configure.selector, address(this));
                
                ERC3000Data.Config memory newConfig = ERC3000Data.Config({
                    executionDelay: _config.executionDelay,
                    scheduleDeposit: ERC3000Data.Collateral({
                        token: _config.scheduleDeposit.token != address(0) ? _config.scheduleDeposit.token : address(token),
                        amount: _config.scheduleDeposit.amount
                    }),
                    challengeDeposit: ERC3000Data.Collateral({
                        token:  _config.challengeDeposit.token != address(0) ? _config.challengeDeposit.token : address(token),
                        amount: _config.challengeDeposit.amount
                    }),
                    resolver: _config.resolver,
                    rules: _config.rules,
                    maxCalldataSize: _config.maxCalldataSize
                });

                queue.configure(newConfig);
                queue.revoke(queue.configure.selector, address(this));
            }
        }

        registry.register(govern, queue, token, address(minter), _name, "");
        
        uint256 bulkSize = _scheduleAccessList.length == 0 ? 7 : 6 + _scheduleAccessList.length;
        ACLData.BulkItem[] memory items = new ACLData.BulkItem[](bulkSize);
        
        items[0] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.execute.selector, ANY_ADDR);
        items[1] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.challenge.selector, ANY_ADDR);
        items[2] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.configure.selector, address(govern));
        items[3] = ACLData.BulkItem(ACLData.BulkOp.Revoke, queue.ROOT_ROLE(), address(this));
        items[4] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.ROOT_ROLE(), address(govern));
        items[5] = ACLData.BulkItem(ACLData.BulkOp.Freeze, queue.ROOT_ROLE(), address(0));

        // If the schedule access list is empty, anyone can schedule
        // otherwise, only the addresses specified are allowed.
        if (_scheduleAccessList.length == 0) { 
            items[6] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.schedule.selector, ANY_ADDR);
        } else { 
            for (uint256 i = 0; i < _scheduleAccessList.length; i++) {
                items[6 + i] = ACLData.BulkItem(
                    ACLData.BulkOp.Grant, 
                    queue.schedule.selector, 
                    _scheduleAccessList[i]
                );
            }
        }

        queue.bulk(items);
    }
    
}

File 18 of 35 : GovernRegistry.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;

import "erc3k/contracts/IERC3000.sol";
import "erc3k/contracts/IERC3000Executor.sol";
import "erc3k/contracts/IERC3000Registry.sol";

import "@aragon/govern-contract-utils/contracts/erc165/ERC165.sol";

contract GovernRegistry is IERC3000Registry {
    mapping(string => bool) public nameUsed;

    function register(
        IERC3000Executor _executor,
        IERC3000 _queue,
        IERC20 _token,
        address minter,
        string calldata _name,
        bytes calldata _initialMetadata
    ) override external
    {
        require(!nameUsed[_name], "registry: name used");

        nameUsed[_name] = true;

        emit Registered(_executor, _queue, _token, minter, msg.sender, _name);
        _setMetadata(_executor, _initialMetadata);
    }

    function setMetadata(bytes memory _metadata) override public {
        _setMetadata(IERC3000Executor(msg.sender), _metadata);
    }

    function _setMetadata(IERC3000Executor _executor, bytes memory _metadata) internal {
        emit SetMetadata(_executor, _metadata);
    }
}

File 19 of 35 : GovernTokenFactory.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;
pragma experimental ABIEncoderV2;

import "@aragon/govern-contract-utils/contracts/minimal-proxies/ERC1167ProxyFactory.sol";
import "./libraries/TokenLib.sol";

import "erc3k/contracts/IERC3000Executor.sol";

import "./GovernToken.sol";
import "./GovernMinter.sol";
import "./MerkleDistributor.sol";

contract GovernTokenFactory {
    using ERC1167ProxyFactory for address;
    
    address public tokenBase;
    address public minterBase;
    address public distributorBase;

    event CreatedToken(GovernToken token, GovernMinter minter);

    constructor() public {
        setupBases();
    }

    function newToken(
        IERC3000Executor _governExecutor,
        TokenLib.TokenConfig calldata _token,
        bool _useProxies
    ) external returns (
        GovernToken token,
        GovernMinter minter
    ) {
        if (!_useProxies) {
            (token, minter) = _deployContracts(_token.tokenName, _token.tokenSymbol, _token.tokenDecimals);
        } else {
            token = GovernToken(tokenBase.clone(abi.encodeWithSelector(
                token.initialize.selector,
                address(this),
                _token.tokenName,
                _token.tokenSymbol,
                _token.tokenDecimals
            ))); 
            minter = GovernMinter(minterBase.clone(abi.encodeWithSelector(
                minter.initialize.selector,
                token,
                address(this),
                MerkleDistributor(distributorBase)
            )));
        }

        token.changeMinter(address(minter));
        
        if (_token.mintAmount > 0) {
            minter.mint(_token.mintAddress, _token.mintAmount, "initial mint");
        }

        if (_token.merkleRoot != bytes32(0)) {
            minter.merkleMint(_token.merkleRoot, _token.merkleMintAmount, _token.merkleTree, _token.merkleContext);
        }

        bytes4 mintRole = minter.mint.selector ^ minter.merkleMint.selector;
        bytes4 rootRole = minter.ROOT_ROLE();

        ACLData.BulkItem[] memory items = new ACLData.BulkItem[](4);

        items[0] = ACLData.BulkItem(ACLData.BulkOp.Grant, mintRole, address(_governExecutor));
        items[1] = ACLData.BulkItem(ACLData.BulkOp.Grant, rootRole, address(_governExecutor));
        items[2] = ACLData.BulkItem(ACLData.BulkOp.Revoke, mintRole, address(this));
        items[3] = ACLData.BulkItem(ACLData.BulkOp.Revoke, rootRole, address(this));

        minter.bulk(items);

        emit CreatedToken(token, minter);
    }

    function setupBases() private {
        distributorBase = address(new MerkleDistributor(ERC20(tokenBase), bytes32(0)));
        
        (GovernToken token, GovernMinter minter) = _deployContracts(
            "GovernToken base",
            "GTB",
            0
        );
        token.changeMinter(address(minter));

        // test the bases
        minter.mint(msg.sender, 1, "test mint");
        minter.merkleMint(bytes32(0), 1, "no tree", "test merkle mint");

        // store bases
        tokenBase = address(token);
        minterBase = address(minter);
    }

    function _deployContracts(
        string memory _tokenName,
        string memory _tokenSymbol,
        uint8 _tokenDecimals
    ) internal returns (
        GovernToken token,
        GovernMinter minter
    ) {
        token = new GovernToken(address(this), _tokenName, _tokenSymbol, _tokenDecimals);
        minter = new GovernMinter(GovernToken(token), address(this), MerkleDistributor(distributorBase));
    }
}

File 20 of 35 : IERC20.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity ^0.6.8;

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}

File 21 of 35 : GovernMinter.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;

import "@aragon/govern-contract-utils/contracts/acl/ACL.sol";
import "@aragon/govern-contract-utils/contracts/minimal-proxies/ERC1167ProxyFactory.sol";

import "./GovernToken.sol";
import "./MerkleDistributor.sol";

contract GovernMinter is ACL {
    using ERC1167ProxyFactory for address;

    bytes4 constant internal MINT_ROLE =
        this.mint.selector ^
        this.merkleMint.selector
    ;

    GovernToken public token;
    address public distributorBase;

    event MintedSingle(address indexed to, uint256 amount, bytes context);
    event MintedMerkle(address indexed distributor, bytes32 indexed merkleRoot, uint256 totalAmount, bytes tree, bytes context);

    constructor(GovernToken _token, address _initialMinter, MerkleDistributor _distributorBase) ACL(_initialMinter) public {
        initialize(_token, _initialMinter, _distributorBase);
    }

    function initialize(GovernToken _token, address _initialMinter, MerkleDistributor _distributorBase) public initACL(_initialMinter) onlyInit("minter") {
        token = _token;
        distributorBase = address(_distributorBase);
        _grant(MINT_ROLE, _initialMinter);
    }

    function mint(address _to, uint256 _amount, bytes calldata _context) external auth(MINT_ROLE) {
        token.mint(_to, _amount);
        emit MintedSingle(_to, _amount, _context);
    }

    function merkleMint(bytes32 _merkleRoot, uint256 _totalAmount, bytes calldata _tree, bytes calldata _context) external auth(MINT_ROLE) returns (MerkleDistributor distributor) {
        address distributorAddr = distributorBase.clone(abi.encodeWithSelector(distributor.initialize.selector, token, _merkleRoot));
        token.mint(distributorAddr, _totalAmount);

        emit MintedMerkle(distributorAddr, _merkleRoot, _totalAmount, _tree, _context);

        return MerkleDistributor(distributorAddr);
    }

    function eject(address _newMinter) external auth(this.eject.selector) {
        token.changeMinter(_newMinter);
    }
}

File 22 of 35 : TokenLib.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

import "../interfaces/IERC20.sol";

library TokenLib {
    
    struct TokenConfig {
        IERC20 tokenAddress;
        uint8  tokenDecimals;
        string tokenName;
        string tokenSymbol;
        address mintAddress; // initial minter address
        uint256 mintAmount; // how much to mint to initial minter address
        // merkle settings
        bytes32 merkleRoot; // merkle distribution root.
        uint256 merkleMintAmount; // how much to mint for the distributor.
        bytes merkleTree; // merkle tree object
        bytes merkleContext; // context/string what's the actual reason is...
    }
    
}

File 23 of 35 : GovernQueueFactory.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;
pragma experimental ABIEncoderV2;

import "@aragon/govern-core/contracts/pipelines/GovernQueue.sol";
import "@aragon/govern-contract-utils/contracts/minimal-proxies/ERC1167ProxyFactory.sol";

contract GovernQueueFactory {
    using ERC1167ProxyFactory for address;

    address public base;

    constructor() public {
        setupBase();
    }

    function newQueue(address _aclRoot, ERC3000Data.Config memory _config, bytes32 _salt) public returns (GovernQueue queue) {
        if (_salt != bytes32(0)) {
            return GovernQueue(base.clone2(_salt, abi.encodeWithSelector(queue.initialize.selector, _aclRoot, _config)));
        } else {
            return new GovernQueue(_aclRoot, _config);
        }
    }

    function setupBase() private {
        ERC3000Data.Collateral memory noCollateral;
        ERC3000Data.Config memory config = ERC3000Data.Config(
            3600,  // how many seconds to wait before being able to call `execute`
            noCollateral,
            noCollateral,
            address(0),
            "",
            100000 // initial maxCalldatasize
        );
        base = address(new GovernQueue(address(2), config));
    }
}

File 24 of 35 : IERC3000Registry.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity 0.6.8;

import "./IERC3000.sol";
import "./IERC3000Executor.sol";

import "@aragon/govern-token/contracts/interfaces/IERC20.sol";

abstract contract IERC3000Registry {
    /**
     * @notice Registers a IERC3000Executor and IERC3000 contract by a name and with his metadata
     * @param executor IERC3000Executor contract
     * @param queue IERC3000 contract
     * @param name The name of this DAO
     * @param token Governance token of the DAO
     * @param initialMetadata Additional data to store for this DAO
     */
    function register(IERC3000Executor executor, IERC3000 queue, IERC20 token, address minter, string calldata name, bytes calldata initialMetadata) virtual external;
    event Registered(IERC3000Executor indexed executor, IERC3000 queue, IERC20 indexed token, address minter, address indexed registrant, string name);

    /**
     * @notice Sets or updates the metadata of a DAO
     * @param metadata Additional data to store for this DAO
     */
    function setMetadata(bytes memory metadata) virtual public;
    event SetMetadata(IERC3000Executor indexed executor, bytes metadata);
}

File 25 of 35 : GovernToken.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity ^0.6.8;

import '@aragon/govern-contract-utils/contracts/initializable/Initializable.sol';
import '@aragon/govern-contract-utils/contracts/safe-math/SafeMath.sol';

import './interfaces/IERC20.sol';

// Copied and slightly modified from https://github.com/aragon/aragon-network-token/blob/v2-v1.0.0/packages/v2/contracts/token.sol
// Lightweight token modelled after UNI-LP: https://github.com/Uniswap/uniswap-v2-core/blob/v1.0.1/contracts/UniswapV2ERC20.sol
// Adds:
//   - An exposed `mint()` with minting role
//   - An exposed `burn()`
//   - ERC-3009 (`transferWithAuthorization()`)
contract GovernToken is IERC20, Initializable {
    using SafeMath for uint256;

    // bytes32 private constant EIP712DOMAIN_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
    bytes32 private constant EIP712DOMAIN_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;
    // bytes32 private constant VERSION_HASH = keccak256("1")
    bytes32 private constant VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;
    // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
    // bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =
    //     keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)");
    bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;

    string public name;
    string public symbol;
    uint8 public decimals;

    address public minter;
    uint256 override public totalSupply;
    mapping (address => uint256) override public balanceOf;
    mapping (address => mapping (address => uint256)) override public allowance;

    // ERC-2612, ERC-3009 state
    mapping (address => uint256) public nonces;
    mapping (address => mapping (bytes32 => bool)) public authorizationState;

    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);
    event ChangeMinter(address indexed minter);

    modifier onlyMinter {
        require(msg.sender == minter, "token: not minter");
        _;
    }

    constructor(address _initialMinter, string memory _name, string memory _symbol, uint8 _decimals) public {
        initialize(_initialMinter, _name, _symbol, _decimals);
    }

    function initialize(address _initialMinter, string memory _name, string memory _symbol, uint8 _decimals) public onlyInit("token") {
        _changeMinter(_initialMinter);
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
    }

    function _validateSignedData(address signer, bytes32 encodeData, uint8 v, bytes32 r, bytes32 s) internal view {
        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                getDomainSeparator(),
                encodeData
            )
        );
        address recoveredAddress = ecrecover(digest, v, r, s);
        // Explicitly disallow authorizations for address(0) as ecrecover returns address(0) on malformed messages
        require(recoveredAddress != address(0) && recoveredAddress == signer, "token: bad sig");
    }

    function _changeMinter(address newMinter) internal {
        minter = newMinter;
        emit ChangeMinter(newMinter);
    }

    function _mint(address to, uint256 value) internal {
        totalSupply = totalSupply.add(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(address(0), to, value);
    }

    function _burn(address from, uint value) internal {
        // Balance is implicitly checked with SafeMath's underflow protection
        balanceOf[from] = balanceOf[from].sub(value);
        totalSupply = totalSupply.sub(value);
        emit Transfer(from, address(0), value);
    }

    function _approve(address owner, address spender, uint256 value) private {
        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    function _transfer(address from, address to, uint256 value) private {
        require(to != address(this) && to != address(0), "token: bad to");

        // Balance is implicitly checked with SafeMath's underflow protection
        balanceOf[from] = balanceOf[from].sub(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(from, to, value);
    }

    function getChainId() public pure returns (uint256 chainId) {
        assembly { chainId := chainid() }
    }

    function getDomainSeparator() public view returns (bytes32) {
        return keccak256(
            abi.encode(
                EIP712DOMAIN_HASH,
                keccak256(abi.encodePacked(name)),
                VERSION_HASH,
                getChainId(),
                address(this)
            )
        );
    }

    function mint(address to, uint256 value) external onlyMinter returns (bool) {
        _mint(to, value);
        return true;
    }

    function changeMinter(address newMinter) external onlyMinter {
        _changeMinter(newMinter);
    }

    function burn(uint256 value) external returns (bool) {
        _burn(msg.sender, value);
        return true;
    }

    function approve(address spender, uint256 value) override external returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    function transfer(address to, uint256 value) override external returns (bool) {
        _transfer(msg.sender, to, value);
        return true;
    }

    function transferFrom(address from, address to, uint256 value) override external returns (bool) {
        uint256 fromAllowance = allowance[from][msg.sender];
        if (fromAllowance != uint256(-1)) {
            // Allowance is implicitly checked with SafeMath's underflow protection
            allowance[from][msg.sender] = fromAllowance.sub(value);
        }
        _transfer(from, to, value);
        return true;
    }

    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external {
        require(deadline >= block.timestamp, "token: auth expired");

        bytes32 encodeData = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline));
        _validateSignedData(owner, encodeData, v, r, s);

        _approve(owner, spender, value);
    }

    function transferWithAuthorization(
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external
    {
        require(block.timestamp > validAfter, "token: auth wait");
        require(block.timestamp < validBefore, "token: auth expired");
        require(!authorizationState[from][nonce],  "token: auth used");

        bytes32 encodeData = keccak256(abi.encode(TRANSFER_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce));
        _validateSignedData(from, encodeData, v, r, s);

        authorizationState[from][nonce] = true;
        emit AuthorizationUsed(from, nonce);

        _transfer(from, to, value);
    }
}

File 26 of 35 : MerkleDistributor.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

// Copied and modified from: https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol

pragma solidity ^0.6.8;

import "@openzeppelin/contracts/cryptography/MerkleProof.sol";

import "@aragon/govern-contract-utils/contracts/erc20/SafeERC20.sol";
import "@aragon/govern-contract-utils/contracts/initializable/Initializable.sol";

contract MerkleDistributor is Initializable {
    
    using SafeERC20 for ERC20;

    ERC20 public token;
    bytes32 public merkleRoot;

    // This is a packed array of booleans.
    mapping (uint256 => uint256) private claimedBitMap;

    event Claimed(uint256 indexed index, address indexed to, uint256 amount);

    constructor(ERC20 _token, bytes32 _merkleRoot) public {
        initialize(_token, _merkleRoot);
    }

    function initialize(ERC20 _token, bytes32 _merkleRoot) public onlyInit("distributor") {
        token = _token;
        merkleRoot = _merkleRoot;
    }

    function claim(uint256 _index, address _to, uint256 _amount, bytes32[] calldata _merkleProof) external {
        require(!isClaimed(_index), "dist: already claimed");
        require(_verifyBalanceOnTree(_index, _to, _amount, _merkleProof), "dist: proof failed");

        _setClaimed(_index);
        token.safeTransfer(_to, _amount);

        emit Claimed(_index, _to, _amount);
    }

    function unclaimedBalance(uint256 _index, address _to, uint256 _amount, bytes32[] memory _proof) public view returns (uint256) {
        if (isClaimed(_index)) return 0;
        return _verifyBalanceOnTree(_index, _to, _amount, _proof) ? _amount : 0;
    }

    function _verifyBalanceOnTree(uint256 _index, address _to, uint256 _amount, bytes32[] memory _proof) internal view returns (bool) {
        bytes32 node = keccak256(abi.encodePacked(_index, _to, _amount));
        return MerkleProof.verify(_proof, merkleRoot, node);
    }

    function isClaimed(uint256 _index) public view returns (bool) {
        uint256 claimedWord_index = _index / 256;
        uint256 claimedBit_index = _index % 256;
        uint256 claimedWord = claimedBitMap[claimedWord_index];
        uint256 mask = (1 << claimedBit_index);
        return claimedWord & mask == mask;
    }

    function _setClaimed(uint256 _index) private {
        uint256 claimedWord_index = _index / 256;
        uint256 claimedBit_index = _index % 256;
        claimedBitMap[claimedWord_index] = claimedBitMap[claimedWord_index] | (1 << claimedBit_index);
    }
}

File 27 of 35 : SafeMath.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity ^0.6.8;

// A library for performing overflow-safe math, courtesy of DappHub: https://github.com/dapphub/ds-math/blob/d0ef6d6a5f/src/math.sol
// Modified to include only the essentials
library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "math: overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "math: underflow");
    }
}

File 28 of 35 : MerkleProof.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev These functions deal with verification of Merkle trees (hash trees),
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        bytes32 computedHash = leaf;

        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];

            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        // Check if the computed hash (root) is equal to the provided root
        return computedHash == root;
    }
}

File 29 of 35 : GovernQueue.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;
pragma experimental ABIEncoderV2; // required for passing structs in calldata (fairly secure at this point)

import "erc3k/contracts/IERC3000.sol";

import "@aragon/govern-contract-utils/contracts/acl/ACL.sol";
import "@aragon/govern-contract-utils/contracts/adaptive-erc165/AdaptiveERC165.sol";
import "@aragon/govern-contract-utils/contracts/deposits/DepositLib.sol";
import "@aragon/govern-contract-utils/contracts/erc20/SafeERC20.sol";
import '@aragon/govern-contract-utils/contracts/safe-math/SafeMath.sol';

import "../protocol/IArbitrable.sol";
import "../protocol/IArbitrator.sol";

library GovernQueueStateLib {
    enum State {
        None,
        Scheduled,
        Challenged,
        Approved,
        Rejected,
        Cancelled,
        Executed
    }

    struct Item {
        State state;
    }

    function checkState(Item storage _item, State _requiredState) internal view {
        require(_item.state == _requiredState, "queue: bad state");
    }

    function setState(Item storage _item, State _state) internal {
        _item.state = _state;
    }

    function checkAndSetState(Item storage _item, State _fromState, State _toState) internal {
        checkState(_item, _fromState);
        setState(_item, _toState);
    }
}

contract GovernQueue is IERC3000, IArbitrable, AdaptiveERC165, ACL {
    // Syntax sugar to enable method-calling syntax on types
    using ERC3000Data for *;
    using DepositLib for ERC3000Data.Collateral;
    using GovernQueueStateLib for GovernQueueStateLib.Item;
    using SafeERC20 for ERC20;
    using SafeMath for uint256;

    // Map '4' as the 'allow' ruling; this implicitly maps '3' as the 'reject' ruling
    uint256 internal constant ALLOW_RULING = 4;

    // Permanent state
    bytes32 public configHash; // keccak256 hash of the current ERC3000Data.Config
    uint256 public nonce; // number of scheduled payloads so far
    mapping (bytes32 => GovernQueueStateLib.Item) public queue; // container hash -> execution state

    // Temporary state
    mapping (bytes32 => address) public challengerCache; // container hash -> challenger addr (used after challenging and before dispute resolution)
    mapping (bytes32 => mapping (IArbitrator => uint256)) public disputeItemCache; // container hash -> arbitrator addr -> dispute id (used between dispute creation and ruling)

    /**
     * @param _aclRoot account that will be given root permissions on ACL (commonly given to factory)
     * @param _initialConfig initial configuration parameters
     */
    constructor(address _aclRoot, ERC3000Data.Config memory _initialConfig)
        public
        ACL(_aclRoot) // note that this contract directly derives from ACL (ACL is local to contract and not global to system in Govern)
    {
        initialize(_aclRoot, _initialConfig);
    }

    function initialize(address _aclRoot, ERC3000Data.Config memory _initialConfig) public initACL(_aclRoot) onlyInit("queue") {
        _setConfig(_initialConfig);
        _registerStandard(type(IERC3000).interfaceId);
    }

     /**
     * @notice Schedules an action for execution, allowing for challenges and vetos on a defined time window. Pulls collateral from submitter into contract.
     * @param _container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     */
    function schedule(ERC3000Data.Container memory _container) // TO FIX: Container is in memory and function has to be public to avoid an unestrutable solidity crash
        public
        override
        auth(this.schedule.selector) // note that all functions in this contract are ACL protected (commonly some of them will be open for any addr to perform)
        returns (bytes32 containerHash)
    {
        // prevent griefing by front-running (the same container is sent by two different people and one must be challenged)
        // and ensure container hashes are unique
        require(_container.payload.nonce == ++nonce, "queue: bad nonce");
        // hash using ERC3000Data.hash(ERC3000Data.Config)
        bytes32 _configHash = _container.config.hash();
        // ensure that the hash of the config passed in the container matches the current config (implicit agreement approval by scheduler)
        require(_configHash == configHash, "queue: bad config");
        // ensure that the time delta to the execution timestamp provided in the payload is at least after the config's execution delay
        require(_container.payload.executionTime >= _container.config.executionDelay.add(block.timestamp), "queue: bad delay");
        // ensure that the submitter of the payload is also the sender of this call
        require(_container.payload.submitter == msg.sender, "queue: bad submitter");
        // Restrict the size of calldata to _container.config.maxCalldataSize to make sure challenge function stays callable
        uint calldataSize;
        assembly {
            calldataSize := calldatasize()
        }
        require(calldataSize <= _container.config.maxCalldataSize, "calldatasize: limit exceeded");
        // store and set container's hash
        containerHash = ERC3000Data.containerHash(_container.payload.hash(), _configHash);
        queue[containerHash].checkAndSetState(
            GovernQueueStateLib.State.None, // ensure that the state for this container is None
            GovernQueueStateLib.State.Scheduled // and if so perform a state transition to Scheduled
        );
        // we don't need to save any more state about the container in storage
        // we just authenticate the hash and assign it a state, since all future
        // actions regarding the container will need to provide it as a witness
        // all witnesses are logged from this contract at least once, so the
        // trust assumption should be the same as storing all on-chain (move complexity to clients)

        ERC3000Data.Collateral memory collateral = _container.config.scheduleDeposit;
        collateral.collectFrom(_container.payload.submitter); // pull collateral from submitter (requires previous approval)

        // the configured resolver may specify additional out-of-band payments for scheduling actions
        // schedule() leaves these requirements up to the callers of `schedule()` or other users to fulfill

        // emit an event to ensure data availability of all state that cannot be otherwise fetched (see how config isn't emitted since an observer should already have it)
        emit Scheduled(containerHash, _container.payload);
    }

    /**
     * @notice Executes an action after its execution delay has passed and its state hasn't been altered by a challenge or veto
     * @param _container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     */
    function execute(ERC3000Data.Container memory _container)
        public
        override
        auth(this.execute.selector) // in most instances this will be open for any addr, but leaving configurable for flexibility
        returns (bytes32 failureMap, bytes[] memory)
    {
        // ensure enough time has passed
        require(block.timestamp >= _container.payload.executionTime, "queue: wait more");

        bytes32 containerHash = _container.hash();
        queue[containerHash].checkAndSetState(
            GovernQueueStateLib.State.Scheduled, // note that we will revert here if the container wasn't previously scheduled
            GovernQueueStateLib.State.Executed
        );

        _container.config.scheduleDeposit.releaseTo(_container.payload.submitter); // release collateral to original submitter

        return _execute(_container.payload, containerHash);
    }

    /**
     * @notice Challenge a container in case its scheduling is illegal as per Config.rules. Pulls collateral and dispute fees from sender into contract
     * @param _container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     * @param _reason Hint for case reviewers as to why the scheduled container is illegal
     */
    function challenge(ERC3000Data.Container memory _container, bytes memory _reason) auth(this.challenge.selector) override public returns (uint256 disputeId) {
        bytes32 containerHash = _container.hash();
        challengerCache[containerHash] = msg.sender; // cache challenger address while it is needed
        queue[containerHash].checkAndSetState(
            GovernQueueStateLib.State.Scheduled,
            GovernQueueStateLib.State.Challenged
        );

        ERC3000Data.Collateral memory collateral = _container.config.challengeDeposit;
        collateral.collectFrom(msg.sender); // pull challenge collateral from sender

        // create dispute on arbitrator
        IArbitrator arbitrator = IArbitrator(_container.config.resolver);
        (address recipient, ERC20 feeToken, uint256 feeAmount) = arbitrator.getDisputeFees();
        require(feeToken.safeTransferFrom(msg.sender, address(this), feeAmount), "queue: bad fee pull");
        require(feeToken.safeApprove(recipient, feeAmount), "queue: bad approve");
        disputeId = arbitrator.createDispute(2, abi.encode(_container)); // create dispute sending full container ABI encoded (could prob just send payload to save gas)
        require(feeToken.safeApprove(recipient, 0), "queue: bad reset"); // reset just in case non-compliant tokens (that fail on non-zero to non-zero approvals) are used

        // submit both arguments as evidence and close evidence period. no more evidence can be submitted and a settlement can't happen (could happen off-protocol)
        arbitrator.submitEvidence(disputeId, _container.payload.submitter, _container.payload.proof);
        arbitrator.submitEvidence(disputeId, msg.sender, _reason);
        arbitrator.closeEvidencePeriod(disputeId);

        disputeItemCache[containerHash][arbitrator] = disputeId + 1; // cache a relation between disputeId and containerHash while needed

        emit Challenged(containerHash, msg.sender, _reason, disputeId, collateral);
    }

    /**
     * @notice Apply arbitrator's ruling over a challenge once it has come to a final ruling
     * @param _container A ERC3000Data.Container struct holding both the payload being scheduled for execution and
     * the current configuration of the system
     * @param _disputeId disputeId in the arbitrator in which the dispute over the container was created
     */
    function resolve(ERC3000Data.Container memory _container, uint256 _disputeId) override public returns (bytes32 failureMap, bytes[] memory) {
        bytes32 containerHash = _container.hash();
        IArbitrator arbitrator = IArbitrator(_container.config.resolver);

        require(disputeItemCache[containerHash][arbitrator] == _disputeId + 1, "queue: bad dispute id");
        delete disputeItemCache[containerHash][arbitrator]; // release state to refund gas; no longer needed in state

        queue[containerHash].checkState(GovernQueueStateLib.State.Challenged);
        (address subject, uint256 ruling) = arbitrator.rule(_disputeId);
        require(subject == address(this), "queue: not subject");
        bool arbitratorApproved = ruling == ALLOW_RULING;

        queue[containerHash].setState(
            arbitratorApproved
              ? GovernQueueStateLib.State.Approved
              : GovernQueueStateLib.State.Rejected
        );

        emit Resolved(containerHash, msg.sender, arbitratorApproved);
        emit Ruled(arbitrator, _disputeId, ruling);

        if (arbitratorApproved) {
            return _executeApproved(_container);
        } else {
            return _settleRejection(_container);
        }
    }

    function veto(ERC3000Data.Container memory _container, bytes memory _reason) auth(this.veto.selector) override public {
        bytes32 containerHash = _container.hash();
        GovernQueueStateLib.Item storage item = queue[containerHash];

        if (item.state == GovernQueueStateLib.State.Challenged) {
            item.checkAndSetState(
                GovernQueueStateLib.State.Challenged,
                GovernQueueStateLib.State.Cancelled
            );

            address challenger = challengerCache[containerHash];
            // release state to refund gas; no longer needed in state
            delete challengerCache[containerHash];
            delete disputeItemCache[containerHash][IArbitrator(_container.config.resolver)];

            // release collateral to challenger and scheduler
            _container.config.scheduleDeposit.releaseTo(_container.payload.submitter);
            _container.config.challengeDeposit.releaseTo(challenger);
        } else {
            // If the given container doesn't have the state Challenged
            // has it to be the Scheduled state and otherwise should it throw as expected
            item.checkAndSetState(
                GovernQueueStateLib.State.Scheduled,
                GovernQueueStateLib.State.Cancelled
            );

            _container.config.scheduleDeposit.releaseTo(_container.payload.submitter);
        }

        emit Vetoed(containerHash, msg.sender, _reason);
    }

    /**
     * @notice Apply a new configuration for all *new* containers to be scheduled
     * @param _config A ERC3000Data.Config struct holding all the new params that will control the queue
     */
    function configure(ERC3000Data.Config memory _config)
        public
        override
        auth(this.configure.selector)
        returns (bytes32)
    {
        return _setConfig(_config);
    }

    // Internal

    function _executeApproved(ERC3000Data.Container memory _container) internal returns (bytes32 failureMap, bytes[] memory) {
        bytes32 containerHash = _container.hash();
        queue[containerHash].checkAndSetState(
            GovernQueueStateLib.State.Approved,
            GovernQueueStateLib.State.Executed
        );

        delete challengerCache[containerHash]; // release state to refund gas; no longer needed in state

        // release all collateral to submitter
        _container.config.scheduleDeposit.releaseTo(_container.payload.submitter);
        _container.config.challengeDeposit.releaseTo(_container.payload.submitter);

        return _execute(_container.payload, containerHash);
    }

    function _settleRejection(ERC3000Data.Container memory _container) internal returns (bytes32, bytes[] memory) {
        bytes32 containerHash = _container.hash();
        queue[containerHash].checkAndSetState(
            GovernQueueStateLib.State.Rejected,
            GovernQueueStateLib.State.Cancelled
        );

        address challenger = challengerCache[containerHash];
        delete challengerCache[containerHash]; // release state to refund gas; no longer needed in state

        // release all collateral to challenger
        _container.config.scheduleDeposit.releaseTo(challenger);
        _container.config.challengeDeposit.releaseTo(challenger);

        // return zero values as nothing is executed on rejection
    }

    function _execute(ERC3000Data.Payload memory _payload, bytes32 _containerHash) internal returns (bytes32, bytes[] memory) {
        emit Executed(_containerHash, msg.sender);
        return _payload.executor.exec(_payload.actions, _payload.allowFailuresMap, _containerHash);
    }

    function _setConfig(ERC3000Data.Config memory _config)
        internal
        returns (bytes32)
    {
        // validate collaterals by calling balanceOf on their interface
        if(_config.challengeDeposit.amount != 0 && _config.challengeDeposit.token != address(0)) {
            (bool ok, bytes memory value) = _config.challengeDeposit.token.call(
                abi.encodeWithSelector(ERC20.balanceOf.selector, address(this))
            );
            require(ok && value.length > 0, "queue: bad config");
        }

        if(_config.scheduleDeposit.amount != 0 && _config.scheduleDeposit.token != address(0)) {
            (bool ok, bytes memory value) = _config.scheduleDeposit.token.call(
                abi.encodeWithSelector(ERC20.balanceOf.selector, address(this))
            );
            require(ok && value.length > 0, "queue: bad config");
        }
        
        configHash = _config.hash();

        emit Configured(configHash, msg.sender, _config);

        return configHash;
    }
}

File 30 of 35 : DepositLib.sol
/*
 * SPDX-License-Identifier:    MIT
 */

pragma solidity ^0.6.8;

import "erc3k/contracts/ERC3000Data.sol";

import "../erc20/ERC20.sol";
import "../erc20/SafeERC20.sol";

library DepositLib {
    using SafeERC20 for ERC20;

    event Locked(address indexed token, address indexed from, uint256 amount);
    event Unlocked(address indexed token, address indexed to, uint256 amount);

    function collectFrom(ERC3000Data.Collateral memory _collateral, address _from) internal {
        if (_collateral.amount > 0) {
            ERC20 token = ERC20(_collateral.token);
            require(token.safeTransferFrom(_from, address(this), _collateral.amount), "deposit: bad token lock");

            emit Locked(_collateral.token, _from, _collateral.amount);
        }
    }

    function releaseTo(ERC3000Data.Collateral memory _collateral, address _to) internal {
        if (_collateral.amount > 0) {
            ERC20 token = ERC20(_collateral.token);
            require(token.safeTransfer(_to, _collateral.amount), "deposit: bad token release");

            emit Unlocked(_collateral.token, _to, _collateral.amount);
        }
    }
}

File 31 of 35 : IArbitrable.sol
/*
 * SPDX-License-Identifier:    MIT
 */

// From https://github.com/aragon/protocol/blob/f1b3361a160da92b9bb449c0a05dee0c30e41594/packages/evm/contracts/arbitration/IArbitrable.sol

pragma solidity ^0.6.8;

import "./IArbitrator.sol";

/**
* @dev The Arbitrable instances actually don't require to follow any specific interface.
*      Note that this is actually optional, although it does allow the Protocol to at least have a way to identify a specific set of instances.
*/
abstract contract IArbitrable {
    /**
    * @dev Emitted when an IArbitrable instance's dispute is ruled by an IArbitrator
    * @param arbitrator IArbitrator instance ruling the dispute
    * @param disputeId Identification number of the dispute being ruled by the arbitrator
    * @param ruling Ruling given by the arbitrator
    */
    event Ruled(IArbitrator indexed arbitrator, uint256 indexed disputeId, uint256 ruling);
}

File 32 of 35 : IArbitrator.sol
/*
 * SPDX-License-Identifier:    MIT
 */

// From https://github.com/aragon/protocol/blob/f1b3361a160da92b9bb449c0a05dee0c30e41594/packages/evm/contracts/arbitration/IArbitrator.sol

pragma solidity ^0.6.8;

import "@aragon/govern-contract-utils/contracts/erc20/ERC20.sol";

interface IArbitrator {
    /**
    * @dev Create a dispute over the Arbitrable sender with a number of possible rulings
    * @param _possibleRulings Number of possible rulings allowed for the dispute
    * @param _metadata Optional metadata that can be used to provide additional information on the dispute to be created
    * @return Dispute identification number
    */
    function createDispute(uint256 _possibleRulings, bytes calldata _metadata) external returns (uint256);

    /**
    * @dev Submit evidence for a dispute
    * @param _disputeId Id of the dispute in the Protocol
    * @param _submitter Address of the account submitting the evidence
    * @param _evidence Data submitted for the evidence related to the dispute
    */
    function submitEvidence(uint256 _disputeId, address _submitter, bytes calldata _evidence) external;

    /**
    * @dev Close the evidence period of a dispute
    * @param _disputeId Identification number of the dispute to close its evidence submitting period
    */
    function closeEvidencePeriod(uint256 _disputeId) external;

    /**
    * @notice Rule dispute #`_disputeId` if ready
    * @param _disputeId Identification number of the dispute to be ruled
    * @return subject Subject associated to the dispute
    * @return ruling Ruling number computed for the given dispute
    */
    function rule(uint256 _disputeId) external returns (address subject, uint256 ruling);

    /**
    * @dev Tell the dispute fees information to create a dispute
    * @return recipient Address where the corresponding dispute fees must be transferred to
    * @return feeToken ERC20 token used for the fees
    * @return feeAmount Total amount of fees that must be allowed to the recipient
    */
    function getDisputeFees() external view returns (address recipient, ERC20 feeToken, uint256 feeAmount);

    /**
    * @dev Tell the payments recipient address
    * @return Address of the payments recipient module
    */
    function getPaymentsRecipient() external view returns (address);
}

File 33 of 35 : GovernTokenFactoryMock.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;
pragma experimental ABIEncoderV2;

import "@aragon/govern-token/contracts/GovernMinter.sol";
import "@aragon/govern-token/contracts/GovernToken.sol";

import "@aragon/govern-token/contracts/libraries/TokenLib.sol";

contract GovernTokenFactoryMock {
   
    event NewTokenCalledWith(address initialMinter, string _tokenName, string _tokenSymbol, uint8 tokenDecimals, address mintAddr, uint256 mintAmount, bool useProxies);
  
    function newToken(
        address _initialMinter,
        TokenLib.TokenConfig calldata _token,
        bool _useProxies
    ) external returns (
        GovernToken token,
        GovernMinter minter
    ) {
        emit NewTokenCalledWith(
            _initialMinter, 
            _token.tokenName, 
            _token.tokenSymbol, 
            _token.tokenDecimals, 
            _token.mintAddress, 
            _token.mintAmount, 
            _useProxies
        );

        token = GovernToken(address(this));
        minter = GovernMinter(address(this));
    }

   
}

File 34 of 35 : GovernQueueFactoryMock.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;
pragma experimental ABIEncoderV2;

import "@aragon/govern-core/contracts/pipelines/GovernQueue.sol";
import "@aragon/govern-contract-utils/contracts/acl/ACL.sol";

contract GovernQueueFactoryMock  {
   
    event NewQueueCalledWith(address aclRoot, bytes32 salt);
    event BulkCalled(ACLData.BulkItem[] items);
    
    bytes4 public constant ROOT_ROLE = "0x";

    function schedule()  public pure  {}
    function execute()   public pure  {}
    function challenge() public pure  {}
    
    function configure(ERC3000Data.Config memory /*_config*/) public pure returns(bool)  {
        // TODO: emit events and catch it in the govern-base-factory-unit.test.ts
        return true;
    }

    // probably ACL inheritance can be used instead of implementing ACL functions again.

    function grant(bytes4 _role, address _who) public pure {
        // TODO: emit events and catch it in the govern-base-factory-unit.test.ts
    }

    function revoke(bytes4 _role, address _who) public pure {
        // TODO: emit events and catch it in the govern-base-factory-unit.test.ts
    }

    function bulk(ACLData.BulkItem[] memory items) public {
        emit BulkCalled(items);
    }

    function newQueue(address _aclRoot, ERC3000Data.Config memory /*_config*/, bytes32 _salt) public returns (GovernQueue queue) {
        /* 
            TODO:There seems to be a bug with waffle. After it's been fixed, emit the _config too and in the test,
            assert it. https://github.com/EthWorks/Waffle/issues/454
        */
        emit NewQueueCalledWith(_aclRoot, _salt);
        return GovernQueue(address(this));
    }
}

File 35 of 35 : GovernFactoryMock.sol
/*
 * SPDX-License-Identifier:    GPL-3.0
 */

pragma solidity 0.6.8;

import "erc3k/contracts/IERC3000.sol";
import "@aragon/govern-core/contracts/Govern.sol";
import "@aragon/govern-contract-utils/contracts/address-utils/AddressUtils.sol";

contract GovernFactoryMock {

    using AddressUtils for address;

    event NewGovernCalledWith(IERC3000 executor, bytes32 salt);

    function newGovern(IERC3000 _initialExecutor, bytes32 _salt) public returns (Govern govern) {
        emit NewGovernCalledWith(_initialExecutor, _salt);
        return Govern(address(this).toPayable());
    }

}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 20000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract GovernRegistry","name":"_registry","type":"address"},{"internalType":"contract GovernFactory","name":"_governFactory","type":"address"},{"internalType":"contract GovernQueueFactory","name":"_queueFactory","type":"address"},{"internalType":"contract GovernTokenFactory","name":"_tokenFactory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"governFactory","outputs":[{"internalType":"contract GovernFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"tokenAddress","type":"address"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"address","name":"mintAddress","type":"address"},{"internalType":"uint256","name":"mintAmount","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"merkleMintAmount","type":"uint256"},{"internalType":"bytes","name":"merkleTree","type":"bytes"},{"internalType":"bytes","name":"merkleContext","type":"bytes"}],"internalType":"struct TokenLib.TokenConfig","name":"_token","type":"tuple"},{"internalType":"address[]","name":"_scheduleAccessList","type":"address[]"},{"internalType":"bool","name":"_useProxies","type":"bool"},{"components":[{"internalType":"uint256","name":"executionDelay","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ERC3000Data.Collateral","name":"scheduleDeposit","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ERC3000Data.Collateral","name":"challengeDeposit","type":"tuple"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"bytes","name":"rules","type":"bytes"},{"internalType":"uint256","name":"maxCalldataSize","type":"uint256"}],"internalType":"struct ERC3000Data.Config","name":"_config","type":"tuple"},{"internalType":"string","name":"_name","type":"string"}],"name":"newGovern","outputs":[{"internalType":"contract Govern","name":"govern","type":"address"},{"internalType":"contract GovernQueue","name":"queue","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"queueFactory","outputs":[{"internalType":"contract GovernQueueFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract GovernRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenFactory","outputs":[{"internalType":"contract GovernTokenFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b50604051620019a6380380620019a6833981016040819052620000349162000089565b600080546001600160a01b03199081166001600160a01b039586161790915560018054821693851693909317909255600280548316918416919091179055600380549091169290911691909117905562000109565b600080600080608085870312156200009f578384fd5b8451620000ac81620000f0565b6020860151909450620000bf81620000f0565b6040860151909350620000d281620000f0565b6060860151909250620000e581620000f0565b939692955090935050565b6001600160a01b03811681146200010657600080fd5b50565b61188d80620001196000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80637b103999116100505780637b103999146100ab57806389409516146100b3578063e77772fe146100bb57610067565b80635f3485551461006c5780636ca4110e14610096575b600080fd5b61007f61007a3660046110c4565b6100c3565b60405161008d929190611499565b60405180910390f35b61009e610e31565b60405161008d9190611452565b61009e610e4d565b61009e610e69565b61009e610e85565b600080600a8888905011156040518060600160405280602381526020016118356023913990610128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161011f9190611692565b60405180910390fd5b50600086610137576000610161565b848460405160200161014a9291906112bc565b604051602081830303815290604052805190602001205b6001546040517fa691fc6700000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169063a691fc67906101bc9030908a9086906004016112cc565b602060405180830381600087803b1580156101d657600080fd5b505af11580156101ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020e919061106f565b6000546040517fad921bf400000000000000000000000000000000000000000000000000000000815291935073ffffffffffffffffffffffffffffffffffffffff169063ad921bf4906102679085908590600401611473565b602060405180830381600087803b15801561028157600080fd5b505af1158015610295573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b9919061106f565b925060006102ca60208c018c610ff4565b9050600073ffffffffffffffffffffffffffffffffffffffff82166107b157600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee3286fe868e8c6040518463ffffffff1660e01b815260040161034893929190611525565b6040805180830381600087803b15801561036157600080fd5b505af1158015610375573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610399919061108b565b909250905060006103b060408a0160208b01610ff4565b73ffffffffffffffffffffffffffffffffffffffff1614806103f7575060006103df60808a0160608b01610ff4565b73ffffffffffffffffffffffffffffffffffffffff16145b156107b1576040517fa157a10d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063a157a10d90610470907f7744efda0000000000000000000000000000000000000000000000000000000090309060040161140a565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050506104aa610ea1565b6040518060c001604052808a6000013581526020016040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168d60200160000160208101906104f89190610ff4565b73ffffffffffffffffffffffffffffffffffffffff16141561051a578661052a565b61052a60408e0160208f01610ff4565b73ffffffffffffffffffffffffffffffffffffffff1681526020018c6020016020013581525081526020016040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168d606001600001602081019061058e9190610ff4565b73ffffffffffffffffffffffffffffffffffffffff1614156105b057866105c0565b6105c060808e0160608f01610ff4565b73ffffffffffffffffffffffffffffffffffffffff16815260808d0135602091820152908252016105f760c08c0160a08d01610ff4565b73ffffffffffffffffffffffffffffffffffffffff16815260200161061f60c08c018c611728565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060e08b01356020909101526040517f7744efda00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff861690637744efda906106b69084906004016116a5565b602060405180830381600087803b1580156106d057600080fd5b505af11580156106e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107089190611017565b506040517f5884973400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86169063588497349061077d907f7744efda0000000000000000000000000000000000000000000000000000000090309060040161140a565b600060405180830381600087803b15801561079757600080fd5b505af11580156107ab573d6000803e3d6000fd5b50505050505b6003546040517f776ff4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063776ff4bd906108119088908890879087908e908e906004016114c0565b600060405180830381600087803b15801561082b57600080fd5b505af115801561083f573d6000803e3d6000fd5b5060009250508b1590506108565760068b01610859565b60075b905060608167ffffffffffffffff8111801561087457600080fd5b506040519080825280602002602001820160405280156108ae57816020015b61089b610ef9565b8152602001906001900390816108935790505b50604080516060810190915290915080600081527f3da956aa00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff6040909101528151829060009061091057fe5b6020908102919091010152604080516060810190915280600081527f1f13405b00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff60409091015281518290600190811061097b57fe5b6020908102919091010152604080516060810190915280600081527f7744efda00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff89166040909101528151829060029081106109e857fe5b6020908102919091010152604080516060810190915280600181526020018773ffffffffffffffffffffffffffffffffffffffff16637e8c7f086040518163ffffffff1660e01b815260040160206040518083038186803b158015610a4c57600080fd5b505afa158015610a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a84919061102f565b7fffffffff0000000000000000000000000000000000000000000000000000000016815230602090910152815182906003908110610abe57fe5b6020908102919091010152604080516060810190915280600081526020018773ffffffffffffffffffffffffffffffffffffffff16637e8c7f086040518163ffffffff1660e01b815260040160206040518083038186803b158015610b2257600080fd5b505afa158015610b36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5a919061102f565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020018873ffffffffffffffffffffffffffffffffffffffff1681525081600481518110610ba557fe5b6020908102919091010152604080516060810190915280600281526020018773ffffffffffffffffffffffffffffffffffffffff16637e8c7f086040518163ffffffff1660e01b815260040160206040518083038186803b158015610c0957600080fd5b505afa158015610c1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c41919061102f565b7fffffffff000000000000000000000000000000000000000000000000000000001681526000602090910152815182906005908110610c7c57fe5b60209081029190910101528b610cfc57604080516060810190915280600081527fc832048000000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff604090910152815182906006908110610cec57fe5b6020026020010181905250610d9c565b60005b8c811015610d9a5760408051606081018252600081527fc83204800000000000000000000000000000000000000000000000000000000060208201529081018f8f84818110610d4a57fe5b9050602002016020810190610d5f9190610ff4565b73ffffffffffffffffffffffffffffffffffffffff16815250828260060181518110610d8757fe5b6020908102919091010152600101610cff565b505b6040517f1c47671b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871690631c47671b90610dee90849060040161136f565b600060405180830381600087803b158015610e0857600080fd5b505af1158015610e1c573d6000803e3d6000fd5b50505050505050505097509795505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060c0016040528060008152602001610ebb610f1b565b8152602001610ec8610f1b565b8152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160608152602001600081525090565b6040805160608101909152806000815260006020820181905260409091015290565b604080518082019091526000808252602082015290565b60008083601f840112610f43578182fd5b50813567ffffffffffffffff811115610f5a578182fd5b6020830191508360208083028501011115610f7457600080fd5b9250929050565b80358015158114610f8b57600080fd5b92915050565b8035610f8b8161180f565b60008083601f840112610fad578182fd5b50813567ffffffffffffffff811115610fc4578182fd5b602083019150836020828501011115610f7457600080fd5b60006101008284031215610fee578081fd5b50919050565b600060208284031215611005578081fd5b81356110108161180f565b9392505050565b600060208284031215611028578081fd5b5051919050565b600060208284031215611040578081fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114611010578182fd5b600060208284031215611080578081fd5b81516110108161180f565b6000806040838503121561109d578081fd5b82516110a88161180f565b60208401519092506110b98161180f565b809150509250929050565b600080600080600080600060a0888a0312156110de578283fd5b873567ffffffffffffffff808211156110f5578485fd5b818a01610140818d031215611108578586fd5b985060208a013591508082111561111d578485fd5b6111298b838c01610f32565b909850965061113b8b60408c01610f7b565b955060608a0135915080821115611150578485fd5b61115c8b838c01610fdc565b945060808a0135915080821115611171578384fd5b5061117e8a828b01610f9c565b989b979a50959850939692959293505050565b73ffffffffffffffffffffffffffffffffffffffff169052565b15159052565b600082845282826020860137806020848601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011685010190509392505050565b60008151808452815b8181101561121e57602081850181015186830182015201611202565b8181111561122f5782602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b803561126d8161180f565b73ffffffffffffffffffffffffffffffffffffffff168252602090810135910152565b805173ffffffffffffffffffffffffffffffffffffffff168252602090810151910152565b60ff169052565b6000828483379101908152919050565b600073ffffffffffffffffffffffffffffffffffffffff808616835260606020840152843560608401526113066080840160208701611262565b61131660c0840160608701611262565b60a08501356113248161180f565b6101008282168186015261133b60c088018861179a565b935091508061012086015250611356610160850183836111b1565b60e0969096013561014085015250505060400152919050565b602080825282518282018190526000919060409081850190868401855b828110156113fd5781518051600381106113a257fe5b8552808701517fffffffff00000000000000000000000000000000000000000000000000000000168786015285015173ffffffffffffffffffffffffffffffffffffffff16858501526060909301929085019060010161138c565b5091979650505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000092909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525060c0608083015261150a60c0830184866111b1565b82810360a09093019290925281526020019695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8516825260606020830152602084016115616060840161155c8388610f91565b611191565b61156b81866117fd565b61157860808501826112b5565b5050611587604085018561179a565b6101408060a086015261159f6101a0860183856111b1565b6115ac606089018961179a565b945092507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0808783030160c08801526115e68286866111b1565b6115f360808b018b61178d565b955061160260e0890187611191565b610100955060a08a013586890152610120945060c08a01358589015260e08a013584890152611633868b018b61179a565b94509250818882030161016089015261164d8185856111b1565b95505061165c848a018a61179a565b935091508087860301610180880152506116778483836111b1565b94505050505061168a60408301846111ab565b949350505050565b60006020825261101060208301846111f9565b6000602082528251602083015260208301516116c46040840182611290565b5060408301516116d76080840182611290565b5073ffffffffffffffffffffffffffffffffffffffff60608401511660c083015260808301516101008060e08501526117146101208501836111f9565b60a095909501519301929092525090919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261175c578283fd5b8084018035925067ffffffffffffffff831115611777578384fd5b60200192505036819003821315610f7457600080fd5b600082356110108161180f565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126117ce578283fd5b830160208101925035905067ffffffffffffffff8111156117ee57600080fd5b803603831315610f7457600080fd5b6000823560ff81168114611010578182fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461183157600080fd5b5056fe62617365666163746f72793a207363686564756c65206c697374206578636565646564a26469706673582212205ba2a73ae95cc85967582fd12e139382da6d9a9584441a33bc67112868eddbfb64736f6c63430006080033000000000000000000000000f2b7d096cd34f228a6413e276132c21d98b198820000000000000000000000006090afbdcf13b3a53323509955279ce0de4003a20000000000000000000000005d2d6a91c8b5fb62f2a6725eb791f412a5d39c4d000000000000000000000000bc0d9988ae5a755031b35415e80b49174791684c

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000f2b7d096cd34f228a6413e276132c21d98b198820000000000000000000000006090afbdcf13b3a53323509955279ce0de4003a20000000000000000000000005d2d6a91c8b5fb62f2a6725eb791f412a5d39c4d000000000000000000000000bc0d9988ae5a755031b35415e80b49174791684c

-----Decoded View---------------
Arg [0] : _registry (address): 0xf2b7d096cd34f228a6413e276132c21d98b19882
Arg [1] : _governFactory (address): 0x6090afbdcf13b3a53323509955279ce0de4003a2
Arg [2] : _queueFactory (address): 0x5d2d6a91c8b5fb62f2a6725eb791f412a5d39c4d
Arg [3] : _tokenFactory (address): 0xbc0d9988ae5a755031b35415e80b49174791684c

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f2b7d096cd34f228a6413e276132c21d98b19882
Arg [1] : 0000000000000000000000006090afbdcf13b3a53323509955279ce0de4003a2
Arg [2] : 0000000000000000000000005d2d6a91c8b5fb62f2a6725eb791f412a5d39c4d
Arg [3] : 000000000000000000000000bc0d9988ae5a755031b35415e80b49174791684c


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.