{
  "language": "Solidity",
  "sources": {
    "src.sol/ChannelFactory.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/utils/Create2.sol\";\n\nimport \"./interfaces/IChannelFactory.sol\";\nimport \"./interfaces/IVectorChannel.sol\";\nimport \"./lib/LibAsset.sol\";\nimport \"./lib/LibERC20.sol\";\n\n/// @title ChannelFactory\n/// @author Connext <support@connext.network>\n/// @notice Creates and sets up a new channel proxy contract\ncontract ChannelFactory is IChannelFactory {\n    // Creation code constants taken from EIP1167\n    bytes private constant proxyCreationCodePrefix =\n        hex\"3d602d80600a3d3981f3_363d3d373d3d3d363d73\";\n    bytes private constant proxyCreationCodeSuffix =\n        hex\"5af43d82803e903d91602b57fd5bf3\";\n\n    bytes32 private creationCodeHash;\n    address private immutable mastercopy;\n    uint256 private immutable chainId;\n\n    /// @dev Creates a new `ChannelFactory`\n    /// @param _mastercopy the address of the `ChannelMastercopy` (channel logic)\n    /// @param _chainId the chain identifier when generating the CREATE2 salt. If zero, the chain identifier used in the proxy salt will be the result of the opcode\n    constructor(address _mastercopy, uint256 _chainId) {\n        mastercopy = _mastercopy;\n        chainId = _chainId;\n        creationCodeHash = keccak256(_getProxyCreationCode(_mastercopy));\n    }\n\n    ////////////////////////////////////////\n    // Public Methods\n\n    /// @dev Allows us to get the mastercopy that this factory will deploy channels against\n    function getMastercopy() external view override returns (address) {\n        return mastercopy;\n    }\n\n    /// @dev Allows us to get the chainId that this factory will use in the create2 salt\n    function getChainId() public view override returns (uint256 _chainId) {\n        // Hold in memory to reduce sload calls\n        uint256 chain = chainId;\n        if (chain == 0) {\n            assembly {\n                _chainId := chainid()\n            }\n        } else {\n            _chainId = chain;\n        }\n    }\n\n    /// @dev Allows us to get the chainId that this factory has stored\n    function getStoredChainId() external view override returns (uint256) {\n        return chainId;\n    }\n\n    /// @dev Returns the proxy code used to both calculate the CREATE2 address and deploy the channel proxy pointed to the `ChannelMastercopy`\n    function getProxyCreationCode()\n        public\n        view\n        override\n        returns (bytes memory)\n    {\n        return _getProxyCreationCode(mastercopy);\n    }\n\n    /// @dev Allows us to get the address for a new channel contract created via `createChannel`\n    /// @param alice address of the igh fidelity channel participant\n    /// @param bob address of the other channel participant\n    function getChannelAddress(address alice, address bob)\n        external\n        view\n        override\n        returns (address)\n    {\n        return\n            Create2.computeAddress(\n                generateSalt(alice, bob),\n                creationCodeHash\n            );\n    }\n\n    /// @dev Allows us to create new channel contract and get it all set up in one transaction\n    /// @param alice address of the high fidelity channel participant\n    /// @param bob address of the other channel participant\n    function createChannel(address alice, address bob)\n        public\n        override\n        returns (address channel)\n    {\n        channel = deployChannelProxy(alice, bob);\n        IVectorChannel(channel).setup(alice, bob);\n        emit ChannelCreation(channel);\n    }\n\n    /// @dev Allows us to create a new channel contract and fund it in one transaction\n    /// @param bob address of the other channel participant\n    function createChannelAndDepositAlice(\n        address alice,\n        address bob,\n        address assetId,\n        uint256 amount\n    ) external payable override returns (address channel) {\n        channel = createChannel(alice, bob);\n        // Deposit funds (if a token) must be approved for the\n        // `ChannelFactory`, which then claims the funds and transfers\n        // to the channel address. While this is inefficient, this is\n        // the safest/clearest way to transfer funds\n        if (!LibAsset.isEther(assetId)) {\n            require(\n                LibERC20.transferFrom(\n                    assetId,\n                    msg.sender,\n                    address(this),\n                    amount\n                ),\n                \"ChannelFactory: ERC20_TRANSFER_FAILED\"\n            );\n            require(\n                LibERC20.approve(assetId, address(channel), amount),\n                \"ChannelFactory: ERC20_APPROVE_FAILED\"\n            );\n        }\n        IVectorChannel(channel).depositAlice{value: msg.value}(assetId, amount);\n    }\n\n    ////////////////////////////////////////\n    // Internal Methods\n\n    function _getProxyCreationCode(address _mastercopy) internal pure returns (bytes memory) {\n      return abi.encodePacked(\n                proxyCreationCodePrefix,\n                _mastercopy,\n                proxyCreationCodeSuffix\n            );\n    }\n\n    /// @dev Allows us to create new channel contact using CREATE2\n    /// @param alice address of the high fidelity participant in the channel\n    /// @param bob address of the other channel participant\n    function deployChannelProxy(address alice, address bob)\n        internal\n        returns (address)\n    {\n        bytes32 salt = generateSalt(alice, bob);\n        return Create2.deploy(0, salt, getProxyCreationCode());\n    }\n\n    /// @dev Generates the unique salt for calculating the CREATE2 address of the channel proxy\n    function generateSalt(address alice, address bob)\n        internal\n        view\n        returns (bytes32)\n    {\n        return keccak256(abi.encodePacked(alice, bob, getChainId()));\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Create2.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.\n * `CREATE2` can be used to compute in advance the address where a smart\n * contract will be deployed, which allows for interesting new mechanisms known\n * as 'counterfactual interactions'.\n *\n * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more\n * information.\n */\nlibrary Create2 {\n    /**\n     * @dev Deploys a contract using `CREATE2`. The address where the contract\n     * will be deployed can be known in advance via {computeAddress}.\n     *\n     * The bytecode for a contract can be obtained from Solidity with\n     * `type(contractName).creationCode`.\n     *\n     * Requirements:\n     *\n     * - `bytecode` must not be empty.\n     * - `salt` must have not been used for `bytecode` already.\n     * - the factory must have a balance of at least `amount`.\n     * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.\n     */\n    function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address) {\n        address addr;\n        require(address(this).balance >= amount, \"Create2: insufficient balance\");\n        require(bytecode.length != 0, \"Create2: bytecode length is zero\");\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)\n        }\n        require(addr != address(0), \"Create2: Failed on deploy\");\n        return addr;\n    }\n\n    /**\n     * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the\n     * `bytecodeHash` or `salt` will result in a new destination address.\n     */\n    function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {\n        return computeAddress(salt, bytecodeHash, address(this));\n    }\n\n    /**\n     * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at\n     * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.\n     */\n    function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address) {\n        bytes32 _data = keccak256(\n            abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash)\n        );\n        return address(uint256(_data));\n    }\n}\n"
    },
    "src.sol/interfaces/IChannelFactory.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\ninterface IChannelFactory {\n    event ChannelCreation(address channel);\n\n    function getMastercopy() external view returns (address);\n\n    function getChainId() external view returns (uint256);\n\n    function getStoredChainId() external view returns (uint256);\n\n    function getProxyCreationCode() external view returns (bytes memory);\n\n    function getChannelAddress(address alice, address bob)\n        external\n        view\n        returns (address);\n\n    function createChannel(address alice, address bob)\n        external\n        returns (address);\n\n    function createChannelAndDepositAlice(\n        address alice,\n        address bob,\n        address assetId,\n        uint256 amount\n    ) external payable returns (address);\n}\n"
    },
    "src.sol/interfaces/IVectorChannel.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./ICMCCore.sol\";\nimport \"./ICMCAsset.sol\";\nimport \"./ICMCDeposit.sol\";\nimport \"./ICMCWithdraw.sol\";\nimport \"./ICMCAdjudicator.sol\";\n\ninterface IVectorChannel is\n    ICMCCore,\n    ICMCAsset,\n    ICMCDeposit,\n    ICMCWithdraw,\n    ICMCAdjudicator\n{}\n"
    },
    "src.sol/lib/LibAsset.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./LibERC20.sol\";\nimport \"./LibUtils.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n\n/// @title LibAsset\n/// @author Connext <support@connext.network>\n/// @notice This library contains helpers for dealing with onchain transfers\n///         of in-channel assets. It is designed to safely handle all asset\n///         transfers out of channel in the event of an onchain dispute. Also\n///         safely handles ERC20 transfers that may be non-compliant\nlibrary LibAsset {\n    address constant ETHER_ASSETID = address(0);\n\n    function isEther(address assetId) internal pure returns (bool) {\n        return assetId == ETHER_ASSETID;\n    }\n\n    function getOwnBalance(address assetId) internal view returns (uint256) {\n        return\n            isEther(assetId)\n                ? address(this).balance\n                : IERC20(assetId).balanceOf(address(this));\n    }\n\n    function transferEther(address payable recipient, uint256 amount)\n        internal\n        returns (bool)\n    {\n        (bool success, bytes memory returnData) =\n            recipient.call{value: amount}(\"\");\n        LibUtils.revertIfCallFailed(success, returnData);\n        return true;\n    }\n\n    function transferERC20(\n        address assetId,\n        address recipient,\n        uint256 amount\n    ) internal returns (bool) {\n        return LibERC20.transfer(assetId, recipient, amount);\n    }\n\n    // This function is a wrapper for transfers of Ether or ERC20 tokens,\n    // both standard-compliant ones as well as tokens that exhibit the\n    // missing-return-value bug.\n    // Although it behaves very much like Solidity's `transfer` function\n    // or the ERC20 `transfer` and is, in fact, designed to replace direct\n    // usage of those, it is deliberately named `unregisteredTransfer`,\n    // because we need to register every transfer out of the channel.\n    // Therefore, it should normally not be used directly, with the single\n    // exception of the `transferAsset` function in `CMCAsset.sol`,\n    // which combines the \"naked\" unregistered transfer given below\n    // with a registration.\n    // USING THIS FUNCTION SOMEWHERE ELSE IS PROBABLY WRONG!\n    function unregisteredTransfer(\n        address assetId,\n        address payable recipient,\n        uint256 amount\n    ) internal returns (bool) {\n        return\n            isEther(assetId)\n                ? transferEther(recipient, amount)\n                : transferERC20(assetId, recipient, amount);\n    }\n}\n"
    },
    "src.sol/lib/LibERC20.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./LibUtils.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/// @title LibERC20\n/// @author Connext <support@connext.network>\n/// @notice This library provides several functions to safely handle\n///         noncompliant tokens (i.e. does not return a boolean from\n///         the transfer function)\n\nlibrary LibERC20 {\n    function wrapCall(address assetId, bytes memory callData)\n        internal\n        returns (bool)\n    {\n        require(Address.isContract(assetId), \"LibERC20: NO_CODE\");\n        (bool success, bytes memory returnData) = assetId.call(callData);\n        LibUtils.revertIfCallFailed(success, returnData);\n        return returnData.length == 0 || abi.decode(returnData, (bool));\n    }\n\n    function approve(\n        address assetId,\n        address spender,\n        uint256 amount\n    ) internal returns (bool) {\n        return\n            wrapCall(\n                assetId,\n                abi.encodeWithSignature(\n                    \"approve(address,uint256)\",\n                    spender,\n                    amount\n                )\n            );\n    }\n\n    function transferFrom(\n        address assetId,\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal returns (bool) {\n        return\n            wrapCall(\n                assetId,\n                abi.encodeWithSignature(\n                    \"transferFrom(address,address,uint256)\",\n                    sender,\n                    recipient,\n                    amount\n                )\n            );\n    }\n\n    function transfer(\n        address assetId,\n        address recipient,\n        uint256 amount\n    ) internal returns (bool) {\n        return\n            wrapCall(\n                assetId,\n                abi.encodeWithSignature(\n                    \"transfer(address,uint256)\",\n                    recipient,\n                    amount\n                )\n            );\n    }\n}\n"
    },
    "src.sol/interfaces/ICMCCore.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\ninterface ICMCCore {\n    function setup(address _alice, address _bob) external;\n\n    function getAlice() external view returns (address);\n\n    function getBob() external view returns (address);\n}\n"
    },
    "src.sol/interfaces/ICMCAsset.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\ninterface ICMCAsset {\n    function getTotalTransferred(address assetId)\n        external\n        view\n        returns (uint256);\n\n    function getExitableAmount(address assetId, address owner)\n        external\n        view\n        returns (uint256);\n\n    function exit(\n        address assetId,\n        address owner,\n        address payable recipient\n    ) external;\n}\n"
    },
    "src.sol/interfaces/ICMCDeposit.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\ninterface ICMCDeposit {\n    event AliceDeposited(address assetId, uint256 amount);\n    \n    function getTotalDepositsAlice(address assetId)\n        external\n        view\n        returns (uint256);\n\n    function getTotalDepositsBob(address assetId)\n        external\n        view\n        returns (uint256);\n\n    function depositAlice(address assetId, uint256 amount) external payable;\n}\n"
    },
    "src.sol/interfaces/ICMCWithdraw.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nstruct WithdrawData {\n    address channelAddress;\n    address assetId;\n    address payable recipient;\n    uint256 amount;\n    uint256 nonce;\n    address callTo;\n    bytes callData;\n}\n\ninterface ICMCWithdraw {\n    function getWithdrawalTransactionRecord(WithdrawData calldata wd)\n        external\n        view\n        returns (bool);\n\n    function withdraw(\n        WithdrawData calldata wd,\n        bytes calldata aliceSignature,\n        bytes calldata bobSignature\n    ) external;\n}\n"
    },
    "src.sol/interfaces/ICMCAdjudicator.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./Types.sol\";\n\ninterface ICMCAdjudicator {\n    struct CoreChannelState {\n        address channelAddress;\n        address alice;\n        address bob;\n        address[] assetIds;\n        Balance[] balances;\n        uint256[] processedDepositsA;\n        uint256[] processedDepositsB;\n        uint256[] defundNonces;\n        uint256 timeout;\n        uint256 nonce;\n        bytes32 merkleRoot;\n    }\n\n    struct CoreTransferState {\n        address channelAddress;\n        bytes32 transferId;\n        address transferDefinition;\n        address initiator;\n        address responder;\n        address assetId;\n        Balance balance;\n        uint256 transferTimeout;\n        bytes32 initialStateHash;\n    }\n\n    struct ChannelDispute {\n        bytes32 channelStateHash;\n        uint256 nonce;\n        bytes32 merkleRoot;\n        uint256 consensusExpiry;\n        uint256 defundExpiry;\n    }\n\n    struct TransferDispute {\n        bytes32 transferStateHash;\n        uint256 transferDisputeExpiry;\n        bool isDefunded;\n    }\n\n    event ChannelDisputed(\n        address disputer,\n        CoreChannelState state,\n        ChannelDispute dispute\n    );\n\n    event ChannelDefunded(\n        address defunder,\n        CoreChannelState state,\n        ChannelDispute dispute,\n        address[] assetIds\n    );\n\n    event TransferDisputed(\n        address disputer,\n        CoreTransferState state,\n        TransferDispute dispute\n    );\n\n    event TransferDefunded(\n        address defunder,\n        CoreTransferState state,\n        TransferDispute dispute,\n        bytes encodedInitialState,\n        bytes encodedResolver,\n        Balance balance\n    );\n\n    function getChannelDispute() external view returns (ChannelDispute memory);\n\n    function getDefundNonce(address assetId) external view returns (uint256);\n\n    function getTransferDispute(bytes32 transferId)\n        external\n        view\n        returns (TransferDispute memory);\n\n    function disputeChannel(\n        CoreChannelState calldata ccs,\n        bytes calldata aliceSignature,\n        bytes calldata bobSignature\n    ) external;\n\n    function defundChannel(\n        CoreChannelState calldata ccs,\n        address[] calldata assetIds,\n        uint256[] calldata indices\n    ) external;\n\n    function disputeTransfer(\n        CoreTransferState calldata cts,\n        bytes32[] calldata merkleProofData\n    ) external;\n\n    function defundTransfer(\n        CoreTransferState calldata cts,\n        bytes calldata encodedInitialTransferState,\n        bytes calldata encodedTransferResolver,\n        bytes calldata responderSignature\n    ) external;\n}\n"
    },
    "src.sol/interfaces/Types.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nstruct Balance {\n    uint256[2] amount; // [alice, bob] in channel, [initiator, responder] in transfer\n    address payable[2] to; // [alice, bob] in channel, [initiator, responder] in transfer\n}\n"
    },
    "src.sol/lib/LibUtils.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\n/// @title LibUtils\n/// @author Connext <support@connext.network>\n/// @notice Contains a helper to revert if a call was not successfully\n///         made\nlibrary LibUtils {\n    // If success is false, reverts and passes on the revert string.\n    function revertIfCallFailed(bool success, bytes memory returnData)\n        internal\n        pure\n    {\n        if (!success) {\n            assembly {\n                revert(add(returnData, 0x20), mload(returnData))\n            }\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
    },
    "@openzeppelin/contracts/utils/Address.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n        // for accounts without code, i.e. `keccak256('')`\n        bytes32 codehash;\n        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n        // solhint-disable-next-line no-inline-assembly\n        assembly { codehash := extcodehash(account) }\n        return (codehash != accountHash && codehash != 0x0);\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n        (bool success, ) = recipient.call{ value: amount }(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain`call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n      return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n        return _functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        return _functionCallWithValue(target, data, value, errorMessage);\n    }\n\n    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n        require(isContract(target), \"Address: call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
    },
    "src.sol/testing/TestChannelFactory.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IVectorChannel.sol\";\nimport \"../ChannelFactory.sol\";\n\n/// @title TestChannelFactory\n/// @author Layne Haber <layne@connext.network>\n/// @notice This factory is used for testing *ONLY* and allows you to\n///         deploy contracts without setting them up (to run the CMCCore\n///         setup tests)\ncontract TestChannelFactory is ChannelFactory {\n    constructor(address _mastercopy, uint256 _chainId)\n        ChannelFactory(_mastercopy, _chainId)\n    {}\n\n    function deployChannelProxyWithoutSetup(address alice, address bob)\n        public\n        returns (address)\n    {\n        return deployChannelProxy(alice, bob);\n    }\n\n    function createChannelWithoutSetup(address alice, address bob)\n        public\n        returns (address channel)\n    {\n        channel = deployChannelProxy(alice, bob);\n        emit ChannelCreation(channel);\n        return channel;\n    }\n}\n"
    },
    "src.sol/testing/ReentrantToken.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.1;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"../interfaces/IVectorChannel.sol\";\n\ncontract ReentrantToken is ERC20 {\n    address private immutable channel;\n\n    constructor(address _channel) ERC20(\"Reentrant Token\", \"BADBOI\") {\n        channel = _channel;\n    }\n\n    function mint(address account, uint256 amount) external {\n        _mint(account, amount);\n    }\n\n    // Designed to be called alongside CMCDeposit.depositAlice\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) public override returns (bool) {\n        IVectorChannel(channel).depositAlice(address(this), amount);\n        return super.transferFrom(sender, recipient, amount);\n    }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n    using SafeMath for uint256;\n    using Address for address;\n\n    mapping (address => uint256) private _balances;\n\n    mapping (address => mapping (address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n    uint8 private _decimals;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n     * a default value of 18.\n     *\n     * To select a different value for {decimals}, use {_setupDecimals}.\n     *\n     * All three of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor (string memory name, string memory symbol) {\n        _name = name;\n        _symbol = symbol;\n        _decimals = 18;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n     * called.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20};\n     *\n     * Requirements:\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(sender, recipient, amount);\n        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n        return true;\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(sender, recipient, amount);\n\n        _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n        _balances[recipient] = _balances[recipient].add(amount);\n        emit Transfer(sender, recipient, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements\n     *\n     * - `to` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n        emit Transfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n        _totalSupply = _totalSupply.sub(amount);\n        emit Transfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Sets {decimals} to a value other than the default one of 18.\n     *\n     * WARNING: This function should only be called from the constructor. Most\n     * applications that interact with token contracts will not expect\n     * {decimals} to ever change, and may work incorrectly if it does.\n     */\n    function _setupDecimals(uint8 decimals_) internal {\n        _decimals = decimals_;\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be to transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n"
    },
    "@openzeppelin/contracts/GSN/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n}\n"
    },
    "@openzeppelin/contracts/math/SafeMath.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n"
    },
    "src.sol/testing/TestToken.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.1;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/* This token is ONLY useful for testing\n * Anybody can mint as many tokens as they like\n * Anybody can burn anyone else's tokens\n */\ncontract TestToken is ERC20 {\n    constructor() ERC20(\"Test Token\", \"TEST\") {\n        _mint(msg.sender, 1000000 ether);\n    }\n\n    function mint(address account, uint256 amount) external {\n        _mint(account, amount);\n    }\n\n    function burn(address account, uint256 amount) external {\n        _burn(account, amount);\n    }\n}\n"
    },
    "src.sol/CMCDeposit.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./interfaces/ICMCDeposit.sol\";\nimport \"./CMCCore.sol\";\nimport \"./CMCAsset.sol\";\nimport \"./lib/LibAsset.sol\";\nimport \"./lib/LibERC20.sol\";\n\n/// @title CMCDeposit\n/// @author Connext <support@connext.network>\n/// @notice Contains logic supporting channel multisig deposits. Channel\n///         funding is asymmetric, with `alice` having to call a deposit\n///         function which tracks the total amount she has deposited so far,\n///         and any other funds in the multisig being attributed to `bob`.\n\ncontract CMCDeposit is CMCCore, CMCAsset, ICMCDeposit {\n    mapping(address => uint256) private depositsAlice;\n\n    receive() external payable onlyViaProxy nonReentrant {}\n\n    function getTotalDepositsAlice(address assetId)\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (uint256)\n    {\n        return _getTotalDepositsAlice(assetId);\n    }\n\n    function _getTotalDepositsAlice(address assetId)\n        internal\n        view\n        returns (uint256)\n    {\n        return depositsAlice[assetId];\n    }\n\n    function getTotalDepositsBob(address assetId)\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (uint256)\n    {\n        return _getTotalDepositsBob(assetId);\n    }\n\n    // Calculated using invariant onchain properties. Note we DONT use safemath here\n    function _getTotalDepositsBob(address assetId)\n        internal\n        view\n        returns (uint256)\n    {\n        return\n            LibAsset.getOwnBalance(assetId) +\n            totalTransferred[assetId] -\n            depositsAlice[assetId];\n    }\n\n    function depositAlice(address assetId, uint256 amount)\n        external\n        payable\n        override\n        onlyViaProxy\n        nonReentrant\n    {\n        if (LibAsset.isEther(assetId)) {\n            require(msg.value == amount, \"CMCDeposit: VALUE_MISMATCH\");\n        } else {\n            // If ETH is sent along, it will be attributed to bob\n            require(msg.value == 0, \"CMCDeposit: ETH_WITH_ERC_TRANSFER\");\n            require(\n                LibERC20.transferFrom(\n                    assetId,\n                    msg.sender,\n                    address(this),\n                    amount\n                ),\n                \"CMCDeposit: ERC20_TRANSFER_FAILED\"\n            );\n        }\n        // NOTE: explicitly do NOT use safemath here\n        depositsAlice[assetId] += amount;\n        emit AliceDeposited(assetId, amount);\n    }\n}\n"
    },
    "src.sol/CMCCore.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./interfaces/ICMCCore.sol\";\nimport \"./ReentrancyGuard.sol\";\n\n/// @title CMCCore\n/// @author Connext <support@connext.network>\n/// @notice Contains logic pertaining to the participants of a channel,\n///         including setting and retrieving the participants and the\n///         mastercopy.\n\ncontract CMCCore is ReentrancyGuard, ICMCCore {\n    address private immutable mastercopyAddress;\n\n    address internal alice;\n    address internal bob;\n\n    /// @notice Set invalid participants to block the mastercopy from being used directly\n    ///         Nonzero address also prevents the mastercopy from being setup\n    ///         Only setting alice is sufficient, setting bob too wouldn't change anything\n    constructor() {\n        mastercopyAddress = address(this);\n    }\n\n    // Prevents us from calling methods directly from the mastercopy contract\n    modifier onlyViaProxy {\n        require(\n            address(this) != mastercopyAddress,\n            \"Mastercopy: ONLY_VIA_PROXY\"\n        );\n        _;\n    }\n\n    /// @notice Contract constructor for Proxied copies\n    /// @param _alice: Address representing user with function deposit\n    /// @param _bob: Address representing user with multisig deposit\n    function setup(address _alice, address _bob)\n        external\n        override\n        onlyViaProxy\n    {\n        require(alice == address(0), \"CMCCore: ALREADY_SETUP\");\n        require(\n            _alice != address(0) && _bob != address(0),\n            \"CMCCore: INVALID_PARTICIPANT\"\n        );\n        require(_alice != _bob, \"CMCCore: IDENTICAL_PARTICIPANTS\");\n        ReentrancyGuard.setup();\n        alice = _alice;\n        bob = _bob;\n    }\n\n    /// @notice A getter function for the bob of the multisig\n    /// @return Bob's signer address\n    function getAlice()\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (address)\n    {\n        return alice;\n    }\n\n    /// @notice A getter function for the bob of the multisig\n    /// @return Alice's signer address\n    function getBob()\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (address)\n    {\n        return bob;\n    }\n}\n"
    },
    "src.sol/CMCAsset.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./interfaces/ICMCAsset.sol\";\nimport \"./interfaces/Types.sol\";\nimport \"./CMCCore.sol\";\nimport \"./lib/LibAsset.sol\";\nimport \"./lib/LibMath.sol\";\nimport \"@openzeppelin/contracts/math/Math.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title CMCAsset\n/// @author Connext <support@connext.network>\n/// @notice Contains logic to safely transfer channel assets (even if they are\n///         noncompliant). During adjudication, balances from defunding the\n///         channel or defunding transfers are registered as withdrawable. Once\n///         they are registered, the owner (or a watchtower on behalf of the\n///         owner), may call `exit` to reclaim funds from the multisig.\n\ncontract CMCAsset is CMCCore, ICMCAsset {\n    using SafeMath for uint256;\n    using LibMath for uint256;\n\n    mapping(address => uint256) internal totalTransferred;\n    mapping(address => mapping(address => uint256))\n        private exitableAmount;\n\n    function registerTransfer(address assetId, uint256 amount) internal {\n        totalTransferred[assetId] += amount;\n    }\n\n    function getTotalTransferred(address assetId)\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (uint256)\n    {\n        return totalTransferred[assetId];\n    }\n\n    function makeExitable(\n        address assetId,\n        address recipient,\n        uint256 amount\n    ) internal {\n        exitableAmount[assetId][\n            recipient\n        ] = exitableAmount[assetId][recipient].satAdd(amount);\n    }\n\n    function makeBalanceExitable(\n        address assetId,\n        Balance memory balance\n    ) internal {\n        for (uint256 i = 0; i < 2; i++) {\n            uint256 amount = balance.amount[i];\n            if (amount > 0) {\n                makeExitable(assetId, balance.to[i], amount);\n            }\n        }\n    }\n\n    function getExitableAmount(address assetId, address owner)\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (uint256)\n    {\n        return exitableAmount[assetId][owner];\n    }\n\n    function getAvailableAmount(address assetId, uint256 maxAmount)\n        internal\n        view\n        returns (uint256)\n    {\n        // Taking the min protects against the case where the multisig\n        // holds less than the amount that is trying to be withdrawn\n        // while still allowing the total of the funds to be removed\n        // without the transaction reverting.\n        return Math.min(maxAmount, LibAsset.getOwnBalance(assetId));\n    }\n\n    function transferAsset(\n        address assetId,\n        address payable recipient,\n        uint256 amount\n    ) internal {\n        registerTransfer(assetId, amount);\n        require(\n            LibAsset.unregisteredTransfer(assetId, recipient, amount),\n            \"CMCAsset: TRANSFER_FAILED\"\n        );\n    }\n\n    function exit(\n        address assetId,\n        address owner,\n        address payable recipient\n    ) external override onlyViaProxy nonReentrant {\n        // Either the owner must be the recipient, or in control\n        // of setting the recipient of the funds to whomever they\n        // choose\n        require(\n            msg.sender == owner || owner == recipient,\n            \"CMCAsset: OWNER_MISMATCH\"\n        );\n\n        uint256 amount =\n            getAvailableAmount(\n                assetId,\n                exitableAmount[assetId][owner]\n            );\n\n        // Revert if amount is 0\n        require(amount > 0, \"CMCAsset: NO_OP\");\n\n        // Reduce the amount claimable from the multisig by the owner\n        exitableAmount[assetId][\n            owner\n        ] = exitableAmount[assetId][owner].sub(amount);\n\n        // Perform transfer\n        transferAsset(assetId, recipient, amount);\n    }\n}\n"
    },
    "src.sol/ReentrancyGuard.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\n/// @title CMCWithdraw\n/// @author Connext <support@connext.network>\n/// @notice A \"mutex\" reentrancy guard, heavily influenced by OpenZeppelin.\n\ncontract ReentrancyGuard {\n    uint256 private constant OPEN = 1;\n    uint256 private constant LOCKED = 2;\n\n    uint256 public lock;\n\n    function setup() internal {\n        lock = OPEN;\n    }\n\n    modifier nonReentrant() {\n        require(lock == OPEN, \"ReentrancyGuard: REENTRANT_CALL\");\n        lock = LOCKED;\n        _;\n        lock = OPEN;\n    }\n\n    modifier nonReentrantView() {\n        require(lock == OPEN, \"ReentrancyGuard: REENTRANT_CALL\");\n        _;\n    }\n}\n"
    },
    "src.sol/lib/LibMath.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\n/// @title LibMath\n/// @author Connext <support@connext.network>\n/// @notice This library allows functions that would otherwise overflow and\n///         revert if SafeMath was used to instead return the UINT_MAX. In the\n///         adjudicator, this is used to ensure you can get the majority of\n///         funds out in the event your balance > UINT_MAX and there is an\n///         onchain dispute.\nlibrary LibMath {\n    /// @dev Returns the maximum uint256 for an addition that would overflow\n    ///      (saturation arithmetic)\n    function satAdd(uint256 x, uint256 y) internal pure returns (uint256) {\n        uint256 sum = x + y;\n        return sum >= x ? sum : type(uint256).max;\n    }\n}\n"
    },
    "@openzeppelin/contracts/math/Math.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a >= b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow, so we distribute\n        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n    }\n}\n"
    },
    "src.sol/CMCAdjudicator.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./interfaces/Commitment.sol\";\nimport \"./interfaces/ICMCAdjudicator.sol\";\nimport \"./interfaces/ITransferDefinition.sol\";\nimport \"./interfaces/Types.sol\";\nimport \"./CMCCore.sol\";\nimport \"./CMCAsset.sol\";\nimport \"./CMCDeposit.sol\";\nimport \"./lib/LibChannelCrypto.sol\";\nimport \"./lib/LibMath.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\n\n/// @title CMCAdjudicator\n/// @author Connext <support@connext.network>\n/// @notice Contains logic for disputing a single channel and all active\n///         transfers associated with the channel. Contains two major phases:\n///         (1) consensus: settle on latest channel state\n///         (2) defund: remove assets and dispute active transfers\ncontract CMCAdjudicator is CMCCore, CMCAsset, CMCDeposit, ICMCAdjudicator {\n    using LibChannelCrypto for bytes32;\n    using LibMath for uint256;\n    using SafeMath for uint256;\n\n    uint256 private constant INITIAL_DEFUND_NONCE = 1;\n\n    ChannelDispute private channelDispute;\n    mapping(address => uint256) private defundNonces;\n    mapping(bytes32 => TransferDispute) private transferDisputes;\n\n    modifier validateChannel(CoreChannelState calldata ccs) {\n        require(\n            ccs.channelAddress == address(this) &&\n                ccs.alice == alice &&\n                ccs.bob == bob,\n            \"CMCAdjudicator: INVALID_CHANNEL\"\n        );\n        _;\n    }\n\n    modifier validateTransfer(CoreTransferState calldata cts) {\n        require(\n            cts.channelAddress == address(this),\n            \"CMCAdjudicator: INVALID_TRANSFER\"\n        );\n        _;\n    }\n\n    function getChannelDispute()\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (ChannelDispute memory)\n    {\n        return channelDispute;\n    }\n\n    function getDefundNonce(address assetId)\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (uint256)\n    {\n        return defundNonces[assetId];\n    }\n\n    function getTransferDispute(bytes32 transferId)\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (TransferDispute memory)\n    {\n        return transferDisputes[transferId];\n    }\n\n    function disputeChannel(\n        CoreChannelState calldata ccs,\n        bytes calldata aliceSignature,\n        bytes calldata bobSignature\n    ) external override onlyViaProxy nonReentrant validateChannel(ccs) {\n        // Generate hash\n        bytes32 ccsHash = hashChannelState(ccs);\n\n        // Verify Alice's and Bob's signature on the channel state\n        verifySignaturesOnChannelStateHash(ccs, ccsHash, aliceSignature, bobSignature);\n\n        // We cannot dispute a channel in its defund phase\n        require(!inDefundPhase(), \"CMCAdjudicator: INVALID_PHASE\");\n\n        // New nonce must be strictly greater than the stored one\n        require(\n            channelDispute.nonce < ccs.nonce,\n            \"CMCAdjudicator: INVALID_NONCE\"\n        );\n\n        if (!inConsensusPhase()) {\n            // We are not already in a dispute\n            // Set expiries\n            // TODO: offchain-ensure that there can't be an overflow\n            channelDispute.consensusExpiry = block.timestamp.add(ccs.timeout);\n            channelDispute.defundExpiry = block.timestamp.add(\n                ccs.timeout.mul(2)\n            );\n        }\n\n        // Store newer state\n        channelDispute.channelStateHash = ccsHash;\n        channelDispute.nonce = ccs.nonce;\n        channelDispute.merkleRoot = ccs.merkleRoot;\n\n        // Emit event\n        emit ChannelDisputed(msg.sender, ccs, channelDispute);\n    }\n\n    function defundChannel(\n        CoreChannelState calldata ccs,\n        address[] calldata assetIds,\n        uint256[] calldata indices\n    ) external override onlyViaProxy nonReentrant validateChannel(ccs) {\n        // These checks are not strictly necessary, but it's a bit cleaner this way\n        require(assetIds.length > 0, \"CMCAdjudicator: NO_ASSETS_GIVEN\");\n        require(\n            indices.length <= assetIds.length,\n            \"CMCAdjudicator: WRONG_ARRAY_LENGTHS\"\n        );\n\n        // Verify that the given channel state matches the stored one\n        require(\n            hashChannelState(ccs) == channelDispute.channelStateHash,\n            \"CMCAdjudicator: INVALID_CHANNEL_HASH\"\n        );\n\n        // We need to be in defund phase for that\n        require(inDefundPhase(), \"CMCAdjudicator: INVALID_PHASE\");\n\n        // TODO SECURITY: Beware of reentrancy\n        // TODO: offchain-ensure that all arrays have the same length:\n        // assetIds, balances, processedDepositsA, processedDepositsB, defundNonces\n        // Make sure there are no duplicates in the assetIds -- duplicates are often a source of double-spends\n\n        // Defund all assets given\n        for (uint256 i = 0; i < assetIds.length; i++) {\n            address assetId = assetIds[i];\n\n            // Verify or find the index of the assetId in the ccs.assetIds\n            uint256 index;\n            if (i < indices.length) {\n                // The index was supposedly given -- we verify\n                index = indices[i];\n                require(\n                    assetId == ccs.assetIds[index],\n                    \"CMCAdjudicator: INDEX_MISMATCH\"\n                );\n            } else {\n                // we search through the assets in ccs\n                for (index = 0; index < ccs.assetIds.length; index++) {\n                    if (assetId == ccs.assetIds[index]) {\n                        break;\n                    }\n                }\n            }\n\n            // Now, if `index`  is equal to the number of assets in ccs,\n            // then the current asset is not in ccs;\n            // otherwise, `index` is the index in ccs for the current asset\n\n            // Check the assets haven't already been defunded + update the\n            // defundNonce for that asset\n            {\n                // Open a new block to avoid \"stack too deep\" error\n                uint256 defundNonce =\n                    (index == ccs.assetIds.length)\n                        ? INITIAL_DEFUND_NONCE\n                        : ccs.defundNonces[index];\n                require(\n                    defundNonces[assetId] < defundNonce,\n                    \"CMCAdjudicator: CHANNEL_ALREADY_DEFUNDED\"\n                );\n                defundNonces[assetId] = defundNonce;\n            }\n\n            // Get total deposits\n            uint256 tdAlice = _getTotalDepositsAlice(assetId);\n            uint256 tdBob = _getTotalDepositsBob(assetId);\n\n            Balance memory balance;\n\n            if (index == ccs.assetIds.length) {\n                // The current asset is not a part of ccs; refund what has been deposited\n                balance = Balance({\n                    amount: [tdAlice, tdBob],\n                    to: [payable(ccs.alice), payable(ccs.bob)]\n                });\n            } else {\n                // Start with the final balances in ccs\n                balance = ccs.balances[index];\n                // Add unprocessed deposits\n                balance.amount[0] = balance.amount[0].satAdd(\n                    tdAlice - ccs.processedDepositsA[index]\n                );\n                balance.amount[1] = balance.amount[1].satAdd(\n                    tdBob - ccs.processedDepositsB[index]\n                );\n            }\n\n            // Add result to exitable amounts\n            makeBalanceExitable(assetId, balance);\n        }\n\n        emit ChannelDefunded(\n            msg.sender,\n            ccs,\n            channelDispute,\n            assetIds\n        );\n    }\n\n    function disputeTransfer(\n        CoreTransferState calldata cts,\n        bytes32[] calldata merkleProofData\n    ) external override onlyViaProxy nonReentrant validateTransfer(cts) {\n        // Verify that the given transfer state is included in the \"finalized\" channel state\n        bytes32 transferStateHash = hashTransferState(cts);\n        verifyMerkleProof(\n            merkleProofData,\n            channelDispute.merkleRoot,\n            transferStateHash\n        );\n\n        // The channel needs to be in defund phase for that, i.e. channel state is \"finalized\"\n        require(inDefundPhase(), \"CMCAdjudicator: INVALID_PHASE\");\n\n        // Get stored dispute for this transfer\n        TransferDispute storage transferDispute =\n            transferDisputes[cts.transferId];\n\n        // Verify that this transfer has not been disputed before\n        require(\n            transferDispute.transferDisputeExpiry == 0,\n            \"CMCAdjudicator: TRANSFER_ALREADY_DISPUTED\"\n        );\n\n        // Store transfer state and set expiry\n        transferDispute.transferStateHash = transferStateHash;\n        // TODO: offchain-ensure that there can't be an overflow\n        transferDispute.transferDisputeExpiry = block.timestamp.add(\n            cts.transferTimeout\n        );\n\n        emit TransferDisputed(\n            msg.sender,\n            cts,\n            transferDispute\n        );\n    }\n\n    function defundTransfer(\n        CoreTransferState calldata cts,\n        bytes calldata encodedInitialTransferState,\n        bytes calldata encodedTransferResolver,\n        bytes calldata responderSignature\n    ) external override onlyViaProxy nonReentrant validateTransfer(cts) {\n        // Get stored dispute for this transfer\n        TransferDispute storage transferDispute =\n            transferDisputes[cts.transferId];\n\n        // Verify that a dispute for this transfer has already been started\n        require(\n            transferDispute.transferDisputeExpiry != 0,\n            \"CMCAdjudicator: TRANSFER_NOT_DISPUTED\"\n        );\n\n        // Verify that the given transfer state matches the stored one\n        require(\n            hashTransferState(cts) == transferDispute.transferStateHash,\n            \"CMCAdjudicator: INVALID_TRANSFER_HASH\"\n        );\n\n        // We can't defund twice\n        require(\n            !transferDispute.isDefunded,\n            \"CMCAdjudicator: TRANSFER_ALREADY_DEFUNDED\"\n        );\n        transferDispute.isDefunded = true;\n\n        Balance memory balance;\n\n        if (block.timestamp < transferDispute.transferDisputeExpiry) {\n            // Ensure the correct hash is provided\n            require(\n                keccak256(encodedInitialTransferState) == cts.initialStateHash,\n                \"CMCAdjudicator: INVALID_TRANSFER_HASH\"\n            );\n            \n            // Before dispute expiry, responder or responder-authorized\n            // agent (i.e. watchtower) can resolve\n            require(\n                msg.sender == cts.responder || cts.initialStateHash.checkSignature(responderSignature, cts.responder),\n                \"CMCAdjudicator: INVALID_RESOLVER\"\n            );\n            \n            ITransferDefinition transferDefinition =\n                ITransferDefinition(cts.transferDefinition);\n            balance = transferDefinition.resolve(\n                abi.encode(cts.balance),\n                encodedInitialTransferState,\n                encodedTransferResolver\n            );\n            // Verify that returned balances don't exceed initial balances\n            require(\n                balance.amount[0].add(balance.amount[1]) <=\n                    cts.balance.amount[0].add(cts.balance.amount[1]),\n                \"CMCAdjudicator: INVALID_BALANCES\"\n            );\n        } else {\n            // After dispute expiry, if the responder hasn't resolved, we defund the initial balance\n            balance = cts.balance;\n        }\n\n        // Depending on previous code path, defund either resolved or initial balance\n        makeBalanceExitable(cts.assetId, balance);\n\n        // Emit event\n        emit TransferDefunded(\n            msg.sender,\n            cts,\n            transferDispute,\n            encodedInitialTransferState,\n            encodedTransferResolver,\n            balance\n        );\n    }\n\n    function verifySignaturesOnChannelStateHash(\n        CoreChannelState calldata ccs,\n        bytes32 ccsHash,\n        bytes calldata aliceSignature,\n        bytes calldata bobSignature\n    ) internal pure {\n        bytes32 commitment =\n            keccak256(abi.encode(CommitmentType.ChannelState, ccsHash));\n        require(\n            commitment.checkSignature(aliceSignature, ccs.alice),\n            \"CMCAdjudicator: INVALID_ALICE_SIG\"\n        );\n        require(\n            commitment.checkSignature(bobSignature, ccs.bob),\n            \"CMCAdjudicator: INVALID_BOB_SIG\"\n        );\n    }\n\n    function verifyMerkleProof(\n        bytes32[] calldata proof,\n        bytes32 root,\n        bytes32 leaf\n    ) internal pure {\n        require(\n            MerkleProof.verify(proof, root, leaf),\n            \"CMCAdjudicator: INVALID_MERKLE_PROOF\"\n        );\n    }\n\n    function inConsensusPhase() internal view returns (bool) {\n        return block.timestamp < channelDispute.consensusExpiry;\n    }\n\n    function inDefundPhase() internal view returns (bool) {\n        return\n            channelDispute.consensusExpiry <= block.timestamp &&\n            block.timestamp < channelDispute.defundExpiry;\n    }\n\n    function hashChannelState(CoreChannelState calldata ccs)\n        internal\n        pure\n        returns (bytes32)\n    {\n        return keccak256(abi.encode(ccs));\n    }\n\n    function hashTransferState(CoreTransferState calldata cts)\n        internal\n        pure\n        returns (bytes32)\n    {\n        return keccak256(abi.encode(cts));\n    }\n}\n"
    },
    "src.sol/interfaces/Commitment.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nenum CommitmentType {ChannelState, WithdrawData}\n"
    },
    "src.sol/interfaces/ITransferDefinition.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./ITransferRegistry.sol\";\nimport \"./Types.sol\";\n\ninterface ITransferDefinition {\n    // Validates the initial state of the transfer.\n    // Called by validator.ts during `create` updates.\n    function create(bytes calldata encodedBalance, bytes calldata)\n        external\n        view\n        returns (bool);\n\n    // Performs a state transition to resolve a transfer and returns final balances.\n    // Called by validator.ts during `resolve` updates.\n    function resolve(\n        bytes calldata encodedBalance,\n        bytes calldata,\n        bytes calldata\n    ) external view returns (Balance memory);\n\n    // Should also have the following properties:\n    // string public constant override Name = \"...\";\n    // string public constant override StateEncoding = \"...\";\n    // string public constant override ResolverEncoding = \"...\";\n    // These properties are included on the transfer specifically\n    // to make it easier for implementers to add new transfers by\n    // only include a `.sol` file\n    function Name() external view returns (string memory);\n\n    function StateEncoding() external view returns (string memory);\n\n    function ResolverEncoding() external view returns (string memory);\n\n    function EncodedCancel() external view returns (bytes memory);\n\n    function getRegistryInformation()\n        external\n        view\n        returns (RegisteredTransfer memory);\n}\n"
    },
    "src.sol/lib/LibChannelCrypto.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/cryptography/ECDSA.sol\";\n\t\t\n/// @author Connext <support@connext.network>\t\t\n/// @notice This library contains helpers for recovering signatures from a\t\t\n///         Vector commitments. Channels do not allow for arbitrary signing of\t\t\n///         messages to prevent misuse of private keys by injected providers,\t\t\n///         and instead only sign messages with a Vector channel prefix.\nlibrary LibChannelCrypto {\n    function checkSignature(\n        bytes32 hash,\n        bytes memory signature,\n        address allegedSigner\n    ) internal pure returns (bool) {\n        return recoverChannelMessageSigner(hash, signature) == allegedSigner;\n    }\n\n    function recoverChannelMessageSigner(bytes32 hash, bytes memory signature)\n        internal\n        pure\n        returns (address)\n    {\n        bytes32 digest = toChannelSignedMessage(hash);\n        return ECDSA.recover(digest, signature);\n    }\n\n    function toChannelSignedMessage(bytes32 hash)\n        internal\n        pure\n        returns (bytes32)\n    {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return\n            keccak256(abi.encodePacked(\"\\x16Vector Signed Message:\\n32\", hash));\n    }\n\n    function checkUtilitySignature(\n        bytes32 hash,\n        bytes memory signature,\n        address allegedSigner\n    ) internal pure returns (bool) {\n        return recoverChannelMessageSigner(hash, signature) == allegedSigner;\n    }\n\n    function recoverUtilityMessageSigner(bytes32 hash, bytes memory signature)\n        internal\n        pure\n        returns (address)\n    {\n        bytes32 digest = toUtilitySignedMessage(hash);\n        return ECDSA.recover(digest, signature);\n    }\n\n    function toUtilitySignedMessage(bytes32 hash)\n        internal\n        pure\n        returns (bytes32)\n    {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return\n            keccak256(abi.encodePacked(\"\\x17Utility Signed Message:\\n32\", hash));\n    }\n}\n"
    },
    "@openzeppelin/contracts/cryptography/MerkleProof.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\n */\nlibrary MerkleProof {\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     */\n    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        bytes32 computedHash = leaf;\n\n        for (uint256 i = 0; i < proof.length; i++) {\n            bytes32 proofElement = proof[i];\n\n            if (computedHash <= proofElement) {\n                // Hash(current computed hash + current element of the proof)\n                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));\n            } else {\n                // Hash(current element of the proof + current computed hash)\n                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));\n            }\n        }\n\n        // Check if the computed hash (root) is equal to the provided root\n        return computedHash == root;\n    }\n}\n"
    },
    "src.sol/interfaces/ITransferRegistry.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental \"ABIEncoderV2\";\n\nstruct RegisteredTransfer {\n    string name;\n    address definition;\n    string stateEncoding;\n    string resolverEncoding;\n    bytes encodedCancel;\n}\n\ninterface ITransferRegistry {\n    event TransferAdded(RegisteredTransfer transfer);\n\n    event TransferRemoved(RegisteredTransfer transfer);\n\n    // Should add a transfer definition to the registry\n    // onlyOwner\n    function addTransferDefinition(RegisteredTransfer memory transfer) external;\n\n    // Should remove a transfer definition to the registry\n    // onlyOwner\n    function removeTransferDefinition(string memory name) external;\n\n    // Should return all transfer defintions in registry\n    function getTransferDefinitions()\n        external\n        view\n        returns (RegisteredTransfer[] memory);\n}\n"
    },
    "@openzeppelin/contracts/cryptography/ECDSA.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        // Check the signature length\n        if (signature.length != 65) {\n            revert(\"ECDSA: invalid signature length\");\n        }\n\n        // Divide the signature in r, s and v variables\n        bytes32 r;\n        bytes32 s;\n        uint8 v;\n\n        // ecrecover takes the signature parameters, and the only way to get them\n        // currently is to use assembly.\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            r := mload(add(signature, 0x20))\n            s := mload(add(signature, 0x40))\n            v := byte(0, mload(add(signature, 0x60)))\n        }\n\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        }\n\n        if (v != 27 && v != 28) {\n            revert(\"ECDSA: invalid signature 'v' value\");\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        require(signer != address(0), \"ECDSA: invalid signature\");\n\n        return signer;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * replicates the behavior of the\n     * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]\n     * JSON-RPC method.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n    }\n}\n"
    },
    "src.sol/testing/NonconformingToken.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.1;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\n\n/* This token is ONLY useful for testing\n * Anybody can mint as many tokens as they like\n * Anybody can burn anyone else's tokens\n * It is intentionally not compliant to the ERC20 standard,\n * i.e. returns nothing instead of `true` for\n * several functions.\n * Based on OpenZeppelin's (standard-conforming) implementation.\n */\ncontract NonconformingToken {\n    using SafeMath for uint256;\n\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n    uint8 private _decimals;\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(\n        address indexed owner,\n        address indexed spender,\n        uint256 value\n    );\n\n    /**\n     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n     * a default value of 18.\n     *\n     * To select a different value for {decimals}, use {_setupDecimals}.\n     *\n     * All three of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor() {\n        _name = \"Nonconforming Token\";\n        _symbol = \"USDT\";\n        _decimals = 18;\n        _mint(msg.sender, 1000000 ether);\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n     * called.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual {\n        _transfer(msg.sender, recipient, amount);\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender)\n        public\n        view\n        virtual\n        returns (uint256)\n    {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual {\n        _approve(msg.sender, spender, amount);\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * Requirements:\n     *\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) public virtual {\n        _transfer(sender, recipient, amount);\n        _approve(\n            sender,\n            msg.sender,\n            _allowances[sender][msg.sender].sub(\n                amount,\n                \"ERC20: transfer amount exceeds allowance\"\n            )\n        );\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue)\n        public\n        virtual\n        returns (bool)\n    {\n        _approve(\n            msg.sender,\n            spender,\n            _allowances[msg.sender][spender].add(addedValue)\n        );\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue)\n        public\n        virtual\n        returns (bool)\n    {\n        _approve(\n            msg.sender,\n            spender,\n            _allowances[msg.sender][spender].sub(\n                subtractedValue,\n                \"ERC20: decreased allowance below zero\"\n            )\n        );\n        return true;\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal virtual {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(sender, recipient, amount);\n\n        _balances[sender] = _balances[sender].sub(\n            amount,\n            \"ERC20: transfer amount exceeds balance\"\n        );\n        _balances[recipient] = _balances[recipient].add(amount);\n        emit Transfer(sender, recipient, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n        emit Transfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        _balances[account] = _balances[account].sub(\n            amount,\n            \"ERC20: burn amount exceeds balance\"\n        );\n        _totalSupply = _totalSupply.sub(amount);\n        emit Transfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Sets {decimals} to a value other than the default one of 18.\n     *\n     * WARNING: This function should only be called from the constructor. Most\n     * applications that interact with token contracts will not expect\n     * {decimals} to ever change, and may work incorrectly if it does.\n     */\n    function _setupDecimals(uint8 decimals_) internal {\n        _decimals = decimals_;\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be to transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n\n    function mint(address account, uint256 amount) external {\n        _mint(account, amount);\n    }\n\n    function burn(address account, uint256 amount) external {\n        _burn(account, amount);\n    }\n}\n"
    },
    "src.sol/CMCWithdraw.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./interfaces/Commitment.sol\";\nimport \"./interfaces/ICMCWithdraw.sol\";\nimport \"./interfaces/WithdrawHelper.sol\";\nimport \"./CMCCore.sol\";\nimport \"./CMCAsset.sol\";\nimport \"./lib/LibAsset.sol\";\nimport \"./lib/LibChannelCrypto.sol\";\nimport \"./lib/LibUtils.sol\";\n\n/// @title CMCWithdraw\n/// @author Connext <support@connext.network>\n/// @notice Contains logic for all cooperative channel multisig withdrawals.\n///         Cooperative withdrawal commitments must be signed by both channel\n///         participants. As part of the channel withdrawals, an arbitrary\n///         call can be made, which is extracted from the withdraw data.\n\ncontract CMCWithdraw is CMCCore, CMCAsset, ICMCWithdraw {\n    using LibChannelCrypto for bytes32;\n\n    mapping(bytes32 => bool) private isExecuted;\n\n    modifier validateWithdrawData(WithdrawData calldata wd) {\n        require(\n            wd.channelAddress == address(this),\n            \"CMCWithdraw: CHANNEL_MISMATCH\"\n        );\n        _;\n    }\n\n    function getWithdrawalTransactionRecord(WithdrawData calldata wd)\n        external\n        view\n        override\n        onlyViaProxy\n        nonReentrantView\n        returns (bool)\n    {\n        return isExecuted[hashWithdrawData(wd)];\n    }\n\n    /// @param wd The withdraw data consisting of\n    /// semantic withdraw information, i.e. assetId, recipient, and amount;\n    /// information to make an optional call in addition to the actual transfer,\n    /// i.e. target address for the call and call payload;\n    /// additional information, i.e. channel address and nonce.\n    /// @param aliceSignature Signature of owner a\n    /// @param bobSignature Signature of owner b\n    function withdraw(\n        WithdrawData calldata wd,\n        bytes calldata aliceSignature,\n        bytes calldata bobSignature\n    ) external override onlyViaProxy nonReentrant validateWithdrawData(wd) {\n        // Generate hash\n        bytes32 wdHash = hashWithdrawData(wd);\n\n        // Verify Alice's and Bob's signature on the withdraw data\n        verifySignaturesOnWithdrawDataHash(wdHash, aliceSignature, bobSignature);\n\n        // Replay protection\n        require(!isExecuted[wdHash], \"CMCWithdraw: ALREADY_EXECUTED\");\n        isExecuted[wdHash] = true;\n\n        // Determine actually transferable amount\n        uint256 actualAmount = getAvailableAmount(wd.assetId, wd.amount);\n\n        // Revert if actualAmount is zero && callTo is 0\n        require(\n            actualAmount > 0 || wd.callTo != address(0),\n            \"CMCWithdraw: NO_OP\"\n        );\n\n        // Register and execute the transfer\n        transferAsset(wd.assetId, wd.recipient, actualAmount);\n\n        // Do we have to make a call in addition to the actual transfer?\n        if (wd.callTo != address(0)) {\n            WithdrawHelper(wd.callTo).execute(wd, actualAmount);\n        }\n    }\n\n    function verifySignaturesOnWithdrawDataHash(\n        bytes32 wdHash,\n        bytes calldata aliceSignature,\n        bytes calldata bobSignature\n    ) internal view {\n        bytes32 commitment =\n            keccak256(abi.encode(CommitmentType.WithdrawData, wdHash));\n        require(\n            commitment.checkSignature(aliceSignature, alice),\n            \"CMCWithdraw: INVALID_ALICE_SIG\"\n        );\n        require(\n            commitment.checkSignature(bobSignature, bob),\n            \"CMCWithdraw: INVALID_BOB_SIG\"\n        );\n    }\n\n    function hashWithdrawData(WithdrawData calldata wd)\n        internal\n        pure\n        returns (bytes32)\n    {\n        return keccak256(abi.encode(wd));\n    }\n}\n"
    },
    "src.sol/interfaces/WithdrawHelper.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./ICMCWithdraw.sol\";\n\ninterface WithdrawHelper {\n    function execute(WithdrawData calldata wd, uint256 actualAmount) external;\n}\n"
    },
    "src.sol/transferDefinitions/Withdraw.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./TransferDefinition.sol\";\nimport \"../lib/LibChannelCrypto.sol\";\n\n/// @title Withdraw\n/// @author Connext <support@connext.network>\n/// @notice This contract burns the initiator's funds if a mutually signed\n///         withdraw commitment can be generated\n\ncontract Withdraw is TransferDefinition {\n    using LibChannelCrypto for bytes32;\n\n    struct TransferState {\n        bytes initiatorSignature;\n        address initiator;\n        address responder;\n        bytes32 data;\n        uint256 nonce; // included so that each withdraw commitment has a unique hash\n        uint256 fee;\n        address callTo;\n        bytes callData;\n    }\n\n    struct TransferResolver {\n        bytes responderSignature;\n    }\n\n    // Provide registry information\n    string public constant override Name = \"Withdraw\";\n    string public constant override StateEncoding =\n        \"tuple(bytes initiatorSignature, address initiator, address responder, bytes32 data, uint256 nonce, uint256 fee, address callTo, bytes callData)\";\n    string public constant override ResolverEncoding =\n        \"tuple(bytes responderSignature)\";\n\n    function EncodedCancel() external pure override returns(bytes memory) {\n      TransferResolver memory resolver;\n      resolver.responderSignature = new bytes(65);\n      return abi.encode(resolver);\n    }\n\n    function create(bytes calldata encodedBalance, bytes calldata encodedState)\n        external\n        pure\n        override\n        returns (bool)\n    {\n        // Get unencoded information\n        TransferState memory state = abi.decode(encodedState, (TransferState));\n        Balance memory balance = abi.decode(encodedBalance, (Balance));\n\n        require(balance.amount[1] == 0, \"Withdraw: NONZERO_RECIPIENT_BALANCE\");\n        require(\n            state.initiator != address(0) && state.responder != address(0),\n            \"Withdraw: EMPTY_SIGNERS\"\n        );\n        require(state.data != bytes32(0), \"Withdraw: EMPTY_DATA\");\n        require(state.nonce != uint256(0), \"Withdraw: EMPTY_NONCE\");\n        require(\n            state.fee <= balance.amount[0],\n            \"Withdraw: INSUFFICIENT_BALANCE\"\n        );\n        require(\n            state.data.checkSignature(\n                state.initiatorSignature,\n                state.initiator\n            ),\n            \"Withdraw: INVALID_INITIATOR_SIG\"\n        );\n        \n        // Valid initial transfer state\n        return true;\n    }\n\n    function resolve(\n        bytes calldata encodedBalance,\n        bytes calldata encodedState,\n        bytes calldata encodedResolver\n    ) external pure override returns (Balance memory) {\n        TransferState memory state = abi.decode(encodedState, (TransferState));\n        TransferResolver memory resolver =\n            abi.decode(encodedResolver, (TransferResolver));\n        Balance memory balance = abi.decode(encodedBalance, (Balance));\n\n        // Allow for a withdrawal to be canceled if an empty signature is \n        // passed in. Should have *specific* cancellation action, not just\n        // any invalid sig\n        bytes memory b = new bytes(65);\n        if (keccak256(resolver.responderSignature) == keccak256(b)) {\n            // Withdraw should be cancelled, no state manipulation needed\n        } else {\n            require(\n                state.data.checkSignature(\n                    resolver.responderSignature,\n                    state.responder\n                ),\n                \"Withdraw: INVALID_RESPONDER_SIG\"\n            );\n            // Reduce withdraw amount by optional fee\n            // It's up to the offchain validators to ensure that the withdraw commitment takes this fee into account\n            balance.amount[1] = state.fee;\n            balance.amount[0] = 0;\n        }\n\n        return balance;\n    }\n}\n"
    },
    "src.sol/transferDefinitions/TransferDefinition.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/ITransferDefinition.sol\";\nimport \"../interfaces/ITransferRegistry.sol\";\n\n/// @title TransferDefinition\n/// @author Connext <support@connext.network>\n/// @notice This contract helps reduce boilerplate needed when creating\n///         new transfer definitions by providing an implementation of\n///         the required getter\n\nabstract contract TransferDefinition is ITransferDefinition {\n    function getRegistryInformation()\n        external\n        view\n        override\n        returns (RegisteredTransfer memory)\n    {\n        return\n            RegisteredTransfer({\n                name: this.Name(),\n                stateEncoding: this.StateEncoding(),\n                resolverEncoding: this.ResolverEncoding(),\n                definition: address(this),\n                encodedCancel: this.EncodedCancel()\n            });\n    }\n}\n"
    },
    "src.sol/TransferRegistry.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./interfaces/ITransferRegistry.sol\";\nimport \"./lib/LibIterableMapping.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/// @title TransferRegistry\n/// @author Connext <support@connext.network>\n/// @notice The TransferRegistry maintains an onchain record of all\n///         supported transfers (specifically holds the registry information\n///         defined within the contracts). The offchain protocol uses\n///         this information to get the correct encodings when generating\n///         signatures. The information stored here can only be updated\n///         by the owner of the contract\n\ncontract TransferRegistry is Ownable, ITransferRegistry {\n    using LibIterableMapping for LibIterableMapping.IterableMapping;\n\n    LibIterableMapping.IterableMapping transfers;\n\n    /// @dev Should add a transfer definition to the registry\n    function addTransferDefinition(RegisteredTransfer memory definition)\n        external\n        override\n        onlyOwner\n    {\n        // Get index transfer will be added at\n        uint256 idx = transfers.length();\n        \n        // Add registered transfer\n        transfers.addTransferDefinition(definition);\n\n        // Emit event\n        emit TransferAdded(transfers.getTransferDefinitionByIndex(idx));\n    }\n\n    /// @dev Should remove a transfer definition from the registry\n    function removeTransferDefinition(string memory name)\n        external\n        override\n        onlyOwner\n    {\n        // Get transfer from library to remove for event\n        RegisteredTransfer memory transfer = transfers.getTransferDefinitionByName(name);\n\n        // Remove transfer\n        transfers.removeTransferDefinition(name);\n\n        // Emit event\n        emit TransferRemoved(transfer);\n    }\n\n    /// @dev Should return all transfer defintions in registry\n    function getTransferDefinitions()\n        external\n        view\n        override\n        returns (RegisteredTransfer[] memory)\n    {\n        return transfers.getTransferDefinitions();\n    }\n}\n"
    },
    "src.sol/lib/LibIterableMapping.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/ITransferRegistry.sol\";\n\n/// @title LibIterableMapping\n/// @author Connext <support@connext.network>\n/// @notice This library provides an efficient way to store and retrieve\n///         RegisteredTransfers. This contract is used to manage the transfers\n///         stored by `TransferRegistry.sol`\nlibrary LibIterableMapping {\n    struct TransferDefinitionWithIndex {\n        RegisteredTransfer transfer;\n        uint256 index;\n    }\n\n    struct IterableMapping {\n        mapping(string => TransferDefinitionWithIndex) transfers;\n        string[] names;\n    }\n\n    function stringEqual(string memory s, string memory t)\n        internal\n        pure\n        returns (bool)\n    {\n        return keccak256(abi.encodePacked(s)) == keccak256(abi.encodePacked(t));\n    }\n\n    function isEmptyString(string memory s) internal pure returns (bool) {\n        return stringEqual(s, \"\");\n    }\n\n    function nameExists(IterableMapping storage self, string memory name)\n        internal\n        view\n        returns (bool)\n    {\n        return\n            !isEmptyString(name) &&\n            self.names.length != 0 &&\n            stringEqual(self.names[self.transfers[name].index], name);\n    }\n\n    function length(IterableMapping storage self)\n        internal\n        view\n        returns (uint256)\n    {\n        return self.names.length;\n    }\n\n    function getTransferDefinitionByName(\n        IterableMapping storage self,\n        string memory name\n    ) internal view returns (RegisteredTransfer memory) {\n        require(nameExists(self, name), \"LibIterableMapping: NAME_NOT_FOUND\");\n        return self.transfers[name].transfer;\n    }\n\n    function getTransferDefinitionByIndex(\n        IterableMapping storage self,\n        uint256 index\n    ) internal view returns (RegisteredTransfer memory) {\n        require(index < self.names.length, \"LibIterableMapping: INVALID_INDEX\");\n        return self.transfers[self.names[index]].transfer;\n    }\n\n    function getTransferDefinitions(IterableMapping storage self)\n        internal\n        view\n        returns (RegisteredTransfer[] memory)\n    {\n        uint256 l = self.names.length;\n        RegisteredTransfer[] memory transfers = new RegisteredTransfer[](l);\n        for (uint256 i = 0; i < l; i++) {\n            transfers[i] = self.transfers[self.names[i]].transfer;\n        }\n        return transfers;\n    }\n\n    function addTransferDefinition(\n        IterableMapping storage self,\n        RegisteredTransfer memory transfer\n    ) internal {\n        string memory name = transfer.name;\n        require(!isEmptyString(name), \"LibIterableMapping: EMPTY_NAME\");\n        require(!nameExists(self, name), \"LibIterableMapping: NAME_ALREADY_ADDED\");\n        self.transfers[name] = TransferDefinitionWithIndex({\n            transfer: transfer,\n            index: self.names.length\n        });\n        self.names.push(name);\n    }\n\n    function removeTransferDefinition(\n        IterableMapping storage self,\n        string memory name\n    ) internal {\n        require(!isEmptyString(name), \"LibIterableMapping: EMPTY_NAME\");\n        require(nameExists(self, name), \"LibIterableMapping: NAME_NOT_FOUND\");\n        uint256 index = self.transfers[name].index;\n        string memory lastName = self.names[self.names.length - 1];\n        self.transfers[lastName].index = index;\n        self.names[index] = lastName;\n        delete self.transfers[name];\n        self.names.pop();\n    }\n}\n"
    },
    "@openzeppelin/contracts/access/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor () {\n        address msgSender = _msgSender();\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(_owner, newOwner);\n        _owner = newOwner;\n    }\n}\n"
    },
    "src.sol/testing/TestLibIterableMapping.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/ITransferRegistry.sol\";\nimport \"../lib/LibIterableMapping.sol\";\n\n/// @title TestLibIterableMapping\n/// @author Layne Haber <layne@connext.network>\n/// @notice Used to easily test the internal methods of\n///         LibIterableMapping.sol by aliasing them to public\n///         methods.\ncontract TestLibIterableMapping {\n    using LibIterableMapping for LibIterableMapping.IterableMapping;\n\n    LibIterableMapping.IterableMapping data;\n\n    constructor() {}\n\n    function stringEqual(string memory s, string memory t)\n        public\n        pure\n        returns (bool)\n    {\n        return LibIterableMapping.stringEqual(s, t);\n    }\n\n    function isEmptyString(string memory s) public pure returns (bool) {\n        return LibIterableMapping.isEmptyString(s);\n    }\n\n    function nameExists(string memory name) public view returns (bool) {\n        return LibIterableMapping.nameExists(data, name);\n    }\n\n    function length() public view returns (uint256) {\n        return LibIterableMapping.length(data);\n    }\n\n    function getTransferDefinitionByName(string memory name)\n        public\n        view\n        returns (RegisteredTransfer memory)\n    {\n        return LibIterableMapping.getTransferDefinitionByName(data, name);\n    }\n\n    function getTransferDefinitionByIndex(uint256 index)\n        public\n        view\n        returns (RegisteredTransfer memory)\n    {\n        return LibIterableMapping.getTransferDefinitionByIndex(data, index);\n    }\n\n    function getTransferDefinitions()\n        public\n        view\n        returns (RegisteredTransfer[] memory)\n    {\n        return LibIterableMapping.getTransferDefinitions(data);\n    }\n\n    function addTransferDefinition(RegisteredTransfer memory transfer) public {\n        return LibIterableMapping.addTransferDefinition(data, transfer);\n    }\n\n    function removeTransferDefinition(string memory name) public {\n        return LibIterableMapping.removeTransferDefinition(data, name);\n    }\n}\n"
    },
    "src.sol/interfaces/ITestChannel.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./IVectorChannel.sol\";\nimport \"./Types.sol\";\n\ninterface ITestChannel is IVectorChannel {\n    function testMakeExitable(\n        address assetId,\n        address payable recipient,\n        uint256 maxAmount\n    ) external;\n\n    function testMakeBalanceExitable(\n        address assetId,\n        Balance memory balance\n    ) external;\n}\n"
    },
    "src.sol/testing/TestChannel.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental \"ABIEncoderV2\";\n\nimport \"../ChannelMastercopy.sol\";\nimport \"../interfaces/ITestChannel.sol\";\n\n/// @title TestChannel\n/// @author Layne Haber <layne@connext.network>\n/// @notice This contract will help test the `ChannelMastercopy` contract and\n///         the associated bits of functionality. This contract should *only*\n///         contain aliases to internal functions that should be unit-tested,\n///         like the `makeExitable` call on `CMCAsset.sol`. Using this\n///         contract will help reduce the amount of boilerplate needed to test\n///         component functionality. For example, `CMCAsset.sol` is only\n///         able to be tested via the adjudicator in many practical cases.\n///         Creating a helper function allows for easier testing of only\n///         that functionality.\n\ncontract TestChannel is ChannelMastercopy, ITestChannel {\n    function testMakeExitable(\n        address assetId,\n        address payable recipient,\n        uint256 maxAmount\n    ) public override {\n        makeExitable(assetId, recipient, maxAmount);\n    }\n\n    function testMakeBalanceExitable(\n        address assetId,\n        Balance memory balance\n    ) public override {\n        makeBalanceExitable(assetId, balance);\n    }\n}\n"
    },
    "src.sol/ChannelMastercopy.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./interfaces/IVectorChannel.sol\";\nimport \"./CMCCore.sol\";\nimport \"./CMCAsset.sol\";\nimport \"./CMCDeposit.sol\";\nimport \"./CMCWithdraw.sol\";\nimport \"./CMCAdjudicator.sol\";\n\n/// @title ChannelMastercopy\n/// @author Connext <support@connext.network>\n/// @notice Contains the logic used by all Vector multisigs. A proxy to this\n///         contract is deployed per-channel using the ChannelFactory.sol.\n///         Supports channel adjudication logic, deposit logic, and arbitrary\n///         calls when a commitment is double-signed.\ncontract ChannelMastercopy is\n    CMCCore,\n    CMCAsset,\n    CMCDeposit,\n    CMCWithdraw,\n    CMCAdjudicator,\n    IVectorChannel\n{\n\n}\n"
    },
    "src.sol/transferDefinitions/HashlockTransfer.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.7.1;\npragma experimental ABIEncoderV2;\n\nimport \"./TransferDefinition.sol\";\n\n/// @title HashlockTransfer\n/// @author Connext <support@connext.network>\n/// @notice This contract allows users to claim a payment locked in\n///         the application if they provide the correct preImage. The payment is\n///         reverted if not unlocked by the timelock if one is provided.\n\ncontract HashlockTransfer is TransferDefinition {\n    struct TransferState {\n        bytes32 lockHash;\n        uint256 expiry; // If 0, then no timelock is enforced\n    }\n\n    struct TransferResolver {\n        bytes32 preImage;\n    }\n\n    // Provide registry information\n    string public constant override Name = \"HashlockTransfer\";\n    string public constant override StateEncoding =\n        \"tuple(bytes32 lockHash, uint256 expiry)\";\n    string public constant override ResolverEncoding =\n        \"tuple(bytes32 preImage)\";\n\n    function EncodedCancel() external pure override returns(bytes memory) {\n      TransferResolver memory resolver;\n      resolver.preImage = bytes32(0);\n      return abi.encode(resolver);\n    } \n\n    function create(bytes calldata encodedBalance, bytes calldata encodedState)\n        external\n        view\n        override\n        returns (bool)\n    {\n        // Decode parameters\n        TransferState memory state = abi.decode(encodedState, (TransferState));\n        Balance memory balance = abi.decode(encodedBalance, (Balance));\n\n        require(\n            balance.amount[0] > 0,\n            \"HashlockTransfer: ZER0_SENDER_BALANCE\"\n        );\n\n        require(\n            balance.amount[1] == 0,\n            \"HashlockTransfer: NONZERO_RECIPIENT_BALANCE\"\n        );\n        require(\n            state.lockHash != bytes32(0),\n            \"HashlockTransfer: EMPTY_LOCKHASH\"\n        );\n        require(\n            state.expiry == 0 || state.expiry > block.timestamp,\n            \"HashlockTransfer: EXPIRED_TIMELOCK\"\n        );\n\n        // Valid transfer state\n        return true;\n    }\n\n    function resolve(\n        bytes calldata encodedBalance,\n        bytes calldata encodedState,\n        bytes calldata encodedResolver\n    ) external view override returns (Balance memory) {\n        TransferState memory state = abi.decode(encodedState, (TransferState));\n        TransferResolver memory resolver =\n            abi.decode(encodedResolver, (TransferResolver));\n        Balance memory balance = abi.decode(encodedBalance, (Balance));\n\n        // If you pass in bytes32(0), payment is canceled\n        // If timelock is nonzero and has expired, payment must be canceled\n        // otherwise resolve will revert\n        if (resolver.preImage != bytes32(0)) {\n            // Payment must not be expired\n            require(state.expiry == 0 || state.expiry > block.timestamp, \"HashlockTransfer: PAYMENT_EXPIRED\");\n\n            // Check hash for normal payment unlock\n            bytes32 generatedHash = sha256(abi.encode(resolver.preImage));\n            require(\n                state.lockHash == generatedHash,\n                \"HashlockTransfer: INVALID_PREIMAGE\"\n            );\n\n            // Update state\n            balance.amount[1] = balance.amount[0];\n            balance.amount[0] = 0;\n        }\n        // To cancel, the preImage must be empty (not simply incorrect)\n        // There are no additional state mutations, and the preImage is\n        // asserted by the `if` statement\n\n        return balance;\n    }\n}\n"
    },
    "src.sol/testing/FailingToken.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.1;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/* This token is ONLY useful for testing\n * Anybody can mint as many tokens as they like\n * Anybody can burn anyone else's tokens\n * Will fail to transfer ANY tokens\n */\ncontract FailingToken is ERC20 {\n    bool public transferShouldRevert;\n    bool public transferShouldFail;\n    bool public rejectEther;\n\n    constructor() ERC20(\"Failing Token\", \"FAIL\") {\n        transferShouldRevert = true;\n        _mint(msg.sender, 1000000 ether);\n    }\n\n    receive() external payable {\n        if (rejectEther) {\n            revert(\"ERC20: ETHER_REJECTED\");\n        }\n    }\n\n    function mint(address account, uint256 amount) external {\n        _mint(account, amount);\n    }\n\n    function burn(address account, uint256 amount) external {\n        _burn(account, amount);\n    }\n\n    function transfer(address recipient, uint256 amount)\n        public\n        override\n        returns (bool)\n    {\n        if (transferShouldRevert) {\n            revert(\"FAIL: Failing token\");\n        }\n        if (transferShouldFail) {\n            return false;\n        }\n        return super.transfer(recipient, amount);\n    }\n\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) public override returns (bool) {\n        if (transferShouldRevert) {\n            revert(\"FAIL: Failing token\");\n        }\n        if (transferShouldFail) {\n            return false;\n        }\n        return super.transferFrom(sender, recipient, amount);\n    }\n\n    function setTransferShouldRevert(bool _transferShouldRevert)\n        public\n        returns (bool)\n    {\n        transferShouldRevert = _transferShouldRevert;\n        return transferShouldRevert;\n    }\n\n    function setTransferShouldFail(bool _transferShouldFail)\n        public\n        returns (bool)\n    {\n        transferShouldFail = _transferShouldFail;\n        return transferShouldFail;\n    }\n\n    function setRejectEther(bool _rejectEther) public returns (bool) {\n        rejectEther = _rejectEther;\n        return rejectEther;\n    }\n\n    function succeedingTransfer(address recipient, uint256 amount)\n        public\n        returns (bool)\n    {\n        return super.transfer(recipient, amount);\n    }\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "storageLayout",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    },
    "metadata": {
      "useLiteralContent": true
    }
  }
}