creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/TokenLockerV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\n\n/**\n  /$$$$$$            /$$           /$$      /$$                                        \n /$$__  $$          | $$          | $$$    /$$$                                        \n| $$  \\ $$ /$$$$$$$ | $$ /$$   /$$| $$$$  /$$$$  /$$$$$$   /$$$$$$  /$$$$$$$   /$$$$$$$\n| $$  | $$| $$__  $$| $$| $$  | $$| $$ $$/$$ $$ /$$__  $$ /$$__  $$| $$__  $$ /$$_____/\n| $$  | $$| $$  \\ $$| $$| $$  | $$| $$  $$$| $$| $$  \\ $$| $$  \\ $$| $$  \\ $$|  $$$$$$ \n| $$  | $$| $$  | $$| $$| $$  | $$| $$\\  $ | $$| $$  | $$| $$  | $$| $$  | $$ \\____  $$\n|  $$$$$$/| $$  | $$| $$|  $$$$$$$| $$ \\/  | $$|  $$$$$$/|  $$$$$$/| $$  | $$ /$$$$$$$/\n \\______/ |__/  |__/|__/ \\____  $$|__/     |__/ \\______/  \\______/ |__/  |__/|_______/ \n                         /$$  | $$                                                     \n                        |  $$$$$$/                                                     \n                         \\______/                                                      \n\n  https://onlymoons.io/\n*/\n\npragma solidity ^0.8.0;\n\nimport { ITokenLockerManagerV1 } from \"./ITokenLockerManagerV1.sol\";\nimport { Ownable } from \"./Ownable.sol\";\nimport { IUniswapV2Pair } from \"./library/Dex.sol\";\nimport { IERC20 } from \"./library/IERC20.sol\";\nimport { Util } from \"./Util.sol\";\n\ncontract TokenLockerV1 is Ownable {\n  event Extended(uint40 newUnlockTime);\n  event Deposited(uint256 amount);\n  event Withdrew();\n\n  constructor(address manager_, uint40 id_, address owner_, address tokenAddress_, uint40 unlockTime_) Ownable(owner_) {\n    require(unlockTime_ > uint40(block.timestamp), \"Unlock time must be in the future\");\n\n    _manager = ITokenLockerManagerV1(manager_);\n    _id = id_;\n    _token = IERC20(tokenAddress_);\n    _createdBy = owner_;\n    _createdAt = uint40(block.timestamp);\n    _unlockTime = unlockTime_;\n    _isLpToken = Util.isLpToken(tokenAddress_);\n  }\n\n  ITokenLockerManagerV1 private _manager;\n  bool private _isLpToken;\n  uint40 private _id;\n  IERC20 private _token;\n  address private _createdBy;\n  uint40 private _createdAt;\n  uint40 private _unlockTime;\n\n  bool private _transferLocked;\n\n  modifier transferLocked() {\n    require(!_transferLocked, \"Transfering is locked. Wait for the previous transaction to complete\");\n    _transferLocked = true;\n    _;\n    _transferLocked = false;\n  }\n\n  function _balance() private view returns (uint256) {\n    return _token.balanceOf(address(this));\n  }\n\n  function getIsLpToken() external view returns (bool) {\n    return _isLpToken;\n  }\n\n  function getLockData() external view returns (\n    bool isLpToken,\n    uint40 id,\n    address contractAddress,\n    address lockOwner,\n    address token,\n    address createdBy,\n    uint40 createdAt,\n    uint40 unlockTime,\n    uint256 balance,\n    uint256 totalSupply\n  ){\n    isLpToken = _isLpToken;\n    id = _id;\n    contractAddress = address(this);\n    lockOwner = _owner();\n    token = address(_token);\n    createdBy = _createdBy;\n    createdAt = _createdAt;\n    unlockTime = _unlockTime;\n    balance = _balance();\n    totalSupply = _token.totalSupply();\n  }\n\n  function getLpData() external view returns (\n    bool hasLpData,\n    uint40 id,\n    address token0,\n    address token1,\n    uint256 balance0,\n    uint256 balance1,\n    uint256 price0,\n    uint256 price1\n  ) {\n    // always return the id\n    id = _id;\n\n    if (!_isLpToken) {\n      // if this isn't an lp token, don't even bother calling getLpData\n      hasLpData = false;\n    } else {\n      // this is an lp token, so let's get some data\n      try Util.getLpData(address(_token)) returns (\n        address token0_,\n        address token1_,\n        uint256 balance0_,\n        uint256 balance1_,\n        uint256 price0_,\n        uint256 price1_\n      ){\n        hasLpData = true;\n        token0 = token0_;\n        token1 = token1_;\n        balance0 = balance0_;\n        balance1 = balance1_;\n        price0 = price0_;\n        price1 = price1_;\n      } catch Error(string memory /* reason */) {\n        hasLpData = false;\n      } catch (bytes memory /* lowLevelData */) {\n        hasLpData = false;\n      }\n    }\n  }\n\n  /**\n   * @dev deposit and extend duration in one call\n   */\n  function deposit(uint256 amount_, uint40 newUnlockTime_) external onlyOwner transferLocked {\n    if (newUnlockTime_ != 0) {\n      require(\n        newUnlockTime_ >= _unlockTime && newUnlockTime_ >= uint40(block.timestamp),\n        \"New unlock time must be a future time beyond the previous value\"\n      );\n      _unlockTime = newUnlockTime_;\n      emit Extended(_unlockTime);\n    }\n\n    if (amount_ != 0) {\n      uint256 oldBalance = _balance();\n      _token.transferFrom(_msgSender(), address(this), amount_);\n      emit Deposited(_balance() - oldBalance);\n    }\n  }\n\n  /**\n   * @dev withdraw all of the deposited token\n   */\n  function withdraw() external onlyOwner transferLocked {\n    require(uint40(block.timestamp) >= _unlockTime, \"Wait until unlockTime to withdraw\");\n\n    _token.transfer(_owner(), _balance());\n\n    emit Withdrew();\n  }\n\n  /**\n   * @dev recovery function -\n   * just in case this contract winds up with additional tokens (from dividends, etc).\n   * attempting to withdraw the locked token will revert.\n   */\n  function withdrawToken(address address_) external onlyOwner transferLocked {\n    require(address_ != address(_token), \"Use 'withdraw' to withdraw the primary locked token\");\n\n    IERC20 theToken = IERC20(address_);\n    theToken.transfer(_owner(), theToken.balanceOf(address(this)));\n  }\n\n  /**\n   * @dev recovery function -\n   * just in case this contract winds up with eth in it (from dividends etc)\n   */\n  function withdrawEth() external onlyOwner transferLocked {\n    address payable receiver = payable(_owner());\n    receiver.transfer(address(this).balance);\n  }\n\n  function _transferOwnership(address newOwner_) override internal onlyOwner {\n    address previousOwner = _owner();\n    super._transferOwnership(newOwner_);\n\n    // we need to notify the manager contract that we transferred\n    // ownership, so that the new owner is searchable.\n    _manager.notifyLockerOwnerChange(_id, newOwner_, previousOwner, _createdBy);\n  }\n\n  receive() external payable {\n    // we need this function to receive eth,\n    // which might happen from dividend tokens.\n    // use `withdrawEth` to remove eth from the contract.\n  }\n}\n"
      },
      "contracts/ITokenLockerManagerV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\n\n/**\n  /$$$$$$            /$$           /$$      /$$                                        \n /$$__  $$          | $$          | $$$    /$$$                                        \n| $$  \\ $$ /$$$$$$$ | $$ /$$   /$$| $$$$  /$$$$  /$$$$$$   /$$$$$$  /$$$$$$$   /$$$$$$$\n| $$  | $$| $$__  $$| $$| $$  | $$| $$ $$/$$ $$ /$$__  $$ /$$__  $$| $$__  $$ /$$_____/\n| $$  | $$| $$  \\ $$| $$| $$  | $$| $$  $$$| $$| $$  \\ $$| $$  \\ $$| $$  \\ $$|  $$$$$$ \n| $$  | $$| $$  | $$| $$| $$  | $$| $$\\  $ | $$| $$  | $$| $$  | $$| $$  | $$ \\____  $$\n|  $$$$$$/| $$  | $$| $$|  $$$$$$$| $$ \\/  | $$|  $$$$$$/|  $$$$$$/| $$  | $$ /$$$$$$$/\n \\______/ |__/  |__/|__/ \\____  $$|__/     |__/ \\______/  \\______/ |__/  |__/|_______/ \n                         /$$  | $$                                                     \n                        |  $$$$$$/                                                     \n                         \\______/                                                      \n\n  https://onlymoons.io/\n*/\n\npragma solidity ^0.8.0;\n\ninterface ITokenLockerManagerV1 {\n  function tokenLockerCount() external view returns (uint40);\n  function creationEnabled() external view returns (bool);\n  function setCreationEnabled(bool value_) external;\n  function createTokenLocker(\n    address tokenAddress_,\n    uint256 amount_,\n    uint40 unlockTime_\n  ) external;\n  function getTokenLockAddress(uint40 id_) external view returns (address);\n  function getTokenLockData(uint40 id_) external view returns (\n    bool isLpToken,\n    uint40 id,\n    address contractAddress,\n    address lockOwner,\n    address token,\n    address createdBy,\n    uint40 createdAt,\n    uint40 unlockTime,\n    uint256 balance,\n    uint256 totalSupply\n  );\n  function getLpData(uint40 id_) external view returns (\n    bool hasLpData,\n    uint40 id,\n    address token0,\n    address token1,\n    uint256 balance0,\n    uint256 balance1,\n    uint256 price0,\n    uint256 price1\n  );\n  function getTokenLockersForAddress(address address_) external view returns (uint40[] memory);\n  function notifyLockerOwnerChange(uint40 id_, address newOwner_, address previousOwner_, address createdBy_) external;\n}\n"
      },
      "contracts/Ownable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\n\n/**\n  /$$$$$$            /$$           /$$      /$$                                        \n /$$__  $$          | $$          | $$$    /$$$                                        \n| $$  \\ $$ /$$$$$$$ | $$ /$$   /$$| $$$$  /$$$$  /$$$$$$   /$$$$$$  /$$$$$$$   /$$$$$$$\n| $$  | $$| $$__  $$| $$| $$  | $$| $$ $$/$$ $$ /$$__  $$ /$$__  $$| $$__  $$ /$$_____/\n| $$  | $$| $$  \\ $$| $$| $$  | $$| $$  $$$| $$| $$  \\ $$| $$  \\ $$| $$  \\ $$|  $$$$$$ \n| $$  | $$| $$  | $$| $$| $$  | $$| $$\\  $ | $$| $$  | $$| $$  | $$| $$  | $$ \\____  $$\n|  $$$$$$/| $$  | $$| $$|  $$$$$$$| $$ \\/  | $$|  $$$$$$/|  $$$$$$/| $$  | $$ /$$$$$$$/\n \\______/ |__/  |__/|__/ \\____  $$|__/     |__/ \\______/  \\______/ |__/  |__/|_______/ \n                         /$$  | $$                                                     \n                        |  $$$$$$/                                                     \n                         \\______/                                                      \n\n  https://onlymoons.io/\n*/\n\npragma solidity ^0.8.0;\n\nimport { Context } from \"./library/Context.sol\";\n\n/**\n * @title Ownable\n * \n * parent for ownable contracts\n */\nabstract contract Ownable is Context {\n  constructor(address owner_) {\n    _owner_ = owner_;\n    emit OwnershipTransferred(address(0), _owner());\n  }\n\n  address private _owner_;\n\n  event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);\n\n  function _owner() internal view returns (address) {\n    return _owner_;\n  }\n\n  function owner() external view returns (address) {\n    return _owner();\n  }\n\n  modifier onlyOwner() {\n    require(_owner() == _msgSender(), \"Only the owner can execute this function\");\n    _;\n  }\n\n  function _transferOwnership(address newOwner_) virtual internal onlyOwner {\n    // keep track of old owner for event\n    address oldOwner = _owner();\n\n    // set the new owner\n    _owner_ = newOwner_;\n\n    // emit event about ownership change\n    emit OwnershipTransferred(oldOwner, _owner());\n  }\n\n  function transferOwnership(address newOwner_) external onlyOwner {\n    _transferOwnership(newOwner_);\n  }\n}\n"
      },
      "contracts/library/Dex.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2;\n\ninterface IUniswapV2Factory {\n  event PairCreated(address indexed token0, address indexed token1, address pair, uint);\n\n  function feeTo() external view returns (address);\n  function feeToSetter() external view returns (address);\n\n  function getPair(address tokenA, address tokenB) external view returns (address pair);\n  function allPairs(uint) external view returns (address pair);\n  function allPairsLength() external view returns (uint);\n\n  function createPair(address tokenA, address tokenB) external returns (address pair);\n\n  function setFeeTo(address) external;\n  function setFeeToSetter(address) external;\n}\n\ninterface IUniswapV2Pair {\n  event Approval(address indexed owner, address indexed spender, uint value);\n  event Transfer(address indexed from, address indexed to, uint value);\n\n  function name() external pure returns (string memory);\n  function symbol() external pure returns (string memory);\n  function decimals() external pure returns (uint8);\n  function totalSupply() external view returns (uint);\n  function balanceOf(address owner) external view returns (uint);\n  function allowance(address owner, address spender) external view returns (uint);\n\n  function approve(address spender, uint value) external returns (bool);\n  function transfer(address to, uint value) external returns (bool);\n  function transferFrom(address from, address to, uint value) external returns (bool);\n\n  function DOMAIN_SEPARATOR() external view returns (bytes32);\n  function PERMIT_TYPEHASH() external pure returns (bytes32);\n  function nonces(address owner) external view returns (uint);\n\n  function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n  event Mint(address indexed sender, uint amount0, uint amount1);\n  event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);\n  event Swap(\n    address indexed sender,\n    uint amount0In,\n    uint amount1In,\n    uint amount0Out,\n    uint amount1Out,\n    address indexed to\n  );\n  event Sync(uint112 reserve0, uint112 reserve1);\n\n  function MINIMUM_LIQUIDITY() external pure returns (uint);\n  function factory() external view returns (address);\n  function token0() external view returns (address);\n  function token1() external view returns (address);\n  function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n  function price0CumulativeLast() external view returns (uint);\n  function price1CumulativeLast() external view returns (uint);\n  function kLast() external view returns (uint);\n\n  function mint(address to) external returns (uint liquidity);\n  function burn(address to) external returns (uint amount0, uint amount1);\n  function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n  function skim(address to) external;\n  function sync() external;\n\n  function initialize(address, address) external;\n}\n\ninterface IUniswapV2Router01 {\n  function factory() external pure returns (address);\n  function WETH() external pure returns (address);\n\n  function addLiquidity(\n    address tokenA,\n    address tokenB,\n    uint amountADesired,\n    uint amountBDesired,\n    uint amountAMin,\n    uint amountBMin,\n    address to,\n    uint deadline\n  ) external returns (uint amountA, uint amountB, uint liquidity);\n  function addLiquidityETH(\n    address token,\n    uint amountTokenDesired,\n    uint amountTokenMin,\n    uint amountETHMin,\n    address to,\n    uint deadline\n  ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n  function removeLiquidity(\n    address tokenA,\n    address tokenB,\n    uint liquidity,\n    uint amountAMin,\n    uint amountBMin,\n    address to,\n    uint deadline\n  ) external returns (uint amountA, uint amountB);\n  function removeLiquidityETH(\n    address token,\n    uint liquidity,\n    uint amountTokenMin,\n    uint amountETHMin,\n    address to,\n    uint deadline\n  ) external returns (uint amountToken, uint amountETH);\n  function removeLiquidityWithPermit(\n    address tokenA,\n    address tokenB,\n    uint liquidity,\n    uint amountAMin,\n    uint amountBMin,\n    address to,\n    uint deadline,\n    bool approveMax, uint8 v, bytes32 r, bytes32 s\n  ) external returns (uint amountA, uint amountB);\n  function removeLiquidityETHWithPermit(\n    address token,\n    uint liquidity,\n    uint amountTokenMin,\n    uint amountETHMin,\n    address to,\n    uint deadline,\n    bool approveMax, uint8 v, bytes32 r, bytes32 s\n  ) external returns (uint amountToken, uint amountETH);\n  function swapExactTokensForTokens(\n    uint amountIn,\n    uint amountOutMin,\n    address[] calldata path,\n    address to,\n    uint deadline\n  ) external returns (uint[] memory amounts);\n  function swapTokensForExactTokens(\n    uint amountOut,\n    uint amountInMax,\n    address[] calldata path,\n    address to,\n    uint deadline\n  ) external returns (uint[] memory amounts);\n  function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n    external\n    payable\n    returns (uint[] memory amounts);\n  function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n    external\n    returns (uint[] memory amounts);\n  function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n    external\n    returns (uint[] memory amounts);\n  function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n    external\n    payable\n    returns (uint[] memory amounts);\n\n  function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n  function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n  function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n  function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n  function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n  function removeLiquidityETHSupportingFeeOnTransferTokens(\n    address token,\n    uint liquidity,\n    uint amountTokenMin,\n    uint amountETHMin,\n    address to,\n    uint deadline\n  ) external returns (uint amountETH);\n  function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n    address token,\n    uint liquidity,\n    uint amountTokenMin,\n    uint amountETHMin,\n    address to,\n    uint deadline,\n    bool approveMax, uint8 v, bytes32 r, bytes32 s\n  ) external returns (uint amountETH);\n\n  function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n    uint amountIn,\n    uint amountOutMin,\n    address[] calldata path,\n    address to,\n    uint deadline\n  ) external;\n  function swapExactETHForTokensSupportingFeeOnTransferTokens(\n    uint amountOutMin,\n    address[] calldata path,\n    address to,\n    uint deadline\n  ) external payable;\n  function swapExactTokensForETHSupportingFeeOnTransferTokens(\n    uint amountIn,\n    uint amountOutMin,\n    address[] calldata path,\n    address to,\n    uint deadline\n  ) external;\n}\n"
      },
      "contracts/library/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/IERC20.sol\ninterface IERC20 {\n  function name() external view returns (string memory);\n  function symbol() external view returns (string memory);\n  function totalSupply() external view returns (uint256);\n  function decimals() external view returns (uint8);\n  function balanceOf(address account) external view returns (uint256);\n  function transfer(address recipient, uint256 amount) external returns (bool);\n  function allowance(address owner, address spender) external view returns (uint256);\n  function approve(address spender, uint256 amount) external returns (bool);\n  function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n  event Transfer(address indexed from, address indexed to, uint256 value);\n  event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "contracts/Util.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\n\n/**\n  /$$$$$$            /$$           /$$      /$$                                        \n /$$__  $$          | $$          | $$$    /$$$                                        \n| $$  \\ $$ /$$$$$$$ | $$ /$$   /$$| $$$$  /$$$$  /$$$$$$   /$$$$$$  /$$$$$$$   /$$$$$$$\n| $$  | $$| $$__  $$| $$| $$  | $$| $$ $$/$$ $$ /$$__  $$ /$$__  $$| $$__  $$ /$$_____/\n| $$  | $$| $$  \\ $$| $$| $$  | $$| $$  $$$| $$| $$  \\ $$| $$  \\ $$| $$  \\ $$|  $$$$$$ \n| $$  | $$| $$  | $$| $$| $$  | $$| $$\\  $ | $$| $$  | $$| $$  | $$| $$  | $$ \\____  $$\n|  $$$$$$/| $$  | $$| $$|  $$$$$$$| $$ \\/  | $$|  $$$$$$/|  $$$$$$/| $$  | $$ /$$$$$$$/\n \\______/ |__/  |__/|__/ \\____  $$|__/     |__/ \\______/  \\______/ |__/  |__/|_______/ \n                         /$$  | $$                                                     \n                        |  $$$$$$/                                                     \n                         \\______/                                                      \n\n  https://onlymoons.io/\n*/\n\npragma solidity ^0.8.0;\n\nimport { IERC20 } from \"./library/IERC20.sol\";\nimport { IUniswapV2Pair } from \"./library/Dex.sol\";\n\nlibrary Util {\n  /**\n   * @dev retrieves basic information about a token, including sender balance\n   */\n  function getTokenData(address address_) external view returns (\n    string memory name,\n    string memory symbol,\n    uint8 decimals,\n    uint256 totalSupply,\n    uint256 balance\n  ){\n    IERC20 _token = IERC20(address_);\n\n    name = _token.name();\n    symbol = _token.symbol();\n    decimals = _token.decimals();\n    totalSupply = _token.totalSupply();\n    balance = _token.balanceOf(msg.sender);\n  }\n\n  /**\n   * @dev this throws an error on false, instead of returning false,\n   * but can still be used the same way on frontend.\n   */\n  function isLpToken(address address_) external view returns (bool) {\n    IUniswapV2Pair pair = IUniswapV2Pair(address_);\n\n    try pair.token0() returns (address tokenAddress_) {\n      // any address returned successfully should be valid?\n      // but we might as well check that it's not 0\n      return tokenAddress_ != address(0);\n    } catch Error(string memory /* reason */) {\n      return false;\n    } catch (bytes memory /* lowLevelData */) {\n      return false;\n    }\n  }\n\n  /**\n   * @dev this function will revert the transaction if it's called\n   * on a token that isn't an LP token. so, it's recommended to be\n   * sure that it's being called on an LP token, or expect the error.\n   */\n  function getLpData(address address_) external view returns (\n    address token0,\n    address token1,\n    uint256 balance0,\n    uint256 balance1,\n    uint256 price0,\n    uint256 price1\n  ) {\n    IUniswapV2Pair _pair = IUniswapV2Pair(address_);\n\n    token0 = _pair.token0();\n    token1 = _pair.token1();\n\n    balance0 = IERC20(token0).balanceOf(address(_pair));\n    balance1 = IERC20(token1).balanceOf(address(_pair));\n\n    price0 = _pair.price0CumulativeLast();\n    price1 = _pair.price1CumulativeLast();\n  }\n}\n"
      },
      "contracts/library/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.3.2 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {
        "contracts/Util.sol": {
          "Util": "0x8bf6fa865f15887a95d3af202ab34ed0c754a2de"
        }
      }
    }
  }}