{
  "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_masterAdmin",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_swapperAdder",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_swapperSetter",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_strategyAdder",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_tradesModifier",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_tradesSettler",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_mechanicsRegistry",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [],
      "name": "ExpiredTrade",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidDeadline",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidPermissions",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidSwapper",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidTrade",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "NotAsyncSwapper",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "NotAuthorized",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "NotSyncSwapper",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "OngoingTrade",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "SwapperInUse",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroAddress",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroAmount",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroRate",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroSlippage",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint256[]",
          "name": "_ids",
          "type": "uint256[]"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_rateTokenInToOut",
          "type": "uint256"
        }
      ],
      "name": "AsyncOTCTradesExecuted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        }
      ],
      "name": "AsyncStrategySwapperSet",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "_id",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_receivedAmount",
          "type": "uint256"
        }
      ],
      "name": "AsyncTradeExecuted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "_id",
          "type": "uint256"
        }
      ],
      "name": "AsyncTradeExpired",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "_firstTradeId",
          "type": "uint256"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "_secondTradeId",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_consumedFirstTrade",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_consumedSecondTrade",
          "type": "uint256"
        }
      ],
      "name": "AsyncTradesMatched",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "_to",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "DustSent",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "_otcPool",
          "type": "address"
        }
      ],
      "name": "OTCPoolSet",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "previousAdminRole",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "newAdminRole",
          "type": "bytes32"
        }
      ],
      "name": "RoleAdminChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        }
      ],
      "name": "RoleGranted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "account",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        }
      ],
      "name": "RoleRevoked",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "bytes1",
          "name": "_permissions",
          "type": "bytes1"
        }
      ],
      "name": "StrategyPermissionsSet",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_token",
          "type": "address"
        }
      ],
      "name": "SwapperAndTokenEnabled",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address[]",
          "name": "_swappers",
          "type": "address[]"
        }
      ],
      "name": "SwappersAdded",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address[]",
          "name": "_swapper",
          "type": "address[]"
        }
      ],
      "name": "SwappersRemoved",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        }
      ],
      "name": "SyncStrategySwapperSet",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_tokenIn",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_tokenOut",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_amountIn",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_maxSlippage",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "bytes",
          "name": "_data",
          "type": "bytes"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_receivedAmount",
          "type": "uint256"
        }
      ],
      "name": "SyncTradeExecuted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "_id",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_tokenIn",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_tokenOut",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_amountIn",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_maxSlippage",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "_deadline",
          "type": "uint256"
        }
      ],
      "name": "TradeCreated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256[]",
          "name": "_ids",
          "type": "uint256[]"
        }
      ],
      "name": "TradesCanceled",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "_anchorTrade",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256[]",
          "name": "_ids",
          "type": "uint256[]"
        }
      ],
      "name": "TradesMerged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint256[]",
          "name": "_ids",
          "type": "uint256[]"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_newSwapper",
          "type": "address"
        }
      ],
      "name": "TradesSwapperChanged",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "DEFAULT_ADMIN_ROLE",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "ETH_ADDRESS",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "MASTER_ADMIN",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "STRATEGY",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "STRATEGY_ADDER",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "SWAPPER_ADDER",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "SWAPPER_SETTER",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "TRADES_MODIFIER",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "TRADES_SETTLER",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address[]",
          "name": "__swappers",
          "type": "address[]"
        }
      ],
      "name": "addSwappers",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256[]",
          "name": "_ids",
          "type": "uint256[]"
        }
      ],
      "name": "cancelPendingTrades",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256[]",
          "name": "_ids",
          "type": "uint256[]"
        },
        {
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        }
      ],
      "name": "changePendingTradesSwapper",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_tokenIn",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_tokenOut",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amountIn",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_maxSlippage",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_deadline",
          "type": "uint256"
        }
      ],
      "name": "create",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "_id",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256[]",
          "name": "_ids",
          "type": "uint256[]"
        },
        {
          "internalType": "uint256",
          "name": "_rateTokenInToOut",
          "type": "uint256"
        }
      ],
      "name": "execute",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_id",
          "type": "uint256"
        },
        {
          "internalType": "bytes",
          "name": "_data",
          "type": "bytes"
        }
      ],
      "name": "execute",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "_receivedAmount",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_firstTradeId",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_secondTradeId",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_consumedFirstTrade",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_consumedSecondTrade",
          "type": "uint256"
        }
      ],
      "name": "execute",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "_receivedAmountAnchorTrade",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_receivedAmountAgainstTrade",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_tokenIn",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_tokenOut",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amountIn",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_maxSlippage",
          "type": "uint256"
        },
        {
          "internalType": "bytes",
          "name": "_data",
          "type": "bytes"
        }
      ],
      "name": "execute",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "_receivedAmount",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_id",
          "type": "uint256"
        }
      ],
      "name": "expire",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "_freedAmount",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        }
      ],
      "name": "getRoleAdmin",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        },
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        }
      ],
      "name": "grantRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        },
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        }
      ],
      "name": "hasRole",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_mechanic",
          "type": "address"
        }
      ],
      "name": "isMechanic",
      "outputs": [
        {
          "internalType": "bool",
          "name": "_isMechanic",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        }
      ],
      "name": "isSwapper",
      "outputs": [
        {
          "internalType": "bool",
          "name": "_isSwapper",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "mechanicsRegistry",
      "outputs": [
        {
          "internalType": "address",
          "name": "_mechanicRegistry",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_anchorTradeId",
          "type": "uint256"
        },
        {
          "internalType": "uint256[]",
          "name": "_toMergeIds",
          "type": "uint256[]"
        }
      ],
      "name": "mergePendingTrades",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "otcPool",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "name": "pendingTradesById",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "_id",
          "type": "uint256"
        },
        {
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_tokenIn",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_tokenOut",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amountIn",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_maxSlippage",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_deadline",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        }
      ],
      "name": "pendingTradesIds",
      "outputs": [
        {
          "internalType": "uint256[]",
          "name": "_pendingIds",
          "type": "uint256[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "pendingTradesIds",
      "outputs": [
        {
          "internalType": "uint256[]",
          "name": "_pendingIds",
          "type": "uint256[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address[]",
          "name": "__swappers",
          "type": "address[]"
        }
      ],
      "name": "removeSwappers",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        },
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        }
      ],
      "name": "renounceRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "role",
          "type": "bytes32"
        },
        {
          "internalType": "address",
          "name": "account",
          "type": "address"
        }
      ],
      "name": "revokeRole",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_to",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amount",
          "type": "uint256"
        }
      ],
      "name": "sendDust",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_mechanicsRegistry",
          "type": "address"
        }
      ],
      "name": "setMechanicsRegistry",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_otcPool",
          "type": "address"
        }
      ],
      "name": "setOTCPool",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        }
      ],
      "name": "setStrategyAsyncSwapper",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "internalType": "bytes1",
          "name": "_permissions",
          "type": "bytes1"
        }
      ],
      "name": "setStrategyPermissions",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_strategy",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        }
      ],
      "name": "setStrategySyncSwapper",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "name": "strategyAsyncSwapper",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "name": "strategyPermissions",
      "outputs": [
        {
          "internalType": "bytes1",
          "name": "",
          "type": "bytes1"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "name": "strategySyncSwapper",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes4",
          "name": "interfaceId",
          "type": "bytes4"
        }
      ],
      "name": "supportsInterface",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_swapper",
          "type": "address"
        }
      ],
      "name": "swapperStrategies",
      "outputs": [
        {
          "internalType": "address[]",
          "name": "_strategies",
          "type": "address[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "swappers",
      "outputs": [
        {
          "internalType": "address[]",
          "name": "_swappersList",
          "type": "address[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
  "receipt": {
    "to": null,
    "from": "0xB82193725471dC7bfaAB1a3AB93c7b42963F3265",
    "contractAddress": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
    "transactionIndex": 22,
    "gasUsed": "4230448",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736",
    "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
    "logs": [
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3"
        ],
        "data": "0x",
        "logIndex": 17,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3",
          "0x0000000000000000000000009f2a061d6fef20ad3a656e23fd9c814b75fd5803",
          "0x000000000000000000000000b82193725471dc7bfaab1a3ab93c7b42963f3265"
        ],
        "data": "0x",
        "logIndex": 18,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff",
          "0x038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd9",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3"
        ],
        "data": "0x",
        "logIndex": 19,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff",
          "0xe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b911",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3"
        ],
        "data": "0x",
        "logIndex": 20,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d",
          "0x038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd9",
          "0x0000000000000000000000009f2a061d6fef20ad3a656e23fd9c814b75fd5803",
          "0x000000000000000000000000b82193725471dc7bfaab1a3ab93c7b42963f3265"
        ],
        "data": "0x",
        "logIndex": 21,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d",
          "0xe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b911",
          "0x0000000000000000000000009f2a061d6fef20ad3a656e23fd9c814b75fd5803",
          "0x000000000000000000000000b82193725471dc7bfaab1a3ab93c7b42963f3265"
        ],
        "data": "0x",
        "logIndex": 22,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff",
          "0x49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f7",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0c98cf5b298d76683bff7ac7eb2544a1c5413c08c055cad5077796993f1b71e5"
        ],
        "data": "0x",
        "logIndex": 23,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff",
          "0x0c98cf5b298d76683bff7ac7eb2544a1c5413c08c055cad5077796993f1b71e5",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3"
        ],
        "data": "0x",
        "logIndex": 24,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d",
          "0x0c98cf5b298d76683bff7ac7eb2544a1c5413c08c055cad5077796993f1b71e5",
          "0x0000000000000000000000009f2a061d6fef20ad3a656e23fd9c814b75fd5803",
          "0x000000000000000000000000b82193725471dc7bfaab1a3ab93c7b42963f3265"
        ],
        "data": "0x",
        "logIndex": 25,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff",
          "0x1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3"
        ],
        "data": "0x",
        "logIndex": 26,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d",
          "0x1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c",
          "0x0000000000000000000000009f2a061d6fef20ad3a656e23fd9c814b75fd5803",
          "0x000000000000000000000000b82193725471dc7bfaab1a3ab93c7b42963f3265"
        ],
        "data": "0x",
        "logIndex": 27,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff",
          "0xf97fb9ac61687d33e6f167fb66bd0dbc2240a42d8369c39aadb26ea8ce05b5fe",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3"
        ],
        "data": "0x",
        "logIndex": 28,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      },
      {
        "transactionIndex": 22,
        "blockNumber": 16750317,
        "transactionHash": "0xf1235573fc84622005fffed610c3963c0c4b2107150672b56fa536d847482102",
        "address": "0x382ec4342775607ad64949bC26402b5F8CD651fe",
        "topics": [
          "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d",
          "0xf97fb9ac61687d33e6f167fb66bd0dbc2240a42d8369c39aadb26ea8ce05b5fe",
          "0x0000000000000000000000009f2a061d6fef20ad3a656e23fd9c814b75fd5803",
          "0x000000000000000000000000b82193725471dc7bfaab1a3ab93c7b42963f3265"
        ],
        "data": "0x",
        "logIndex": 29,
        "blockHash": "0x00008273000007b2cafe604a3db5a306967cc93bef698c8a156b9cc4a0954736"
      }
    ],
    "blockNumber": 16750317,
    "cumulativeGasUsed": "6652099",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0x9f2A061d6fEF20ad3A656e23fd9C814b75fd5803",
    "0x9f2A061d6fEF20ad3A656e23fd9C814b75fd5803",
    "0x9f2A061d6fEF20ad3A656e23fd9C814b75fd5803",
    "0x9f2A061d6fEF20ad3A656e23fd9C814b75fd5803",
    "0x9f2A061d6fEF20ad3A656e23fd9C814b75fd5803",
    "0x9f2A061d6fEF20ad3A656e23fd9C814b75fd5803",
    "0x7f462B92F92114A2D57A03e5Ae2DB5DA28b77d73"
  ],
  "solcInputHash": "103fe0381f2366411e44059448d5f613",
  "metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_masterAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_swapperAdder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_swapperSetter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_strategyAdder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tradesModifier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tradesSettler\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_mechanicsRegistry\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredTrade\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeadline\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPermissions\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSwapper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrade\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAsyncSwapper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotSyncSwapper\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OngoingTrade\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SwapperInUse\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroRate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroSlippage\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_rateTokenInToOut\",\"type\":\"uint256\"}],\"name\":\"AsyncOTCTradesExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"}],\"name\":\"AsyncStrategySwapperSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_receivedAmount\",\"type\":\"uint256\"}],\"name\":\"AsyncTradeExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"AsyncTradeExpired\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_firstTradeId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_secondTradeId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_consumedFirstTrade\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_consumedSecondTrade\",\"type\":\"uint256\"}],\"name\":\"AsyncTradesMatched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DustSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_otcPool\",\"type\":\"address\"}],\"name\":\"OTCPoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes1\",\"name\":\"_permissions\",\"type\":\"bytes1\"}],\"name\":\"StrategyPermissionsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"SwapperAndTokenEnabled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"_swappers\",\"type\":\"address[]\"}],\"name\":\"SwappersAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"_swapper\",\"type\":\"address[]\"}],\"name\":\"SwappersRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"}],\"name\":\"SyncStrategySwapperSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_tokenIn\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxSlippage\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_receivedAmount\",\"type\":\"uint256\"}],\"name\":\"SyncTradeExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_tokenIn\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_tokenOut\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amountIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_maxSlippage\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"}],\"name\":\"TradeCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"TradesCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_anchorTrade\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"TradesMerged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newSwapper\",\"type\":\"address\"}],\"name\":\"TradesSwapperChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ETH_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MASTER_ADMIN\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STRATEGY\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STRATEGY_ADDER\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SWAPPER_ADDER\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SWAPPER_SETTER\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TRADES_MODIFIER\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TRADES_SETTLER\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"__swappers\",\"type\":\"address[]\"}],\"name\":\"addSwappers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"cancelPendingTrades\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"}],\"name\":\"changePendingTradesSwapper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxSlippage\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"}],\"name\":\"create\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"_rateTokenInToOut\",\"type\":\"uint256\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_firstTradeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_secondTradeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_consumedFirstTrade\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_consumedSecondTrade\",\"type\":\"uint256\"}],\"name\":\"execute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_receivedAmountAnchorTrade\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_receivedAmountAgainstTrade\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxSlippage\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_receivedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"expire\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_freedAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_mechanic\",\"type\":\"address\"}],\"name\":\"isMechanic\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isMechanic\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"}],\"name\":\"isSwapper\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"_isSwapper\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mechanicsRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"_mechanicRegistry\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_anchorTradeId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_toMergeIds\",\"type\":\"uint256[]\"}],\"name\":\"mergePendingTrades\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"otcPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"pendingTradesById\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenIn\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_tokenOut\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxSlippage\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"}],\"name\":\"pendingTradesIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_pendingIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingTradesIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_pendingIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"__swappers\",\"type\":\"address[]\"}],\"name\":\"removeSwappers\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"sendDust\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_mechanicsRegistry\",\"type\":\"address\"}],\"name\":\"setMechanicsRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_otcPool\",\"type\":\"address\"}],\"name\":\"setOTCPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"}],\"name\":\"setStrategyAsyncSwapper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"internalType\":\"bytes1\",\"name\":\"_permissions\",\"type\":\"bytes1\"}],\"name\":\"setStrategyPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_strategy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"}],\"name\":\"setStrategySyncSwapper\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"strategyAsyncSwapper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"strategyPermissions\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"\",\"type\":\"bytes1\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"strategySyncSwapper\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_swapper\",\"type\":\"address\"}],\"name\":\"swapperStrategies\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_strategies\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"swappers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"_swappersList\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"grantRole(bytes32,address)\":{\"details\":\"Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role.\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`.\"},\"revokeRole(bytes32,address)\":{\"details\":\"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TradeFactory/TradeFactory.sol\":\"TradeFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":9999},\"remappings\":[]},\"sources\":{\"@lbertenasco/contract-utils/contracts/utils/CollectableDust.sol\":{\"content\":\"\\n// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.4;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport '../../interfaces/utils/ICollectableDust.sol';\\n\\nabstract\\ncontract CollectableDust is ICollectableDust {\\n  using SafeERC20 for IERC20;\\n  using EnumerableSet for EnumerableSet.AddressSet;\\n\\n  address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n  EnumerableSet.AddressSet internal protocolTokens;\\n\\n  constructor() {}\\n\\n  function _addProtocolToken(address _token) internal {\\n    require(!protocolTokens.contains(_token), 'collectable-dust/token-is-part-of-the-protocol');\\n    protocolTokens.add(_token);\\n  }\\n\\n  function _removeProtocolToken(address _token) internal {\\n    require(protocolTokens.contains(_token), 'collectable-dust/token-not-part-of-the-protocol');\\n    protocolTokens.remove(_token);\\n  }\\n\\n  function _sendDust(\\n    address _to,\\n    address _token,\\n    uint256 _amount\\n  ) internal {\\n    require(_to != address(0), 'collectable-dust/cant-send-dust-to-zero-address');\\n    require(!protocolTokens.contains(_token), 'collectable-dust/token-is-part-of-the-protocol');\\n    if (_token == ETH_ADDRESS) {\\n      payable(_to).transfer(_amount);\\n    } else {\\n      IERC20(_token).safeTransfer(_to, _amount);\\n    }\\n    emit DustSent(_to, _token, _amount);\\n  }\\n}\\n\",\"keccak256\":\"0xea815f8af6516d2d83d12d5a9bd70f798b38578ed94924a2eb0943a0f93e7803\",\"license\":\"MIT\"},\"@lbertenasco/contract-utils/contracts/utils/Governable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.4;\\n\\nimport '../../interfaces/utils/IGovernable.sol';\\n\\ncontract Governable is IGovernable {\\n  address public override governor;\\n  address public override pendingGovernor;\\n\\n  constructor(address _governor) {\\n    require(_governor != address(0), 'governable/governor-should-not-be-zero-address');\\n    governor = _governor;\\n  }\\n\\n  function setPendingGovernor(address _pendingGovernor) external virtual override onlyGovernor {\\n    _setPendingGovernor(_pendingGovernor);\\n  }\\n\\n  function acceptGovernor() external virtual override onlyPendingGovernor {\\n    _acceptGovernor();\\n  }\\n\\n  function _setPendingGovernor(address _pendingGovernor) internal {\\n    require(_pendingGovernor != address(0), 'governable/pending-governor-should-not-be-zero-addres');\\n    pendingGovernor = _pendingGovernor;\\n    emit PendingGovernorSet(_pendingGovernor);\\n  }\\n\\n  function _acceptGovernor() internal {\\n    governor = pendingGovernor;\\n    pendingGovernor = address(0);\\n    emit GovernorAccepted();\\n  }\\n\\n  function isGovernor(address _account) public view override returns (bool _isGovernor) {\\n    return _account == governor;\\n  }\\n\\n  modifier onlyGovernor {\\n    require(isGovernor(msg.sender), 'governable/only-governor');\\n    _;\\n  }\\n\\n  modifier onlyPendingGovernor {\\n    require(msg.sender == pendingGovernor, 'governable/only-pending-governor');\\n    _;\\n  }\\n}\\n\",\"keccak256\":\"0x793f77e9f581d63c8a6e7f64cabef9d10844fce8e7f61a39201664f194d8bdbc\",\"license\":\"MIT\"},\"@lbertenasco/contract-utils/contracts/utils/Machinery.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport '../../interfaces/utils/IMachinery.sol';\\nimport '../../interfaces/mechanics/IMechanicsRegistry.sol';\\n\\ncontract Machinery is IMachinery {\\n  using EnumerableSet for EnumerableSet.AddressSet;\\n\\n  IMechanicsRegistry internal _mechanicsRegistry;\\n\\n  constructor(address __mechanicsRegistry) {\\n    _setMechanicsRegistry(__mechanicsRegistry);\\n  }\\n\\n  modifier onlyMechanic {\\n    require(_mechanicsRegistry.isMechanic(msg.sender), 'Machinery: not mechanic');\\n    _;\\n  }\\n\\n  function setMechanicsRegistry(address __mechanicsRegistry) external virtual override {\\n    _setMechanicsRegistry(__mechanicsRegistry);\\n  }\\n\\n  function _setMechanicsRegistry(address __mechanicsRegistry) internal {\\n    _mechanicsRegistry = IMechanicsRegistry(__mechanicsRegistry);\\n  }\\n\\n  // View helpers\\n  function mechanicsRegistry() external view override returns (address _mechanicRegistry) {\\n    return address(_mechanicsRegistry);\\n  }\\n\\n  function isMechanic(address _mechanic) public view override returns (bool _isMechanic) {\\n    return _mechanicsRegistry.isMechanic(_mechanic);\\n  }\\n\\n}\\n\",\"keccak256\":\"0xa24e42137dce45e51a72dfde5bfd4f44abb1d1b9a90cbab43b545c3233c8d86d\",\"license\":\"MIT\"},\"@lbertenasco/contract-utils/interfaces/mechanics/IMechanicsRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.4;\\n\\ninterface IMechanicsRegistry {\\n    event MechanicAdded(address _mechanic);\\n    event MechanicRemoved(address _mechanic);\\n\\n    function addMechanic(address _mechanic) external;\\n\\n    function removeMechanic(address _mechanic) external;\\n\\n    function mechanics() external view returns (address[] memory _mechanicsList);\\n\\n    function isMechanic(address mechanic) external view returns (bool _isMechanic);\\n\\n}\\n\",\"keccak256\":\"0x6d32691d648433e6739a46f156f279c1e43b9b09432d6feb07fd1b9db04c85d1\",\"license\":\"MIT\"},\"@lbertenasco/contract-utils/interfaces/utils/ICollectableDust.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.4;\\n\\ninterface ICollectableDust {\\n  event DustSent(address _to, address token, uint256 amount);\\n\\n  function sendDust(address _to, address _token, uint256 _amount) external;\\n}\\n\",\"keccak256\":\"0xbc17399974d1bf723ee94625274454ed028f209e18e2978f3531d12a5a08a10f\",\"license\":\"MIT\"},\"@lbertenasco/contract-utils/interfaces/utils/IGovernable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.4;\\n\\ninterface IGovernable {\\n  event PendingGovernorSet(address pendingGovernor);\\n  event GovernorAccepted();\\n\\n  function setPendingGovernor(address _pendingGovernor) external;\\n  function acceptGovernor() external;\\n\\n  function governor() external view returns (address _governor);\\n  function pendingGovernor() external view returns (address _pendingGovernor);\\n\\n  function isGovernor(address _account) external view returns (bool _isGovernor);\\n}\\n\",\"keccak256\":\"0xb28881a80a14bd691ef413aea97d65a2a3d4b9a690403c57223d0f56b5656e4e\",\"license\":\"MIT\"},\"@lbertenasco/contract-utils/interfaces/utils/IMachinery.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.4;\\n\\ninterface IMachinery {\\n    // View helpers\\n    function mechanicsRegistry() external view returns (address _mechanicsRegistry);\\n    function isMechanic(address mechanic) external view returns (bool _isMechanic);\\n\\n    // Setters\\n    function setMechanicsRegistry(address _mechanicsRegistry) external;\\n\\n}\\n\",\"keccak256\":\"0xa5dd7e40d7414cd417bbd7841b9b4c1a83122bfdf7d961430b49af1b39981003\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n *     require(hasRole(MY_ROLE, msg.sender));\\n *     ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n    struct RoleData {\\n        mapping(address => bool) members;\\n        bytes32 adminRole;\\n    }\\n\\n    mapping(bytes32 => RoleData) private _roles;\\n\\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n    /**\\n     * @dev Modifier that checks that an account has a specific role. Reverts\\n     * with a standardized message including the required role.\\n     *\\n     * The format of the revert reason is given by the following regular expression:\\n     *\\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n     *\\n     * _Available since v4.1._\\n     */\\n    modifier onlyRole(bytes32 role) {\\n        _checkRole(role, _msgSender());\\n        _;\\n    }\\n\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n    }\\n\\n    /**\\n     * @dev Returns `true` if `account` has been granted `role`.\\n     */\\n    function hasRole(bytes32 role, address account) public view override returns (bool) {\\n        return _roles[role].members[account];\\n    }\\n\\n    /**\\n     * @dev Revert with a standard message if `account` is missing `role`.\\n     *\\n     * The format of the revert reason is given by the following regular expression:\\n     *\\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n     */\\n    function _checkRole(bytes32 role, address account) internal view {\\n        if (!hasRole(role, account)) {\\n            revert(\\n                string(\\n                    abi.encodePacked(\\n                        \\\"AccessControl: account \\\",\\n                        Strings.toHexString(uint160(account), 20),\\n                        \\\" is missing role \\\",\\n                        Strings.toHexString(uint256(role), 32)\\n                    )\\n                )\\n            );\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\\n     * {revokeRole}.\\n     *\\n     * To change a role's admin, use {_setRoleAdmin}.\\n     */\\n    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n        return _roles[role].adminRole;\\n    }\\n\\n    /**\\n     * @dev Grants `role` to `account`.\\n     *\\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n        _grantRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Revokes `role` from `account`.\\n     *\\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n        _revokeRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Revokes `role` from the calling account.\\n     *\\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n     * purpose is to provide a mechanism for accounts to lose their privileges\\n     * if they are compromised (such as when a trusted device is misplaced).\\n     *\\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be `account`.\\n     */\\n    function renounceRole(bytes32 role, address account) public virtual override {\\n        require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n        _revokeRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Grants `role` to `account`.\\n     *\\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\\n     * event. Note that unlike {grantRole}, this function doesn't perform any\\n     * checks on the calling account.\\n     *\\n     * [WARNING]\\n     * ====\\n     * This function should only be called from the constructor when setting\\n     * up the initial roles for the system.\\n     *\\n     * Using this function in any other way is effectively circumventing the admin\\n     * system imposed by {AccessControl}.\\n     * ====\\n     */\\n    function _setupRole(bytes32 role, address account) internal virtual {\\n        _grantRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Sets `adminRole` as ``role``'s admin role.\\n     *\\n     * Emits a {RoleAdminChanged} event.\\n     */\\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n        bytes32 previousAdminRole = getRoleAdmin(role);\\n        _roles[role].adminRole = adminRole;\\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n    }\\n\\n    function _grantRole(bytes32 role, address account) private {\\n        if (!hasRole(role, account)) {\\n            _roles[role].members[account] = true;\\n            emit RoleGranted(role, account, _msgSender());\\n        }\\n    }\\n\\n    function _revokeRole(bytes32 role, address account) private {\\n        if (hasRole(role, account)) {\\n            _roles[role].members[account] = false;\\n            emit RoleRevoked(role, account, _msgSender());\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n    /**\\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n     *\\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n     * {RoleAdminChanged} not being emitted signaling this.\\n     *\\n     * _Available since v3.1._\\n     */\\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n    /**\\n     * @dev Emitted when `account` is granted `role`.\\n     *\\n     * `sender` is the account that originated the contract call, an admin role\\n     * bearer except when using {AccessControl-_setupRole}.\\n     */\\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n    /**\\n     * @dev Emitted when `account` is revoked `role`.\\n     *\\n     * `sender` is the account that originated the contract call:\\n     *   - if using `revokeRole`, it is the admin role bearer\\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n     */\\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n    /**\\n     * @dev Returns `true` if `account` has been granted `role`.\\n     */\\n    function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n    /**\\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\\n     * {revokeRole}.\\n     *\\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n     */\\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n    /**\\n     * @dev Grants `role` to `account`.\\n     *\\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function grantRole(bytes32 role, address account) external;\\n\\n    /**\\n     * @dev Revokes `role` from `account`.\\n     *\\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function revokeRole(bytes32 role, address account) external;\\n\\n    /**\\n     * @dev Revokes `role` from the calling account.\\n     *\\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n     * purpose is to provide a mechanism for accounts to lose their privileges\\n     * if they are compromised (such as when a trusted device is misplaced).\\n     *\\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be `account`.\\n     */\\n    function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.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(\\n        address sender,\\n        address recipient,\\n        uint256 amount\\n    ) 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\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the symbol of the token.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the decimals places of the token.\\n     */\\n    function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n    using Address for address;\\n\\n    function safeTransfer(\\n        IERC20 token,\\n        address to,\\n        uint256 value\\n    ) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n    }\\n\\n    function safeTransferFrom(\\n        IERC20 token,\\n        address from,\\n        address to,\\n        uint256 value\\n    ) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n    }\\n\\n    /**\\n     * @dev Deprecated. This function has issues similar to the ones found in\\n     * {IERC20-approve}, and its usage is discouraged.\\n     *\\n     * Whenever possible, use {safeIncreaseAllowance} and\\n     * {safeDecreaseAllowance} instead.\\n     */\\n    function safeApprove(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        // safeApprove should only be called when setting an initial allowance,\\n        // or when resetting it to zero. To increase and decrease it, use\\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n        require(\\n            (value == 0) || (token.allowance(address(this), spender) == 0),\\n            \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n        );\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n    }\\n\\n    function safeIncreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n    }\\n\\n    function safeDecreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        unchecked {\\n            uint256 oldAllowance = token.allowance(address(this), spender);\\n            require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n            uint256 newAllowance = oldAllowance - value;\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n        }\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     */\\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n        // the target address contains contract code and also asserts for success in the low-level call.\\n\\n        bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n        if (returndata.length > 0) {\\n            // Return data is optional\\n            require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.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        // This method relies on extcodesize, which returns 0 for contracts in\\n        // construction, since the code is only stored at the end of the\\n        // constructor execution.\\n\\n        uint256 size;\\n        assembly {\\n            size := extcodesize(account)\\n        }\\n        return size > 0;\\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        (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(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) 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(\\n        address target,\\n        bytes memory data,\\n        uint256 value\\n    ) 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(\\n        address target,\\n        bytes memory data,\\n        uint256 value,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason using the provided one.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function verifyCallResult(\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal pure returns (bytes memory) {\\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                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\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.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 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) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n    bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n     */\\n    function toString(uint256 value) internal pure returns (string memory) {\\n        // Inspired by OraclizeAPI's implementation - MIT licence\\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n        if (value == 0) {\\n            return \\\"0\\\";\\n        }\\n        uint256 temp = value;\\n        uint256 digits;\\n        while (temp != 0) {\\n            digits++;\\n            temp /= 10;\\n        }\\n        bytes memory buffer = new bytes(digits);\\n        while (value != 0) {\\n            digits -= 1;\\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n            value /= 10;\\n        }\\n        return string(buffer);\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(uint256 value) internal pure returns (string memory) {\\n        if (value == 0) {\\n            return \\\"0x00\\\";\\n        }\\n        uint256 temp = value;\\n        uint256 length = 0;\\n        while (temp != 0) {\\n            length++;\\n            temp >>= 8;\\n        }\\n        return toHexString(value, length);\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n     */\\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n        bytes memory buffer = new bytes(2 * length + 2);\\n        buffer[0] = \\\"0\\\";\\n        buffer[1] = \\\"x\\\";\\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n            value >>= 4;\\n        }\\n        require(value == 0, \\\"Strings: hex length insufficient\\\");\\n        return string(buffer);\\n    }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n    /**\\n     * @dev See {IERC165-supportsInterface}.\\n     */\\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n        return interfaceId == type(IERC165).interfaceId;\\n    }\\n}\\n\",\"keccak256\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.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.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds up instead\\n     * of rounding down.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b - 1) / b can overflow on addition, so we distribute.\\n        return a / b + (a % b == 0 ? 0 : 1);\\n    }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n *     // Declare a set state variable\\n *     EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n    // To implement this library for multiple types with as little code\\n    // repetition as possible, we write it in terms of a generic Set type with\\n    // bytes32 values.\\n    // The Set implementation uses private functions, and user-facing\\n    // implementations (such as AddressSet) are just wrappers around the\\n    // underlying Set.\\n    // This means that we can only create new EnumerableSets for types that fit\\n    // in bytes32.\\n\\n    struct Set {\\n        // Storage of set values\\n        bytes32[] _values;\\n        // Position of the value in the `values` array, plus 1 because index 0\\n        // means a value is not in the set.\\n        mapping(bytes32 => uint256) _indexes;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function _add(Set storage set, bytes32 value) private returns (bool) {\\n        if (!_contains(set, value)) {\\n            set._values.push(value);\\n            // The value is stored at length-1, but we add 1 to all indexes\\n            // and use 0 as a sentinel value\\n            set._indexes[value] = set._values.length;\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\\n        // We read and store the value's index to prevent multiple reads from the same storage slot\\n        uint256 valueIndex = set._indexes[value];\\n\\n        if (valueIndex != 0) {\\n            // Equivalent to contains(set, value)\\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\\n            // This modifies the order of the array, as noted in {at}.\\n\\n            uint256 toDeleteIndex = valueIndex - 1;\\n            uint256 lastIndex = set._values.length - 1;\\n\\n            if (lastIndex != toDeleteIndex) {\\n                bytes32 lastvalue = set._values[lastIndex];\\n\\n                // Move the last value to the index where the value to delete is\\n                set._values[toDeleteIndex] = lastvalue;\\n                // Update the index for the moved value\\n                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n            }\\n\\n            // Delete the slot where the moved value was stored\\n            set._values.pop();\\n\\n            // Delete the index for the deleted slot\\n            delete set._indexes[value];\\n\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n        return set._indexes[value] != 0;\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function _length(Set storage set) private view returns (uint256) {\\n        return set._values.length;\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n        return set._values[index];\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function _values(Set storage set) private view returns (bytes32[] memory) {\\n        return set._values;\\n    }\\n\\n    // Bytes32Set\\n\\n    struct Bytes32Set {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _add(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _remove(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n        return _contains(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(Bytes32Set storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n        return _at(set._inner, index);\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n        return _values(set._inner);\\n    }\\n\\n    // AddressSet\\n\\n    struct AddressSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(AddressSet storage set, address value) internal returns (bool) {\\n        return _add(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(AddressSet storage set, address value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(AddressSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n        return address(uint160(uint256(_at(set._inner, index))));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(AddressSet storage set) internal view returns (address[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        address[] memory result;\\n\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // UintSet\\n\\n    struct UintSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _add(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function length(UintSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n        return uint256(_at(set._inner, index));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        uint256[] memory result;\\n\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/OTCPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nimport '@lbertenasco/contract-utils/contracts/utils/Governable.sol';\\nimport '@lbertenasco/contract-utils/contracts/utils/CollectableDust.sol';\\n\\nimport './libraries/CommonErrors.sol';\\n\\ninterface IOTCPool is IGovernable {\\n  event TradeFactorySet(address indexed _tradeFactory);\\n\\n  event OfferCreate(address indexed _offeredToken, uint256 _amount);\\n\\n  event OfferTaken(address indexed _wantedToken, uint256 _amount, address _receiver);\\n\\n  function tradeFactory() external view returns (address);\\n\\n  function offers(address) external view returns (uint256);\\n\\n  function setTradeFactory(address _tradeFactory) external;\\n\\n  function create(address _offeredToken, uint256 _amount) external;\\n\\n  function take(\\n    address _wantedToken,\\n    uint256 _amount,\\n    address _receiver\\n  ) external;\\n}\\n\\ncontract OTCPool is IOTCPool, CollectableDust, Governable {\\n  using SafeERC20 for IERC20;\\n\\n  address public override tradeFactory;\\n\\n  mapping(address => uint256) public override offers;\\n\\n  constructor(address _governor, address _tradeFactory) Governable(_governor) {\\n    if (_tradeFactory == address(0)) revert CommonErrors.ZeroAddress();\\n    tradeFactory = _tradeFactory;\\n  }\\n\\n  modifier onlyTradeFactory() {\\n    if (msg.sender != tradeFactory) revert CommonErrors.NotAuthorized();\\n    _;\\n  }\\n\\n  function setTradeFactory(address _tradeFactory) external override onlyGovernor {\\n    if (_tradeFactory == address(0)) revert CommonErrors.ZeroAddress();\\n    tradeFactory = _tradeFactory;\\n    emit TradeFactorySet(_tradeFactory);\\n  }\\n\\n  function create(address _offeredToken, uint256 _amount) external override onlyGovernor {\\n    if (_offeredToken == address(0)) revert CommonErrors.ZeroAddress();\\n    if (_amount == 0) revert CommonErrors.ZeroAmount();\\n    if (IERC20(_offeredToken).allowance(governor, address(this)) < offers[_offeredToken]) revert CommonErrors.NotAuthorized();\\n    offers[_offeredToken] += _amount;\\n    emit OfferCreate(_offeredToken, _amount);\\n  }\\n\\n  function take(\\n    address _wantedToken,\\n    uint256 _amount,\\n    address _receiver\\n  ) external override onlyTradeFactory {\\n    // No checks more than permission are made, since every argument should be already valid\\n    IERC20(_wantedToken).safeTransferFrom(governor, _receiver, _amount);\\n    offers[_wantedToken] -= _amount;\\n    emit OfferTaken(_wantedToken, _amount, _receiver);\\n  }\\n\\n  // CollectableDust\\n  function sendDust(\\n    address _to,\\n    address _token,\\n    uint256 _amount\\n  ) external override onlyGovernor {\\n    _sendDust(_to, _token, _amount);\\n  }\\n}\\n\",\"keccak256\":\"0x31f2595a25da208d84cd82cb8bdb6b61d799b7f9d615009c0e2612b5be606197\",\"license\":\"MIT\"},\"contracts/Swapper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/token/ERC20/IERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\n\\nimport '@lbertenasco/contract-utils/contracts/utils/Governable.sol';\\nimport '@lbertenasco/contract-utils/contracts/utils/CollectableDust.sol';\\n\\nimport './libraries/CommonErrors.sol';\\n\\ninterface ISwapper {\\n  enum SwapperType {\\n    ASYNC,\\n    SYNC\\n  }\\n\\n  event Swapped(\\n    address _receiver,\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    uint256 _receivedAmount,\\n    bytes _data\\n  );\\n\\n  // solhint-disable-next-line func-name-mixedcase\\n  function SLIPPAGE_PRECISION() external view returns (uint256);\\n\\n  // solhint-disable-next-line func-name-mixedcase\\n  function TRADE_FACTORY() external view returns (address);\\n\\n  // solhint-disable-next-line func-name-mixedcase\\n  function SWAPPER_TYPE() external view returns (SwapperType);\\n\\n  function swap(\\n    address _receiver,\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    bytes calldata _data\\n  ) external returns (uint256 _receivedAmount);\\n}\\n\\nabstract contract Swapper is ISwapper, Governable, CollectableDust {\\n  using SafeERC20 for IERC20;\\n\\n  // solhint-disable-next-line var-name-mixedcase\\n  uint256 public immutable override SLIPPAGE_PRECISION = 10000; // 1 is 0.0001%, 1_000 is 0.1%\\n\\n  // solhint-disable-next-line var-name-mixedcase\\n  address public immutable override TRADE_FACTORY;\\n\\n  constructor(address _governor, address _tradeFactory) Governable(_governor) {\\n    if (_tradeFactory == address(0)) revert CommonErrors.ZeroAddress();\\n    TRADE_FACTORY = _tradeFactory;\\n  }\\n\\n  modifier onlyTradeFactory() {\\n    if (msg.sender != TRADE_FACTORY) revert CommonErrors.NotAuthorized();\\n    _;\\n  }\\n\\n  function _assertPreSwap(\\n    address _receiver,\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage\\n  ) internal pure {\\n    if (_receiver == address(0) || _tokenIn == address(0) || _tokenOut == address(0)) revert CommonErrors.ZeroAddress();\\n    if (_amountIn == 0) revert CommonErrors.ZeroAmount();\\n    if (_maxSlippage == 0) revert CommonErrors.ZeroSlippage();\\n  }\\n\\n  function _executeSwap(\\n    address _receiver,\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    bytes calldata _data\\n  ) internal virtual returns (uint256 _receivedAmount);\\n\\n  function swap(\\n    address _receiver,\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    bytes calldata _data\\n  ) external virtual override onlyTradeFactory returns (uint256 _receivedAmount) {\\n    _assertPreSwap(_receiver, _tokenIn, _tokenOut, _amountIn, _maxSlippage);\\n    _receivedAmount = _executeSwap(_receiver, _tokenIn, _tokenOut, _amountIn, _maxSlippage, _data);\\n    emit Swapped(_receiver, _tokenIn, _tokenOut, _amountIn, _maxSlippage, _receivedAmount, _data);\\n  }\\n\\n  function sendDust(\\n    address _to,\\n    address _token,\\n    uint256 _amount\\n  ) external virtual override onlyGovernor {\\n    _sendDust(_to, _token, _amount);\\n  }\\n}\\n\",\"keccak256\":\"0x49f5d7e5da69408e559d92d361e480ba6880efdc2d738727b4951ffc2b319f54\",\"license\":\"MIT\"},\"contracts/TradeFactory/TradeFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@lbertenasco/contract-utils/contracts/utils/CollectableDust.sol';\\n\\nimport './TradeFactoryPositionsHandler.sol';\\nimport './TradeFactoryExecutor.sol';\\n\\ninterface ITradeFactory is ITradeFactoryExecutor, ITradeFactoryPositionsHandler {}\\n\\ncontract TradeFactory is TradeFactoryExecutor, CollectableDust, ITradeFactory {\\n  constructor(\\n    address _masterAdmin,\\n    address _swapperAdder,\\n    address _swapperSetter,\\n    address _strategyAdder,\\n    address _tradesModifier,\\n    address _tradesSettler,\\n    address _mechanicsRegistry\\n  )\\n    TradeFactoryAccessManager(_masterAdmin)\\n    TradeFactoryPositionsHandler(_strategyAdder, _tradesModifier)\\n    TradeFactorySwapperHandler(_swapperAdder, _swapperSetter)\\n    TradeFactoryExecutor(_tradesSettler, _mechanicsRegistry)\\n  {}\\n\\n  // Collectable Dust\\n  function sendDust(\\n    address _to,\\n    address _token,\\n    uint256 _amount\\n  ) external virtual override onlyRole(MASTER_ADMIN) {\\n    _sendDust(_to, _token, _amount);\\n  }\\n}\\n\",\"keccak256\":\"0x654d4ff307b074a1587b6ae6f1e909188319bb1bb14c0300bb0860f627cf622a\",\"license\":\"MIT\"},\"contracts/TradeFactory/TradeFactoryAccessManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/access/AccessControl.sol';\\n\\nimport '../libraries/CommonErrors.sol';\\n\\nabstract contract TradeFactoryAccessManager is AccessControl {\\n  bytes32 public constant MASTER_ADMIN = keccak256('MASTER_ADMIN');\\n\\n  constructor(address _masterAdmin) {\\n    if (_masterAdmin == address(0)) revert CommonErrors.ZeroAddress();\\n    _setRoleAdmin(MASTER_ADMIN, MASTER_ADMIN);\\n    _setupRole(MASTER_ADMIN, _masterAdmin);\\n  }\\n}\\n\",\"keccak256\":\"0x34761ece86a466e001258147434828b501846c7ea721ba8e8401a88b797bfe81\",\"license\":\"MIT\"},\"contracts/TradeFactory/TradeFactoryExecutor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/math/Math.sol';\\nimport '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\\nimport '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\n\\nimport '@lbertenasco/contract-utils/contracts/utils/Machinery.sol';\\n\\nimport '../OTCPool.sol';\\n\\nimport './TradeFactoryPositionsHandler.sol';\\n\\ninterface ITradeFactoryExecutor {\\n  event SyncTradeExecuted(\\n    address indexed _strategy,\\n    address indexed _swapper,\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    bytes _data,\\n    uint256 _receivedAmount\\n  );\\n\\n  event AsyncTradeExecuted(uint256 indexed _id, uint256 _receivedAmount);\\n\\n  event AsyncTradesMatched(\\n    uint256 indexed _firstTradeId,\\n    uint256 indexed _secondTradeId,\\n    uint256 _consumedFirstTrade,\\n    uint256 _consumedSecondTrade\\n  );\\n\\n  event AsyncOTCTradesExecuted(uint256[] _ids, uint256 _rateTokenInToOut);\\n\\n  event AsyncTradeExpired(uint256 indexed _id);\\n\\n  event SwapperAndTokenEnabled(address indexed _swapper, address _token);\\n\\n  error OngoingTrade();\\n\\n  error ExpiredTrade();\\n\\n  error ZeroRate();\\n\\n  function execute(\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    bytes calldata _data\\n  ) external returns (uint256 _receivedAmount);\\n\\n  function execute(uint256 _id, bytes calldata _data) external returns (uint256 _receivedAmount);\\n\\n  function expire(uint256 _id) external returns (uint256 _freedAmount);\\n}\\n\\nabstract contract TradeFactoryExecutor is ITradeFactoryExecutor, TradeFactoryPositionsHandler, Machinery {\\n  using SafeERC20 for IERC20;\\n  using EnumerableSet for EnumerableSet.UintSet;\\n  using EnumerableSet for EnumerableSet.AddressSet;\\n\\n  bytes32 public constant TRADES_SETTLER = keccak256('TRADES_SETTLER');\\n\\n  constructor(address _tradesSettler, address _mechanicsRegistry) Machinery(_mechanicsRegistry) {\\n    _setRoleAdmin(TRADES_SETTLER, MASTER_ADMIN);\\n    _setupRole(TRADES_SETTLER, _tradesSettler);\\n  }\\n\\n  // Machinery\\n  function setMechanicsRegistry(address _mechanicsRegistry) external virtual override onlyRole(MASTER_ADMIN) {\\n    _setMechanicsRegistry(_mechanicsRegistry);\\n  }\\n\\n  function execute(\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    bytes calldata _data\\n  ) external override onlyRole(STRATEGY) returns (uint256 _receivedAmount) {\\n    address _swapper = strategySyncSwapper[msg.sender];\\n    if (_tokenIn == address(0) || _tokenOut == address(0)) revert CommonErrors.ZeroAddress();\\n    if (_amountIn == 0) revert CommonErrors.ZeroAmount();\\n    if (_maxSlippage == 0) revert CommonErrors.ZeroSlippage();\\n    IERC20(_tokenIn).safeTransferFrom(msg.sender, _swapper, _amountIn);\\n    _receivedAmount = ISwapper(_swapper).swap(msg.sender, _tokenIn, _tokenOut, _amountIn, _maxSlippage, _data);\\n    emit SyncTradeExecuted(msg.sender, _swapper, _tokenIn, _tokenOut, _amountIn, _maxSlippage, _data, _receivedAmount);\\n  }\\n\\n  // TradeFactoryExecutor\\n  function execute(uint256 _id, bytes calldata _data) external override onlyMechanic returns (uint256 _receivedAmount) {\\n    if (!_pendingTradesIds.contains(_id)) revert InvalidTrade();\\n    Trade storage _trade = pendingTradesById[_id];\\n    if (block.timestamp > _trade._deadline) revert ExpiredTrade();\\n    if (!_swappers.contains(_trade._swapper)) revert InvalidSwapper();\\n    IERC20(_trade._tokenIn).safeTransferFrom(_trade._strategy, _trade._swapper, _trade._amountIn);\\n    _receivedAmount = ISwapper(_trade._swapper).swap(\\n      _trade._strategy,\\n      _trade._tokenIn,\\n      _trade._tokenOut,\\n      _trade._amountIn,\\n      _trade._maxSlippage,\\n      _data\\n    );\\n    _removePendingTrade(_trade._strategy, _id);\\n    emit AsyncTradeExecuted(_id, _receivedAmount);\\n  }\\n\\n  function expire(uint256 _id) external override onlyMechanic returns (uint256 _freedAmount) {\\n    if (!_pendingTradesIds.contains(_id)) revert InvalidTrade();\\n    Trade storage _trade = pendingTradesById[_id];\\n    if (block.timestamp < _trade._deadline) revert OngoingTrade();\\n    _freedAmount = _trade._amountIn;\\n    // We have to take tokens from strategy, to decrease the allowance\\n    IERC20(_trade._tokenIn).safeTransferFrom(_trade._strategy, address(this), _trade._amountIn);\\n    // Send tokens back to strategy\\n    IERC20(_trade._tokenIn).safeTransfer(_trade._strategy, _trade._amountIn);\\n    // Remove trade\\n    _removePendingTrade(_trade._strategy, _id);\\n    emit AsyncTradeExpired(_id);\\n  }\\n\\n  function execute(uint256[] calldata _ids, uint256 _rateTokenInToOut) external onlyMechanic {\\n    if (_rateTokenInToOut == 0) revert ZeroRate();\\n    address _tokenIn = pendingTradesById[_ids[0]]._tokenIn;\\n    address _tokenOut = pendingTradesById[_ids[0]]._tokenOut;\\n    uint256 _magnitudeIn = 10**IERC20Metadata(_tokenIn).decimals();\\n    for (uint256 i; i < _ids.length; i++) {\\n      Trade storage _trade = pendingTradesById[_ids[i]];\\n      if (i > 0 && (_trade._tokenIn != _tokenIn || _trade._tokenOut != _tokenOut)) revert InvalidTrade();\\n      if (block.timestamp > _trade._deadline) revert ExpiredTrade();\\n      if ((strategyPermissions[_trade._strategy] & _OTC_MASK) != _OTC_MASK) revert CommonErrors.NotAuthorized();\\n      uint256 _consumedOut = (_trade._amountIn * _rateTokenInToOut) / _magnitudeIn;\\n      IERC20(_trade._tokenIn).safeTransferFrom(_trade._strategy, IOTCPool(otcPool).governor(), _trade._amountIn);\\n      IOTCPool(otcPool).take(_trade._tokenOut, _consumedOut, _trade._strategy);\\n      _removePendingTrade(_trade._strategy, _trade._id);\\n    }\\n    emit AsyncOTCTradesExecuted(_ids, _rateTokenInToOut);\\n  }\\n\\n  function execute(\\n    uint256 _firstTradeId,\\n    uint256 _secondTradeId,\\n    uint256 _consumedFirstTrade,\\n    uint256 _consumedSecondTrade\\n  ) external onlyRole(TRADES_SETTLER) returns (uint256 _receivedAmountAnchorTrade, uint256 _receivedAmountAgainstTrade) {\\n    Trade storage _firstTrade = pendingTradesById[_firstTradeId];\\n    Trade storage _secondTrade = pendingTradesById[_secondTradeId];\\n    if (_firstTrade._tokenIn != _secondTrade._tokenOut || _firstTrade._tokenOut != _secondTrade._tokenIn) revert InvalidTrade();\\n    if (block.timestamp > _firstTrade._deadline || block.timestamp > _secondTrade._deadline) revert ExpiredTrade();\\n    if (\\n      (strategyPermissions[_firstTrade._strategy] & _COW_MASK) != _COW_MASK ||\\n      (strategyPermissions[_secondTrade._strategy] & _COW_MASK) != _COW_MASK\\n    ) revert CommonErrors.NotAuthorized();\\n\\n    IERC20(_firstTrade._tokenIn).safeTransferFrom(_firstTrade._strategy, _secondTrade._strategy, _consumedFirstTrade);\\n    IERC20(_secondTrade._tokenIn).safeTransferFrom(_secondTrade._strategy, _firstTrade._strategy, _consumedSecondTrade);\\n\\n    if (_consumedFirstTrade != _firstTrade._amountIn) {\\n      _firstTrade._amountIn -= _consumedFirstTrade;\\n    } else {\\n      _removePendingTrade(_firstTrade._strategy, _firstTradeId);\\n    }\\n\\n    if (_consumedSecondTrade != _secondTrade._amountIn) {\\n      _secondTrade._amountIn -= _consumedSecondTrade;\\n    } else {\\n      _removePendingTrade(_secondTrade._strategy, _secondTradeId);\\n    }\\n\\n    emit AsyncTradesMatched(_firstTradeId, _secondTradeId, _consumedFirstTrade, _consumedSecondTrade);\\n  }\\n}\\n\",\"keccak256\":\"0x7a76968fdd2789452af6f314c494b9645fc36e5421c91edb71a9ee454ddc2cc1\",\"license\":\"MIT\"},\"contracts/TradeFactory/TradeFactoryPositionsHandler.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\nimport './TradeFactorySwapperHandler.sol';\\nimport '../Swapper.sol';\\n\\ninterface ITradeFactoryPositionsHandler {\\n  struct Trade {\\n    uint256 _id;\\n    address _strategy;\\n    address _swapper;\\n    address _tokenIn;\\n    address _tokenOut;\\n    uint256 _amountIn;\\n    uint256 _maxSlippage;\\n    uint256 _deadline;\\n  }\\n\\n  event TradeCreated(\\n    uint256 indexed _id,\\n    address _strategy,\\n    address _swapper,\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    uint256 _deadline\\n  );\\n\\n  event TradesCanceled(address indexed _strategy, uint256[] _ids);\\n\\n  event TradesSwapperChanged(uint256[] _ids, address _newSwapper);\\n\\n  event TradesMerged(uint256 indexed _anchorTrade, uint256[] _ids);\\n\\n  error InvalidTrade();\\n\\n  error InvalidDeadline();\\n\\n  function pendingTradesById(uint256)\\n    external\\n    view\\n    returns (\\n      uint256 _id,\\n      address _strategy,\\n      address _swapper,\\n      address _tokenIn,\\n      address _tokenOut,\\n      uint256 _amountIn,\\n      uint256 _maxSlippage,\\n      uint256 _deadline\\n    );\\n\\n  function pendingTradesIds() external view returns (uint256[] memory _pendingIds);\\n\\n  function pendingTradesIds(address _strategy) external view returns (uint256[] memory _pendingIds);\\n\\n  function create(\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    uint256 _deadline\\n  ) external returns (uint256 _id);\\n\\n  function cancelPendingTrades(uint256[] calldata _ids) external;\\n\\n  function changePendingTradesSwapper(uint256[] calldata _ids, address _swapper) external;\\n\\n  function mergePendingTrades(uint256 _anchorTradeId, uint256[] calldata _toMergeIds) external;\\n}\\n\\nabstract contract TradeFactoryPositionsHandler is ITradeFactoryPositionsHandler, TradeFactorySwapperHandler {\\n  using EnumerableSet for EnumerableSet.UintSet;\\n  using EnumerableSet for EnumerableSet.AddressSet;\\n\\n  bytes32 public constant STRATEGY = keccak256('STRATEGY');\\n  bytes32 public constant STRATEGY_ADDER = keccak256('STRATEGY_ADDER');\\n  bytes32 public constant TRADES_MODIFIER = keccak256('TRADES_MODIFIER');\\n\\n  uint256 private _tradeCounter = 1;\\n\\n  mapping(uint256 => Trade) public override pendingTradesById;\\n\\n  EnumerableSet.UintSet internal _pendingTradesIds;\\n\\n  mapping(address => EnumerableSet.UintSet) internal _pendingTradesByOwner;\\n\\n  constructor(address _strategyAdder, address _tradesModifier) {\\n    if (_strategyAdder == address(0) || _tradesModifier == address(0)) revert CommonErrors.ZeroAddress();\\n    _setRoleAdmin(STRATEGY, STRATEGY_ADDER);\\n    _setRoleAdmin(STRATEGY_ADDER, MASTER_ADMIN);\\n    _setupRole(STRATEGY_ADDER, _strategyAdder);\\n    _setRoleAdmin(TRADES_MODIFIER, MASTER_ADMIN);\\n    _setupRole(TRADES_MODIFIER, _tradesModifier);\\n  }\\n\\n  function pendingTradesIds() external view override returns (uint256[] memory _pendingIds) {\\n    _pendingIds = _pendingTradesIds.values();\\n  }\\n\\n  function pendingTradesIds(address _strategy) external view override returns (uint256[] memory _pendingIds) {\\n    _pendingIds = _pendingTradesByOwner[_strategy].values();\\n  }\\n\\n  function create(\\n    address _tokenIn,\\n    address _tokenOut,\\n    uint256 _amountIn,\\n    uint256 _maxSlippage,\\n    uint256 _deadline\\n  ) external override onlyRole(STRATEGY) returns (uint256 _id) {\\n    if (strategyAsyncSwapper[msg.sender] == address(0)) revert InvalidSwapper();\\n    if (_tokenIn == address(0) || _tokenOut == address(0)) revert CommonErrors.ZeroAddress();\\n    if (_amountIn == 0) revert CommonErrors.ZeroAmount();\\n    if (_maxSlippage == 0) revert CommonErrors.ZeroSlippage();\\n    if (_deadline <= block.timestamp) revert InvalidDeadline();\\n    _id = _tradeCounter;\\n    Trade memory _trade = Trade(\\n      _tradeCounter,\\n      msg.sender,\\n      strategyAsyncSwapper[msg.sender],\\n      _tokenIn,\\n      _tokenOut,\\n      _amountIn,\\n      _maxSlippage,\\n      _deadline\\n    );\\n    pendingTradesById[_trade._id] = _trade;\\n    _pendingTradesByOwner[msg.sender].add(_trade._id);\\n    _pendingTradesIds.add(_trade._id);\\n    _tradeCounter += 1;\\n    emit TradeCreated(\\n      _trade._id,\\n      _trade._strategy,\\n      _trade._swapper,\\n      _trade._tokenIn,\\n      _trade._tokenOut,\\n      _trade._amountIn,\\n      _trade._maxSlippage,\\n      _trade._deadline\\n    );\\n  }\\n\\n  function cancelPendingTrades(uint256[] calldata _ids) external override onlyRole(STRATEGY) {\\n    for (uint256 i; i < _ids.length; i++) {\\n      if (!_pendingTradesIds.contains(_ids[i])) revert InvalidTrade();\\n      if (pendingTradesById[_ids[i]]._strategy != msg.sender) revert CommonErrors.NotAuthorized();\\n      _removePendingTrade(msg.sender, _ids[i]);\\n    }\\n    emit TradesCanceled(msg.sender, _ids);\\n  }\\n\\n  // onlyStrategyHandler or master admin ?\\n  function changePendingTradesSwapper(uint256[] calldata _ids, address _swapper) external override onlyRole(TRADES_MODIFIER) {\\n    if (ISwapper(_swapper).SWAPPER_TYPE() != ISwapper.SwapperType.ASYNC) revert NotAsyncSwapper();\\n    if (!_swappers.contains(_swapper)) revert InvalidSwapper();\\n    for (uint256 i; i < _ids.length; i++) {\\n      if (!_pendingTradesIds.contains(_ids[i])) revert InvalidTrade();\\n      pendingTradesById[_ids[i]]._swapper = _swapper;\\n    }\\n    emit TradesSwapperChanged(_ids, _swapper);\\n  }\\n\\n  function mergePendingTrades(uint256 _anchorTradeId, uint256[] calldata _toMergeIds) external override onlyRole(TRADES_MODIFIER) {\\n    Trade storage _anchorTrade = pendingTradesById[_anchorTradeId];\\n    for (uint256 i; i < _toMergeIds.length; i++) {\\n      Trade storage _trade = pendingTradesById[_toMergeIds[i]];\\n      if (\\n        _anchorTrade._id == _trade._id ||\\n        _anchorTrade._strategy != _trade._strategy ||\\n        _anchorTrade._tokenIn != _trade._tokenIn ||\\n        _anchorTrade._tokenOut != _trade._tokenOut\\n      ) revert InvalidTrade();\\n      _anchorTrade._amountIn += _trade._amountIn;\\n      _removePendingTrade(_trade._strategy, _trade._id);\\n    }\\n    emit TradesMerged(_anchorTradeId, _toMergeIds);\\n  }\\n\\n  function _removePendingTrade(address _strategy, uint256 _id) internal {\\n    _pendingTradesByOwner[_strategy].remove(_id);\\n    _pendingTradesIds.remove(_id);\\n    delete pendingTradesById[_id];\\n  }\\n}\\n\",\"keccak256\":\"0xe904054aed1f66fe51ed64f3b745c75566f2cdf05eef55e57188eca5b5754e3b\",\"license\":\"MIT\"},\"contracts/TradeFactory/TradeFactorySwapperHandler.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nimport '@openzeppelin/contracts/access/AccessControl.sol';\\nimport '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';\\n\\nimport '../Swapper.sol';\\n\\nimport './TradeFactoryAccessManager.sol';\\n\\ninterface ITradeFactorySwapperHandler {\\n  event SyncStrategySwapperSet(address indexed _strategy, address _swapper);\\n  event AsyncStrategySwapperSet(address indexed _strategy, address _swapper);\\n  event StrategyPermissionsSet(address indexed _strategy, bytes1 _permissions);\\n  event OTCPoolSet(address _otcPool);\\n  event SwappersAdded(address[] _swappers);\\n  event SwappersRemoved(address[] _swapper);\\n\\n  error NotAsyncSwapper();\\n  error NotSyncSwapper();\\n  error InvalidSwapper();\\n  error InvalidPermissions();\\n  error SwapperInUse();\\n\\n  function strategySyncSwapper(address _strategy) external view returns (address _swapper);\\n\\n  function strategyAsyncSwapper(address _strategy) external view returns (address _swapper);\\n\\n  function strategyPermissions(address _strategy) external view returns (bytes1 _permissions);\\n\\n  function swappers() external view returns (address[] memory _swappersList);\\n\\n  function isSwapper(address _swapper) external view returns (bool _isSwapper);\\n\\n  function swapperStrategies(address _swapper) external view returns (address[] memory _strategies);\\n\\n  function setStrategyPermissions(address _strategy, bytes1 _permissions) external;\\n\\n  function setOTCPool(address _otcPool) external;\\n\\n  function setStrategySyncSwapper(address _strategy, address _swapper) external;\\n\\n  function setStrategyAsyncSwapper(address _strategy, address _swapper) external;\\n\\n  function addSwappers(address[] memory __swappers) external;\\n\\n  function removeSwappers(address[] memory __swappers) external;\\n}\\n\\nabstract contract TradeFactorySwapperHandler is ITradeFactorySwapperHandler, TradeFactoryAccessManager {\\n  using EnumerableSet for EnumerableSet.AddressSet;\\n\\n  bytes32 public constant SWAPPER_ADDER = keccak256('SWAPPER_ADDER');\\n  bytes32 public constant SWAPPER_SETTER = keccak256('SWAPPER_SETTER');\\n\\n  bytes1 internal constant _OTC_MASK = 0x01;\\n  bytes1 internal constant _COW_MASK = 0x02;\\n\\n  // OTC Handler\\n  address public otcPool;\\n  // swappers list\\n  EnumerableSet.AddressSet internal _swappers;\\n  // swapper -> strategy list (useful to know if we can safely deprecate a swapper)\\n  mapping(address => EnumerableSet.AddressSet) internal _swapperStrategies;\\n  // strategy -> async swapper\\n  mapping(address => address) public override strategyAsyncSwapper;\\n  // strategy -> sync swapper\\n  mapping(address => address) public override strategySyncSwapper;\\n  // strategy -> permissions\\n  // permissions[_OTC_PERMISSION_INDEX] => OTC\\n  // permissions[_COW_PERMISSION_INDEX] => COW\\n  mapping(address => bytes1) public override strategyPermissions;\\n\\n  constructor(address _swapperAdder, address _swapperSetter) {\\n    if (_swapperAdder == address(0) || _swapperSetter == address(0)) revert CommonErrors.ZeroAddress();\\n    _setRoleAdmin(SWAPPER_ADDER, MASTER_ADMIN);\\n    _setRoleAdmin(SWAPPER_SETTER, MASTER_ADMIN);\\n    _setupRole(SWAPPER_ADDER, _swapperAdder);\\n    _setupRole(SWAPPER_SETTER, _swapperSetter);\\n  }\\n\\n  function isSwapper(address _swapper) external view override returns (bool _isSwapper) {\\n    _isSwapper = _swappers.contains(_swapper);\\n  }\\n\\n  function swappers() external view override returns (address[] memory _swappersList) {\\n    _swappersList = _swappers.values();\\n  }\\n\\n  function swapperStrategies(address _swapper) external view override returns (address[] memory _strategies) {\\n    _strategies = _swapperStrategies[_swapper].values();\\n  }\\n\\n  function setStrategyPermissions(address _strategy, bytes1 _permissions) external override onlyRole(SWAPPER_SETTER) {\\n    if (_strategy == address(0)) revert CommonErrors.ZeroAddress();\\n    strategyPermissions[_strategy] = _permissions;\\n    emit StrategyPermissionsSet(_strategy, _permissions);\\n  }\\n\\n  function setOTCPool(address _otcPool) external override onlyRole(MASTER_ADMIN) {\\n    if (_otcPool == address(0)) revert CommonErrors.ZeroAddress();\\n    otcPool = _otcPool;\\n    emit OTCPoolSet(_otcPool);\\n  }\\n\\n  function setStrategySyncSwapper(address _strategy, address _swapper) external override onlyRole(SWAPPER_SETTER) {\\n    if (_strategy == address(0) || _swapper == address(0)) revert CommonErrors.ZeroAddress();\\n    // we check that swapper being added is async\\n    if (ISwapper(_swapper).SWAPPER_TYPE() != ISwapper.SwapperType.SYNC) revert NotSyncSwapper();\\n    // we check that swapper is not already added\\n    if (!_swappers.contains(_swapper)) revert InvalidSwapper();\\n    // remove strategy from previous swapper if any\\n    if (strategySyncSwapper[_strategy] != address(0)) _swapperStrategies[strategySyncSwapper[_strategy]].remove(_strategy);\\n    // set new strategy's sync swapper\\n    strategySyncSwapper[_strategy] = _swapper;\\n    // add strategy into new swapper\\n    _swapperStrategies[_swapper].add(_strategy);\\n    // emit event\\n    emit SyncStrategySwapperSet(_strategy, _swapper);\\n  }\\n\\n  function setStrategyAsyncSwapper(address _strategy, address _swapper) external override onlyRole(SWAPPER_SETTER) {\\n    if (_strategy == address(0) || _swapper == address(0)) revert CommonErrors.ZeroAddress();\\n    // we check that swapper being added is async\\n    if (ISwapper(_swapper).SWAPPER_TYPE() != ISwapper.SwapperType.ASYNC) revert NotAsyncSwapper();\\n    // we check that swapper is not already added\\n    if (!_swappers.contains(_swapper)) revert InvalidSwapper();\\n    // remove strategy from previous swapper if any\\n    if (strategyAsyncSwapper[_strategy] != address(0)) _swapperStrategies[strategyAsyncSwapper[_strategy]].remove(_strategy);\\n    // set new strategy's async swapper\\n    strategyAsyncSwapper[_strategy] = _swapper;\\n    // add strategy into new swapper\\n    _swapperStrategies[_swapper].add(_strategy);\\n    // emit event\\n    emit AsyncStrategySwapperSet(_strategy, _swapper);\\n  }\\n\\n  function addSwappers(address[] memory __swappers) external override onlyRole(SWAPPER_ADDER) {\\n    for (uint256 i; i < __swappers.length; i++) {\\n      if (__swappers[i] == address(0)) revert CommonErrors.ZeroAddress();\\n      _swappers.add(__swappers[i]);\\n    }\\n    emit SwappersAdded(__swappers);\\n  }\\n\\n  function removeSwappers(address[] memory __swappers) external override onlyRole(SWAPPER_ADDER) {\\n    for (uint256 i; i < __swappers.length; i++) {\\n      if (_swapperStrategies[__swappers[i]].length() > 0) revert SwapperInUse();\\n      _swappers.remove(__swappers[i]);\\n    }\\n    emit SwappersRemoved(__swappers);\\n  }\\n}\\n\",\"keccak256\":\"0xbdb491c88fc6608fd85f52f54df54ce042f115f2d4f0374f7d4da7de7e3ac816\",\"license\":\"MIT\"},\"contracts/libraries/CommonErrors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4 <0.9.0;\\n\\nlibrary CommonErrors {\\n  error ZeroAddress();\\n  error NotAuthorized();\\n  error ZeroAmount();\\n  error ZeroSlippage();\\n  error IncorrectSwapInformation();\\n}\\n\",\"keccak256\":\"0xe2171a8953429c2aabd489384f45fac651cbd08f6dd907cb06460a8fb3aecd1b\",\"license\":\"MIT\"}},\"version\":1}",
  "bytecode": "0x608060405260016008553480156200001657600080fd5b5060405162004aa738038062004aa7833981016040819052620000399162000417565b81818086868a8a8d6001600160a01b038116620000695760405163d92e233d60e01b815260040160405180910390fd5b6200008460008051602062004a8783398151915280620002ff565b6200009f60008051602062004a87833981519152826200034a565b506001600160a01b0382161580620000be57506001600160a01b038116155b15620000dd5760405163d92e233d60e01b815260040160405180910390fd5b6200010760008051602062004a0783398151915260008051602062004a87833981519152620002ff565b620001427fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b91160008051602062004a87833981519152620002ff565b6200015d60008051602062004a07833981519152836200034a565b620001897fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b911826200034a565b50506001600160a01b0382161580620001a957506001600160a01b038116155b15620001c85760405163d92e233d60e01b815260040160405180910390fd5b620002037f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f760008051602062004a47833981519152620002ff565b6200022d60008051602062004a4783398151915260008051602062004a87833981519152620002ff565b6200024860008051602062004a47833981519152836200034a565b6200027260008051602062004a6783398151915260008051602062004a87833981519152620002ff565b6200028d60008051602062004a67833981519152826200034a565b5050600d80546001600160a01b0319166001600160a01b03831617905550620002d560008051602062004a2783398151915260008051602062004a87833981519152620002ff565b620002f060008051602062004a27833981519152836200034a565b505050505050505050620004ab565b600082815260208190526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b6200035682826200035a565b5050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000356576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620003b63390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b80516001600160a01b03811681146200041257600080fd5b919050565b600080600080600080600060e0888a03121562000432578283fd5b6200043d88620003fa565b96506200044d60208901620003fa565b95506200045d60408901620003fa565b94506200046d60608901620003fa565b93506200047d60808901620003fa565b92506200048d60a08901620003fa565b91506200049d60c08901620003fa565b905092959891949750929550565b61454c80620004bb6000396000f3fe608060405234801561001057600080fd5b50600436106102f45760003560e01c806391d1485411610191578063ccf61a41116100e3578063e454a5ed11610097578063f48221a311610071578063f48221a314610807578063f7bd381f1461081a578063fdd619e01461082d57600080fd5b8063e454a5ed146107ba578063ef47da6d146107e1578063f070cd89146107f457600080fd5b8063dbab687a116100c8578063dbab687a14610740578063e0b1bba714610794578063e0b95113146107a757600080fd5b8063ccf61a4114610704578063d547741f1461072d57600080fd5b8063a734f06e11610145578063c0137f7a1161011f578063c0137f7a146106ad578063c32e4f8d146106d5578063cbf8e6c4146106fc57600080fd5b8063a734f06e1461066c578063b64230ba14610687578063bf81bf431461069a57600080fd5b8063a217fddf11610176578063a217fddf14610649578063a2c6f17414610651578063a63513d81461065957600080fd5b806391d14854146105ff5780639f87641d1461063657600080fd5b80634d1dd98f1161024a57806365834acc116101fe5780638f05819a116101d85780638f05819a146105c65780638f9745f2146105d9578063907ab008146105ec57600080fd5b806365834acc14610579578063687020d81461058c578063891b1a00146105b357600080fd5b80635877e98e1161022f5780635877e98e1461049657806359cd24241461054657806359efcb151461056657600080fd5b80634d1dd98f1461044f578063504254911461047657600080fd5b8063211428c0116102ac5780632f2ff15d116102865780632f2ff15d1461041657806336568abe146104295780634a2c1bab1461043c57600080fd5b8063211428c0146103b7578063248a9ca3146103e05780632db8c1291461040357600080fd5b806306b70639116102dd57806306b70639146103565780631078f3881461036b578063185025ef1461039057600080fd5b806301ffc9a7146102f9578063057535b014610321575b600080fd5b61030c610307366004613efc565b610854565b60405190151581526020015b60405180910390f35b6103487ff97fb9ac61687d33e6f167fb66bd0dbc2240a42d8369c39aadb26ea8ce05b5fe81565b604051908152602001610318565b610369610364366004613e56565b6108ed565b005b600d546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6103487f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f781565b6103786103c5366004613b2f565b6005602052600090815260409020546001600160a01b031681565b6103486103ee366004613ec0565b60009081526020819052604090206001015490565b610369610411366004613b9f565b610e7e565b610369610424366004613ed8565b610eba565b610369610437366004613ed8565b610ee5565b61036961044a366004613cfa565b610f71565b6103487fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b91181565b610489610484366004613b2f565b6110a6565b60405161031891906141fb565b6104f86104a4366004613ec0565b6009602052600090815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495966001600160a01b039586169694861695938416949290931692909188565b604080519889526001600160a01b0397881660208a01529587169588019590955292851660608701529316608085015260a084019290925260c083019190915260e082015261010001610318565b610559610554366004613b2f565b6110ca565b60405161031891906142ad565b610348610574366004613fbd565b6110ee565b61030c610587366004613b2f565b6113fd565b6103487f038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd981565b6103486105c1366004613c59565b611494565b6103696105d4366004613b67565b6118b2565b6103696105e7366004613b2f565b611b2f565b6103696105fa366004613cfa565b611c00565b61030c61060d366004613ed8565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b610369610644366004613f73565b611d43565b610348600081565b610559611ef1565b600154610378906001600160a01b031681565b61037873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b61030c610695366004613b2f565b611f02565b6103486106a8366004613ec0565b611f0f565b6106c06106bb366004613ffa565b612117565b60408051928352602083019190915201610318565b6103487f0c98cf5b298d76683bff7ac7eb2544a1c5413c08c055cad5077796993f1b71e581565b610489612400565b610378610712366004613b2f565b6006602052600090815260409020546001600160a01b031681565b61036961073b366004613ed8565b61240c565b61076361074e366004613b2f565b60076020526000908152604090205460f81b81565b6040517fff000000000000000000000000000000000000000000000000000000000000009091168152602001610318565b6103696107a2366004613dc1565b612432565b6103696107b5366004613ca9565b6125d8565b6103487f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d381565b6103696107ef366004613b2f565b6126da565b610369610802366004613e01565b61273c565b610348610815366004613bdf565b61298b565b610369610828366004613b67565b612bab565b6103487f1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806108e757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03909116906365834acc9060240160206040518083038186803b15801561094957600080fd5b505afa15801561095d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109819190613ea0565b6109d25760405162461bcd60e51b815260206004820152601760248201527f4d616368696e6572793a206e6f74206d656368616e696300000000000000000060448201526064015b60405180910390fd5b80610a09576040517f299dcf9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006009600085856000818110610a3057634e487b7160e01b600052603260045260246000fd5b602090810292909201358352508101919091526040016000908120600301546001600160a01b0316915060098186868281610a7b57634e487b7160e01b600052603260045260246000fd5b90506020020135815260200190815260200160002060040160009054906101000a90046001600160a01b031690506000826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610ae457600080fd5b505afa158015610af8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1c919061402b565b610b2790600a614393565b905060005b85811015610e3a57600060096000898985818110610b5a57634e487b7160e01b600052603260045260246000fd5b9050602002013581526020019081526020016000209050600082118015610bab575060038101546001600160a01b038681169116141580610bab575060048101546001600160a01b03858116911614155b15610be2576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060070154421115610c20576040517f8d93cc8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101546001600160a01b031660009081526007602052604090205460f81b7f010000000000000000000000000000000000000000000000000000000000000090811614610c9b576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083878360050154610cae919061443e565b610cb89190614330565b6001838101549054604080517f0c340a240000000000000000000000000000000000000000000000000000000081529051939450610d79936001600160a01b039384169390921691630c340a2491600480820192602092909190829003018186803b158015610d2657600080fd5b505afa158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e9190613b4b565b600585015460038601546001600160a01b0316929190612e1f565b60018054600484810154928501546040517f8033d6870000000000000000000000000000000000000000000000000000000081526001600160a01b03948516928101929092526024820185905283166044820152911690638033d68790606401600060405180830381600087803b158015610df357600080fd5b505af1158015610e07573d6000803e3d6000fd5b5050505060018201548254610e25916001600160a01b031690612ed0565b50508080610e32906144b7565b915050610b2c565b507f0210feaf40876b7bc453fe389be6733e7d450692bf07adab2d3c11980f94dcd6868686604051610e6e93929190614289565b60405180910390a1505050505050565b7f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3610ea98133612f71565b610eb4848484612fef565b50505050565b600082815260208190526040902060010154610ed68133612f71565b610ee083836131ae565b505050565b6001600160a01b0381163314610f635760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016109c9565b610f6d828261326a565b5050565b7f038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd9610f9c8133612f71565b60005b825181101561106a5760006001600160a01b0316838281518110610fd357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561101c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105783828151811061103f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600261330790919063ffffffff16565b5080611062816144b7565b915050610f9f565b507f5d1fd21744530253cbd801d1685bf9e6f5d8a13044c3a7df5628b4c60d7d9e3b8260405161109a91906141fb565b60405180910390a15050565b6001600160a01b03811660009081526004602052604090206060906108e790613323565b6001600160a01b0381166000908152600c602052604090206060906108e790613323565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081523360048201526000916001600160a01b0316906365834acc9060240160206040518083038186803b15801561114b57600080fd5b505afa15801561115f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111839190613ea0565b6111cf5760405162461bcd60e51b815260206004820152601760248201527f4d616368696e6572793a206e6f74206d656368616e696300000000000000000060448201526064016109c9565b6111da600a85613330565b611210576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600960205260409020600781015442111561125c576040517f8d93cc8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028082015461127591906001600160a01b0316613348565b6112ab576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101546002820154600583015460038401546112db936001600160a01b039182169390821692911690612e1f565b600281015460018201546003830154600480850154600586015460068701546040517fa5d4096b0000000000000000000000000000000000000000000000000000000081526001600160a01b039788169763a5d4096b9761134e9790821696908216959091169392918d918d9101614160565b602060405180830381600087803b15801561136857600080fd5b505af115801561137c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a09190613f5b565b60018201549092506113bb906001600160a01b031686612ed0565b847ff3b176b50ba6ec4473f418ce17c562a616f7715b23a6bcea8e41d78621f56b34836040516113ed91815260200190565b60405180910390a2509392505050565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260009216906365834acc9060240160206040518083038186803b15801561145c57600080fd5b505afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e79190613ea0565b60007f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f76114c18133612f71565b336000908152600560205260409020546001600160a01b0316611510576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038716158061152d57506001600160a01b038616155b15611564576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8461159b576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836115d2576040517f5380c59d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b42831161160b576040517f769d11e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854915060006040518061010001604052806008548152602001336001600160a01b0316815260200160056000336001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b03166001600160a01b03168152602001896001600160a01b03168152602001886001600160a01b031681526020018781526020018681526020018581525090508060096000836000015181526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a0820151816005015560c0820151816006015560e082015181600701559050506117de8160000151600c6000336001600160a01b03166001600160a01b0316815260200190815260200160002061336a90919063ffffffff16565b5080516117ed90600a9061336a565b506001600860008282546118019190614318565b9091555050805160208201516040808401516060850151608086015160a087015160c088015160e089015195517f399699ab6f1401e7784608cbdabe944658876a522eb163c69fd166dbf2776c4f9761189f97909695949392916001600160a01b03978816815295871660208701529386166040860152919094166060840152608083019390935260a082019290925260c081019190915260e00190565b60405180910390a2505095945050505050565b7fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b9116118dd8133612f71565b6001600160a01b03831615806118fa57506001600160a01b038216155b15611931576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826001600160a01b031663cd985af06040518163ffffffff1660e01b815260040160206040518083038186803b15801561196c57600080fd5b505afa158015611980573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a49190613f3c565b60018111156119c357634e487b7160e01b600052602160045260246000fd5b146119fa576040517fa2d3ada200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a05600283613348565b611a3b576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381166000908152600560205260409020541615611a8e576001600160a01b0380841660009081526005602090815260408083205490931682526004905220611a8c9084613376565b505b6001600160a01b03838116600090815260056020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694871694851790559282526004905220611ae89084613307565b506040516001600160a01b0383811682528416907f1a70401259f8cfe91ae1c8d3f5b4f357d27664794f83e3bcd4648f047554f680906020015b60405180910390a2505050565b7f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3611b5a8133612f71565b6001600160a01b038216611b9a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091556040519081527fd820b9bd66f5f69e0ee876fe38d41d612586cb5dfdab23721469fc9c6dd5950d9060200161109a565b7f038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd9611c2b8133612f71565b60005b8251811015611d13576000611c8d60046000868581518110611c6057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002061338b565b1115611cc5576040517f61c45a0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d00838281518110611ce857634e487b7160e01b600052603260045260246000fd5b6020026020010151600261337690919063ffffffff16565b5080611d0b816144b7565b915050611c2e565b507f4290941fe8d89409196966ddfc719772595cef6116ed6bde0bcc72e1182b52b58260405161109a91906141fb565b7f1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c611d6e8133612f71565b6000848152600960205260408120905b83811015611eaf57600060096000878785818110611dac57634e487b7160e01b600052603260045260246000fd5b9050602002013581526020019081526020016000209050806000015483600001541480611dee5750600180820154908401546001600160a01b03908116911614155b80611e0e5750600380820154908401546001600160a01b03908116911614155b80611e2e5750600480820154908401546001600160a01b03908116911614155b15611e65576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060050154836005016000828254611e7d9190614318565b909155505060018101548154611e9c916001600160a01b031690612ed0565b5080611ea7816144b7565b915050611d7e565b50847fbba31c5a03767b9eba75f83badce7bc719848c62b42334ab0984c13b96c66bbe8585604051611ee2929190614248565b60405180910390a25050505050565b6060611efd600a613323565b905090565b60006108e7600283613348565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081523360048201526000916001600160a01b0316906365834acc9060240160206040518083038186803b158015611f6c57600080fd5b505afa158015611f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa49190613ea0565b611ff05760405162461bcd60e51b815260206004820152601760248201527f4d616368696e6572793a206e6f74206d656368616e696300000000000000000060448201526064016109c9565b611ffb600a83613330565b612031576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600960205260409020600781015442101561207d576040517fdae7dbed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005810154600182015460038301549193506120a7916001600160a01b0390811691163085612e1f565b6001810154600582015460038301546120ce926001600160a01b0391821692911690613395565b60018101546120e6906001600160a01b031684612ed0565b60405183907f9e52c476c07e14b40a7ee505cae05543e63c4c2d0c69323803c1fe0b4dd23b8a90600090a250919050565b6000807ff97fb9ac61687d33e6f167fb66bd0dbc2240a42d8369c39aadb26ea8ce05b5fe6121458133612f71565b6000878152600960205260408082208883529120600481015460038301546001600160a01b0390811691161415806121925750600381015460048301546001600160a01b03908116911614155b156121c9576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600701544211806121de5750806007015442115b15612215576040517f8d93cc8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018201546001600160a01b031660009081526007602052604090205460f81b7f02000000000000000000000000000000000000000000000000000000000000009081161415806122a8575060018101546001600160a01b031660009081526007602052604090205460f81b7f020000000000000000000000000000000000000000000000000000000000000090811614155b156122df576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180830154908201546003840154612309926001600160a01b039182169290821691168a612e1f565b600180820154908301546003830154612333926001600160a01b0391821692908216911689612e1f565b8160050154871461235d5786826005016000828254612352919061445d565b909155506123759050565b6001820154612375906001600160a01b03168a612ed0565b8060050154861461239f5785816005016000828254612394919061445d565b909155506123b79050565b60018101546123b7906001600160a01b031689612ed0565b604080518881526020810188905289918b917fe5d287a20ff8c99c44a2f83dd58978ff9b7555963447c92435c01981a84cb3b0910160405180910390a350505094509492505050565b6060611efd6002613323565b6000828152602081905260409020600101546124288133612f71565b610ee0838361326a565b7f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f761245d8133612f71565b60005b8281101561259c576124a284848381811061248b57634e487b7160e01b600052603260045260246000fd5b90506020020135600a61333090919063ffffffff16565b6124d8576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600960008686858181106124fd57634e487b7160e01b600052603260045260246000fd5b60209081029290920135835250810191909152604001600020600101546001600160a01b03161461255a576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61258a3385858481811061257e57634e487b7160e01b600052603260045260246000fd5b90506020020135612ed0565b80612594816144b7565b915050612460565b50336001600160a01b03167fbc02525bfba972df6ef3d6d34e6f4773de0e098177c254a62a4926ec94fdaea68484604051611b22929190614248565b7fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b9116126038133612f71565b6001600160a01b038316612643576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03831660008181526007602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660f887901c17905590517fff00000000000000000000000000000000000000000000000000000000000000851681527f3c0408280ff44f7512ae2e74ad6e1f6c56d3de609831a70405ea1b97adb768119101611b22565b7f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d36127058133612f71565b600d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384161790555050565b7f1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c6127678133612f71565b6000826001600160a01b031663cd985af06040518163ffffffff1660e01b815260040160206040518083038186803b1580156127a257600080fd5b505afa1580156127b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127da9190613f3c565b60018111156127f957634e487b7160e01b600052602160045260246000fd5b14612830576040517fa2d3ada200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61283b600283613348565b612871576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156129495761289f85858381811061248b57634e487b7160e01b600052603260045260246000fd5b6128d5576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600960008787858181106128fa57634e487b7160e01b600052603260045260246000fd5b90506020020135815260200190815260200160002060020160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080612941906144b7565b915050612874565b507f9be161fbaf23021e26ce5dc13fd51f0392db66c9989662b8fc4b4cc1a9e5ec9884848460405161297d9392919061425c565b60405180910390a150505050565b60007f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f76129b88133612f71565b336000908152600660205260409020546001600160a01b0390811690891615806129e957506001600160a01b038816155b15612a20576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86612a57576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85612a8e576040517f5380c59d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612aa36001600160a01b038a1633838a612e1f565b6040517fa5d4096b0000000000000000000000000000000000000000000000000000000081526001600160a01b0382169063a5d4096b90612af49033908d908d908d908d908d908d90600401614160565b602060405180830381600087803b158015612b0e57600080fd5b505af1158015612b22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b469190613f5b565b9250806001600160a01b0316336001600160a01b03167f1d816b1b1d67ea42ff2f6dae0a85f237a27e76afccb32ba25e4175330f3703e18b8b8b8b8b8b8b604051612b9797969594939291906141ae565b60405180910390a350509695505050505050565b7fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b911612bd68133612f71565b6001600160a01b0383161580612bf357506001600160a01b038216155b15612c2a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001826001600160a01b031663cd985af06040518163ffffffff1660e01b815260040160206040518083038186803b158015612c6557600080fd5b505afa158015612c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9d9190613f3c565b6001811115612cbc57634e487b7160e01b600052602160045260246000fd5b14612cf3576040517f967ade6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612cfe600283613348565b612d34576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381166000908152600660205260409020541615612d87576001600160a01b0380841660009081526006602090815260408083205490931682526004905220612d859084613376565b505b6001600160a01b03838116600090815260066020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694871694851790559282526004905220612de19084613307565b506040516001600160a01b0383811682528416907f09864ed308dfc2a9cc6804e3b86d38a1aaa4f7adec68be5562b9dd8feb9c1b0590602001611b22565b6040516001600160a01b0380851660248301528316604482015260648101829052610eb49085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526133de565b6001600160a01b0382166000908152600c60205260409020612ef290826134c3565b50612efe600a826134c3565b5060009081526009602052604081208181556001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000009081169091556002820180548216905560038201805482169055600482018054909116905560058101829055600681018290556007015550565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610f6d57612fad816001600160a01b031660146134cf565b612fb88360206134cf565b604051602001612fc99291906140df565b60408051601f198184030181529082905262461bcd60e51b82526109c9916004016142e5565b6001600160a01b03831661306b5760405162461bcd60e51b815260206004820152602f60248201527f636f6c6c65637461626c652d647573742f63616e742d73656e642d647573742d60448201527f746f2d7a65726f2d61646472657373000000000000000000000000000000000060648201526084016109c9565b613076600e83613348565b156130e95760405162461bcd60e51b815260206004820152602e60248201527f636f6c6c65637461626c652d647573742f746f6b656e2d69732d706172742d6f60448201527f662d7468652d70726f746f636f6c00000000000000000000000000000000000060648201526084016109c9565b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561314a576040516001600160a01b0384169082156108fc029083906000818181858888f19350505050158015613144573d6000803e3d6000fd5b5061315e565b61315e6001600160a01b0383168483613395565b604080516001600160a01b038086168252841660208201529081018290527f1e34c1aee8e83c2dcc14c21bb4bfeea7f46c0c998cb797ac7cc4d7a18f5c656b9060600160405180910390a1505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610f6d576000828152602081815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556132263390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610f6d576000828152602081815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061331c836001600160a01b03841661373e565b9392505050565b6060600061331c8361378d565b6000818152600183016020526040812054151561331c565b6001600160a01b0381166000908152600183016020526040812054151561331c565b600061331c838361373e565b600061331c836001600160a01b0384166137e9565b60006108e7825490565b6040516001600160a01b038316602482015260448101829052610ee09084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612e6c565b6000613433826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166139069092919063ffffffff16565b805190915015610ee057808060200190518101906134519190613ea0565b610ee05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016109c9565b600061331c83836137e9565b606060006134de83600261443e565b6134e9906002614318565b67ffffffffffffffff81111561350f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613539576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061357e57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106135ef57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061362b84600261443e565b613636906001614318565b90505b60018111156136ef577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061368557634e487b7160e01b600052603260045260246000fd5b1a60f81b8282815181106136a957634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936136e8816144a0565b9050613639565b50831561331c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109c9565b6000818152600183016020526040812054613785575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108e7565b5060006108e7565b6060816000018054806020026020016040519081016040528092919081815260200182805480156137dd57602002820191906000526020600020905b8154815260200190600101908083116137c9575b50505050509050919050565b600081815260018301602052604081205480156138fc57600061380d60018361445d565b85549091506000906138219060019061445d565b90508181146138a257600086600001828154811061384f57634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061388057634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b85548690806138c157634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108e7565b60009150506108e7565b6060613915848460008561391d565b949350505050565b6060824710156139955760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016109c9565b843b6139e35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c9565b600080866001600160a01b031685876040516139ff91906140c3565b60006040518083038185875af1925050503d8060008114613a3c576040519150601f19603f3d011682016040523d82523d6000602084013e613a41565b606091505b5091509150613a51828286613a5c565b979650505050505050565b60608315613a6b57508161331c565b825115613a7b5782518084602001fd5b8160405162461bcd60e51b81526004016109c991906142e5565b8035613aa0816144fe565b919050565b60008083601f840112613ab6578182fd5b50813567ffffffffffffffff811115613acd578182fd5b6020830191508360208260051b8501011115613ae857600080fd5b9250929050565b60008083601f840112613b00578182fd5b50813567ffffffffffffffff811115613b17578182fd5b602083019150836020828501011115613ae857600080fd5b600060208284031215613b40578081fd5b813561331c816144fe565b600060208284031215613b5c578081fd5b815161331c816144fe565b60008060408385031215613b79578081fd5b8235613b84816144fe565b91506020830135613b94816144fe565b809150509250929050565b600080600060608486031215613bb3578081fd5b8335613bbe816144fe565b92506020840135613bce816144fe565b929592945050506040919091013590565b60008060008060008060a08789031215613bf7578182fd5b8635613c02816144fe565b95506020870135613c12816144fe565b94506040870135935060608701359250608087013567ffffffffffffffff811115613c3b578283fd5b613c4789828a01613aef565b979a9699509497509295939492505050565b600080600080600060a08688031215613c70578081fd5b8535613c7b816144fe565b94506020860135613c8b816144fe565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215613cbb578182fd5b8235613cc6816144fe565b915060208301357fff0000000000000000000000000000000000000000000000000000000000000081168114613b94578182fd5b60006020808385031215613d0c578182fd5b823567ffffffffffffffff80821115613d23578384fd5b818501915085601f830112613d36578384fd5b813581811115613d4857613d486144e8565b8060051b604051601f19603f83011681018181108582111715613d6d57613d6d6144e8565b604052828152858101935084860182860187018a1015613d8b578788fd5b8795505b83861015613db457613da081613a95565b855260019590950194938601938601613d8f565b5098975050505050505050565b60008060208385031215613dd3578182fd5b823567ffffffffffffffff811115613de9578283fd5b613df585828601613aa5565b90969095509350505050565b600080600060408486031215613e15578283fd5b833567ffffffffffffffff811115613e2b578384fd5b613e3786828701613aa5565b9094509250506020840135613e4b816144fe565b809150509250925092565b600080600060408486031215613e6a578081fd5b833567ffffffffffffffff811115613e80578182fd5b613e8c86828701613aa5565b909790965060209590950135949350505050565b600060208284031215613eb1578081fd5b8151801515811461331c578182fd5b600060208284031215613ed1578081fd5b5035919050565b60008060408385031215613eea578182fd5b823591506020830135613b94816144fe565b600060208284031215613f0d578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461331c578182fd5b600060208284031215613f4d578081fd5b81516002811061331c578182fd5b600060208284031215613f6c578081fd5b5051919050565b600080600060408486031215613f87578081fd5b83359250602084013567ffffffffffffffff811115613fa4578182fd5b613fb086828701613aa5565b9497909650939450505050565b600080600060408486031215613fd1578081fd5b83359250602084013567ffffffffffffffff811115613fee578182fd5b613fb086828701613aef565b6000806000806080858703121561400f578182fd5b5050823594602084013594506040840135936060013592509050565b60006020828403121561403c578081fd5b815160ff8116811461331c578182fd5b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561407d578081fd5b8260051b80836020870137939093016020019283525090919050565b8183528181602085013750600080602083850101526020601f19601f840116840101905092915050565b600082516140d5818460208701614474565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614117816017850160208801614474565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614154816028840160208801614474565b01602801949350505050565b60006001600160a01b03808a168352808916602084015280881660408401525085606083015284608083015260c060a08301526141a160c083018486614099565b9998505050505050505050565b60006001600160a01b03808a16835280891660208401525086604083015285606083015260c060808301526141e760c083018587614099565b90508260a083015298975050505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561423c5783516001600160a01b031683529284019291840191600101614217565b50909695505050505050565b60208152600061391560208301848661404c565b60408152600061427060408301858761404c565b90506001600160a01b0383166020830152949350505050565b60408152600061429d60408301858761404c565b9050826020830152949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561423c578351835292840192918401916001016142c9565b6020815260008251806020840152614304816040850160208701614474565b601f01601f19169190910160400192915050565b6000821982111561432b5761432b6144d2565b500190565b60008261434b57634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561438b578160001904821115614371576143716144d2565b8085161561437e57918102915b93841c9390800290614355565b509250929050565b600061331c60ff8416836000826143ac575060016108e7565b816143b9575060006108e7565b81600181146143cf57600281146143d9576143f5565b60019150506108e7565b60ff8411156143ea576143ea6144d2565b50506001821b6108e7565b5060208310610133831016604e8410600b8410161715614418575081810a6108e7565b6144228383614350565b8060001904821115614436576144366144d2565b029392505050565b6000816000190483118215151615614458576144586144d2565b500290565b60008282101561446f5761446f6144d2565b500390565b60005b8381101561448f578181015183820152602001614477565b83811115610eb45750506000910152565b6000816144af576144af6144d2565b506000190190565b60006000198214156144cb576144cb6144d2565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461451357600080fd5b5056fea26469706673582212208fcbb6daae8eb8d450c2cddd708a1e2b4993813a7af7f6e586104d3ef9aa421364736f6c63430008040033038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd9f97fb9ac61687d33e6f167fb66bd0dbc2240a42d8369c39aadb26ea8ce05b5fe0c98cf5b298d76683bff7ac7eb2544a1c5413c08c055cad5077796993f1b71e51ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102f45760003560e01c806391d1485411610191578063ccf61a41116100e3578063e454a5ed11610097578063f48221a311610071578063f48221a314610807578063f7bd381f1461081a578063fdd619e01461082d57600080fd5b8063e454a5ed146107ba578063ef47da6d146107e1578063f070cd89146107f457600080fd5b8063dbab687a116100c8578063dbab687a14610740578063e0b1bba714610794578063e0b95113146107a757600080fd5b8063ccf61a4114610704578063d547741f1461072d57600080fd5b8063a734f06e11610145578063c0137f7a1161011f578063c0137f7a146106ad578063c32e4f8d146106d5578063cbf8e6c4146106fc57600080fd5b8063a734f06e1461066c578063b64230ba14610687578063bf81bf431461069a57600080fd5b8063a217fddf11610176578063a217fddf14610649578063a2c6f17414610651578063a63513d81461065957600080fd5b806391d14854146105ff5780639f87641d1461063657600080fd5b80634d1dd98f1161024a57806365834acc116101fe5780638f05819a116101d85780638f05819a146105c65780638f9745f2146105d9578063907ab008146105ec57600080fd5b806365834acc14610579578063687020d81461058c578063891b1a00146105b357600080fd5b80635877e98e1161022f5780635877e98e1461049657806359cd24241461054657806359efcb151461056657600080fd5b80634d1dd98f1461044f578063504254911461047657600080fd5b8063211428c0116102ac5780632f2ff15d116102865780632f2ff15d1461041657806336568abe146104295780634a2c1bab1461043c57600080fd5b8063211428c0146103b7578063248a9ca3146103e05780632db8c1291461040357600080fd5b806306b70639116102dd57806306b70639146103565780631078f3881461036b578063185025ef1461039057600080fd5b806301ffc9a7146102f9578063057535b014610321575b600080fd5b61030c610307366004613efc565b610854565b60405190151581526020015b60405180910390f35b6103487ff97fb9ac61687d33e6f167fb66bd0dbc2240a42d8369c39aadb26ea8ce05b5fe81565b604051908152602001610318565b610369610364366004613e56565b6108ed565b005b600d546001600160a01b03165b6040516001600160a01b039091168152602001610318565b6103487f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f781565b6103786103c5366004613b2f565b6005602052600090815260409020546001600160a01b031681565b6103486103ee366004613ec0565b60009081526020819052604090206001015490565b610369610411366004613b9f565b610e7e565b610369610424366004613ed8565b610eba565b610369610437366004613ed8565b610ee5565b61036961044a366004613cfa565b610f71565b6103487fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b91181565b610489610484366004613b2f565b6110a6565b60405161031891906141fb565b6104f86104a4366004613ec0565b6009602052600090815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495966001600160a01b039586169694861695938416949290931692909188565b604080519889526001600160a01b0397881660208a01529587169588019590955292851660608701529316608085015260a084019290925260c083019190915260e082015261010001610318565b610559610554366004613b2f565b6110ca565b60405161031891906142ad565b610348610574366004613fbd565b6110ee565b61030c610587366004613b2f565b6113fd565b6103487f038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd981565b6103486105c1366004613c59565b611494565b6103696105d4366004613b67565b6118b2565b6103696105e7366004613b2f565b611b2f565b6103696105fa366004613cfa565b611c00565b61030c61060d366004613ed8565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b610369610644366004613f73565b611d43565b610348600081565b610559611ef1565b600154610378906001600160a01b031681565b61037873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b61030c610695366004613b2f565b611f02565b6103486106a8366004613ec0565b611f0f565b6106c06106bb366004613ffa565b612117565b60408051928352602083019190915201610318565b6103487f0c98cf5b298d76683bff7ac7eb2544a1c5413c08c055cad5077796993f1b71e581565b610489612400565b610378610712366004613b2f565b6006602052600090815260409020546001600160a01b031681565b61036961073b366004613ed8565b61240c565b61076361074e366004613b2f565b60076020526000908152604090205460f81b81565b6040517fff000000000000000000000000000000000000000000000000000000000000009091168152602001610318565b6103696107a2366004613dc1565b612432565b6103696107b5366004613ca9565b6125d8565b6103487f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d381565b6103696107ef366004613b2f565b6126da565b610369610802366004613e01565b61273c565b610348610815366004613bdf565b61298b565b610369610828366004613b67565b612bab565b6103487f1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806108e757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03909116906365834acc9060240160206040518083038186803b15801561094957600080fd5b505afa15801561095d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109819190613ea0565b6109d25760405162461bcd60e51b815260206004820152601760248201527f4d616368696e6572793a206e6f74206d656368616e696300000000000000000060448201526064015b60405180910390fd5b80610a09576040517f299dcf9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006009600085856000818110610a3057634e487b7160e01b600052603260045260246000fd5b602090810292909201358352508101919091526040016000908120600301546001600160a01b0316915060098186868281610a7b57634e487b7160e01b600052603260045260246000fd5b90506020020135815260200190815260200160002060040160009054906101000a90046001600160a01b031690506000826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610ae457600080fd5b505afa158015610af8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1c919061402b565b610b2790600a614393565b905060005b85811015610e3a57600060096000898985818110610b5a57634e487b7160e01b600052603260045260246000fd5b9050602002013581526020019081526020016000209050600082118015610bab575060038101546001600160a01b038681169116141580610bab575060048101546001600160a01b03858116911614155b15610be2576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060070154421115610c20576040517f8d93cc8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101546001600160a01b031660009081526007602052604090205460f81b7f010000000000000000000000000000000000000000000000000000000000000090811614610c9b576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083878360050154610cae919061443e565b610cb89190614330565b6001838101549054604080517f0c340a240000000000000000000000000000000000000000000000000000000081529051939450610d79936001600160a01b039384169390921691630c340a2491600480820192602092909190829003018186803b158015610d2657600080fd5b505afa158015610d3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5e9190613b4b565b600585015460038601546001600160a01b0316929190612e1f565b60018054600484810154928501546040517f8033d6870000000000000000000000000000000000000000000000000000000081526001600160a01b03948516928101929092526024820185905283166044820152911690638033d68790606401600060405180830381600087803b158015610df357600080fd5b505af1158015610e07573d6000803e3d6000fd5b5050505060018201548254610e25916001600160a01b031690612ed0565b50508080610e32906144b7565b915050610b2c565b507f0210feaf40876b7bc453fe389be6733e7d450692bf07adab2d3c11980f94dcd6868686604051610e6e93929190614289565b60405180910390a1505050505050565b7f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3610ea98133612f71565b610eb4848484612fef565b50505050565b600082815260208190526040902060010154610ed68133612f71565b610ee083836131ae565b505050565b6001600160a01b0381163314610f635760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016109c9565b610f6d828261326a565b5050565b7f038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd9610f9c8133612f71565b60005b825181101561106a5760006001600160a01b0316838281518110610fd357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561101c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61105783828151811061103f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600261330790919063ffffffff16565b5080611062816144b7565b915050610f9f565b507f5d1fd21744530253cbd801d1685bf9e6f5d8a13044c3a7df5628b4c60d7d9e3b8260405161109a91906141fb565b60405180910390a15050565b6001600160a01b03811660009081526004602052604090206060906108e790613323565b6001600160a01b0381166000908152600c602052604090206060906108e790613323565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081523360048201526000916001600160a01b0316906365834acc9060240160206040518083038186803b15801561114b57600080fd5b505afa15801561115f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111839190613ea0565b6111cf5760405162461bcd60e51b815260206004820152601760248201527f4d616368696e6572793a206e6f74206d656368616e696300000000000000000060448201526064016109c9565b6111da600a85613330565b611210576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000848152600960205260409020600781015442111561125c576040517f8d93cc8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028082015461127591906001600160a01b0316613348565b6112ab576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018101546002820154600583015460038401546112db936001600160a01b039182169390821692911690612e1f565b600281015460018201546003830154600480850154600586015460068701546040517fa5d4096b0000000000000000000000000000000000000000000000000000000081526001600160a01b039788169763a5d4096b9761134e9790821696908216959091169392918d918d9101614160565b602060405180830381600087803b15801561136857600080fd5b505af115801561137c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a09190613f5b565b60018201549092506113bb906001600160a01b031686612ed0565b847ff3b176b50ba6ec4473f418ce17c562a616f7715b23a6bcea8e41d78621f56b34836040516113ed91815260200190565b60405180910390a2509392505050565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260009216906365834acc9060240160206040518083038186803b15801561145c57600080fd5b505afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e79190613ea0565b60007f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f76114c18133612f71565b336000908152600560205260409020546001600160a01b0316611510576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038716158061152d57506001600160a01b038616155b15611564576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8461159b576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836115d2576040517f5380c59d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b42831161160b576040517f769d11e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854915060006040518061010001604052806008548152602001336001600160a01b0316815260200160056000336001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a90046001600160a01b03166001600160a01b03168152602001896001600160a01b03168152602001886001600160a01b031681526020018781526020018681526020018581525090508060096000836000015181526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060a0820151816005015560c0820151816006015560e082015181600701559050506117de8160000151600c6000336001600160a01b03166001600160a01b0316815260200190815260200160002061336a90919063ffffffff16565b5080516117ed90600a9061336a565b506001600860008282546118019190614318565b9091555050805160208201516040808401516060850151608086015160a087015160c088015160e089015195517f399699ab6f1401e7784608cbdabe944658876a522eb163c69fd166dbf2776c4f9761189f97909695949392916001600160a01b03978816815295871660208701529386166040860152919094166060840152608083019390935260a082019290925260c081019190915260e00190565b60405180910390a2505095945050505050565b7fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b9116118dd8133612f71565b6001600160a01b03831615806118fa57506001600160a01b038216155b15611931576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826001600160a01b031663cd985af06040518163ffffffff1660e01b815260040160206040518083038186803b15801561196c57600080fd5b505afa158015611980573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a49190613f3c565b60018111156119c357634e487b7160e01b600052602160045260246000fd5b146119fa576040517fa2d3ada200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611a05600283613348565b611a3b576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381166000908152600560205260409020541615611a8e576001600160a01b0380841660009081526005602090815260408083205490931682526004905220611a8c9084613376565b505b6001600160a01b03838116600090815260056020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694871694851790559282526004905220611ae89084613307565b506040516001600160a01b0383811682528416907f1a70401259f8cfe91ae1c8d3f5b4f357d27664794f83e3bcd4648f047554f680906020015b60405180910390a2505050565b7f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d3611b5a8133612f71565b6001600160a01b038216611b9a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384169081179091556040519081527fd820b9bd66f5f69e0ee876fe38d41d612586cb5dfdab23721469fc9c6dd5950d9060200161109a565b7f038c8d5a0695aa8e4bf7e2d14cb85443db816cf8bdf8985d9f1a65519aeb6cd9611c2b8133612f71565b60005b8251811015611d13576000611c8d60046000868581518110611c6057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002061338b565b1115611cc5576040517f61c45a0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d00838281518110611ce857634e487b7160e01b600052603260045260246000fd5b6020026020010151600261337690919063ffffffff16565b5080611d0b816144b7565b915050611c2e565b507f4290941fe8d89409196966ddfc719772595cef6116ed6bde0bcc72e1182b52b58260405161109a91906141fb565b7f1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c611d6e8133612f71565b6000848152600960205260408120905b83811015611eaf57600060096000878785818110611dac57634e487b7160e01b600052603260045260246000fd5b9050602002013581526020019081526020016000209050806000015483600001541480611dee5750600180820154908401546001600160a01b03908116911614155b80611e0e5750600380820154908401546001600160a01b03908116911614155b80611e2e5750600480820154908401546001600160a01b03908116911614155b15611e65576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060050154836005016000828254611e7d9190614318565b909155505060018101548154611e9c916001600160a01b031690612ed0565b5080611ea7816144b7565b915050611d7e565b50847fbba31c5a03767b9eba75f83badce7bc719848c62b42334ab0984c13b96c66bbe8585604051611ee2929190614248565b60405180910390a25050505050565b6060611efd600a613323565b905090565b60006108e7600283613348565b600d546040517f65834acc0000000000000000000000000000000000000000000000000000000081523360048201526000916001600160a01b0316906365834acc9060240160206040518083038186803b158015611f6c57600080fd5b505afa158015611f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa49190613ea0565b611ff05760405162461bcd60e51b815260206004820152601760248201527f4d616368696e6572793a206e6f74206d656368616e696300000000000000000060448201526064016109c9565b611ffb600a83613330565b612031576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600960205260409020600781015442101561207d576040517fdae7dbed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005810154600182015460038301549193506120a7916001600160a01b0390811691163085612e1f565b6001810154600582015460038301546120ce926001600160a01b0391821692911690613395565b60018101546120e6906001600160a01b031684612ed0565b60405183907f9e52c476c07e14b40a7ee505cae05543e63c4c2d0c69323803c1fe0b4dd23b8a90600090a250919050565b6000807ff97fb9ac61687d33e6f167fb66bd0dbc2240a42d8369c39aadb26ea8ce05b5fe6121458133612f71565b6000878152600960205260408082208883529120600481015460038301546001600160a01b0390811691161415806121925750600381015460048301546001600160a01b03908116911614155b156121c9576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600701544211806121de5750806007015442115b15612215576040517f8d93cc8000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018201546001600160a01b031660009081526007602052604090205460f81b7f02000000000000000000000000000000000000000000000000000000000000009081161415806122a8575060018101546001600160a01b031660009081526007602052604090205460f81b7f020000000000000000000000000000000000000000000000000000000000000090811614155b156122df576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180830154908201546003840154612309926001600160a01b039182169290821691168a612e1f565b600180820154908301546003830154612333926001600160a01b0391821692908216911689612e1f565b8160050154871461235d5786826005016000828254612352919061445d565b909155506123759050565b6001820154612375906001600160a01b03168a612ed0565b8060050154861461239f5785816005016000828254612394919061445d565b909155506123b79050565b60018101546123b7906001600160a01b031689612ed0565b604080518881526020810188905289918b917fe5d287a20ff8c99c44a2f83dd58978ff9b7555963447c92435c01981a84cb3b0910160405180910390a350505094509492505050565b6060611efd6002613323565b6000828152602081905260409020600101546124288133612f71565b610ee0838361326a565b7f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f761245d8133612f71565b60005b8281101561259c576124a284848381811061248b57634e487b7160e01b600052603260045260246000fd5b90506020020135600a61333090919063ffffffff16565b6124d8576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600960008686858181106124fd57634e487b7160e01b600052603260045260246000fd5b60209081029290920135835250810191909152604001600020600101546001600160a01b03161461255a576040517fea8e4eb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61258a3385858481811061257e57634e487b7160e01b600052603260045260246000fd5b90506020020135612ed0565b80612594816144b7565b915050612460565b50336001600160a01b03167fbc02525bfba972df6ef3d6d34e6f4773de0e098177c254a62a4926ec94fdaea68484604051611b22929190614248565b7fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b9116126038133612f71565b6001600160a01b038316612643576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03831660008181526007602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660f887901c17905590517fff00000000000000000000000000000000000000000000000000000000000000851681527f3c0408280ff44f7512ae2e74ad6e1f6c56d3de609831a70405ea1b97adb768119101611b22565b7f0b43cb2c88b4e8fc5d4ac1352ba889b22584df0c58c4b5b589731a1c9f6f29d36127058133612f71565b600d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384161790555050565b7f1ed19b7d0b1c0348ffe4846e5ac48d95c752b9576e5f8791436d013fb3e84b5c6127678133612f71565b6000826001600160a01b031663cd985af06040518163ffffffff1660e01b815260040160206040518083038186803b1580156127a257600080fd5b505afa1580156127b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127da9190613f3c565b60018111156127f957634e487b7160e01b600052602160045260246000fd5b14612830576040517fa2d3ada200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61283b600283613348565b612871576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156129495761289f85858381811061248b57634e487b7160e01b600052603260045260246000fd5b6128d5576040517fd69b537900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600960008787858181106128fa57634e487b7160e01b600052603260045260246000fd5b90506020020135815260200190815260200160002060020160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080612941906144b7565b915050612874565b507f9be161fbaf23021e26ce5dc13fd51f0392db66c9989662b8fc4b4cc1a9e5ec9884848460405161297d9392919061425c565b60405180910390a150505050565b60007f49e347583a7b9e7f325e8963ee1f94127eba81e401796874b5a22f7c8f9d45f76129b88133612f71565b336000908152600660205260409020546001600160a01b0390811690891615806129e957506001600160a01b038816155b15612a20576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b86612a57576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85612a8e576040517f5380c59d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612aa36001600160a01b038a1633838a612e1f565b6040517fa5d4096b0000000000000000000000000000000000000000000000000000000081526001600160a01b0382169063a5d4096b90612af49033908d908d908d908d908d908d90600401614160565b602060405180830381600087803b158015612b0e57600080fd5b505af1158015612b22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b469190613f5b565b9250806001600160a01b0316336001600160a01b03167f1d816b1b1d67ea42ff2f6dae0a85f237a27e76afccb32ba25e4175330f3703e18b8b8b8b8b8b8b604051612b9797969594939291906141ae565b60405180910390a350509695505050505050565b7fe39dc63caee7a15eb0ffb77a826d10c23d40b5f7182b000737ab5c078838b911612bd68133612f71565b6001600160a01b0383161580612bf357506001600160a01b038216155b15612c2a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001826001600160a01b031663cd985af06040518163ffffffff1660e01b815260040160206040518083038186803b158015612c6557600080fd5b505afa158015612c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9d9190613f3c565b6001811115612cbc57634e487b7160e01b600052602160045260246000fd5b14612cf3576040517f967ade6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612cfe600283613348565b612d34576040517fc94f7a9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381166000908152600660205260409020541615612d87576001600160a01b0380841660009081526006602090815260408083205490931682526004905220612d859084613376565b505b6001600160a01b03838116600090815260066020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694871694851790559282526004905220612de19084613307565b506040516001600160a01b0383811682528416907f09864ed308dfc2a9cc6804e3b86d38a1aaa4f7adec68be5562b9dd8feb9c1b0590602001611b22565b6040516001600160a01b0380851660248301528316604482015260648101829052610eb49085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526133de565b6001600160a01b0382166000908152600c60205260409020612ef290826134c3565b50612efe600a826134c3565b5060009081526009602052604081208181556001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000009081169091556002820180548216905560038201805482169055600482018054909116905560058101829055600681018290556007015550565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610f6d57612fad816001600160a01b031660146134cf565b612fb88360206134cf565b604051602001612fc99291906140df565b60408051601f198184030181529082905262461bcd60e51b82526109c9916004016142e5565b6001600160a01b03831661306b5760405162461bcd60e51b815260206004820152602f60248201527f636f6c6c65637461626c652d647573742f63616e742d73656e642d647573742d60448201527f746f2d7a65726f2d61646472657373000000000000000000000000000000000060648201526084016109c9565b613076600e83613348565b156130e95760405162461bcd60e51b815260206004820152602e60248201527f636f6c6c65637461626c652d647573742f746f6b656e2d69732d706172742d6f60448201527f662d7468652d70726f746f636f6c00000000000000000000000000000000000060648201526084016109c9565b6001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141561314a576040516001600160a01b0384169082156108fc029083906000818181858888f19350505050158015613144573d6000803e3d6000fd5b5061315e565b61315e6001600160a01b0383168483613395565b604080516001600160a01b038086168252841660208201529081018290527f1e34c1aee8e83c2dcc14c21bb4bfeea7f46c0c998cb797ac7cc4d7a18f5c656b9060600160405180910390a1505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610f6d576000828152602081815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556132263390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610f6d576000828152602081815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061331c836001600160a01b03841661373e565b9392505050565b6060600061331c8361378d565b6000818152600183016020526040812054151561331c565b6001600160a01b0381166000908152600183016020526040812054151561331c565b600061331c838361373e565b600061331c836001600160a01b0384166137e9565b60006108e7825490565b6040516001600160a01b038316602482015260448101829052610ee09084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612e6c565b6000613433826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166139069092919063ffffffff16565b805190915015610ee057808060200190518101906134519190613ea0565b610ee05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016109c9565b600061331c83836137e9565b606060006134de83600261443e565b6134e9906002614318565b67ffffffffffffffff81111561350f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613539576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061357e57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106135ef57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061362b84600261443e565b613636906001614318565b90505b60018111156136ef577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061368557634e487b7160e01b600052603260045260246000fd5b1a60f81b8282815181106136a957634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936136e8816144a0565b9050613639565b50831561331c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109c9565b6000818152600183016020526040812054613785575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108e7565b5060006108e7565b6060816000018054806020026020016040519081016040528092919081815260200182805480156137dd57602002820191906000526020600020905b8154815260200190600101908083116137c9575b50505050509050919050565b600081815260018301602052604081205480156138fc57600061380d60018361445d565b85549091506000906138219060019061445d565b90508181146138a257600086600001828154811061384f57634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061388057634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b85548690806138c157634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108e7565b60009150506108e7565b6060613915848460008561391d565b949350505050565b6060824710156139955760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016109c9565b843b6139e35760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c9565b600080866001600160a01b031685876040516139ff91906140c3565b60006040518083038185875af1925050503d8060008114613a3c576040519150601f19603f3d011682016040523d82523d6000602084013e613a41565b606091505b5091509150613a51828286613a5c565b979650505050505050565b60608315613a6b57508161331c565b825115613a7b5782518084602001fd5b8160405162461bcd60e51b81526004016109c991906142e5565b8035613aa0816144fe565b919050565b60008083601f840112613ab6578182fd5b50813567ffffffffffffffff811115613acd578182fd5b6020830191508360208260051b8501011115613ae857600080fd5b9250929050565b60008083601f840112613b00578182fd5b50813567ffffffffffffffff811115613b17578182fd5b602083019150836020828501011115613ae857600080fd5b600060208284031215613b40578081fd5b813561331c816144fe565b600060208284031215613b5c578081fd5b815161331c816144fe565b60008060408385031215613b79578081fd5b8235613b84816144fe565b91506020830135613b94816144fe565b809150509250929050565b600080600060608486031215613bb3578081fd5b8335613bbe816144fe565b92506020840135613bce816144fe565b929592945050506040919091013590565b60008060008060008060a08789031215613bf7578182fd5b8635613c02816144fe565b95506020870135613c12816144fe565b94506040870135935060608701359250608087013567ffffffffffffffff811115613c3b578283fd5b613c4789828a01613aef565b979a9699509497509295939492505050565b600080600080600060a08688031215613c70578081fd5b8535613c7b816144fe565b94506020860135613c8b816144fe565b94979496505050506040830135926060810135926080909101359150565b60008060408385031215613cbb578182fd5b8235613cc6816144fe565b915060208301357fff0000000000000000000000000000000000000000000000000000000000000081168114613b94578182fd5b60006020808385031215613d0c578182fd5b823567ffffffffffffffff80821115613d23578384fd5b818501915085601f830112613d36578384fd5b813581811115613d4857613d486144e8565b8060051b604051601f19603f83011681018181108582111715613d6d57613d6d6144e8565b604052828152858101935084860182860187018a1015613d8b578788fd5b8795505b83861015613db457613da081613a95565b855260019590950194938601938601613d8f565b5098975050505050505050565b60008060208385031215613dd3578182fd5b823567ffffffffffffffff811115613de9578283fd5b613df585828601613aa5565b90969095509350505050565b600080600060408486031215613e15578283fd5b833567ffffffffffffffff811115613e2b578384fd5b613e3786828701613aa5565b9094509250506020840135613e4b816144fe565b809150509250925092565b600080600060408486031215613e6a578081fd5b833567ffffffffffffffff811115613e80578182fd5b613e8c86828701613aa5565b909790965060209590950135949350505050565b600060208284031215613eb1578081fd5b8151801515811461331c578182fd5b600060208284031215613ed1578081fd5b5035919050565b60008060408385031215613eea578182fd5b823591506020830135613b94816144fe565b600060208284031215613f0d578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461331c578182fd5b600060208284031215613f4d578081fd5b81516002811061331c578182fd5b600060208284031215613f6c578081fd5b5051919050565b600080600060408486031215613f87578081fd5b83359250602084013567ffffffffffffffff811115613fa4578182fd5b613fb086828701613aa5565b9497909650939450505050565b600080600060408486031215613fd1578081fd5b83359250602084013567ffffffffffffffff811115613fee578182fd5b613fb086828701613aef565b6000806000806080858703121561400f578182fd5b5050823594602084013594506040840135936060013592509050565b60006020828403121561403c578081fd5b815160ff8116811461331c578182fd5b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561407d578081fd5b8260051b80836020870137939093016020019283525090919050565b8183528181602085013750600080602083850101526020601f19601f840116840101905092915050565b600082516140d5818460208701614474565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614117816017850160208801614474565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614154816028840160208801614474565b01602801949350505050565b60006001600160a01b03808a168352808916602084015280881660408401525085606083015284608083015260c060a08301526141a160c083018486614099565b9998505050505050505050565b60006001600160a01b03808a16835280891660208401525086604083015285606083015260c060808301526141e760c083018587614099565b90508260a083015298975050505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561423c5783516001600160a01b031683529284019291840191600101614217565b50909695505050505050565b60208152600061391560208301848661404c565b60408152600061427060408301858761404c565b90506001600160a01b0383166020830152949350505050565b60408152600061429d60408301858761404c565b9050826020830152949350505050565b6020808252825182820181905260009190848201906040850190845b8181101561423c578351835292840192918401916001016142c9565b6020815260008251806020840152614304816040850160208701614474565b601f01601f19169190910160400192915050565b6000821982111561432b5761432b6144d2565b500190565b60008261434b57634e487b7160e01b81526012600452602481fd5b500490565b600181815b8085111561438b578160001904821115614371576143716144d2565b8085161561437e57918102915b93841c9390800290614355565b509250929050565b600061331c60ff8416836000826143ac575060016108e7565b816143b9575060006108e7565b81600181146143cf57600281146143d9576143f5565b60019150506108e7565b60ff8411156143ea576143ea6144d2565b50506001821b6108e7565b5060208310610133831016604e8410600b8410161715614418575081810a6108e7565b6144228383614350565b8060001904821115614436576144366144d2565b029392505050565b6000816000190483118215151615614458576144586144d2565b500290565b60008282101561446f5761446f6144d2565b500390565b60005b8381101561448f578181015183820152602001614477565b83811115610eb45750506000910152565b6000816144af576144af6144d2565b506000190190565b60006000198214156144cb576144cb6144d2565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461451357600080fd5b5056fea26469706673582212208fcbb6daae8eb8d450c2cddd708a1e2b4993813a7af7f6e586104d3ef9aa421364736f6c63430008040033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "getRoleAdmin(bytes32)": {
        "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}."
      },
      "grantRole(bytes32,address)": {
        "details": "Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role."
      },
      "hasRole(bytes32,address)": {
        "details": "Returns `true` if `account` has been granted `role`."
      },
      "renounceRole(bytes32,address)": {
        "details": "Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`."
      },
      "revokeRole(bytes32,address)": {
        "details": "Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role."
      },
      "supportsInterface(bytes4)": {
        "details": "See {IERC165-supportsInterface}."
      }
    },
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 478,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "_roles",
        "offset": 0,
        "slot": "0",
        "type": "t_mapping(t_bytes32,t_struct(RoleData)473_storage)"
      },
      {
        "astId": 5607,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "otcPool",
        "offset": 0,
        "slot": "1",
        "type": "t_address"
      },
      {
        "astId": 5610,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "_swappers",
        "offset": 0,
        "slot": "2",
        "type": "t_struct(AddressSet)2664_storage"
      },
      {
        "astId": 5615,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "_swapperStrategies",
        "offset": 0,
        "slot": "4",
        "type": "t_mapping(t_address,t_struct(AddressSet)2664_storage)"
      },
      {
        "astId": 5620,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "strategyAsyncSwapper",
        "offset": 0,
        "slot": "5",
        "type": "t_mapping(t_address,t_address)"
      },
      {
        "astId": 5625,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "strategySyncSwapper",
        "offset": 0,
        "slot": "6",
        "type": "t_mapping(t_address,t_address)"
      },
      {
        "astId": 5630,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "strategyPermissions",
        "offset": 0,
        "slot": "7",
        "type": "t_mapping(t_address,t_bytes1)"
      },
      {
        "astId": 4959,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "_tradeCounter",
        "offset": 0,
        "slot": "8",
        "type": "t_uint256"
      },
      {
        "astId": 4965,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "pendingTradesById",
        "offset": 0,
        "slot": "9",
        "type": "t_mapping(t_uint256,t_struct(Trade)4813_storage)"
      },
      {
        "astId": 4968,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "_pendingTradesIds",
        "offset": 0,
        "slot": "10",
        "type": "t_struct(UintSet)2821_storage"
      },
      {
        "astId": 4973,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "_pendingTradesByOwner",
        "offset": 0,
        "slot": "12",
        "type": "t_mapping(t_address,t_struct(UintSet)2821_storage)"
      },
      {
        "astId": 272,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "_mechanicsRegistry",
        "offset": 0,
        "slot": "13",
        "type": "t_contract(IMechanicsRegistry)379"
      },
      {
        "astId": 21,
        "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
        "label": "protocolTokens",
        "offset": 0,
        "slot": "14",
        "type": "t_struct(AddressSet)2664_storage"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_array(t_bytes32)dyn_storage": {
        "base": "t_bytes32",
        "encoding": "dynamic_array",
        "label": "bytes32[]",
        "numberOfBytes": "32"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_bytes1": {
        "encoding": "inplace",
        "label": "bytes1",
        "numberOfBytes": "1"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_contract(IMechanicsRegistry)379": {
        "encoding": "inplace",
        "label": "contract IMechanicsRegistry",
        "numberOfBytes": "20"
      },
      "t_mapping(t_address,t_address)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => address)",
        "numberOfBytes": "32",
        "value": "t_address"
      },
      "t_mapping(t_address,t_bool)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => bool)",
        "numberOfBytes": "32",
        "value": "t_bool"
      },
      "t_mapping(t_address,t_bytes1)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => bytes1)",
        "numberOfBytes": "32",
        "value": "t_bytes1"
      },
      "t_mapping(t_address,t_struct(AddressSet)2664_storage)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => struct EnumerableSet.AddressSet)",
        "numberOfBytes": "32",
        "value": "t_struct(AddressSet)2664_storage"
      },
      "t_mapping(t_address,t_struct(UintSet)2821_storage)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => struct EnumerableSet.UintSet)",
        "numberOfBytes": "32",
        "value": "t_struct(UintSet)2821_storage"
      },
      "t_mapping(t_bytes32,t_struct(RoleData)473_storage)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => struct AccessControl.RoleData)",
        "numberOfBytes": "32",
        "value": "t_struct(RoleData)473_storage"
      },
      "t_mapping(t_bytes32,t_uint256)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_mapping(t_uint256,t_struct(Trade)4813_storage)": {
        "encoding": "mapping",
        "key": "t_uint256",
        "label": "mapping(uint256 => struct ITradeFactoryPositionsHandler.Trade)",
        "numberOfBytes": "32",
        "value": "t_struct(Trade)4813_storage"
      },
      "t_struct(AddressSet)2664_storage": {
        "encoding": "inplace",
        "label": "struct EnumerableSet.AddressSet",
        "members": [
          {
            "astId": 2663,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_inner",
            "offset": 0,
            "slot": "0",
            "type": "t_struct(Set)2363_storage"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_struct(RoleData)473_storage": {
        "encoding": "inplace",
        "label": "struct AccessControl.RoleData",
        "members": [
          {
            "astId": 470,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "members",
            "offset": 0,
            "slot": "0",
            "type": "t_mapping(t_address,t_bool)"
          },
          {
            "astId": 472,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "adminRole",
            "offset": 0,
            "slot": "1",
            "type": "t_bytes32"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_struct(Set)2363_storage": {
        "encoding": "inplace",
        "label": "struct EnumerableSet.Set",
        "members": [
          {
            "astId": 2358,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_values",
            "offset": 0,
            "slot": "0",
            "type": "t_array(t_bytes32)dyn_storage"
          },
          {
            "astId": 2362,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_indexes",
            "offset": 0,
            "slot": "1",
            "type": "t_mapping(t_bytes32,t_uint256)"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_struct(Trade)4813_storage": {
        "encoding": "inplace",
        "label": "struct ITradeFactoryPositionsHandler.Trade",
        "members": [
          {
            "astId": 4798,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_id",
            "offset": 0,
            "slot": "0",
            "type": "t_uint256"
          },
          {
            "astId": 4800,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_strategy",
            "offset": 0,
            "slot": "1",
            "type": "t_address"
          },
          {
            "astId": 4802,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_swapper",
            "offset": 0,
            "slot": "2",
            "type": "t_address"
          },
          {
            "astId": 4804,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_tokenIn",
            "offset": 0,
            "slot": "3",
            "type": "t_address"
          },
          {
            "astId": 4806,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_tokenOut",
            "offset": 0,
            "slot": "4",
            "type": "t_address"
          },
          {
            "astId": 4808,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_amountIn",
            "offset": 0,
            "slot": "5",
            "type": "t_uint256"
          },
          {
            "astId": 4810,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_maxSlippage",
            "offset": 0,
            "slot": "6",
            "type": "t_uint256"
          },
          {
            "astId": 4812,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_deadline",
            "offset": 0,
            "slot": "7",
            "type": "t_uint256"
          }
        ],
        "numberOfBytes": "256"
      },
      "t_struct(UintSet)2821_storage": {
        "encoding": "inplace",
        "label": "struct EnumerableSet.UintSet",
        "members": [
          {
            "astId": 2820,
            "contract": "contracts/TradeFactory/TradeFactory.sol:TradeFactory",
            "label": "_inner",
            "offset": 0,
            "slot": "0",
            "type": "t_struct(Set)2363_storage"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}