{
  "address": "0xde87A91358FE9C2506290cA21E81438Cd9543d58",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_masterDeployer",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [],
      "name": "InvalidTokenOrder",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "UnauthorisedDeployer",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroAddress",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "configAddress",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes",
          "name": "_deployData",
          "type": "bytes"
        }
      ],
      "name": "deployPool",
      "outputs": [
        {
          "internalType": "address",
          "name": "pool",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "token0",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token1",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "startIndex",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "count",
          "type": "uint256"
        }
      ],
      "name": "getPools",
      "outputs": [
        {
          "internalType": "address[]",
          "name": "pairPools",
          "type": "address[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "masterDeployer",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "name": "pools",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "token0",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "token1",
          "type": "address"
        }
      ],
      "name": "poolsCount",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "count",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0xc958afef82c4b92a3c8933a38d01e805abf1fa194d8aea9dd698abf029cb3280",
  "receipt": {
    "to": null,
    "from": "0x58B4B6951e9174F153635574076241315D7d3503",
    "contractAddress": "0xde87A91358FE9C2506290cA21E81438Cd9543d58",
    "transactionIndex": 0,
    "gasUsed": "4566900",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x6fa7c18139fb2ec0d7769861acae77d6f2b972a915015f5a81cefef7a1f0d071",
    "transactionHash": "0xc958afef82c4b92a3c8933a38d01e805abf1fa194d8aea9dd698abf029cb3280",
    "logs": [],
    "blockNumber": 28497204,
    "cumulativeGasUsed": "4566900",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0xdCFaae69E67E4bA73d5A890Fcae097eB3C615e96"
  ],
  "solcInputHash": "426130bf1086dd12d6f15ed5763ff493",
  "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_masterDeployer\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidTokenOrder\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorisedDeployer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"configAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_deployData\",\"type\":\"bytes\"}],\"name\":\"deployPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token1\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"getPools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"pairPools\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"masterDeployer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"pools\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token1\",\"type\":\"address\"}],\"name\":\"poolsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Mudit Gupta.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Contract for deploying Trident exchange Constant Product Pool with configurations.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/pool/ConstantProductPoolFactory.sol\":\"ConstantProductPoolFactory\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":99999},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IBentoBoxMinimal.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\nimport \\\"../libraries/RebaseLibrary.sol\\\";\\n\\n/// @notice Minimal BentoBox vault interface.\\n/// @dev `token` is aliased as `address` from `IERC20` for simplicity.\\ninterface IBentoBoxMinimal {\\n    /// @notice Balance per ERC-20 token per account in shares.\\n    function balanceOf(address, address) external view returns (uint256);\\n\\n    /// @dev Helper function to represent an `amount` of `token` in shares.\\n    /// @param token The ERC-20 token.\\n    /// @param amount The `token` amount.\\n    /// @param roundUp If the result `share` should be rounded up.\\n    /// @return share The token amount represented in shares.\\n    function toShare(\\n        address token,\\n        uint256 amount,\\n        bool roundUp\\n    ) external view returns (uint256 share);\\n\\n    /// @dev Helper function to represent shares back into the `token` amount.\\n    /// @param token The ERC-20 token.\\n    /// @param share The amount of shares.\\n    /// @param roundUp If the result should be rounded up.\\n    /// @return amount The share amount back into native representation.\\n    function toAmount(\\n        address token,\\n        uint256 share,\\n        bool roundUp\\n    ) external view returns (uint256 amount);\\n\\n    /// @notice Registers this contract so that users can approve it for BentoBox.\\n    function registerProtocol() external;\\n\\n    /// @notice Deposit an amount of `token` represented in either `amount` or `share`.\\n    /// @param token The ERC-20 token to deposit.\\n    /// @param from which account to pull the tokens.\\n    /// @param to which account to push the tokens.\\n    /// @param amount Token amount in native representation to deposit.\\n    /// @param share Token amount represented in shares to deposit. Takes precedence over `amount`.\\n    /// @return amountOut The amount deposited.\\n    /// @return shareOut The deposited amount represented in shares.\\n    function deposit(\\n        address token,\\n        address from,\\n        address to,\\n        uint256 amount,\\n        uint256 share\\n    ) external payable returns (uint256 amountOut, uint256 shareOut);\\n\\n    /// @notice Withdraws an amount of `token` from a user account.\\n    /// @param token_ The ERC-20 token to withdraw.\\n    /// @param from which user to pull the tokens.\\n    /// @param to which user to push the tokens.\\n    /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.\\n    /// @param share Like above, but `share` takes precedence over `amount`.\\n    function withdraw(\\n        address token_,\\n        address from,\\n        address to,\\n        uint256 amount,\\n        uint256 share\\n    ) external returns (uint256 amountOut, uint256 shareOut);\\n\\n    /// @notice Transfer shares from a user account to another one.\\n    /// @param token The ERC-20 token to transfer.\\n    /// @param from which user to pull the tokens.\\n    /// @param to which user to push the tokens.\\n    /// @param share The amount of `token` in shares.\\n    function transfer(\\n        address token,\\n        address from,\\n        address to,\\n        uint256 share\\n    ) external;\\n\\n    /// @dev Reads the Rebase `totals`from storage for a given token\\n    function totals(address token) external view returns (Rebase memory total);\\n\\n    /// @dev Approves users' BentoBox assets to a \\\"master\\\" contract.\\n    function setMasterContractApproval(\\n        address user,\\n        address masterContract,\\n        bool approved,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) external;\\n}\\n\",\"keccak256\":\"0x80ef2859d876a6b464e28dcaa03b4b0e8d1f81a946e3b3875d4fba66314dc369\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/IMasterDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident pool deployer interface.\\ninterface IMasterDeployer {\\n    function barFee() external view returns (uint256);\\n\\n    function barFeeTo() external view returns (address);\\n\\n    function bento() external view returns (address);\\n\\n    function migrator() external view returns (address);\\n\\n    function pools(address pool) external view returns (bool);\\n\\n    function deployPool(address factory, bytes calldata deployData) external returns (address);\\n}\\n\",\"keccak256\":\"0x91c23deb7e4372faa35a0ae4ef6ccd684049aea7b2c75cf63009b28591b91cbc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/IPool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.5.0;\\npragma experimental ABIEncoderV2;\\n\\n/// @notice Trident pool interface.\\ninterface IPool {\\n    /// @notice Executes a swap from one token to another.\\n    /// @dev The input tokens must've already been sent to the pool.\\n    /// @param data ABI-encoded params that the pool requires.\\n    /// @return finalAmountOut The amount of output tokens that were sent to the user.\\n    function swap(bytes calldata data) external returns (uint256 finalAmountOut);\\n\\n    /// @notice Executes a swap from one token to another with a callback.\\n    /// @dev This function allows borrowing the output tokens and sending the input tokens in the callback.\\n    /// @param data ABI-encoded params that the pool requires.\\n    /// @return finalAmountOut The amount of output tokens that were sent to the user.\\n    function flashSwap(bytes calldata data) external returns (uint256 finalAmountOut);\\n\\n    /// @notice Mints liquidity tokens.\\n    /// @param data ABI-encoded params that the pool requires.\\n    /// @return liquidity The amount of liquidity tokens that were minted for the user.\\n    function mint(bytes calldata data) external returns (uint256 liquidity);\\n\\n    /// @notice Burns liquidity tokens.\\n    /// @dev The input LP tokens must've already been sent to the pool.\\n    /// @param data ABI-encoded params that the pool requires.\\n    /// @return withdrawnAmounts The amount of various output tokens that were sent to the user.\\n    function burn(bytes calldata data) external returns (TokenAmount[] memory withdrawnAmounts);\\n\\n    /// @notice Burns liquidity tokens for a single output token.\\n    /// @dev The input LP tokens must've already been sent to the pool.\\n    /// @param data ABI-encoded params that the pool requires.\\n    /// @return amountOut The amount of output tokens that were sent to the user.\\n    function burnSingle(bytes calldata data) external returns (uint256 amountOut);\\n\\n    /// @return A unique identifier for the pool type.\\n    function poolIdentifier() external pure returns (bytes32);\\n\\n    /// @return An array of tokens supported by the pool.\\n    function getAssets() external view returns (address[] memory);\\n\\n    /// @notice Simulates a trade and returns the expected output.\\n    /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\\n    /// @param data ABI-encoded params that the pool requires.\\n    /// @return finalAmountOut The amount of output tokens that will be sent to the user if the trade is executed.\\n    function getAmountOut(bytes calldata data) external view returns (uint256 finalAmountOut);\\n\\n    /// @notice Simulates a trade and returns the expected output.\\n    /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\\n    /// @param data ABI-encoded params that the pool requires.\\n    /// @return finalAmountIn The amount of input tokens that are required from the user if the trade is executed.\\n    function getAmountIn(bytes calldata data) external view returns (uint256 finalAmountIn);\\n\\n    /// @dev This event must be emitted on all swaps.\\n    event Swap(address indexed recipient, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut);\\n\\n    /// @dev This struct frames output tokens for burns.\\n    struct TokenAmount {\\n        address token;\\n        uint256 amount;\\n    }\\n}\\n\",\"keccak256\":\"0xa6f92ccb525b018c0c209819640e8d746f1134b4c4d9acd4f22d3e170323f1fa\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/ITridentCallee.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident pool callback interface.\\ninterface ITridentCallee {\\n    function tridentSwapCallback(bytes calldata data) external;\\n\\n    function tridentMintCallback(bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x256e838362a3064201b37b3b7c08bc1421b173a6fea633176123f0b827b868c9\",\"license\":\"GPL-3.0-or-later\"},\"contracts/libraries/RebaseLibrary.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity ^0.8;\\n\\nstruct Rebase {\\n    uint128 elastic;\\n    uint128 base;\\n}\\n\\n/// @notice A rebasing library\\nlibrary RebaseLibrary {\\n    /// @notice Calculates the base value in relationship to `elastic` and `total`.\\n    function toBase(Rebase memory total, uint256 elastic) internal pure returns (uint256 base) {\\n        if (total.elastic == 0) {\\n            base = elastic;\\n        } else {\\n            base = (elastic * total.base) / total.elastic;\\n        }\\n    }\\n\\n    /// @notice Calculates the elastic value in relationship to `base` and `total`.\\n    function toElastic(Rebase memory total, uint256 base) internal pure returns (uint256 elastic) {\\n        if (total.base == 0) {\\n            elastic = base;\\n        } else {\\n            elastic = (base * total.elastic) / total.base;\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xa83360497e7e2a04332211832a8ceb41ef0301892fcf1b17174d7d4466782d44\",\"license\":\"GPL-3.0-or-later\"},\"contracts/libraries/TridentMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident sqrt helper library.\\nlibrary TridentMath {\\n    /// @notice Calculate sqrt (x) rounding down, where `x` is unsigned 256-bit integer number.\\n    /// @dev Adapted from https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol, \\n    /// \\u00a9 2019 ABDK Consulting, License-Identifier: BSD-4-Clause.\\n    /// @param x Unsigned 256-bit integer number.\\n    /// @return result Sqrt result.\\n    function sqrt(uint256 x) internal pure returns (uint256 result) {\\n        unchecked {\\n            if (x == 0) result = 0;\\n            else {\\n                uint256 xx = x;\\n                uint256 r = 1;\\n                if (xx >= 0x100000000000000000000000000000000) {\\n                    xx >>= 128;\\n                    r <<= 64;\\n                }\\n                if (xx >= 0x10000000000000000) {\\n                    xx >>= 64;\\n                    r <<= 32;\\n                }\\n                if (xx >= 0x100000000) {\\n                    xx >>= 32;\\n                    r <<= 16;\\n                }\\n                if (xx >= 0x10000) {\\n                    xx >>= 16;\\n                    r <<= 8;\\n                }\\n                if (xx >= 0x100) {\\n                    xx >>= 8;\\n                    r <<= 4;\\n                }\\n                if (xx >= 0x10) {\\n                    xx >>= 4;\\n                    r <<= 2;\\n                }\\n                if (xx >= 0x8) {\\n                    r <<= 1;\\n                }\\n                r = (r + x / r) >> 1;\\n                r = (r + x / r) >> 1;\\n                r = (r + x / r) >> 1;\\n                r = (r + x / r) >> 1;\\n                r = (r + x / r) >> 1;\\n                r = (r + x / r) >> 1;\\n                r = (r + x / r) >> 1; // @dev Seven iterations should be enough.\\n                uint256 r1 = x / r;\\n                result = r < r1 ? r : r1;\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xccbada517ace78149a4602ce782e6faf408404ee300569b8adf76e0eb7f0dd3b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/pool/ConstantProductPool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\nimport \\\"../interfaces/IBentoBoxMinimal.sol\\\";\\nimport \\\"../interfaces/IMasterDeployer.sol\\\";\\nimport \\\"../interfaces/IPool.sol\\\";\\nimport \\\"../interfaces/ITridentCallee.sol\\\";\\nimport \\\"../libraries/TridentMath.sol\\\";\\nimport \\\"./TridentERC20.sol\\\";\\n\\n/// @notice Trident exchange pool template with constant product formula for swapping between an ERC-20 token pair.\\n/// @dev The reserves are stored as bento shares.\\n///      The curve is applied to shares as well. This pool does not care about the underlying amounts.\\ncontract ConstantProductPool is IPool, TridentERC20 {\\n    event Mint(address indexed sender, uint256 amount0, uint256 amount1, address indexed recipient, uint256 liquidity);\\n    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed recipient, uint256 liquidity);\\n    event Sync(uint256 reserve0, uint256 reserve1);\\n\\n    uint256 internal constant MINIMUM_LIQUIDITY = 1000;\\n\\n    uint8 internal constant PRECISION = 112;\\n    uint256 internal constant MAX_FEE = 10000; // @dev 100%.\\n    uint256 internal constant MAX_FEE_SQUARE = 100000000;\\n    uint256 public immutable swapFee;\\n    uint256 internal immutable MAX_FEE_MINUS_SWAP_FEE;\\n\\n    address public immutable barFeeTo;\\n    IBentoBoxMinimal public immutable bento;\\n    IMasterDeployer public immutable masterDeployer;\\n    address public immutable token0;\\n    address public immutable token1;\\n\\n    uint256 public barFee;\\n    uint256 public price0CumulativeLast;\\n    uint256 public price1CumulativeLast;\\n    uint256 public kLast;\\n\\n    uint112 internal reserve0;\\n    uint112 internal reserve1;\\n    uint32 internal blockTimestampLast;\\n\\n    bytes32 public constant override poolIdentifier = \\\"Trident:ConstantProduct\\\";\\n\\n    uint256 internal unlocked;\\n    modifier lock() {\\n        require(unlocked == 1, \\\"LOCKED\\\");\\n        unlocked = 2;\\n        _;\\n        unlocked = 1;\\n    }\\n\\n    constructor(bytes memory _deployData, address _masterDeployer) {\\n        (address _token0, address _token1, uint256 _swapFee, bool _twapSupport) = abi.decode(\\n            _deployData,\\n            (address, address, uint256, bool)\\n        );\\n\\n        // @dev Factory ensures that the tokens are sorted.\\n        require(_token0 != address(0), \\\"ZERO_ADDRESS\\\");\\n        require(_token0 != _token1, \\\"IDENTICAL_ADDRESSES\\\");\\n        require(_token0 != address(this), \\\"INVALID_TOKEN\\\");\\n        require(_token1 != address(this), \\\"INVALID_TOKEN\\\");\\n        require(_swapFee <= MAX_FEE, \\\"INVALID_SWAP_FEE\\\");\\n\\n        token0 = _token0;\\n        token1 = _token1;\\n        swapFee = _swapFee;\\n        // @dev This is safe from underflow - `swapFee` cannot exceed `MAX_FEE` per previous check.\\n        unchecked {\\n            MAX_FEE_MINUS_SWAP_FEE = MAX_FEE - _swapFee;\\n        }\\n        barFee = IMasterDeployer(_masterDeployer).barFee();\\n        barFeeTo = IMasterDeployer(_masterDeployer).barFeeTo();\\n        bento = IBentoBoxMinimal(IMasterDeployer(_masterDeployer).bento());\\n        masterDeployer = IMasterDeployer(_masterDeployer);\\n        unlocked = 1;\\n        if (_twapSupport) blockTimestampLast = 1;\\n    }\\n\\n    /// @dev Mints LP tokens - should be called via the router after transferring `bento` tokens.\\n    /// The router must ensure that sufficient LP tokens are minted by using the return value.\\n    function mint(bytes calldata data) public override lock returns (uint256 liquidity) {\\n        address recipient = abi.decode(data, (address));\\n        (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n        (uint256 balance0, uint256 balance1) = _balance();\\n\\n        uint256 computed = TridentMath.sqrt(balance0 * balance1);\\n        uint256 amount0 = balance0 - _reserve0;\\n        uint256 amount1 = balance1 - _reserve1;\\n\\n        (uint256 fee0, uint256 fee1) = _nonOptimalMintFee(amount0, amount1, _reserve0, _reserve1);\\n        _reserve0 += uint112(fee0);\\n        _reserve1 += uint112(fee1);\\n\\n        (uint256 _totalSupply, uint256 k) = _mintFee(_reserve0, _reserve1);\\n\\n        if (_totalSupply == 0) {\\n            require(amount0 > 0 && amount1 > 0, \\\"INVALID_AMOUNTS\\\");\\n            liquidity = computed - MINIMUM_LIQUIDITY;\\n            _mint(address(0), MINIMUM_LIQUIDITY);\\n        } else {\\n            uint256 kIncrease;\\n            unchecked {\\n                kIncrease = computed - k;\\n            }\\n            liquidity = (kIncrease * _totalSupply) / k;\\n        }\\n        require(liquidity != 0, \\\"INSUFFICIENT_LIQUIDITY_MINTED\\\");\\n        _mint(recipient, liquidity);\\n        _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n        kLast = computed;\\n        uint256 liquidityForEvent = liquidity;\\n        emit Mint(msg.sender, amount0, amount1, recipient, liquidityForEvent);\\n    }\\n\\n    /// @dev Burns LP tokens sent to this contract. The router must ensure that the user gets sufficient output tokens.\\n    function burn(bytes calldata data) public override lock returns (IPool.TokenAmount[] memory withdrawnAmounts) {\\n        (address recipient, bool unwrapBento) = abi.decode(data, (address, bool));\\n        (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n        (uint256 balance0, uint256 balance1) = _balance();\\n        uint256 liquidity = balanceOf[address(this)];\\n\\n        (uint256 _totalSupply, ) = _mintFee(_reserve0, _reserve1);\\n\\n        uint256 amount0 = (liquidity * balance0) / _totalSupply;\\n        uint256 amount1 = (liquidity * balance1) / _totalSupply;\\n\\n        _burn(address(this), liquidity);\\n        _transfer(token0, amount0, recipient, unwrapBento);\\n        _transfer(token1, amount1, recipient, unwrapBento);\\n        // @dev This is safe from underflow - amounts are lesser figures derived from balances.\\n        unchecked {\\n            balance0 -= amount0;\\n            balance1 -= amount1;\\n        }\\n        _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n        kLast = TridentMath.sqrt(balance0 * balance1);\\n\\n        withdrawnAmounts = new TokenAmount[](2);\\n        withdrawnAmounts[0] = TokenAmount({token: address(token0), amount: amount0});\\n        withdrawnAmounts[1] = TokenAmount({token: address(token1), amount: amount1});\\n        emit Burn(msg.sender, amount0, amount1, recipient, liquidity);\\n    }\\n\\n    /// @dev Burns LP tokens sent to this contract and swaps one of the output tokens for another\\n    /// - i.e., the user gets a single token out by burning LP tokens.\\n    function burnSingle(bytes calldata data) public override lock returns (uint256 amountOut) {\\n        (address tokenOut, address recipient, bool unwrapBento) = abi.decode(data, (address, address, bool));\\n        (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n        uint256 liquidity = balanceOf[address(this)];\\n\\n        (uint256 _totalSupply, ) = _mintFee(_reserve0, _reserve1);\\n\\n        uint256 amount0 = (liquidity * _reserve0) / _totalSupply;\\n        uint256 amount1 = (liquidity * _reserve1) / _totalSupply;\\n\\n        kLast = TridentMath.sqrt((_reserve0 - amount0) * (_reserve1 - amount1));\\n\\n        _burn(address(this), liquidity);\\n\\n        // Swap one token for another\\n        unchecked {\\n            if (tokenOut == token1) {\\n                // @dev Swap `token0` for `token1`\\n                // - calculate `amountOut` as if the user first withdrew balanced liquidity and then swapped `token0` for `token1`.\\n                amount1 += _getAmountOut(amount0, _reserve0 - amount0, _reserve1 - amount1);\\n                _transfer(token1, amount1, recipient, unwrapBento);\\n                amountOut = amount1;\\n                amount0 = 0;\\n            } else {\\n                // @dev Swap `token1` for `token0`.\\n                require(tokenOut == token0, \\\"INVALID_OUTPUT_TOKEN\\\");\\n                amount0 += _getAmountOut(amount1, _reserve1 - amount1, _reserve0 - amount0);\\n                _transfer(token0, amount0, recipient, unwrapBento);\\n                amountOut = amount0;\\n                amount1 = 0;\\n            }\\n        }\\n\\n        (uint256 balance0, uint256 balance1) = _balance();\\n        _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n\\n        emit Burn(msg.sender, amount0, amount1, recipient, liquidity);\\n    }\\n\\n    /// @dev Swaps one token for another. The router must prefund this contract and ensure there isn't too much slippage.\\n    function swap(bytes calldata data) public override lock returns (uint256 amountOut) {\\n        (address tokenIn, address recipient, bool unwrapBento) = abi.decode(data, (address, address, bool));\\n        (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n        require(_reserve0 > 0, \\\"POOL_UNINITIALIZED\\\");\\n        (uint256 balance0, uint256 balance1) = _balance();\\n        uint256 amountIn;\\n        address tokenOut;\\n        unchecked {\\n            if (tokenIn == token0) {\\n                tokenOut = token1;\\n                amountIn = balance0 - _reserve0;\\n                amountOut = _getAmountOut(amountIn, _reserve0, _reserve1);\\n                balance1 -= amountOut;\\n            } else {\\n                require(tokenIn == token1, \\\"INVALID_INPUT_TOKEN\\\");\\n                tokenOut = token0;\\n                amountIn = balance1 - reserve1;\\n                amountOut = _getAmountOut(amountIn, _reserve1, _reserve0);\\n                balance0 -= amountOut;\\n            }\\n        }\\n        _transfer(tokenOut, amountOut, recipient, unwrapBento);\\n        _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n        emit Swap(recipient, tokenIn, tokenOut, amountIn, amountOut);\\n    }\\n\\n    /// @dev Swaps one token for another. The router must support swap callbacks and ensure there isn't too much slippage.\\n    function flashSwap(bytes calldata data) public override lock returns (uint256 amountOut) {\\n        (address tokenIn, address recipient, bool unwrapBento, uint256 amountIn, bytes memory context) = abi.decode(\\n            data,\\n            (address, address, bool, uint256, bytes)\\n        );\\n        (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n        require(_reserve0 > 0, \\\"POOL_UNINITIALIZED\\\");\\n        unchecked {\\n            if (tokenIn == token0) {\\n                amountOut = _getAmountOut(amountIn, _reserve0, _reserve1);\\n                _transfer(token1, amountOut, recipient, unwrapBento);\\n                ITridentCallee(msg.sender).tridentSwapCallback(context);\\n                (uint256 balance0, uint256 balance1) = _balance();\\n                require(balance0 - _reserve0 >= amountIn, \\\"INSUFFICIENT_AMOUNT_IN\\\");\\n                _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n                emit Swap(recipient, tokenIn, token1, amountIn, amountOut);\\n            } else {\\n                require(tokenIn == token1, \\\"INVALID_INPUT_TOKEN\\\");\\n                amountOut = _getAmountOut(amountIn, _reserve1, _reserve0);\\n                _transfer(token0, amountOut, recipient, unwrapBento);\\n                ITridentCallee(msg.sender).tridentSwapCallback(context);\\n                (uint256 balance0, uint256 balance1) = _balance();\\n                require(balance1 - _reserve1 >= amountIn, \\\"INSUFFICIENT_AMOUNT_IN\\\");\\n                _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n                emit Swap(recipient, tokenIn, token0, amountIn, amountOut);\\n            }\\n        }\\n    }\\n\\n    /// @dev Updates `barFee` for Trident protocol.\\n    function updateBarFee() public {\\n        barFee = IMasterDeployer(masterDeployer).barFee();\\n    }\\n\\n    function _getReserves()\\n        internal\\n        view\\n        returns (\\n            uint112 _reserve0,\\n            uint112 _reserve1,\\n            uint32 _blockTimestampLast\\n        )\\n    {\\n        _reserve0 = reserve0;\\n        _reserve1 = reserve1;\\n        _blockTimestampLast = blockTimestampLast;\\n    }\\n\\n    function _balance() internal view returns (uint256 balance0, uint256 balance1) {\\n        balance0 = bento.balanceOf(token0, address(this));\\n        balance1 = bento.balanceOf(token1, address(this));\\n    }\\n\\n    function _update(\\n        uint256 balance0,\\n        uint256 balance1,\\n        uint112 _reserve0,\\n        uint112 _reserve1,\\n        uint32 _blockTimestampLast\\n    ) internal {\\n        require(balance0 <= type(uint112).max && balance1 <= type(uint112).max, \\\"OVERFLOW\\\");\\n        if (_blockTimestampLast == 0) {\\n            // @dev TWAP support is disabled for gas efficiency.\\n            reserve0 = uint112(balance0);\\n            reserve1 = uint112(balance1);\\n        } else {\\n            uint32 blockTimestamp = uint32(block.timestamp);\\n            if (blockTimestamp != _blockTimestampLast && _reserve0 != 0 && _reserve1 != 0) {\\n                unchecked {\\n                    uint32 timeElapsed = blockTimestamp - _blockTimestampLast;\\n                    uint256 price0 = (uint256(_reserve1) << PRECISION) / _reserve0;\\n                    price0CumulativeLast += price0 * timeElapsed;\\n                    uint256 price1 = (uint256(_reserve0) << PRECISION) / _reserve1;\\n                    price1CumulativeLast += price1 * timeElapsed;\\n                }\\n            }\\n            reserve0 = uint112(balance0);\\n            reserve1 = uint112(balance1);\\n            blockTimestampLast = blockTimestamp;\\n        }\\n        emit Sync(balance0, balance1);\\n    }\\n\\n    function _mintFee(uint112 _reserve0, uint112 _reserve1) internal returns (uint256 _totalSupply, uint256 computed) {\\n        _totalSupply = totalSupply;\\n        uint256 _kLast = kLast;\\n        if (_kLast != 0) {\\n            computed = TridentMath.sqrt(uint256(_reserve0) * _reserve1);\\n            if (computed > _kLast) {\\n                // @dev `barFee` % of increase in liquidity.\\n                // It's going to be slightly less than `barFee` % in reality due to the math.\\n                uint256 liquidity = (_totalSupply * (computed - _kLast) * barFee) / computed / MAX_FEE;\\n                if (liquidity != 0) {\\n                    _mint(barFeeTo, liquidity);\\n                    _totalSupply += liquidity;\\n                }\\n            }\\n        }\\n    }\\n\\n    function _getAmountOut(\\n        uint256 amountIn,\\n        uint256 reserveAmountIn,\\n        uint256 reserveAmountOut\\n    ) internal view returns (uint256 amountOut) {\\n        uint256 amountInWithFee = amountIn * MAX_FEE_MINUS_SWAP_FEE;\\n        amountOut = (amountInWithFee * reserveAmountOut) / (reserveAmountIn * MAX_FEE + amountInWithFee);\\n    }\\n\\n    function _getAmountIn(\\n        uint256 amountOut,\\n        uint256 reserveAmountIn,\\n        uint256 reserveAmountOut\\n    ) internal view returns (uint256 amountIn) {\\n        amountIn = (reserveAmountIn * amountOut * MAX_FEE) / ((reserveAmountOut - amountOut) * MAX_FEE_MINUS_SWAP_FEE) + 1;\\n    }\\n\\n    function _transfer(\\n        address token,\\n        uint256 shares,\\n        address to,\\n        bool unwrapBento\\n    ) internal {\\n        if (unwrapBento) {\\n            bento.withdraw(token, address(this), to, 0, shares);\\n        } else {\\n            bento.transfer(token, address(this), to, shares);\\n        }\\n    }\\n\\n    /// @dev This fee is charged to cover for `swapFee` when users add unbalanced liquidity.\\n    function _nonOptimalMintFee(\\n        uint256 _amount0,\\n        uint256 _amount1,\\n        uint256 _reserve0,\\n        uint256 _reserve1\\n    ) internal view returns (uint256 token0Fee, uint256 token1Fee) {\\n        if (_reserve0 == 0 || _reserve1 == 0) return (0, 0);\\n        uint256 amount1Optimal = (_amount0 * _reserve1) / _reserve0;\\n        if (amount1Optimal <= _amount1) {\\n            token1Fee = (swapFee * (_amount1 - amount1Optimal)) / (2 * MAX_FEE);\\n        } else {\\n            uint256 amount0Optimal = (_amount1 * _reserve0) / _reserve1;\\n            token0Fee = (swapFee * (_amount0 - amount0Optimal)) / (2 * MAX_FEE);\\n        }\\n    }\\n\\n    function getAssets() public view override returns (address[] memory assets) {\\n        assets = new address[](2);\\n        assets[0] = token0;\\n        assets[1] = token1;\\n    }\\n\\n    function getAmountOut(bytes calldata data) public view override returns (uint256 finalAmountOut) {\\n        (address tokenIn, uint256 amountIn) = abi.decode(data, (address, uint256));\\n        (uint112 _reserve0, uint112 _reserve1, ) = _getReserves();\\n        if (tokenIn == token0) {\\n            finalAmountOut = _getAmountOut(amountIn, _reserve0, _reserve1);\\n        } else {\\n            require(tokenIn == token1, \\\"INVALID_INPUT_TOKEN\\\");\\n            finalAmountOut = _getAmountOut(amountIn, _reserve1, _reserve0);\\n        }\\n    }\\n\\n    function getAmountIn(bytes calldata data) public view override returns (uint256 finalAmountIn) {\\n        (address tokenOut, uint256 amountOut) = abi.decode(data, (address, uint256));\\n        (uint112 _reserve0, uint112 _reserve1, ) = _getReserves();\\n        if (tokenOut == token1) {\\n            finalAmountIn = _getAmountIn(amountOut, _reserve0, _reserve1);\\n        } else {\\n            require(tokenOut == token0, \\\"INVALID_OUTPUT_TOKEN\\\");\\n            finalAmountIn = _getAmountIn(amountOut, _reserve1, _reserve0);\\n        }\\n    }\\n\\n    /// @dev returned values are in terms of BentoBox \\\"shares\\\".\\n    function getReserves()\\n        public\\n        view\\n        returns (\\n            uint112 _reserve0,\\n            uint112 _reserve1,\\n            uint32 _blockTimestampLast\\n        )\\n    {\\n        return _getReserves();\\n    }\\n\\n    /// @dev returned values are the native ERC20 token amounts.\\n    function getNativeReserves()\\n        public\\n        view\\n        returns (\\n            uint256 _nativeReserve0,\\n            uint256 _nativeReserve1,\\n            uint32 _blockTimestampLast\\n        )\\n    {\\n        (uint112 _reserve0, uint112 _reserve1, uint32 __blockTimestampLast) = _getReserves();\\n        _nativeReserve0 = bento.toAmount(token0, _reserve0, false);\\n        _nativeReserve1 = bento.toAmount(token1, _reserve1, false);\\n        _blockTimestampLast = __blockTimestampLast;\\n    }\\n}\\n\",\"keccak256\":\"0x13a24ecb5d717a5ec992d18bf47b6d28feaaf5f6a68b0cb09fc9214d9ca804b3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/pool/ConstantProductPoolFactory.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\nimport \\\"./ConstantProductPool.sol\\\";\\nimport \\\"./PoolDeployer.sol\\\";\\n\\n/// @notice Contract for deploying Trident exchange Constant Product Pool with configurations.\\n/// @author Mudit Gupta.\\ncontract ConstantProductPoolFactory is PoolDeployer {\\n    constructor(address _masterDeployer) PoolDeployer(_masterDeployer) {}\\n\\n    function deployPool(bytes memory _deployData) external returns (address pool) {\\n        (address tokenA, address tokenB, uint256 swapFee, bool twapSupport) = abi.decode(_deployData, (address, address, uint256, bool));\\n\\n        if (tokenA > tokenB) {\\n            (tokenA, tokenB) = (tokenB, tokenA);\\n        }\\n\\n        // @dev Strips any extra data.\\n        _deployData = abi.encode(tokenA, tokenB, swapFee, twapSupport);\\n\\n        address[] memory tokens = new address[](2);\\n        tokens[0] = tokenA;\\n        tokens[1] = tokenB;\\n\\n        // @dev Salt is not actually needed since `_deployData` is part of creationCode and already contains the salt.\\n        bytes32 salt = keccak256(_deployData);\\n        pool = address(new ConstantProductPool{salt: salt}(_deployData, masterDeployer));\\n        _registerPool(pool, tokens, salt);\\n    }\\n}\\n\",\"keccak256\":\"0x3deab7704b9619a914ae8b6c4b933392e1049a761457a06f61af3e2bbe3f97d1\",\"license\":\"GPL-3.0-or-later\"},\"contracts/pool/PoolDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident pool deployer for whitelisted template factories.\\n/// @author Mudit Gupta.\\nabstract contract PoolDeployer {\\n    address public immutable masterDeployer;\\n\\n    mapping(address => mapping(address => address[])) public pools;\\n    mapping(bytes32 => address) public configAddress;\\n\\n    error UnauthorisedDeployer();\\n    error ZeroAddress();\\n    error InvalidTokenOrder();\\n\\n    modifier onlyMaster() {\\n        if (msg.sender != masterDeployer) revert UnauthorisedDeployer();\\n        _;\\n    }\\n\\n    constructor(address _masterDeployer) {\\n        if (_masterDeployer == address(0)) revert ZeroAddress();\\n        masterDeployer = _masterDeployer;\\n    }\\n\\n    function _registerPool(\\n        address pool,\\n        address[] memory tokens,\\n        bytes32 salt\\n    ) internal onlyMaster {\\n        // @dev Store the address of the deployed contract.\\n        configAddress[salt] = pool;\\n        // @dev Attacker used underflow, it was not very effective. poolimon!\\n        // null token array would cause deployment to fail via out of bounds memory axis/gas limit.\\n        unchecked {\\n            for (uint256 i; i < tokens.length - 1; i++) {\\n                if (tokens[i] >= tokens[i + 1]) revert InvalidTokenOrder();\\n                for (uint256 j = i + 1; j < tokens.length; j++) {\\n                    pools[tokens[i]][tokens[j]].push(pool);\\n                    pools[tokens[j]][tokens[i]].push(pool);\\n                }\\n            }\\n        }\\n    }\\n\\n    function poolsCount(address token0, address token1) external view returns (uint256 count) {\\n        count = pools[token0][token1].length;\\n    }\\n\\n    function getPools(\\n        address token0,\\n        address token1,\\n        uint256 startIndex,\\n        uint256 count\\n    ) external view returns (address[] memory pairPools) {\\n        pairPools = new address[](count);\\n        for (uint256 i = 0; i < count; i++) {\\n            pairPools[i] = pools[token0][token1][startIndex + i];\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x34c44a489ccaf9a7b2bc05527113552a2ebc5a8b4b9d47035e465c39cf569b81\",\"license\":\"GPL-3.0-or-later\"},\"contracts/pool/TridentERC20.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident pool ERC-20 with EIP-2612 extension.\\n/// @author Adapted from RariCapital, https://github.com/Rari-Capital/solmate/blob/main/src/erc20/ERC20.sol,\\n/// License-Identifier: AGPL-3.0-only.\\nabstract contract TridentERC20 {\\n    event Transfer(address indexed sender, address indexed recipient, uint256 amount);\\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n    string public constant name = \\\"Sushi LP Token\\\";\\n    string public constant symbol = \\\"SLP\\\";\\n    uint8 public constant decimals = 18;\\n\\n    uint256 public totalSupply;\\n    /// @notice owner -> balance mapping.\\n    mapping(address => uint256) public balanceOf;\\n    /// @notice owner -> spender -> allowance mapping.\\n    mapping(address => mapping(address => uint256)) public allowance;\\n\\n    /// @notice Chain Id at this contract's deployment.\\n    uint256 internal immutable DOMAIN_SEPARATOR_CHAIN_ID;\\n    /// @notice EIP-712 typehash for this contract's domain at deployment.\\n    bytes32 internal immutable _DOMAIN_SEPARATOR;\\n    /// @notice EIP-712 typehash for this contract's {permit} struct.\\n    bytes32 public constant PERMIT_TYPEHASH =\\n        keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n    /// @notice owner -> nonce mapping used in {permit}.\\n    mapping(address => uint256) public nonces;\\n\\n    constructor() {\\n        DOMAIN_SEPARATOR_CHAIN_ID = block.chainid;\\n        _DOMAIN_SEPARATOR = _calculateDomainSeparator();\\n    }\\n\\n    function _calculateDomainSeparator() internal view returns (bytes32 domainSeperator) {\\n        domainSeperator = keccak256(\\n            abi.encode(\\n                keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n                keccak256(bytes(name)),\\n                keccak256(bytes(\\\"1\\\")),\\n                block.chainid,\\n                address(this)\\n            )\\n        );\\n    }\\n\\n    /// @notice EIP-712 typehash for this contract's domain.\\n    function DOMAIN_SEPARATOR() public view returns (bytes32 domainSeperator) {\\n        domainSeperator = block.chainid == DOMAIN_SEPARATOR_CHAIN_ID ? _DOMAIN_SEPARATOR : _calculateDomainSeparator();\\n    }\\n\\n    /// @notice Approves `amount` from `msg.sender` to be spent by `spender`.\\n    /// @param spender Address of the party that can pull tokens from `msg.sender`'s account.\\n    /// @param amount The maximum collective `amount` that `spender` can pull.\\n    /// @return (bool) Returns 'true' if succeeded.\\n    function approve(address spender, uint256 amount) external returns (bool) {\\n        allowance[msg.sender][spender] = amount;\\n        emit Approval(msg.sender, spender, amount);\\n        return true;\\n    }\\n\\n    /// @notice Transfers `amount` tokens from `msg.sender` to `recipient`.\\n    /// @param recipient The address to move tokens to.\\n    /// @param amount The token `amount` to move.\\n    /// @return (bool) Returns 'true' if succeeded.\\n    function transfer(address recipient, uint256 amount) external returns (bool) {\\n        balanceOf[msg.sender] -= amount;\\n        // @dev This is safe from overflow - the sum of all user\\n        // balances can't exceed 'type(uint256).max'.\\n        unchecked {\\n            balanceOf[recipient] += amount;\\n        }\\n        emit Transfer(msg.sender, recipient, amount);\\n        return true;\\n    }\\n\\n    /// @notice Transfers `amount` tokens from `sender` to `recipient`. Caller needs approval from `from`.\\n    /// @param sender Address to pull tokens `from`.\\n    /// @param recipient The address to move tokens to.\\n    /// @param amount The token `amount` to move.\\n    /// @return (bool) Returns 'true' if succeeded.\\n    function transferFrom(\\n        address sender,\\n        address recipient,\\n        uint256 amount\\n    ) external returns (bool) {\\n        if (allowance[sender][msg.sender] != type(uint256).max) {\\n            allowance[sender][msg.sender] -= amount;\\n        }\\n        balanceOf[sender] -= amount;\\n        // @dev This is safe from overflow - the sum of all user\\n        // balances can't exceed 'type(uint256).max'.\\n        unchecked {\\n            balanceOf[recipient] += amount;\\n        }\\n        emit Transfer(sender, recipient, amount);\\n        return true;\\n    }\\n\\n    /// @notice Triggers an approval from `owner` to `spender`.\\n    /// @param owner The address to approve from.\\n    /// @param spender The address to be approved.\\n    /// @param amount The number of tokens that are approved (2^256-1 means infinite).\\n    /// @param deadline The time at which to expire the signature.\\n    /// @param v The recovery byte of the signature.\\n    /// @param r Half of the ECDSA signature pair.\\n    /// @param s Half of the ECDSA signature pair.\\n    function permit(\\n        address owner,\\n        address spender,\\n        uint256 amount,\\n        uint256 deadline,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) external {\\n        require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n        bytes32 digest = keccak256(\\n            abi.encodePacked(\\n                \\\"\\\\x19\\\\x01\\\",\\n                DOMAIN_SEPARATOR(),\\n                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, nonces[owner]++, deadline))\\n            )\\n        );\\n        address recoveredAddress = ecrecover(digest, v, r, s);\\n        require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_PERMIT_SIGNATURE\\\");\\n        allowance[recoveredAddress][spender] = amount;\\n        emit Approval(owner, spender, amount);\\n    }\\n\\n    function _mint(address recipient, uint256 amount) internal {\\n        totalSupply += amount;\\n        // @dev This is safe from overflow - the sum of all user\\n        // balances can't exceed 'type(uint256).max'.\\n        unchecked {\\n            balanceOf[recipient] += amount;\\n        }\\n        emit Transfer(address(0), recipient, amount);\\n    }\\n\\n    function _burn(address sender, uint256 amount) internal {\\n        balanceOf[sender] -= amount;\\n        // @dev This is safe from underflow - users won't ever\\n        // have a balance larger than `totalSupply`.\\n        unchecked {\\n            totalSupply -= amount;\\n        }\\n        emit Transfer(sender, address(0), amount);\\n    }\\n}\\n\",\"keccak256\":\"0xb249a6d507f6911b7de4f9655a9736710fac9847982ad9afa18650db9a84794d\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}",
  "bytecode": "0x60a060405234801561001057600080fd5b5060405161533138038061533183398101604081905261002f9161006d565b806001600160a01b0381166100575760405163d92e233d60e01b815260040160405180910390fd5b60601b6001600160601b0319166080525061009d565b60006020828403121561007f57600080fd5b81516001600160a01b038116811461009657600080fd5b9392505050565b60805160601c6152686100c96000396000818161015a0152818161038d015261054201526152686000f3fe60806040523480156200001157600080fd5b50600436106200007b5760003560e01c806371a25812116200005657806371a25812146200012e578063cf58879a1462000154578063f6ab6d99146200017c57600080fd5b8063169c4cef146200008057806327c3cae114620000c15780635bc93d6c14620000d8575b600080fd5b620000976200009136600462000938565b620001b5565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b62000097620000d2366004620009e3565b62000208565b6200011f620000e9366004620008fa565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526020818152604080832093909416825291909152205490565b604051908152602001620000b8565b620001456200013f3660046200097e565b62000401565b604051620000b8919062000abc565b620000977f000000000000000000000000000000000000000000000000000000000000000081565b620000976200018d366004620009c9565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60006020528260005260406000206020528160005260406000208181548110620001de57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16925083915050565b6000806000806000858060200190518101906200022691906200089a565b93509350935093508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111562000267579192915b6040805173ffffffffffffffffffffffffffffffffffffffff808716602083015285169181019190915260608101839052811515608082015260a001604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152600280845260608401909252975060009190816020016020820280368337019050509050848160008151811062000309576200030962000c32565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505083816001815181106200035a576200035a62000c32565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101820152875190880120604051819089907f000000000000000000000000000000000000000000000000000000000000000090620003b8906200088c565b620003c592919062000b18565b8190604051809103906000f5905080158015620003e6573d6000803e3d6000fd5b509650620003f68783836200052a565b505050505050919050565b60608167ffffffffffffffff8111156200041f576200041f62000c61565b60405190808252806020026020018201604052801562000449578160200160208202803683370190505b50905060005b82811015620005215773ffffffffffffffffffffffffffffffffffffffff80871660009081526020818152604080832093891683529290522062000494828662000bac565b81548110620004a757620004a762000c32565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828281518110620004e757620004e762000c32565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015280620005188162000bc7565b9150506200044f565b50949350505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146200059a576040517f03781a5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260016020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86161790555b600183510381101562000886578281600101815181106200060c576200060c62000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168382815181106200063f576200063f62000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161062000695576040517f3f06bf8100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015b83518110156200087c57600080858481518110620006bc57620006bc62000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085838151811062000715576200071562000c32565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811683528282019390935260409091016000908120805460018101825590825291812090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169288169290921790915584518190869084908110620007a457620007a462000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858481518110620007fd57620007fd62000c32565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff908116835282820193909352604090910160009081208054600180820183559183529290912090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001692881692909217909155016200069a565b50600101620005e7565b50505050565b61457c8062000cb783390190565b60008060008060808587031215620008b157600080fd5b8451620008be8162000c90565b6020860151909450620008d18162000c90565b6040860151606087015191945092508015158114620008ef57600080fd5b939692955090935050565b600080604083850312156200090e57600080fd5b82356200091b8162000c90565b915060208301356200092d8162000c90565b809150509250929050565b6000806000606084860312156200094e57600080fd5b83356200095b8162000c90565b925060208401356200096d8162000c90565b929592945050506040919091013590565b600080600080608085870312156200099557600080fd5b8435620009a28162000c90565b93506020850135620009b48162000c90565b93969395505050506040820135916060013590565b600060208284031215620009dc57600080fd5b5035919050565b600060208284031215620009f657600080fd5b813567ffffffffffffffff8082111562000a0f57600080fd5b818401915084601f83011262000a2457600080fd5b81358181111562000a395762000a3962000c61565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171562000a825762000a8262000c61565b8160405282815287602084870101111562000a9c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6020808252825182820181905260009190848201906040850190845b8181101562000b0c57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010162000ad8565b50909695505050505050565b604081526000835180604084015260005b8181101562000b48576020818701810151606086840101520162000b29565b8181111562000b5b576000606083860101525b5073ffffffffffffffffffffffffffffffffffffffff93909316602083015250601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601606001919050565b6000821982111562000bc25762000bc262000c03565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141562000bfc5762000bfc62000c03565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811462000cb357600080fd5b5056fe6101a06040523480156200001257600080fd5b506040516200457c3803806200457c833981016040819052620000359162000562565b4660805262000112604080518082018252600e81526d29bab9b434902628102a37b5b2b760911b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527fc2bf45081e840722410522aa366600d7fe4da5bfb5a5b417f4d5125b4ed180a4818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c0909101909252815191012090565b60a081815250506000806000808580602001905181019062000135919062000502565b929650909450925090506001600160a01b0384166200018a5760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b60448201526064015b60405180910390fd5b826001600160a01b0316846001600160a01b03161415620001ee5760405162461bcd60e51b815260206004820152601360248201527f4944454e544943414c5f41444452455353455300000000000000000000000000604482015260640162000181565b6001600160a01b038416301415620002395760405162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22faa27a5a2a760991b604482015260640162000181565b6001600160a01b038316301415620002845760405162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22faa27a5a2a760991b604482015260640162000181565b612710821115620002cb5760405162461bcd60e51b815260206004820152601060248201526f494e56414c49445f535741505f46454560801b604482015260640162000181565b6001600160601b0319606085811b82166101605284901b166101805260c082905261271082900360e052604080516360a56c0160e11b815290516001600160a01b0387169163c14ad802916004808301926020929190829003018186803b1580156200033657600080fd5b505afa1580156200034b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000371919062000653565b600481905550846001600160a01b0316630c0a0cd26040518163ffffffff1660e01b815260040160206040518083038186803b158015620003b157600080fd5b505afa158015620003c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ec9190620004db565b6001600160a01b0316610100816001600160a01b031660601b81525050846001600160a01b0316634da318276040518163ffffffff1660e01b815260040160206040518083038186803b1580156200044357600080fd5b505afa15801562000458573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200047e9190620004db565b6001600160601b0319606091821b8116610120529086901b166101405260016009558015620004bd57600880546001600160e01b0316600160e01b1790555b5050505050506200069c565b8051620004d68162000683565b919050565b600060208284031215620004ee57600080fd5b8151620004fb8162000683565b9392505050565b600080600080608085870312156200051957600080fd5b8451620005268162000683565b6020860151909450620005398162000683565b60408601516060870151919450925080151581146200055757600080fd5b939692955090935050565b600080604083850312156200057657600080fd5b82516001600160401b03808211156200058e57600080fd5b818501915085601f830112620005a357600080fd5b815181811115620005b857620005b86200066d565b604051601f8201601f19908116603f01168101908382118183101715620005e357620005e36200066d565b816040528281526020935088848487010111156200060057600080fd5b600091505b8282101562000624578482018401518183018501529083019062000605565b82821115620006365760008484830101525b955062000648915050858201620004c9565b925050509250929050565b6000602082840312156200066657600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200069957600080fd5b50565b60805160a05160c05160e0516101005160601c6101205160601c6101405160601c6101605160601c6101805160601c613d4f6200082d600039600081816106060152818161085e0152818161098d01528181610a3b015281816110be015281816111c60152818161145c0152818161179c0152818161180b01528181611b6201528181611cc10152818161221f01528181612530015281816125b70152612e16015260008181610364015281816107da01528181610b2001528181610c4f015281816110920152818161115d015281816114e201528181611748015281816118ec01528181611a5c01528181611c53015281816121a0015281816125ec015281816126d70152612d2c0152600081816105df015261208801526000818161042301528181611aa901528181611baa01528181612bb001528181612c8c01528181612d5f0152612e47015260008181610318015261322c015260008181612aee015261348401526000818161044a0152818161354601526135b1015260006113c30152600061129a0152613d4f6000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063627dd56a11610145578063a69840a8116100bd578063c14ad8021161008c578063d21220a711610071578063d21220a714610601578063d505accf14610628578063dd62ed3e1461063b57600080fd5b8063c14ad802146105d1578063cf58879a146105da57600080fd5b8063a69840a814610571578063a8f1f52e14610598578063a9059cbb146105ab578063af8c09bf146105be57600080fd5b80637464fc3d116101145780637ecebe00116100f95780637ecebe001461050b57806392bc32191461052b57806395d89b411461053557600080fd5b80637464fc3d146104ef5780637ba0e2e7146104f857600080fd5b8063627dd56a1461047e57806365dfc7671461049157806367e4ac2c146104ba57806370a08231146104cf57600080fd5b80632a07b6c7116101d8578063499a3c50116101a757806354cf2aeb1161018c57806354cf2aeb146104455780635909c0d51461046c5780635a3d54931461047557600080fd5b8063499a3c501461040b5780634da318271461041e57600080fd5b80632a07b6c7146103a257806330adf81f146103c2578063313ce567146103e95780633644e5151461040357600080fd5b80630c0a0cd2116102145780630c0a0cd2146103135780630dfe16811461035f57806318160ddd1461038657806323b872dd1461038f57600080fd5b8063053da1c81461024657806306fdde031461026c5780630902f1ac146102b5578063095ea7b3146102f0575b600080fd5b61025961025436600461393a565b610666565b6040519081526020015b60405180910390f35b6102a86040518060400160405280600e81526020017f5375736869204c5020546f6b656e00000000000000000000000000000000000081525081565b6040516102639190613b13565b6102bd610d0b565b604080516dffffffffffffffffffffffffffff948516815293909216602084015263ffffffff1690820152606001610263565b6103036102fe36600461381d565b610d74565b6040519015158152602001610263565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610263565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b61025960005481565b61030361039d366004613882565b610ded565b6103b56103b036600461393a565b610f39565b6040516102639190613aae565b6102597f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6103f1601281565b60405160ff9091168152602001610263565b610259611296565b61025961041936600461393a565b6113e5565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b6102597f000000000000000000000000000000000000000000000000000000000000000081565b61025960055481565b61025960065481565b61025961048c36600461393a565b6115cd565b6104996119bd565b60408051938452602084019290925263ffffffff1690820152606001610263565b6104c2611c31565b6040516102639190613a54565b6102596104dd36600461366e565b60016020526000908152604090205481565b61025960075481565b61025961050636600461393a565b611d30565b61025961051936600461366e565b60036020526000908152604090205481565b610533612086565b005b6102a86040518060400160405280600381526020017f534c50000000000000000000000000000000000000000000000000000000000081525081565b6102597f54726964656e743a436f6e7374616e7450726f6475637400000000000000000081565b6102596105a636600461393a565b612129565b6103036105b936600461381d565b6122fd565b6102596105cc36600461393a565b612382565b61025960045481565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b6105336106363660046138c3565b612794565b610259610649366004613849565b600260209081526000928352604080842090915290825290205481565b60006009546001146106d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60026009556000808080806106f0878901896136d9565b9450945094509450945060008060006107586008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b9250925092506000836dffffffffffffffffffffffffffff16116107d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f504f4f4c5f554e494e495449414c495a4544000000000000000000000000000060448201526064016106d0565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415610a395761085785846dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff16612ae6565b98506108857f00000000000000000000000000000000000000000000000000000000000000008a8989612b49565b6040517fbd50c7b1000000000000000000000000000000000000000000000000000000008152339063bd50c7b1906108c1908790600401613b13565b600060405180830381600087803b1580156108db57600080fd5b505af11580156108ef573d6000803e3d6000fd5b505050506000806108fe612cef565b9150915086856dffffffffffffffffffffffffffff168303101561097e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f494e53554646494349454e545f414d4f554e545f494e0000000000000000000060448201526064016106d0565b61098b8282878787612ec9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e460628a8f604051610a2a929190918252602082015260400190565b60405180910390a45050610cf7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f494e56414c49445f494e5055545f544f4b454e0000000000000000000000000060448201526064016106d0565b610b1985836dffffffffffffffffffffffffffff16856dffffffffffffffffffffffffffff16612ae6565b9850610b477f00000000000000000000000000000000000000000000000000000000000000008a8989612b49565b6040517fbd50c7b1000000000000000000000000000000000000000000000000000000008152339063bd50c7b190610b83908790600401613b13565b600060405180830381600087803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50505050600080610bc0612cef565b9150915086846dffffffffffffffffffffffffffff1682031015610c40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f494e53554646494349454e545f414d4f554e545f494e0000000000000000000060448201526064016106d0565b610c4d8282878787612ec9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e460628a8f604051610cec929190918252602082015260400190565b60405180910390a450505b505060016009555094979650505050505050565b6000806000610d696008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b925092509250909192565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610ddc9086815260200190565b60405180910390a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610e8a5773ffffffffffffffffffffffffffffffffffffffff8416600090815260026020908152604080832033845290915281208054849290610e84908490613be8565b90915550505b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604081208054849290610ebf908490613be8565b909155505073ffffffffffffffffffffffffffffffffffffffff808416600081815260016020526040908190208054860190555190918616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610f279086815260200190565b60405180910390a35060019392505050565b6060600954600114610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b6002600955600080610fbb848601866137e8565b91509150600080600061101d6008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b92509250925060008061102e612cef565b3060009081526001602052604081205492945090925061104e87876131a8565b50905060008161105e8685613bab565b6110689190613b70565b90506000826110778686613bab565b6110819190613b70565b905061108d3085613268565b6110b97f0000000000000000000000000000000000000000000000000000000000000000838d8d612b49565b6110e57f0000000000000000000000000000000000000000000000000000000000000000828d8d612b49565b818603955080850394506110fc86868b8b8b612ec9565b61110e6111098688613bab565b6132fb565b6007556040805160028082526060820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081611127579050509b5060405180604001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168152602001838152508c6000815181106111ae576111ae613c96565b602002602001018190525060405180604001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168152602001828152508c60018151811061121757611217613c96565b60209081029190910181019190915260408051848152918201839052810185905273ffffffffffffffffffffffffffffffffffffffff8c169033907fa476cebfbe7485684f5578d84d8a64a8afe93a0a2a3047bd6f3e681e108b8f119060600160405180910390a35050600160095550979a9950505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146113c05750604080518082018252600e81527f5375736869204c5020546f6b656e00000000000000000000000000000000000060209182015281518083018352600181527f31000000000000000000000000000000000000000000000000000000000000009082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527fc2bf45081e840722410522aa366600d7fe4da5bfb5a5b417f4d5125b4ed180a4818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c0909101909252815191012090565b507f000000000000000000000000000000000000000000000000000000000000000090565b600080806113f58486018661381d565b915091506000806114556008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b50915091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114e0576114d983836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff16613480565b94506115c3565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f494e56414c49445f4f55545055545f544f4b454e00000000000000000000000060448201526064016106d0565b6115c083826dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff16613480565b94505b5050505092915050565b600060095460011461163b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b60026009556000808061165085870187613692565b92509250925060008060006116b46008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b9250925092506000836dffffffffffffffffffffffffffff1611611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f504f4f4c5f554e494e495449414c495a4544000000000000000000000000000060448201526064016106d0565b60008061173f612cef565b915091506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161415611809577f00000000000000000000000000000000000000000000000000000000000000009050866dffffffffffffffffffffffffffff16840391506117fd82886dffffffffffffffffffffffffffff16886dffffffffffffffffffffffffffff16612ae6565b9a508a83039250611925565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16146118be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f494e56414c49445f494e5055545f544f4b454e0000000000000000000000000060448201526064016106d0565b50506008546dffffffffffffffffffffffffffff6e01000000000000000000000000000090910481168203907f00000000000000000000000000000000000000000000000000000000000000009061191d908390888116908a16612ae6565b9a508a840393505b611931818c8b8b612b49565b61193e8484898989612ec9565b8073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e46062858f604051610cec929190918252602082015260400190565b600080600080600080611a1f6008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b6040517f5662311800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526dffffffffffffffffffffffffffff851660248301526000604483015293965091945092507f00000000000000000000000000000000000000000000000000000000000000009091169063566231189060640160206040518083038186803b158015611aed57600080fd5b505afa158015611b01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2591906139ac565b6040517f5662311800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526dffffffffffffffffffffffffffff85166024830152600060448301529197507f00000000000000000000000000000000000000000000000000000000000000009091169063566231189060640160206040518083038186803b158015611bee57600080fd5b505afa158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2691906139ac565b959690945092505050565b60408051600280825260608083018452926020830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110611c8557611c85613c96565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110611cf357611cf3613c96565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505090565b6000600954600114611d9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b60026009556000611db18385018561366e565b90506000806000611e116008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b925092509250600080611e22612cef565b90925090506000611e366111098385613bab565b90506000611e546dffffffffffffffffffffffffffff881685613be8565b90506000611e726dffffffffffffffffffffffffffff881685613be8565b9050600080611ea384848c6dffffffffffffffffffffffffffff168c6dffffffffffffffffffffffffffff166134eb565b9092509050611eb2828b613b26565b9950611ebe818a613b26565b9850600080611ecd8c8c6131a8565b915091508160001415611f7057600086118015611eea5750600085115b611f50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f494e56414c49445f414d4f554e5453000000000000000000000000000000000060448201526064016106d0565b611f5c6103e888613be8565b9d50611f6b60006103e86135ee565b611f8c565b80870381611f7e8483613bab565b611f889190613b70565b9e50505b8d611ff3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f494e53554646494349454e545f4c49515549444954595f4d494e54454400000060448201526064016106d0565b611ffd8d8f6135ee565b61200a89898e8e8e612ec9565b600787905560408051878152602081018790529081018f90528e9073ffffffffffffffffffffffffffffffffffffffff8f169033907ff9c32fbc56ff04f32a233ebc26e388564223745e28abd8d0781dd906537f563e9060600160405180910390a350506001600955509a9d9c50505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c14ad8026040518163ffffffff1660e01b815260040160206040518083038186803b1580156120ec57600080fd5b505afa158015612100573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212491906139ac565b600455565b600080806121398486018661381d565b915091506000806121996008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b50915091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561221d576114d983836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff16612ae6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146122d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f494e56414c49445f494e5055545f544f4b454e0000000000000000000000000060448201526064016106d0565b6115c083826dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff16612ae6565b3360009081526001602052604081208054839190839061231e908490613be8565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260016020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610ddc9086815260200190565b60006009546001146123f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b60026009556000808061240585870187613692565b92509250925060008060006124696008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b30600090815260016020526040812054939650919450925061248b85856131a8565b5090506000816124ab6dffffffffffffffffffffffffffff881685613bab565b6124b59190613b70565b90506000826124d46dffffffffffffffffffffffffffff881686613bab565b6124de9190613b70565b90506125216124fd826dffffffffffffffffffffffffffff8916613be8565b612517846dffffffffffffffffffffffffffff8b16613be8565b6111099190613bab565b60075561252e3085613268565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614156125ea576125b18283896dffffffffffffffffffffffffffff160383896dffffffffffffffffffffffffffff1603612ae6565b016125de7f0000000000000000000000000000000000000000000000000000000000000000828b8b612b49565b809a5060009150612705565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161461269f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f494e56414c49445f4f55545055545f544f4b454e00000000000000000000000060448201526064016106d0565b6126ce8182886dffffffffffffffffffffffffffff1603848a6dffffffffffffffffffffffffffff1603612ae6565b820191506126fe7f0000000000000000000000000000000000000000000000000000000000000000838b8b612b49565b5098508860005b600080612710612cef565b9150915061272182828b8b8b612ec9565b604080518581526020810185905290810187905273ffffffffffffffffffffffffffffffffffffffff8c169033907fa476cebfbe7485684f5578d84d8a64a8afe93a0a2a3047bd6f3e681e108b8f119060600160405180910390a35050600160095550989b9a5050505050505050505050565b428410156127fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016106d0565b6000612808611296565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928c928c928c9290919061286383613bff565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810187905260e001604051602081830303815290604052805190602001206040516020016129049291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa15801561298d573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590612a0857508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b612a6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f494e56414c49445f5045524d49545f5349474e4154555245000000000000000060448201526064016106d0565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526002602090815260408083208c8516808552908352928190208b9055518a815291928c16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600080612b137f000000000000000000000000000000000000000000000000000000000000000086613bab565b905080612b2261271086613bab565b612b2c9190613b58565b612b368483613bab565b612b409190613b70565b95945050505050565b8015612c32576040517f97da6d3000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152306024830152838116604483015260006064830152608482018590527f000000000000000000000000000000000000000000000000000000000000000016906397da6d309060a4016040805180830381600087803b158015612bf357600080fd5b505af1158015612c07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c2b91906139c5565b5050612ce9565b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301528381166044830152606482018590527f0000000000000000000000000000000000000000000000000000000000000000169063f18d03cc90608401600060405180830381600087803b158015612cd057600080fd5b505af1158015612ce4573d6000803e3d6000fd5b505050505b50505050565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063f7888aec9060440160206040518083038186803b158015612da157600080fd5b505afa158015612db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd991906139ac565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301529193507f00000000000000000000000000000000000000000000000000000000000000009091169063f7888aec9060440160206040518083038186803b158015612e8b57600080fd5b505afa158015612e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ec391906139ac565b90509091565b6dffffffffffffffffffffffffffff8511801590612ef557506dffffffffffffffffffffffffffff8411155b612f5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f4f564552464c4f5700000000000000000000000000000000000000000000000060448201526064016106d0565b63ffffffff8116612fbd57600880546dffffffffffffffffffffffffffff8681166e010000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090921690881617179055613168565b4263ffffffff80821690831614801590612fe657506dffffffffffffffffffffffffffff841615155b801561300157506dffffffffffffffffffffffffffff831615155b156130c65781810360006dffffffffffffffffffffffffffff86167bffffffffffffffffffffffffffff0000000000000000000000000000607087901b168161304c5761304c613c67565b600580549290910463ffffffff851681029092019055905060006dffffffffffffffffffffffffffff8616607088901b7bffffffffffffffffffffffffffff000000000000000000000000000016816130a7576130a7613c67565b0490508263ffffffff1681026006600082825401925050819055505050505b6008805463ffffffff9092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff6dffffffffffffffffffffffffffff8881166e010000000000000000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909516908a161793909317929092169190911790555b60408051868152602081018690527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a15050505050565b600080546007549091908015613260576131d86111096dffffffffffffffffffffffffffff808716908816613bab565b9150808211156132605760006127108360045484866131f79190613be8565b6132019088613bab565b61320b9190613bab565b6132159190613b70565b61321f9190613b70565b9050801561325e576132517f0000000000000000000000000000000000000000000000000000000000000000826135ee565b61325b8185613b58565b93505b505b509250929050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260408120805483929061329d908490613be8565b909155505060008054829003815560405182815273ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b60008161330a57506000919050565b81600170010000000000000000000000000000000082106133305760809190911c9060401b5b68010000000000000000821061334b5760409190911c9060201b5b64010000000082106133625760209190911c9060101b5b6201000082106133775760109190911c9060081b5b610100821061338b5760089190911c9060041b5b6010821061339e5760049190911c9060021b5b600882106133aa5760011b5b60018185816133bb576133bb613c67565b048201901c905060018185816133d3576133d3613c67565b048201901c905060018185816133eb576133eb613c67565b048201901c9050600181858161340357613403613c67565b048201901c9050600181858161341b5761341b613c67565b048201901c9050600181858161343357613433613c67565b048201901c9050600181858161344b5761344b613c67565b048201901c9050600081858161346357613463613c67565b0490508082106134735780613475565b815b93505050505b919050565b60007f00000000000000000000000000000000000000000000000000000000000000006134ad8584613be8565b6134b79190613bab565b6127106134c48686613bab565b6134ce9190613bab565b6134d89190613b70565b6134e3906001613b58565b949350505050565b6000808315806134f9575082155b15613509575060009050806135e5565b6000846135168589613bab565b6135209190613b70565b905085811161357b576135366127106002613bab565b6135408288613be8565b61356a907f0000000000000000000000000000000000000000000000000000000000000000613bab565b6135749190613b70565b91506135e3565b6000846135888789613bab565b6135929190613b70565b90506135a16127106002613bab565b6135ab828a613be8565b6135d5907f0000000000000000000000000000000000000000000000000000000000000000613bab565b6135df9190613b70565b9350505b505b94509492505050565b806000808282546135ff9190613b58565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016132ef565b8035801515811461347b57600080fd5b60006020828403121561368057600080fd5b813561368b81613cf4565b9392505050565b6000806000606084860312156136a757600080fd5b83356136b281613cf4565b925060208401356136c281613cf4565b91506136d06040850161365e565b90509250925092565b600080600080600060a086880312156136f157600080fd5b85356136fc81613cf4565b9450602086013561370c81613cf4565b935061371a6040870161365e565b925060608601359150608086013567ffffffffffffffff8082111561373e57600080fd5b818801915088601f83011261375257600080fd5b81358181111561376457613764613cc5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156137aa576137aa613cc5565b816040528281528b60208487010111156137c357600080fd5b8260208601602083013760006020848301015280955050505050509295509295909350565b600080604083850312156137fb57600080fd5b823561380681613cf4565b91506138146020840161365e565b90509250929050565b6000806040838503121561383057600080fd5b823561383b81613cf4565b946020939093013593505050565b6000806040838503121561385c57600080fd5b823561386781613cf4565b9150602083013561387781613cf4565b809150509250929050565b60008060006060848603121561389757600080fd5b83356138a281613cf4565b925060208401356138b281613cf4565b929592945050506040919091013590565b600080600080600080600060e0888a0312156138de57600080fd5b87356138e981613cf4565b965060208801356138f981613cf4565b95506040880135945060608801359350608088013560ff8116811461391d57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806020838503121561394d57600080fd5b823567ffffffffffffffff8082111561396557600080fd5b818501915085601f83011261397957600080fd5b81358181111561398857600080fd5b86602082850101111561399a57600080fd5b60209290920196919550909350505050565b6000602082840312156139be57600080fd5b5051919050565b600080604083850312156139d857600080fd5b505080516020909101519092909150565b6000815180845260005b81811015613a0f576020818501810151868301820152016139f3565b81811115613a21576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020808252825182820181905260009190848201906040850190845b81811015613aa257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a70565b50909695505050505050565b602080825282518282018190526000919060409081850190868401855b82811015613b06578151805173ffffffffffffffffffffffffffffffffffffffff168552860151868501529284019290850190600101613acb565b5091979650505050505050565b60208152600061368b60208301846139e9565b60006dffffffffffffffffffffffffffff808316818516808303821115613b4f57613b4f613c38565b01949350505050565b60008219821115613b6b57613b6b613c38565b500190565b600082613ba6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613be357613be3613c38565b500290565b600082821015613bfa57613bfa613c38565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613c3157613c31613c38565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114613d1657600080fd5b5056fea2646970667358221220c53c5cf6f9cb8b7e269fceb7679cf92974d918605fd12748f1e47ae0f9e5d8da64736f6c63430008070033a264697066735822122051d90a1744a16d7db99e44d739049f1b38b18b970e9de3c4b3b8c86c36c6059b64736f6c63430008070033",
  "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200007b5760003560e01c806371a25812116200005657806371a25812146200012e578063cf58879a1462000154578063f6ab6d99146200017c57600080fd5b8063169c4cef146200008057806327c3cae114620000c15780635bc93d6c14620000d8575b600080fd5b620000976200009136600462000938565b620001b5565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b62000097620000d2366004620009e3565b62000208565b6200011f620000e9366004620008fa565b73ffffffffffffffffffffffffffffffffffffffff91821660009081526020818152604080832093909416825291909152205490565b604051908152602001620000b8565b620001456200013f3660046200097e565b62000401565b604051620000b8919062000abc565b620000977f000000000000000000000000000000000000000000000000000000000000000081565b620000976200018d366004620009c9565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60006020528260005260406000206020528160005260406000208181548110620001de57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16925083915050565b6000806000806000858060200190518101906200022691906200089a565b93509350935093508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111562000267579192915b6040805173ffffffffffffffffffffffffffffffffffffffff808716602083015285169181019190915260608101839052811515608082015260a001604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152600280845260608401909252975060009190816020016020820280368337019050509050848160008151811062000309576200030962000c32565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505083816001815181106200035a576200035a62000c32565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101820152875190880120604051819089907f000000000000000000000000000000000000000000000000000000000000000090620003b8906200088c565b620003c592919062000b18565b8190604051809103906000f5905080158015620003e6573d6000803e3d6000fd5b509650620003f68783836200052a565b505050505050919050565b60608167ffffffffffffffff8111156200041f576200041f62000c61565b60405190808252806020026020018201604052801562000449578160200160208202803683370190505b50905060005b82811015620005215773ffffffffffffffffffffffffffffffffffffffff80871660009081526020818152604080832093891683529290522062000494828662000bac565b81548110620004a757620004a762000c32565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828281518110620004e757620004e762000c32565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015280620005188162000bc7565b9150506200044f565b50949350505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146200059a576040517f03781a5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260016020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86161790555b600183510381101562000886578281600101815181106200060c576200060c62000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168382815181106200063f576200063f62000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff161062000695576040517f3f06bf8100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600181015b83518110156200087c57600080858481518110620006bc57620006bc62000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085838151811062000715576200071562000c32565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811683528282019390935260409091016000908120805460018101825590825291812090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169288169290921790915584518190869084908110620007a457620007a462000c32565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858481518110620007fd57620007fd62000c32565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff908116835282820193909352604090910160009081208054600180820183559183529290912090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001692881692909217909155016200069a565b50600101620005e7565b50505050565b61457c8062000cb783390190565b60008060008060808587031215620008b157600080fd5b8451620008be8162000c90565b6020860151909450620008d18162000c90565b6040860151606087015191945092508015158114620008ef57600080fd5b939692955090935050565b600080604083850312156200090e57600080fd5b82356200091b8162000c90565b915060208301356200092d8162000c90565b809150509250929050565b6000806000606084860312156200094e57600080fd5b83356200095b8162000c90565b925060208401356200096d8162000c90565b929592945050506040919091013590565b600080600080608085870312156200099557600080fd5b8435620009a28162000c90565b93506020850135620009b48162000c90565b93969395505050506040820135916060013590565b600060208284031215620009dc57600080fd5b5035919050565b600060208284031215620009f657600080fd5b813567ffffffffffffffff8082111562000a0f57600080fd5b818401915084601f83011262000a2457600080fd5b81358181111562000a395762000a3962000c61565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171562000a825762000a8262000c61565b8160405282815287602084870101111562000a9c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b6020808252825182820181905260009190848201906040850190845b8181101562000b0c57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010162000ad8565b50909695505050505050565b604081526000835180604084015260005b8181101562000b48576020818701810151606086840101520162000b29565b8181111562000b5b576000606083860101525b5073ffffffffffffffffffffffffffffffffffffffff93909316602083015250601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601606001919050565b6000821982111562000bc25762000bc262000c03565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141562000bfc5762000bfc62000c03565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811462000cb357600080fd5b5056fe6101a06040523480156200001257600080fd5b506040516200457c3803806200457c833981016040819052620000359162000562565b4660805262000112604080518082018252600e81526d29bab9b434902628102a37b5b2b760911b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527fc2bf45081e840722410522aa366600d7fe4da5bfb5a5b417f4d5125b4ed180a4818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c0909101909252815191012090565b60a081815250506000806000808580602001905181019062000135919062000502565b929650909450925090506001600160a01b0384166200018a5760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b60448201526064015b60405180910390fd5b826001600160a01b0316846001600160a01b03161415620001ee5760405162461bcd60e51b815260206004820152601360248201527f4944454e544943414c5f41444452455353455300000000000000000000000000604482015260640162000181565b6001600160a01b038416301415620002395760405162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22faa27a5a2a760991b604482015260640162000181565b6001600160a01b038316301415620002845760405162461bcd60e51b815260206004820152600d60248201526c24a72b20a624a22faa27a5a2a760991b604482015260640162000181565b612710821115620002cb5760405162461bcd60e51b815260206004820152601060248201526f494e56414c49445f535741505f46454560801b604482015260640162000181565b6001600160601b0319606085811b82166101605284901b166101805260c082905261271082900360e052604080516360a56c0160e11b815290516001600160a01b0387169163c14ad802916004808301926020929190829003018186803b1580156200033657600080fd5b505afa1580156200034b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000371919062000653565b600481905550846001600160a01b0316630c0a0cd26040518163ffffffff1660e01b815260040160206040518083038186803b158015620003b157600080fd5b505afa158015620003c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ec9190620004db565b6001600160a01b0316610100816001600160a01b031660601b81525050846001600160a01b0316634da318276040518163ffffffff1660e01b815260040160206040518083038186803b1580156200044357600080fd5b505afa15801562000458573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200047e9190620004db565b6001600160601b0319606091821b8116610120529086901b166101405260016009558015620004bd57600880546001600160e01b0316600160e01b1790555b5050505050506200069c565b8051620004d68162000683565b919050565b600060208284031215620004ee57600080fd5b8151620004fb8162000683565b9392505050565b600080600080608085870312156200051957600080fd5b8451620005268162000683565b6020860151909450620005398162000683565b60408601516060870151919450925080151581146200055757600080fd5b939692955090935050565b600080604083850312156200057657600080fd5b82516001600160401b03808211156200058e57600080fd5b818501915085601f830112620005a357600080fd5b815181811115620005b857620005b86200066d565b604051601f8201601f19908116603f01168101908382118183101715620005e357620005e36200066d565b816040528281526020935088848487010111156200060057600080fd5b600091505b8282101562000624578482018401518183018501529083019062000605565b82821115620006365760008484830101525b955062000648915050858201620004c9565b925050509250929050565b6000602082840312156200066657600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200069957600080fd5b50565b60805160a05160c05160e0516101005160601c6101205160601c6101405160601c6101605160601c6101805160601c613d4f6200082d600039600081816106060152818161085e0152818161098d01528181610a3b015281816110be015281816111c60152818161145c0152818161179c0152818161180b01528181611b6201528181611cc10152818161221f01528181612530015281816125b70152612e16015260008181610364015281816107da01528181610b2001528181610c4f015281816110920152818161115d015281816114e201528181611748015281816118ec01528181611a5c01528181611c53015281816121a0015281816125ec015281816126d70152612d2c0152600081816105df015261208801526000818161042301528181611aa901528181611baa01528181612bb001528181612c8c01528181612d5f0152612e47015260008181610318015261322c015260008181612aee015261348401526000818161044a0152818161354601526135b1015260006113c30152600061129a0152613d4f6000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063627dd56a11610145578063a69840a8116100bd578063c14ad8021161008c578063d21220a711610071578063d21220a714610601578063d505accf14610628578063dd62ed3e1461063b57600080fd5b8063c14ad802146105d1578063cf58879a146105da57600080fd5b8063a69840a814610571578063a8f1f52e14610598578063a9059cbb146105ab578063af8c09bf146105be57600080fd5b80637464fc3d116101145780637ecebe00116100f95780637ecebe001461050b57806392bc32191461052b57806395d89b411461053557600080fd5b80637464fc3d146104ef5780637ba0e2e7146104f857600080fd5b8063627dd56a1461047e57806365dfc7671461049157806367e4ac2c146104ba57806370a08231146104cf57600080fd5b80632a07b6c7116101d8578063499a3c50116101a757806354cf2aeb1161018c57806354cf2aeb146104455780635909c0d51461046c5780635a3d54931461047557600080fd5b8063499a3c501461040b5780634da318271461041e57600080fd5b80632a07b6c7146103a257806330adf81f146103c2578063313ce567146103e95780633644e5151461040357600080fd5b80630c0a0cd2116102145780630c0a0cd2146103135780630dfe16811461035f57806318160ddd1461038657806323b872dd1461038f57600080fd5b8063053da1c81461024657806306fdde031461026c5780630902f1ac146102b5578063095ea7b3146102f0575b600080fd5b61025961025436600461393a565b610666565b6040519081526020015b60405180910390f35b6102a86040518060400160405280600e81526020017f5375736869204c5020546f6b656e00000000000000000000000000000000000081525081565b6040516102639190613b13565b6102bd610d0b565b604080516dffffffffffffffffffffffffffff948516815293909216602084015263ffffffff1690820152606001610263565b6103036102fe36600461381d565b610d74565b6040519015158152602001610263565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610263565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b61025960005481565b61030361039d366004613882565b610ded565b6103b56103b036600461393a565b610f39565b6040516102639190613aae565b6102597f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6103f1601281565b60405160ff9091168152602001610263565b610259611296565b61025961041936600461393a565b6113e5565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b6102597f000000000000000000000000000000000000000000000000000000000000000081565b61025960055481565b61025960065481565b61025961048c36600461393a565b6115cd565b6104996119bd565b60408051938452602084019290925263ffffffff1690820152606001610263565b6104c2611c31565b6040516102639190613a54565b6102596104dd36600461366e565b60016020526000908152604090205481565b61025960075481565b61025961050636600461393a565b611d30565b61025961051936600461366e565b60036020526000908152604090205481565b610533612086565b005b6102a86040518060400160405280600381526020017f534c50000000000000000000000000000000000000000000000000000000000081525081565b6102597f54726964656e743a436f6e7374616e7450726f6475637400000000000000000081565b6102596105a636600461393a565b612129565b6103036105b936600461381d565b6122fd565b6102596105cc36600461393a565b612382565b61025960045481565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b61033a7f000000000000000000000000000000000000000000000000000000000000000081565b6105336106363660046138c3565b612794565b610259610649366004613849565b600260209081526000928352604080842090915290825290205481565b60006009546001146106d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60026009556000808080806106f0878901896136d9565b9450945094509450945060008060006107586008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b9250925092506000836dffffffffffffffffffffffffffff16116107d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f504f4f4c5f554e494e495449414c495a4544000000000000000000000000000060448201526064016106d0565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415610a395761085785846dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff16612ae6565b98506108857f00000000000000000000000000000000000000000000000000000000000000008a8989612b49565b6040517fbd50c7b1000000000000000000000000000000000000000000000000000000008152339063bd50c7b1906108c1908790600401613b13565b600060405180830381600087803b1580156108db57600080fd5b505af11580156108ef573d6000803e3d6000fd5b505050506000806108fe612cef565b9150915086856dffffffffffffffffffffffffffff168303101561097e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f494e53554646494349454e545f414d4f554e545f494e0000000000000000000060448201526064016106d0565b61098b8282878787612ec9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e460628a8f604051610a2a929190918252602082015260400190565b60405180910390a45050610cf7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f494e56414c49445f494e5055545f544f4b454e0000000000000000000000000060448201526064016106d0565b610b1985836dffffffffffffffffffffffffffff16856dffffffffffffffffffffffffffff16612ae6565b9850610b477f00000000000000000000000000000000000000000000000000000000000000008a8989612b49565b6040517fbd50c7b1000000000000000000000000000000000000000000000000000000008152339063bd50c7b190610b83908790600401613b13565b600060405180830381600087803b158015610b9d57600080fd5b505af1158015610bb1573d6000803e3d6000fd5b50505050600080610bc0612cef565b9150915086846dffffffffffffffffffffffffffff1682031015610c40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f494e53554646494349454e545f414d4f554e545f494e0000000000000000000060448201526064016106d0565b610c4d8282878787612ec9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e460628a8f604051610cec929190918252602082015260400190565b60405180910390a450505b505060016009555094979650505050505050565b6000806000610d696008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b925092509250909192565b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610ddc9086815260200190565b60405180910390a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14610e8a5773ffffffffffffffffffffffffffffffffffffffff8416600090815260026020908152604080832033845290915281208054849290610e84908490613be8565b90915550505b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604081208054849290610ebf908490613be8565b909155505073ffffffffffffffffffffffffffffffffffffffff808416600081815260016020526040908190208054860190555190918616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610f279086815260200190565b60405180910390a35060019392505050565b6060600954600114610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b6002600955600080610fbb848601866137e8565b91509150600080600061101d6008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b92509250925060008061102e612cef565b3060009081526001602052604081205492945090925061104e87876131a8565b50905060008161105e8685613bab565b6110689190613b70565b90506000826110778686613bab565b6110819190613b70565b905061108d3085613268565b6110b97f0000000000000000000000000000000000000000000000000000000000000000838d8d612b49565b6110e57f0000000000000000000000000000000000000000000000000000000000000000828d8d612b49565b818603955080850394506110fc86868b8b8b612ec9565b61110e6111098688613bab565b6132fb565b6007556040805160028082526060820190925290816020015b6040805180820190915260008082526020820152815260200190600190039081611127579050509b5060405180604001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168152602001838152508c6000815181106111ae576111ae613c96565b602002602001018190525060405180604001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168152602001828152508c60018151811061121757611217613c96565b60209081029190910181019190915260408051848152918201839052810185905273ffffffffffffffffffffffffffffffffffffffff8c169033907fa476cebfbe7485684f5578d84d8a64a8afe93a0a2a3047bd6f3e681e108b8f119060600160405180910390a35050600160095550979a9950505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146113c05750604080518082018252600e81527f5375736869204c5020546f6b656e00000000000000000000000000000000000060209182015281518083018352600181527f31000000000000000000000000000000000000000000000000000000000000009082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527fc2bf45081e840722410522aa366600d7fe4da5bfb5a5b417f4d5125b4ed180a4818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c0909101909252815191012090565b507f000000000000000000000000000000000000000000000000000000000000000090565b600080806113f58486018661381d565b915091506000806114556008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b50915091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114e0576114d983836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff16613480565b94506115c3565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f494e56414c49445f4f55545055545f544f4b454e00000000000000000000000060448201526064016106d0565b6115c083826dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff16613480565b94505b5050505092915050565b600060095460011461163b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b60026009556000808061165085870187613692565b92509250925060008060006116b46008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b9250925092506000836dffffffffffffffffffffffffffff1611611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f504f4f4c5f554e494e495449414c495a4544000000000000000000000000000060448201526064016106d0565b60008061173f612cef565b915091506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161415611809577f00000000000000000000000000000000000000000000000000000000000000009050866dffffffffffffffffffffffffffff16840391506117fd82886dffffffffffffffffffffffffffff16886dffffffffffffffffffffffffffff16612ae6565b9a508a83039250611925565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff16146118be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f494e56414c49445f494e5055545f544f4b454e0000000000000000000000000060448201526064016106d0565b50506008546dffffffffffffffffffffffffffff6e01000000000000000000000000000090910481168203907f00000000000000000000000000000000000000000000000000000000000000009061191d908390888116908a16612ae6565b9a508a840393505b611931818c8b8b612b49565b61193e8484898989612ec9565b8073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167fcd3829a3813dc3cdd188fd3d01dcf3268c16be2fdd2dd21d0665418816e46062858f604051610cec929190918252602082015260400190565b600080600080600080611a1f6008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b6040517f5662311800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526dffffffffffffffffffffffffffff851660248301526000604483015293965091945092507f00000000000000000000000000000000000000000000000000000000000000009091169063566231189060640160206040518083038186803b158015611aed57600080fd5b505afa158015611b01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2591906139ac565b6040517f5662311800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526dffffffffffffffffffffffffffff85166024830152600060448301529197507f00000000000000000000000000000000000000000000000000000000000000009091169063566231189060640160206040518083038186803b158015611bee57600080fd5b505afa158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2691906139ac565b959690945092505050565b60408051600280825260608083018452926020830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110611c8557611c85613c96565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110611cf357611cf3613c96565b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505090565b6000600954600114611d9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b60026009556000611db18385018561366e565b90506000806000611e116008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b925092509250600080611e22612cef565b90925090506000611e366111098385613bab565b90506000611e546dffffffffffffffffffffffffffff881685613be8565b90506000611e726dffffffffffffffffffffffffffff881685613be8565b9050600080611ea384848c6dffffffffffffffffffffffffffff168c6dffffffffffffffffffffffffffff166134eb565b9092509050611eb2828b613b26565b9950611ebe818a613b26565b9850600080611ecd8c8c6131a8565b915091508160001415611f7057600086118015611eea5750600085115b611f50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f494e56414c49445f414d4f554e5453000000000000000000000000000000000060448201526064016106d0565b611f5c6103e888613be8565b9d50611f6b60006103e86135ee565b611f8c565b80870381611f7e8483613bab565b611f889190613b70565b9e50505b8d611ff3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f494e53554646494349454e545f4c49515549444954595f4d494e54454400000060448201526064016106d0565b611ffd8d8f6135ee565b61200a89898e8e8e612ec9565b600787905560408051878152602081018790529081018f90528e9073ffffffffffffffffffffffffffffffffffffffff8f169033907ff9c32fbc56ff04f32a233ebc26e388564223745e28abd8d0781dd906537f563e9060600160405180910390a350506001600955509a9d9c50505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c14ad8026040518163ffffffff1660e01b815260040160206040518083038186803b1580156120ec57600080fd5b505afa158015612100573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212491906139ac565b600455565b600080806121398486018661381d565b915091506000806121996008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b50915091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561221d576114d983836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff16612ae6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146122d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f494e56414c49445f494e5055545f544f4b454e0000000000000000000000000060448201526064016106d0565b6115c083826dffffffffffffffffffffffffffff16846dffffffffffffffffffffffffffff16612ae6565b3360009081526001602052604081208054839190839061231e908490613be8565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260016020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610ddc9086815260200190565b60006009546001146123f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f4c4f434b4544000000000000000000000000000000000000000000000000000060448201526064016106d0565b60026009556000808061240585870187613692565b92509250925060008060006124696008546dffffffffffffffffffffffffffff808216926e01000000000000000000000000000083049091169163ffffffff7c01000000000000000000000000000000000000000000000000000000009091041690565b30600090815260016020526040812054939650919450925061248b85856131a8565b5090506000816124ab6dffffffffffffffffffffffffffff881685613bab565b6124b59190613b70565b90506000826124d46dffffffffffffffffffffffffffff881686613bab565b6124de9190613b70565b90506125216124fd826dffffffffffffffffffffffffffff8916613be8565b612517846dffffffffffffffffffffffffffff8b16613be8565b6111099190613bab565b60075561252e3085613268565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614156125ea576125b18283896dffffffffffffffffffffffffffff160383896dffffffffffffffffffffffffffff1603612ae6565b016125de7f0000000000000000000000000000000000000000000000000000000000000000828b8b612b49565b809a5060009150612705565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161461269f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f494e56414c49445f4f55545055545f544f4b454e00000000000000000000000060448201526064016106d0565b6126ce8182886dffffffffffffffffffffffffffff1603848a6dffffffffffffffffffffffffffff1603612ae6565b820191506126fe7f0000000000000000000000000000000000000000000000000000000000000000838b8b612b49565b5098508860005b600080612710612cef565b9150915061272182828b8b8b612ec9565b604080518581526020810185905290810187905273ffffffffffffffffffffffffffffffffffffffff8c169033907fa476cebfbe7485684f5578d84d8a64a8afe93a0a2a3047bd6f3e681e108b8f119060600160405180910390a35050600160095550989b9a5050505050505050505050565b428410156127fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016106d0565b6000612808611296565b73ffffffffffffffffffffffffffffffffffffffff8916600090815260036020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928c928c928c9290919061286383613bff565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810187905260e001604051602081830303815290604052805190602001206040516020016129049291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa15801561298d573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590612a0857508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b612a6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f494e56414c49445f5045524d49545f5349474e4154555245000000000000000060448201526064016106d0565b73ffffffffffffffffffffffffffffffffffffffff81811660009081526002602090815260408083208c8516808552908352928190208b9055518a815291928c16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050505050505050565b600080612b137f000000000000000000000000000000000000000000000000000000000000000086613bab565b905080612b2261271086613bab565b612b2c9190613b58565b612b368483613bab565b612b409190613b70565b95945050505050565b8015612c32576040517f97da6d3000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152306024830152838116604483015260006064830152608482018590527f000000000000000000000000000000000000000000000000000000000000000016906397da6d309060a4016040805180830381600087803b158015612bf357600080fd5b505af1158015612c07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c2b91906139c5565b5050612ce9565b6040517ff18d03cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301523060248301528381166044830152606482018590527f0000000000000000000000000000000000000000000000000000000000000000169063f18d03cc90608401600060405180830381600087803b158015612cd057600080fd5b505af1158015612ce4573d6000803e3d6000fd5b505050505b50505050565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015260009182917f0000000000000000000000000000000000000000000000000000000000000000169063f7888aec9060440160206040518083038186803b158015612da157600080fd5b505afa158015612db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd991906139ac565b6040517ff7888aec00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301529193507f00000000000000000000000000000000000000000000000000000000000000009091169063f7888aec9060440160206040518083038186803b158015612e8b57600080fd5b505afa158015612e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ec391906139ac565b90509091565b6dffffffffffffffffffffffffffff8511801590612ef557506dffffffffffffffffffffffffffff8411155b612f5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f4f564552464c4f5700000000000000000000000000000000000000000000000060448201526064016106d0565b63ffffffff8116612fbd57600880546dffffffffffffffffffffffffffff8681166e010000000000000000000000000000027fffffffff0000000000000000000000000000000000000000000000000000000090921690881617179055613168565b4263ffffffff80821690831614801590612fe657506dffffffffffffffffffffffffffff841615155b801561300157506dffffffffffffffffffffffffffff831615155b156130c65781810360006dffffffffffffffffffffffffffff86167bffffffffffffffffffffffffffff0000000000000000000000000000607087901b168161304c5761304c613c67565b600580549290910463ffffffff851681029092019055905060006dffffffffffffffffffffffffffff8616607088901b7bffffffffffffffffffffffffffff000000000000000000000000000016816130a7576130a7613c67565b0490508263ffffffff1681026006600082825401925050819055505050505b6008805463ffffffff9092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff6dffffffffffffffffffffffffffff8881166e010000000000000000000000000000027fffffffff00000000000000000000000000000000000000000000000000000000909516908a161793909317929092169190911790555b60408051868152602081018690527fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a910160405180910390a15050505050565b600080546007549091908015613260576131d86111096dffffffffffffffffffffffffffff808716908816613bab565b9150808211156132605760006127108360045484866131f79190613be8565b6132019088613bab565b61320b9190613bab565b6132159190613b70565b61321f9190613b70565b9050801561325e576132517f0000000000000000000000000000000000000000000000000000000000000000826135ee565b61325b8185613b58565b93505b505b509250929050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600160205260408120805483929061329d908490613be8565b909155505060008054829003815560405182815273ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b60008161330a57506000919050565b81600170010000000000000000000000000000000082106133305760809190911c9060401b5b68010000000000000000821061334b5760409190911c9060201b5b64010000000082106133625760209190911c9060101b5b6201000082106133775760109190911c9060081b5b610100821061338b5760089190911c9060041b5b6010821061339e5760049190911c9060021b5b600882106133aa5760011b5b60018185816133bb576133bb613c67565b048201901c905060018185816133d3576133d3613c67565b048201901c905060018185816133eb576133eb613c67565b048201901c9050600181858161340357613403613c67565b048201901c9050600181858161341b5761341b613c67565b048201901c9050600181858161343357613433613c67565b048201901c9050600181858161344b5761344b613c67565b048201901c9050600081858161346357613463613c67565b0490508082106134735780613475565b815b93505050505b919050565b60007f00000000000000000000000000000000000000000000000000000000000000006134ad8584613be8565b6134b79190613bab565b6127106134c48686613bab565b6134ce9190613bab565b6134d89190613b70565b6134e3906001613b58565b949350505050565b6000808315806134f9575082155b15613509575060009050806135e5565b6000846135168589613bab565b6135209190613b70565b905085811161357b576135366127106002613bab565b6135408288613be8565b61356a907f0000000000000000000000000000000000000000000000000000000000000000613bab565b6135749190613b70565b91506135e3565b6000846135888789613bab565b6135929190613b70565b90506135a16127106002613bab565b6135ab828a613be8565b6135d5907f0000000000000000000000000000000000000000000000000000000000000000613bab565b6135df9190613b70565b9350505b505b94509492505050565b806000808282546135ff9190613b58565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016132ef565b8035801515811461347b57600080fd5b60006020828403121561368057600080fd5b813561368b81613cf4565b9392505050565b6000806000606084860312156136a757600080fd5b83356136b281613cf4565b925060208401356136c281613cf4565b91506136d06040850161365e565b90509250925092565b600080600080600060a086880312156136f157600080fd5b85356136fc81613cf4565b9450602086013561370c81613cf4565b935061371a6040870161365e565b925060608601359150608086013567ffffffffffffffff8082111561373e57600080fd5b818801915088601f83011261375257600080fd5b81358181111561376457613764613cc5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156137aa576137aa613cc5565b816040528281528b60208487010111156137c357600080fd5b8260208601602083013760006020848301015280955050505050509295509295909350565b600080604083850312156137fb57600080fd5b823561380681613cf4565b91506138146020840161365e565b90509250929050565b6000806040838503121561383057600080fd5b823561383b81613cf4565b946020939093013593505050565b6000806040838503121561385c57600080fd5b823561386781613cf4565b9150602083013561387781613cf4565b809150509250929050565b60008060006060848603121561389757600080fd5b83356138a281613cf4565b925060208401356138b281613cf4565b929592945050506040919091013590565b600080600080600080600060e0888a0312156138de57600080fd5b87356138e981613cf4565b965060208801356138f981613cf4565b95506040880135945060608801359350608088013560ff8116811461391d57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806020838503121561394d57600080fd5b823567ffffffffffffffff8082111561396557600080fd5b818501915085601f83011261397957600080fd5b81358181111561398857600080fd5b86602082850101111561399a57600080fd5b60209290920196919550909350505050565b6000602082840312156139be57600080fd5b5051919050565b600080604083850312156139d857600080fd5b505080516020909101519092909150565b6000815180845260005b81811015613a0f576020818501810151868301820152016139f3565b81811115613a21576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020808252825182820181905260009190848201906040850190845b81811015613aa257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613a70565b50909695505050505050565b602080825282518282018190526000919060409081850190868401855b82811015613b06578151805173ffffffffffffffffffffffffffffffffffffffff168552860151868501529284019290850190600101613acb565b5091979650505050505050565b60208152600061368b60208301846139e9565b60006dffffffffffffffffffffffffffff808316818516808303821115613b4f57613b4f613c38565b01949350505050565b60008219821115613b6b57613b6b613c38565b500190565b600082613ba6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613be357613be3613c38565b500290565b600082821015613bfa57613bfa613c38565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613c3157613c31613c38565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114613d1657600080fd5b5056fea2646970667358221220c53c5cf6f9cb8b7e269fceb7679cf92974d918605fd12748f1e47ae0f9e5d8da64736f6c63430008070033a264697066735822122051d90a1744a16d7db99e44d739049f1b38b18b970e9de3c4b3b8c86c36c6059b64736f6c63430008070033",
  "devdoc": {
    "author": "Mudit Gupta.",
    "kind": "dev",
    "methods": {},
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "notice": "Contract for deploying Trident exchange Constant Product Pool with configurations.",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 11607,
        "contract": "contracts/pool/ConstantProductPoolFactory.sol:ConstantProductPoolFactory",
        "label": "pools",
        "offset": 0,
        "slot": "0",
        "type": "t_mapping(t_address,t_mapping(t_address,t_array(t_address)dyn_storage))"
      },
      {
        "astId": 11611,
        "contract": "contracts/pool/ConstantProductPoolFactory.sol:ConstantProductPoolFactory",
        "label": "configAddress",
        "offset": 0,
        "slot": "1",
        "type": "t_mapping(t_bytes32,t_address)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_array(t_address)dyn_storage": {
        "base": "t_address",
        "encoding": "dynamic_array",
        "label": "address[]",
        "numberOfBytes": "32"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_mapping(t_address,t_array(t_address)dyn_storage)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => address[])",
        "numberOfBytes": "32",
        "value": "t_array(t_address)dyn_storage"
      },
      "t_mapping(t_address,t_mapping(t_address,t_array(t_address)dyn_storage))": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => mapping(address => address[]))",
        "numberOfBytes": "32",
        "value": "t_mapping(t_address,t_array(t_address)dyn_storage)"
      },
      "t_mapping(t_bytes32,t_address)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => address)",
        "numberOfBytes": "32",
        "value": "t_address"
      }
    }
  }
}