Contract 0x46013753f3a02ab4239cA936632E6C6B39235CCE

Contract Overview

Balance:
0 Ether

Token:
Txn Hash
Method
Block
From
To
Value
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf0x5f348555109654322022-07-04 12:40:162 days 6 hrs ago0x1555d9dd364168ce671a92493aa01f05caf68cb4 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00170938 1.5
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c0x5f348555109653192022-07-04 12:11:552 days 7 hrs ago0xd92fe8b91ab9ec967ec4208eac1d4ea625cdff03 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00170967 1.5
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d0x5f348555109304522022-06-28 10:40:278 days 8 hrs ago0xeae8af157623269a6461a0fb305a4a161048e511 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00173209 1.50000001
0x054b7ebe0a84c3fe880a5060784856b9b4b67b4a6e781d0b4df5613f8ea024c70x5f348555109301582022-06-28 9:26:438 days 10 hrs ago0xeae8af157623269a6461a0fb305a4a161048e511 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00106987 1.50001515
0x8b0099fa74567c699727803015baeffd577599f99be3164bc2c8dc527edcb5e60x5f348555109263052022-06-27 17:21:379 days 2 hrs ago0xeb84afbedfd3beec64c8f3436dca7626c3912632 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00171056 1.50000002
0x26dd4e1dd8df82d2fefa5387d2a7223e63af9b7c48876cf7a1615977cfe8ae720x5f348555109082652022-06-24 13:37:5112 days 5 hrs ago0xe650580ab0b22c253e13257430b1102db8c27d1e IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00225629 1.97955798
0x02cbb9a81afe4eb1f9d5d8c736d838f1216af247a65c40195972ea3c35da6f280x5f348555109074322022-06-24 10:08:5812 days 9 hrs ago0x45933834957b7935fb7a24d88d100bf0a2bc7479 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00107008 1.50000001
0x7474970e591c3dbf9ef6d470658d579d3865fe7bfcc9dbffb1861e97511d0b320x5f348555109072892022-06-24 9:33:0712 days 9 hrs ago0x2db75d8404144cd5918815a44b8ac3f4db2a7faf IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00174102 1.50000002
0x80f67e485efda5decd956e129699a176ba2a30b6289948300337cefdfd7c3e680x5f348555109072422022-06-24 9:21:1912 days 10 hrs ago0x10656c07e857b7f3338ea26ecd9a0936a24c0ae3 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00170958 1.50000001
0xa0f9261544a9db8d8d597399a7c73edabb82febedfa3381f4781282411124f9e0x5f348555109044602022-06-23 21:35:0312 days 21 hrs ago0x45933834957b7935fb7a24d88d100bf0a2bc7479 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00106897 1.5
0x495a95477512d7c8ee2d89b60a819e5d1ea77d99f4ddf8711e575866a85341040x5f348555109036412022-06-23 18:09:2513 days 1 hr ago0xdab36fb6b852f0861ac16b9d4e128fab0bc36d0b IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00114964 1.61024009
0xf219d5e1df189f9c59196543d4f86c2b6c2937b70a0924a80b3ad8dac96a01d70x5f348555109032712022-06-23 16:36:4313 days 2 hrs ago0xdab36fb6b852f0861ac16b9d4e128fab0bc36d0b IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.0010691 1.50000001
0xc61e95caff73a21045add2a813c5b84420df544ef1a5d8cd4b18cd0ef18d00ab0x5f348555109013352022-06-23 8:27:1813 days 11 hrs ago0x901741c5283286bc46f992ea9ff6d334d9ec56a6 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.01168121 10.00930319
0xc36663fc5e1006aefc121d248056809ce9545f415aacafab912b77973218d5ac0x5f348555109013112022-06-23 8:21:1813 days 11 hrs ago0x0b638a1e4684f1b0ac1db8829b308aba91ba90fd IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00171652 1.50499893
0x1d1c9227a0a909db375f2bbb5a4cb1571ba2e69c0eac0f9bec841e332bc7acad0x5f348555108831752022-06-20 4:29:1816 days 14 hrs ago0x6d9d9f469f72afe71fe06383aad9015a33d320e4 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00119052 1.50000001
0x795dc21377a4c5888e9b5737da6f8363cfd32506de83a353fc3286a5c26bc6da0x5f348555108831612022-06-20 4:25:4816 days 15 hrs ago0x6d9d9f469f72afe71fe06383aad9015a33d320e4 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00115767 1.5
0x1f6fefdfdec3a054121e4d5ea36cd4e13d818f199615ca2aa77efa4d429a9cf70x5f348555108830862022-06-20 4:07:0116 days 15 hrs ago0x6d9d9f469f72afe71fe06383aad9015a33d320e4 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00183084 1.50000001
0xa3f32f5ad5a11e9c515641e54439d3da378bec5735a230a6d253480e1a5c7a2e0x5f348555108830812022-06-20 4:05:4616 days 15 hrs ago0x80eaef3d37b147eb34f9f0ea33a4ea9a32598b6d IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00114999 1.50000001
0x3427eb6612ab18c4d651c564b09c2bfb242467a6f9a3bf0dcb52dadcd4fe4aee0x5f348555108830462022-06-20 3:57:0016 days 15 hrs ago0x80eaef3d37b147eb34f9f0ea33a4ea9a32598b6d IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00877843 1.50000001
0x745e360dce95395e913cb5ed16b7a37328ea29b7f3f65e01992c4cad0c06aa550x5f348555108829532022-06-20 3:33:4316 days 15 hrs ago0x80eaef3d37b147eb34f9f0ea33a4ea9a32598b6d IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.0138832 1.50000001
0xf7f31274938658b5bdcd34eb48aaa489a8855c66d952926712bc240f5e36a0420x5f348555108829082022-06-20 3:22:2516 days 16 hrs ago0x6d9d9f469f72afe71fe06383aad9015a33d320e4 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00170938 1.50000001
0xc79efdff44bac7992fddb2501fa03b6e7dae646464b3b5d4305c4c5176af39700x5f348555108632742022-06-16 17:24:5720 days 2 hrs ago0xed89595d2ba472fdd56720afb8667251a60d29c0 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00214603 1.88180059
0x0a8517c335263fe770768e1b88356c118df1ec15a1c2e5010445f619215ceea90x5f348555108447492022-06-13 12:03:2323 days 7 hrs ago0x9494f3ee32d36a981bf07f7f66e42ff6538d4d40 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00171045 1.50058809
0x1a622b371cc843218a403ee592da7bf30cecacb3cb355228d0e508807c8161110x5f348555108447082022-06-13 11:53:0723 days 7 hrs ago0x9494f3ee32d36a981bf07f7f66e42ff6538d4d40 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00171019 1.50032681
0x034bef4fbcbd620cf4efff87ea3ef6a9ceee11f6a2b4c93c2d549dd0a60ba9250x5f348555108422832022-06-13 1:45:3623 days 17 hrs ago0x6d9d9f469f72afe71fe06383aad9015a33d320e4 IN  0x46013753f3a02ab4239ca936632e6c6b39235cce0 Ether0.00106917 1.5
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x54c80f3e006f16ce0d0515aaf4dfdbb05acff08b0 Ether
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x54c80f3e006f16ce0d0515aaf4dfdbb05acff08b0 Ether
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x54c80f3e006f16ce0d0515aaf4dfdbb05acff08b0 Ether
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x54c80f3e006f16ce0d0515aaf4dfdbb05acff08b0 Ether
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xf46253ef29faedabf63aa8ca6c0a41cbbdc939480 Ether
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xf6ee55bed4f4830a085798bc0d722b19c4daa4990 Ether
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x0d8c92c63b74a3d506e9aa96206a469ea57910b10 Ether
0x4234d447db947495bbc67b76eb4382e2197fed9567cb7672f325181bf6ba3abf109654322022-07-04 12:40:162 days 6 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xc1b65960281f25eb7a3140e1d0beb0e5bdc1d9af0 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x4c54c1b6849af08af06e402bf10254c4ee9d51600 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x4c54c1b6849af08af06e402bf10254c4ee9d51600 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x4c54c1b6849af08af06e402bf10254c4ee9d51600 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x4c54c1b6849af08af06e402bf10254c4ee9d51600 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xf46253ef29faedabf63aa8ca6c0a41cbbdc939480 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xf6ee55bed4f4830a085798bc0d722b19c4daa4990 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x0d8c92c63b74a3d506e9aa96206a469ea57910b10 Ether
0x5218e9ba28731c2ba5fdc57852fb1fc29c705a55e39494e3fed3a92119e3fe0c109653192022-07-04 12:11:552 days 7 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xc1b65960281f25eb7a3140e1d0beb0e5bdc1d9af0 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x17ff7d68314ffb6d5109f7200b18246f30fe78b90 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x17ff7d68314ffb6d5109f7200b18246f30fe78b90 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x17ff7d68314ffb6d5109f7200b18246f30fe78b90 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x17ff7d68314ffb6d5109f7200b18246f30fe78b90 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xf46253ef29faedabf63aa8ca6c0a41cbbdc939480 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x17ff7d68314ffb6d5109f7200b18246f30fe78b90 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x17ff7d68314ffb6d5109f7200b18246f30fe78b90 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0x17ff7d68314ffb6d5109f7200b18246f30fe78b90 Ether
0x1bfcef1a5b1adcd89abd5e3ae9b0a15628c64722fd889685458052bcf3cf763d109304522022-06-28 10:40:278 days 8 hrs ago 0x46013753f3a02ab4239ca936632e6c6b39235cce 0xf6ee55bed4f4830a085798bc0d722b19c4daa4990 Ether
[ Download CSV Export 
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x0f75Dd5E00f0A153fCee92A1C242Dbdf32D87196

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 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"}]

60806040523480156200001157600080fd5b50604051620019a6380380620019a6833981016040819052620000349162000089565b600080546001600160a01b03199081166001600160a01b039586161790915560018054821693851693909317909255600280548316918416919091179055600380549091169290911691909117905562000109565b600080600080608085870312156200009f578384fd5b8451620000ac81620000f0565b6020860151909450620000bf81620000f0565b6040860151909350620000d281620000f0565b6060860151909250620000e581620000f0565b939692955090935050565b6001600160a01b03811681146200010657600080fd5b50565b61188d80620001196000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80637b103999116100505780637b103999146100ab57806389409516146100b3578063e77772fe146100bb57610067565b80635f3485551461006c5780636ca4110e14610096575b600080fd5b61007f61007a3660046110c4565b6100c3565b60405161008d929190611499565b60405180910390f35b61009e610e31565b60405161008d9190611452565b61009e610e4d565b61009e610e69565b61009e610e85565b600080600a8888905011156040518060600160405280602381526020016118356023913990610128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161011f9190611692565b60405180910390fd5b50600086610137576000610161565b848460405160200161014a9291906112bc565b604051602081830303815290604052805190602001205b6001546040517fa691fc6700000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169063a691fc67906101bc9030908a9086906004016112cc565b602060405180830381600087803b1580156101d657600080fd5b505af11580156101ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020e919061106f565b6000546040517fad921bf400000000000000000000000000000000000000000000000000000000815291935073ffffffffffffffffffffffffffffffffffffffff169063ad921bf4906102679085908590600401611473565b602060405180830381600087803b15801561028157600080fd5b505af1158015610295573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102b9919061106f565b925060006102ca60208c018c610ff4565b9050600073ffffffffffffffffffffffffffffffffffffffff82166107b157600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee3286fe868e8c6040518463ffffffff1660e01b815260040161034893929190611525565b6040805180830381600087803b15801561036157600080fd5b505af1158015610375573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610399919061108b565b909250905060006103b060408a0160208b01610ff4565b73ffffffffffffffffffffffffffffffffffffffff1614806103f7575060006103df60808a0160608b01610ff4565b73ffffffffffffffffffffffffffffffffffffffff16145b156107b1576040517fa157a10d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063a157a10d90610470907f7744efda0000000000000000000000000000000000000000000000000000000090309060040161140a565b600060405180830381600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050506104aa610ea1565b6040518060c001604052808a6000013581526020016040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168d60200160000160208101906104f89190610ff4565b73ffffffffffffffffffffffffffffffffffffffff16141561051a578661052a565b61052a60408e0160208f01610ff4565b73ffffffffffffffffffffffffffffffffffffffff1681526020018c6020016020013581525081526020016040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168d606001600001602081019061058e9190610ff4565b73ffffffffffffffffffffffffffffffffffffffff1614156105b057866105c0565b6105c060808e0160608f01610ff4565b73ffffffffffffffffffffffffffffffffffffffff16815260808d0135602091820152908252016105f760c08c0160a08d01610ff4565b73ffffffffffffffffffffffffffffffffffffffff16815260200161061f60c08c018c611728565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060e08b01356020909101526040517f7744efda00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff861690637744efda906106b69084906004016116a5565b602060405180830381600087803b1580156106d057600080fd5b505af11580156106e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107089190611017565b506040517f5884973400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86169063588497349061077d907f7744efda0000000000000000000000000000000000000000000000000000000090309060040161140a565b600060405180830381600087803b15801561079757600080fd5b505af11580156107ab573d6000803e3d6000fd5b50505050505b6003546040517f776ff4bd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063776ff4bd906108119088908890879087908e908e906004016114c0565b600060405180830381600087803b15801561082b57600080fd5b505af115801561083f573d6000803e3d6000fd5b5060009250508b1590506108565760068b01610859565b60075b905060608167ffffffffffffffff8111801561087457600080fd5b506040519080825280602002602001820160405280156108ae57816020015b61089b610ef9565b8152602001906001900390816108935790505b50604080516060810190915290915080600081527f3da956aa00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff6040909101528151829060009061091057fe5b6020908102919091010152604080516060810190915280600081527f1f13405b00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff60409091015281518290600190811061097b57fe5b6020908102919091010152604080516060810190915280600081527f7744efda00000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff89166040909101528151829060029081106109e857fe5b6020908102919091010152604080516060810190915280600181526020018773ffffffffffffffffffffffffffffffffffffffff16637e8c7f086040518163ffffffff1660e01b815260040160206040518083038186803b158015610a4c57600080fd5b505afa158015610a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a84919061102f565b7fffffffff0000000000000000000000000000000000000000000000000000000016815230602090910152815182906003908110610abe57fe5b6020908102919091010152604080516060810190915280600081526020018773ffffffffffffffffffffffffffffffffffffffff16637e8c7f086040518163ffffffff1660e01b815260040160206040518083038186803b158015610b2257600080fd5b505afa158015610b36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5a919061102f565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020018873ffffffffffffffffffffffffffffffffffffffff1681525081600481518110610ba557fe5b6020908102919091010152604080516060810190915280600281526020018773ffffffffffffffffffffffffffffffffffffffff16637e8c7f086040518163ffffffff1660e01b815260040160206040518083038186803b158015610c0957600080fd5b505afa158015610c1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c41919061102f565b7fffffffff000000000000000000000000000000000000000000000000000000001681526000602090910152815182906005908110610c7c57fe5b60209081029190910101528b610cfc57604080516060810190915280600081527fc832048000000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff604090910152815182906006908110610cec57fe5b6020026020010181905250610d9c565b60005b8c811015610d9a5760408051606081018252600081527fc83204800000000000000000000000000000000000000000000000000000000060208201529081018f8f84818110610d4a57fe5b9050602002016020810190610d5f9190610ff4565b73ffffffffffffffffffffffffffffffffffffffff16815250828260060181518110610d8757fe5b6020908102919091010152600101610cff565b505b6040517f1c47671b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871690631c47671b90610dee90849060040161136f565b600060405180830381600087803b158015610e0857600080fd5b505af1158015610e1c573d6000803e3d6000fd5b50505050505050505097509795505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060c0016040528060008152602001610ebb610f1b565b8152602001610ec8610f1b565b8152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160608152602001600081525090565b6040805160608101909152806000815260006020820181905260409091015290565b604080518082019091526000808252602082015290565b60008083601f840112610f43578182fd5b50813567ffffffffffffffff811115610f5a578182fd5b6020830191508360208083028501011115610f7457600080fd5b9250929050565b80358015158114610f8b57600080fd5b92915050565b8035610f8b8161180f565b60008083601f840112610fad578182fd5b50813567ffffffffffffffff811115610fc4578182fd5b602083019150836020828501011115610f7457600080fd5b60006101008284031215610fee578081fd5b50919050565b600060208284031215611005578081fd5b81356110108161180f565b9392505050565b600060208284031215611028578081fd5b5051919050565b600060208284031215611040578081fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114611010578182fd5b600060208284031215611080578081fd5b81516110108161180f565b6000806040838503121561109d578081fd5b82516110a88161180f565b60208401519092506110b98161180f565b809150509250929050565b600080600080600080600060a0888a0312156110de578283fd5b873567ffffffffffffffff808211156110f5578485fd5b818a01610140818d031215611108578586fd5b985060208a013591508082111561111d578485fd5b6111298b838c01610f32565b909850965061113b8b60408c01610f7b565b955060608a0135915080821115611150578485fd5b61115c8b838c01610fdc565b945060808a0135915080821115611171578384fd5b5061117e8a828b01610f9c565b989b979a50959850939692959293505050565b73ffffffffffffffffffffffffffffffffffffffff169052565b15159052565b600082845282826020860137806020848601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011685010190509392505050565b60008151808452815b8181101561121e57602081850181015186830182015201611202565b8181111561122f5782602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b803561126d8161180f565b73ffffffffffffffffffffffffffffffffffffffff168252602090810135910152565b805173ffffffffffffffffffffffffffffffffffffffff168252602090810151910152565b60ff169052565b6000828483379101908152919050565b600073ffffffffffffffffffffffffffffffffffffffff808616835260606020840152843560608401526113066080840160208701611262565b61131660c0840160608701611262565b60a08501356113248161180f565b6101008282168186015261133b60c088018861179a565b935091508061012086015250611356610160850183836111b1565b60e0969096013561014085015250505060400152919050565b602080825282518282018190526000919060409081850190868401855b828110156113fd5781518051600381106113a257fe5b8552808701517fffffffff00000000000000000000000000000000000000000000000000000000168786015285015173ffffffffffffffffffffffffffffffffffffffff16858501526060909301929085019060010161138c565b5091979650505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000092909216825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525060c0608083015261150a60c0830184866111b1565b82810360a09093019290925281526020019695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8516825260606020830152602084016115616060840161155c8388610f91565b611191565b61156b81866117fd565b61157860808501826112b5565b5050611587604085018561179a565b6101408060a086015261159f6101a0860183856111b1565b6115ac606089018961179a565b945092507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0808783030160c08801526115e68286866111b1565b6115f360808b018b61178d565b955061160260e0890187611191565b610100955060a08a013586890152610120945060c08a01358589015260e08a013584890152611633868b018b61179a565b94509250818882030161016089015261164d8185856111b1565b95505061165c848a018a61179a565b935091508087860301610180880152506116778483836111b1565b94505050505061168a60408301846111ab565b949350505050565b60006020825261101060208301846111f9565b6000602082528251602083015260208301516116c46040840182611290565b5060408301516116d76080840182611290565b5073ffffffffffffffffffffffffffffffffffffffff60608401511660c083015260808301516101008060e08501526117146101208501836111f9565b60a095909501519301929092525090919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261175c578283fd5b8084018035925067ffffffffffffffff831115611777578384fd5b60200192505036819003821315610f7457600080fd5b600082356110108161180f565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126117ce578283fd5b830160208101925035905067ffffffffffffffff8111156117ee57600080fd5b803603831315610f7457600080fd5b6000823560ff81168114611010578182fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461183157600080fd5b5056fe62617365666163746f72793a207363686564756c65206c697374206578636565646564a26469706673582212205ba2a73ae95cc85967582fd12e139382da6d9a9584441a33bc67112868eddbfb64736f6c63430006080033000000000000000000000000cc3f32957d316a12afcfed04c0716af4814ecb2b0000000000000000000000003ddc3e8bbf3f6987e4008a7d6f486dae4d0f120f0000000000000000000000007e9f0fa00545ac62f224e23aae0ff0e7bc5b0dc3000000000000000000000000d4b22050b8ea9fdd28bbc59e6f2a6aea64dbd1a6

Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.