creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "/contracts/SDAOTokenStaking.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.6.12;\r\npragma experimental ABIEncoderV2;\r\n\r\nimport \"./libraries/BoringMath.sol\";\r\nimport \"./libraries/SignedSafeMath.sol\";\r\nimport \"./libraries/BoringERC20.sol\";\r\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\r\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\r\n/************************************************************************************************\r\nOriginally from\r\nhttps://github.com/sushiswap/sushiswap/blob/master/contracts/MasterChefV2.sol\r\nand\r\nhttps://github.com/sdaoswap/sushiswap/blob/master/contracts/MasterChef.sol\r\nThis source code has been modified from the original, which was copied from the github repository\r\nat commit hash 10148a31d9192bc803dac5d24fe0319b52ae99a4.\r\n*************************************************************************************************/\r\n\r\n\r\ncontract SDAOTokenStaking is Ownable,ReentrancyGuard {\r\n  using BoringMath for uint256;\r\n  using BoringERC20 for IERC20;\r\n  using SignedSafeMath for int256;\r\n\r\n  //==========  Structs  ==========\r\n  \r\n  /// @dev Info of each user.\r\n  /// @param amount LP token amount the user has provided.\r\n  /// @param rewardDebt The amount of rewards entitled to the user.\r\n  struct UserInfo {\r\n    uint256 amount;\r\n    int256 rewardDebt;\r\n  }\r\n\r\n\r\n  /// @dev Info of each rewards pool.\r\n  /// @param tokenPerBlock Reward tokens per block number.\r\n  /// @param lpSupply Total staked amount.\r\n  /// @param accRewardsPerShare Total rewards accumulated per staked token.\r\n  /// @param lastRewardBlock Last time rewards were updated for the pool.\r\n  /// @param endOfEpochBlock End of epoc block number for compute and to avoid deposits.\r\n  struct PoolInfo {\r\n    uint256 tokenPerBlock;\r\n    uint256 lpSupply;\r\n    uint256 accRewardsPerShare;\r\n    uint256 lastRewardBlock;\r\n    uint256 endOfEpochBlock;\r\n  }\r\n\r\n  //==========  Constants  ==========\r\n\r\n  /// @dev For percision calculation while computing the rewards.\r\n  uint256 private constant ACC_REWARDS_PRECISION = 1e18;\r\n\r\n  /// @dev ERC20 token used to distribute rewards.   \r\n  IERC20 public immutable rewardsToken;\r\n\r\n  /** ==========  Storage  ========== */\r\n\r\n  /// @dev Indicates whether a staking pool exists for a given staking token.\r\n  //mapping(address => bool) public stakingPoolExists;\r\n  \r\n  /// @dev Info of each staking pool.\r\n  PoolInfo[] public poolInfo;\r\n  \r\n  /// @dev Address of the LP token for each staking pool.\r\n  mapping(uint256 => IERC20) public lpToken;\r\n  \r\n  /// @dev Info of each user that stakes tokens.\r\n  mapping(uint256 => mapping(address => UserInfo)) public userInfo;\r\n\r\n  /// @dev Total rewards received from governance for distribution.\r\n  /// Used to return remaining rewards if staking is canceled.\r\n  uint256 public totalRewardsReceived;\r\n\r\n  // ==========  Events  ==========\r\n\r\n  event Deposit(address indexed user, uint256 indexed pid, uint256 amount, address indexed to);\r\n  event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address indexed to);\r\n  event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount, address indexed to);\r\n  event Harvest(address indexed user, uint256 indexed pid, uint256 amount);\r\n  event LogPoolAddition(uint256 indexed pid, IERC20 indexed lpToken);\r\n  event LogUpdatePool(uint256 indexed pid, uint256 lastRewardBlock, uint256 lpSupply, uint256 accRewardsPerShare);\r\n  event RewardsAdded(uint256 amount);\r\n  event ExtendPool(uint256 indexed pid, uint256 rewardBlock, uint256 endOfEpochBlock);\r\n\r\n  // ==========  Constructor  ==========\r\n\r\n  /// @dev During the deployment of the contract pass the ERC-20 contract address used for rewards.\r\n  constructor(address _rewardsToken) public {\r\n    rewardsToken = IERC20(_rewardsToken);\r\n  }\r\n\r\n  /// @dev Add rewards to be distributed.\r\n  /// Note: This function must be used to add rewards if the owner\r\n  /// wants to retain the option to cancel distribution and reclaim\r\n  /// undistributed tokens.  \r\n  function addRewards(uint256 amount) external onlyOwner {\r\n    \r\n    require(rewardsToken.balanceOf(msg.sender) > 0, \"ERC20: not enough tokens to transfer\");\r\n\r\n    totalRewardsReceived = totalRewardsReceived.add(amount);\r\n    rewardsToken.safeTransferFrom(msg.sender, address(this), amount);\r\n    \r\n    emit RewardsAdded(amount);\r\n  }\r\n\r\n  // ==========  Pools  ==========\r\n  \r\n  /// @dev Add a new LP to the pool.\r\n  /// Can only be called by the owner or the points allocator.\r\n  /// @param _lpToken Address of the LP ERC-20 token.\r\n  /// @param _sdaoPerBlock Rewards per block.\r\n  /// @param _endOfEpochBlock Epocs end block number.\r\n  function add(IERC20 _lpToken, uint256 _sdaoPerBlock, uint256 _endOfEpochBlock) public onlyOwner {\r\n\r\n    //This is not needed as we are going to use the contract for multiple pools with the same LP Tokens\r\n    //require(!stakingPoolExists[address(_lpToken)], \" Staking pool already exists.\");\r\n    \r\n    require(_endOfEpochBlock > block.number, \"Cannot create the pool for past time.\");\r\n\r\n    uint256 pid = poolInfo.length;\r\n\r\n    lpToken[pid] = _lpToken;\r\n\r\n    poolInfo.push(PoolInfo({\r\n      tokenPerBlock: _sdaoPerBlock,\r\n      endOfEpochBlock:_endOfEpochBlock,\r\n      lastRewardBlock: block.number,\r\n      lpSupply:0,\r\n      accRewardsPerShare: 0\r\n    }));\r\n\r\n    //stakingPoolExists[address(_lpToken)] = true;\r\n\r\n    emit LogPoolAddition(pid, _lpToken);\r\n  }\r\n\r\n  /// @dev Add a new LP to the pool.\r\n  /// Can only be called by the owner or the points allocator.\r\n  /// @param _pid Pool Id to extend the schedule.\r\n  /// @param _sdaoPerBlock Rewards per block.\r\n  /// @param _endOfEpochBlock Epocs end block number.\r\n  function extendPool(uint256 _pid, uint256 _sdaoPerBlock, uint256 _endOfEpochBlock) public onlyOwner {\r\n    \r\n    require(_endOfEpochBlock > block.number && _endOfEpochBlock > poolInfo[_pid].endOfEpochBlock, \"Cannot extend the pool for past time.\");\r\n\r\n    // Update the accumulated rewards\r\n    PoolInfo memory pool = updatePool(_pid);\r\n\r\n    pool.tokenPerBlock = _sdaoPerBlock;\r\n    pool.endOfEpochBlock = _endOfEpochBlock;\r\n    pool.lastRewardBlock = block.number;\r\n\r\n    // Update the Pool Storage\r\n    poolInfo[_pid] = pool;\r\n\r\n    emit ExtendPool(_pid, _sdaoPerBlock, _endOfEpochBlock);\r\n  }\r\n\r\n  /// @dev To get the rewards per block.\r\n  function sdaoPerBlock(uint256 _pid) public view returns (uint256 amount) {\r\n      PoolInfo memory pool = poolInfo[_pid];\r\n      amount = pool.tokenPerBlock;\r\n  }\r\n\r\n  /// @dev Update reward variables for all pools in `pids`.\r\n  /// Note: This can become very expensive.\r\n  /// @param pids Pool IDs of all to be updated. Make sure to update all active pools.\r\n  function massUpdatePools(uint256[] calldata pids) external onlyOwner {\r\n    uint256 len = pids.length;\r\n    for (uint256 i = 0; i < len; ++i) {\r\n      updatePool(pids[i]);\r\n    }\r\n  }\r\n\r\n\r\n  /// @dev Update reward variables of the given pool.\r\n  /// @param _pid The index of the pool. See `poolInfo`.\r\n  /// @return pool Returns the pool that was updated.\r\n function updatePool(uint256 _pid) private returns (PoolInfo memory pool) {\r\n\r\n    pool = poolInfo[_pid];\r\n    uint256 lpSupply = pool.lpSupply;\r\n\r\n    if (block.number > pool.lastRewardBlock && pool.lastRewardBlock < pool.endOfEpochBlock) {\r\n\r\n       if(lpSupply > 0){\r\n         \r\n           uint256 blocks;\r\n           if(block.number < pool.endOfEpochBlock) {\r\n             blocks = block.number.sub(pool.lastRewardBlock);\r\n           } else {\r\n             blocks = pool.endOfEpochBlock.sub(pool.lastRewardBlock);\r\n          }\r\n\r\n          uint256 sdaoReward = blocks.mul(sdaoPerBlock(_pid));\r\n          pool.accRewardsPerShare = pool.accRewardsPerShare.add((sdaoReward.mul(ACC_REWARDS_PRECISION) / lpSupply));\r\n\r\n       }\r\n\r\n       pool.lastRewardBlock = block.number;\r\n       poolInfo[_pid] = pool;\r\n       emit LogUpdatePool(_pid, pool.lastRewardBlock, lpSupply, pool.accRewardsPerShare);\r\n\r\n    }\r\n\r\n  }\r\n\r\n\r\n\r\n  // ==========  Users  ==========\r\n\r\n  /// @dev View function to see pending rewards on frontend.\r\n  /// @param _pid The index of the pool. See `poolInfo`.\r\n  /// @param _user Address of user.\r\n  /// @return pending rewards for a given user.\r\n  function pendingRewards(uint256 _pid, address _user) external view returns (uint256 pending) {\r\n\r\n    PoolInfo memory pool = poolInfo[_pid];\r\n    UserInfo storage user = userInfo[_pid][_user];\r\n\r\n    uint256 accRewardsPerShare = pool.accRewardsPerShare;\r\n    uint256 lpSupply = pool.lpSupply;\r\n\r\n    if (block.number > pool.lastRewardBlock && pool.lastRewardBlock < pool.endOfEpochBlock) {\r\n\r\n      if(lpSupply > 0){\r\n\r\n        uint256 blocks;\r\n\r\n        if(block.number < pool.endOfEpochBlock) {\r\n            blocks = block.number.sub(pool.lastRewardBlock);\r\n        } else {\r\n          blocks = pool.endOfEpochBlock.sub(pool.lastRewardBlock);\r\n        }\r\n        \r\n        uint256 sdaoReward = blocks.mul(sdaoPerBlock(_pid));\r\n        accRewardsPerShare = accRewardsPerShare.add(sdaoReward.mul(ACC_REWARDS_PRECISION) / lpSupply);\r\n\r\n      }\r\n\r\n    }\r\n\r\n    pending = int256(user.amount.mul(accRewardsPerShare) / ACC_REWARDS_PRECISION).sub(user.rewardDebt).toUInt256();\r\n  }\r\n\r\n\r\n  /// @dev Deposit LP tokens to earn rewards.\r\n  /// @param _pid The index of the pool. See `poolInfo`.\r\n  /// @param _amount LP token amount to deposit.\r\n  /// @param _to The receiver of `_amount` deposit benefit.\r\n  function deposit(uint256 _pid, uint256 _amount, address _to) external nonReentrant {\r\n\r\n    // Input Validation\r\n    require(_amount > 0 && _to != address(0), \"Invalid inputs for deposit.\");\r\n\r\n    PoolInfo memory pool = updatePool(_pid);\r\n    UserInfo storage user = userInfo[_pid][_to];\r\n\r\n    // check if epoch as ended or if pool doesnot exist \r\n    require (pool.endOfEpochBlock > block.number,\"This pool epoch has ended. Please join staking new session.\");\r\n    \r\n    user.amount = user.amount.add(_amount);\r\n    user.rewardDebt = user.rewardDebt.add(int256(_amount.mul(pool.accRewardsPerShare) / ACC_REWARDS_PRECISION));\r\n\r\n    // Add to total supply\r\n    pool.lpSupply = pool.lpSupply.add(_amount);\r\n    // Update the pool back\r\n    poolInfo[_pid] = pool;\r\n\r\n    // Interactions\r\n    lpToken[_pid].safeTransferFrom(msg.sender, address(this), _amount);\r\n\r\n    emit Deposit(msg.sender, _pid, _amount, _to);\r\n  }\r\n\r\n  /// @dev Withdraw LP tokens from the staking contract.\r\n  /// @param _pid The index of the pool. See `poolInfo`.\r\n  /// @param _amount LP token amount to withdraw.\r\n  /// @param _to Receiver of the LP tokens.\r\n  function withdraw(uint256 _pid, uint256 _amount, address _to) external nonReentrant {\r\n\r\n    require(_to != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n    PoolInfo memory pool = updatePool(_pid);\r\n    UserInfo storage user = userInfo[_pid][msg.sender];\r\n\r\n    // Check whether user has deposited stake\r\n    require(user.amount >= _amount && _amount > 0, \"Invalid amount to withdraw.\");\r\n\r\n    // Effects\r\n    user.rewardDebt = user.rewardDebt.sub(int256(_amount.mul(pool.accRewardsPerShare) / ACC_REWARDS_PRECISION));\r\n    user.amount = user.amount.sub(_amount);\r\n\r\n    // Subtract from total supply\r\n    pool.lpSupply = pool.lpSupply.sub(_amount);\r\n    // Update the pool back\r\n    poolInfo[_pid] = pool;\r\n\r\n    // Interactions\r\n    lpToken[_pid].safeTransfer(_to, _amount);\r\n\r\n    emit Withdraw(msg.sender, _pid, _amount, _to);\r\n  }\r\n\r\n\r\n   /// @dev Harvest proceeds for transaction sender to `_to`.\r\n   /// @param _pid The index of the pool. See `poolInfo`.\r\n   /// @param _to Receiver of rewards.\r\n   function harvest(uint256 _pid, address _to) external nonReentrant {\r\n    \r\n    require(_to != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n    PoolInfo memory pool = updatePool(_pid);\r\n    UserInfo storage user = userInfo[_pid][msg.sender];\r\n\r\n    int256 accumulatedRewards = int256(user.amount.mul(pool.accRewardsPerShare) / ACC_REWARDS_PRECISION);\r\n    uint256 _pendingRewards = accumulatedRewards.sub(user.rewardDebt).toUInt256();\r\n\r\n    // Effects\r\n    user.rewardDebt = accumulatedRewards;\r\n\r\n    // Interactions\r\n    if(_pendingRewards > 0 ) {\r\n      rewardsToken.safeTransfer(_to, _pendingRewards);\r\n    }\r\n    \r\n    emit Harvest(msg.sender, _pid, _pendingRewards);\r\n  }\r\n\r\n  //// @dev Withdraw LP tokens and harvest accumulated rewards, sending both to `to`.\r\n  /// @param _pid The index of the pool. See `poolInfo`.\r\n  /// @param _amount LP token amount to withdraw.\r\n  /// @param _to Receiver of the LP tokens and rewards.\r\n  function withdrawAndHarvest(uint256 _pid, uint256 _amount, address _to) external nonReentrant {\r\n\r\n    require(_to != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n    PoolInfo memory pool = updatePool(_pid);\r\n    UserInfo storage user = userInfo[_pid][msg.sender];\r\n\r\n    // Check if the user has stake in the pool\r\n    require(user.amount >= _amount && _amount > 0, \"Cannot withdraw more than staked.\");\r\n\r\n    int256 accumulatedRewards = int256(user.amount.mul(pool.accRewardsPerShare) / ACC_REWARDS_PRECISION);\r\n    uint256 _pendingRewards = accumulatedRewards.sub(user.rewardDebt).toUInt256();\r\n\r\n    // Effects\r\n    user.rewardDebt = accumulatedRewards.sub(int256(_amount.mul(pool.accRewardsPerShare) / ACC_REWARDS_PRECISION));\r\n    user.amount = user.amount.sub(_amount);\r\n\r\n    // Subtract from total supply\r\n    pool.lpSupply = pool.lpSupply.sub(_amount);\r\n    // Update the pool back\r\n    poolInfo[_pid] = pool;\r\n\r\n    // Interactions\r\n    if(_pendingRewards > 0) {\r\n      rewardsToken.safeTransfer(_to, _pendingRewards);\r\n    }\r\n    lpToken[_pid].safeTransfer(_to, _amount);\r\n\r\n    emit Harvest(msg.sender, _pid, _pendingRewards);\r\n    emit Withdraw(msg.sender, _pid, _amount, _to);\r\n  }\r\n\r\n\r\n  /// @dev Withdraw without caring about rewards. EMERGENCY ONLY.\r\n  /// @param _pid The index of the pool. See `poolInfo`.\r\n  /// @param _to Receiver of the LP tokens.  \r\n  function emergencyWithdraw(uint256 _pid, address _to) external nonReentrant { \r\n\r\n    require(_to != address(0), \"ERC20: transfer to the zero address\");\r\n\r\n    UserInfo storage user = userInfo[_pid][msg.sender];\r\n    uint256 amount = user.amount;\r\n    user.amount = 0;\r\n    user.rewardDebt = 0;\r\n\r\n    PoolInfo memory pool = updatePool(_pid);\r\n    pool.lpSupply = pool.lpSupply.sub(amount);\r\n    // Update the pool back\r\n    poolInfo[_pid] = pool;\r\n\r\n    // Note: transfer can fail or succeed if `amount` is zero.\r\n    lpToken[_pid].safeTransfer(_to, amount);\r\n\r\n    emit EmergencyWithdraw(msg.sender, _pid, amount, _to);\r\n  }\r\n\r\n\r\n  function withdrawETHAndAnyTokens(address token) external onlyOwner {\r\n    msg.sender.send(address(this).balance);\r\n    IERC20 Token = IERC20(token);\r\n    uint256 currentTokenBalance = Token.balanceOf(address(this));\r\n    Token.safeTransfer(msg.sender, currentTokenBalance); \r\n  }\r\n\r\n  // ==========  Getter Functions  ==========\r\n\r\n  function poolLength() external view returns (uint256) {\r\n    return poolInfo.length;\r\n  }\r\n\r\n\r\n\r\n}"
      },
      "/contracts/libraries/SignedSafeMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.6.12;\r\n\r\nlibrary SignedSafeMath {\r\n  int256 constant private _INT256_MIN = -2**255;\r\n\r\n  /**\r\n    * @dev Returns the multiplication of two signed integers, reverting on\r\n    * overflow.\r\n    *\r\n    * Counterpart to Solidity's `*` operator.\r\n    *\r\n    * Requirements:\r\n    *\r\n    * - Multiplication cannot overflow.\r\n    */\r\n  function mul(int256 a, int256 b) internal pure returns (int256) {\r\n    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\r\n    // benefit is lost if 'b' is also tested.\r\n    // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\r\n    if (a == 0) {\r\n      return 0;\r\n    }\r\n\r\n    require(!(a == -1 && b == _INT256_MIN), \"SignedSafeMath: multiplication overflow\");\r\n\r\n    int256 c = a * b;\r\n    require(c / a == b, \"SignedSafeMath: multiplication overflow\");\r\n\r\n    return c;\r\n  }\r\n\r\n  /**\r\n    * @dev Returns the integer division of two signed integers. Reverts on\r\n    * division by zero. The result is rounded towards zero.\r\n    *\r\n    * Counterpart to Solidity's `/` operator. Note: this function uses a\r\n    * `revert` opcode (which leaves remaining gas untouched) while Solidity\r\n    * uses an invalid opcode to revert (consuming all remaining gas).\r\n    *\r\n    * Requirements:\r\n    *\r\n    * - The divisor cannot be zero.\r\n    */\r\n  function div(int256 a, int256 b) internal pure returns (int256) {\r\n    require(b != 0, \"SignedSafeMath: division by zero\");\r\n    require(!(b == -1 && a == _INT256_MIN), \"SignedSafeMath: division overflow\");\r\n\r\n    int256 c = a / b;\r\n\r\n    return c;\r\n  }\r\n\r\n  /**\r\n    * @dev Returns the subtraction of two signed integers, reverting on\r\n    * overflow.\r\n    *\r\n    * Counterpart to Solidity's `-` operator.\r\n    *\r\n    * Requirements:\r\n    *\r\n    * - Subtraction cannot overflow.\r\n    */\r\n  function sub(int256 a, int256 b) internal pure returns (int256) {\r\n    int256 c = a - b;\r\n    require((b >= 0 && c <= a) || (b < 0 && c > a), \"SignedSafeMath: subtraction overflow\");\r\n\r\n    return c;\r\n  }\r\n\r\n  /**\r\n    * @dev Returns the addition of two signed integers, reverting on\r\n    * overflow.\r\n    *\r\n    * Counterpart to Solidity's `+` operator.\r\n    *\r\n    * Requirements:\r\n    *\r\n    * - Addition cannot overflow.\r\n    */\r\n  function add(int256 a, int256 b) internal pure returns (int256) {\r\n    int256 c = a + b;\r\n    require((b >= 0 && c >= a) || (b < 0 && c < a), \"SignedSafeMath: addition overflow\");\r\n\r\n    return c;\r\n  }\r\n\r\n  function toUInt256(int256 a) internal pure returns (uint256) {\r\n    require(a >= 0, \"Integer < 0\");\r\n    return uint256(a);\r\n  }\r\n}"
      },
      "/contracts/libraries/BoringMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.6.12;\r\n\r\n/// @notice A library for performing overflow-/underflow-safe math,\r\n/// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math).\r\nlibrary BoringMath {\r\n    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {\r\n        require((c = a + b) >= b, \"BoringMath: Add Overflow\");\r\n    }\r\n\r\n    function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {\r\n        require((c = a - b) <= a, \"BoringMath: Underflow\");\r\n    }\r\n\r\n    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {\r\n        require(b == 0 || (c = a * b) / b == a, \"BoringMath: Mul Overflow\");\r\n    }\r\n\r\n    function to128(uint256 a) internal pure returns (uint128 c) {\r\n        require(a <= uint128(-1), \"BoringMath: uint128 Overflow\");\r\n        c = uint128(a);\r\n    }\r\n\r\n    function to64(uint256 a) internal pure returns (uint64 c) {\r\n        require(a <= uint64(-1), \"BoringMath: uint64 Overflow\");\r\n        c = uint64(a);\r\n    }\r\n\r\n    function to32(uint256 a) internal pure returns (uint32 c) {\r\n        require(a <= uint32(-1), \"BoringMath: uint32 Overflow\");\r\n        c = uint32(a);\r\n    }\r\n}\r\n\r\n/// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint128.\r\nlibrary BoringMath128 {\r\n    function add(uint128 a, uint128 b) internal pure returns (uint128 c) {\r\n        require((c = a + b) >= b, \"BoringMath: Add Overflow\");\r\n    }\r\n\r\n    function sub(uint128 a, uint128 b) internal pure returns (uint128 c) {\r\n        require((c = a - b) <= a, \"BoringMath: Underflow\");\r\n    }\r\n}\r\n\r\n/// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint64.\r\nlibrary BoringMath64 {\r\n    function add(uint64 a, uint64 b) internal pure returns (uint64 c) {\r\n        require((c = a + b) >= b, \"BoringMath: Add Overflow\");\r\n    }\r\n\r\n    function sub(uint64 a, uint64 b) internal pure returns (uint64 c) {\r\n        require((c = a - b) <= a, \"BoringMath: Underflow\");\r\n    }\r\n}\r\n\r\n/// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32.\r\nlibrary BoringMath32 {\r\n    function add(uint32 a, uint32 b) internal pure returns (uint32 c) {\r\n        require((c = a + b) >= b, \"BoringMath: Add Overflow\");\r\n    }\r\n\r\n    function sub(uint32 a, uint32 b) internal pure returns (uint32 c) {\r\n        require((c = a - b) <= a, \"BoringMath: Underflow\");\r\n    }\r\n}"
      },
      "/contracts/libraries/BoringERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.6.12;\r\nimport \"../interfaces/IERC20.sol\";\r\n\r\n// solhint-disable avoid-low-level-calls\r\n\r\nlibrary BoringERC20 {\r\n    bytes4 private constant SIG_SYMBOL = 0x95d89b41; // symbol()\r\n    bytes4 private constant SIG_NAME = 0x06fdde03; // name()\r\n    bytes4 private constant SIG_DECIMALS = 0x313ce567; // decimals()\r\n    bytes4 private constant SIG_TRANSFER = 0xa9059cbb; // transfer(address,uint256)\r\n    bytes4 private constant SIG_TRANSFER_FROM = 0x23b872dd; // transferFrom(address,address,uint256)\r\n\r\n    function returnDataToString(bytes memory data) internal pure returns (string memory) {\r\n        if (data.length >= 64) {\r\n            return abi.decode(data, (string));\r\n        } else if (data.length == 32) {\r\n            uint8 i = 0;\r\n            while(i < 32 && data[i] != 0) {\r\n                i++;\r\n            }\r\n            bytes memory bytesArray = new bytes(i);\r\n            for (i = 0; i < 32 && data[i] != 0; i++) {\r\n                bytesArray[i] = data[i];\r\n            }\r\n            return string(bytesArray);\r\n        } else {\r\n            return \"???\";\r\n        }\r\n    }\r\n\r\n    /// @notice Provides a safe ERC20.symbol version which returns '???' as fallback string.\r\n    /// @param token The address of the ERC-20 token contract.\r\n    /// @return (string) Token symbol.\r\n    function safeSymbol(IERC20 token) internal view returns (string memory) {\r\n        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_SYMBOL));\r\n        return success ? returnDataToString(data) : \"???\";\r\n    }\r\n\r\n    /// @notice Provides a safe ERC20.name version which returns '???' as fallback string.\r\n    /// @param token The address of the ERC-20 token contract.\r\n    /// @return (string) Token name.\r\n    function safeName(IERC20 token) internal view returns (string memory) {\r\n        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_NAME));\r\n        return success ? returnDataToString(data) : \"???\";\r\n    }\r\n\r\n    /// @notice Provides a safe ERC20.decimals version which returns '18' as fallback value.\r\n    /// @param token The address of the ERC-20 token contract.\r\n    /// @return (uint8) Token decimals.\r\n    function safeDecimals(IERC20 token) internal view returns (uint8) {\r\n        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_DECIMALS));\r\n        return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;\r\n    }\r\n\r\n    /// @notice Provides a safe ERC20.transfer version for different ERC-20 implementations.\r\n    /// Reverts on a failed transfer.\r\n    /// @param token The address of the ERC-20 token.\r\n    /// @param to Transfer tokens to.\r\n    /// @param amount The token amount.\r\n    function safeTransfer(\r\n        IERC20 token,\r\n        address to,\r\n        uint256 amount\r\n    ) internal {\r\n        (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(SIG_TRANSFER, to, amount));\r\n        require(success && (data.length == 0 || abi.decode(data, (bool))), \"BoringERC20: Transfer failed\");\r\n    }\r\n\r\n    /// @notice Provides a safe ERC20.transferFrom version for different ERC-20 implementations.\r\n    /// Reverts on a failed transfer.\r\n    /// @param token The address of the ERC-20 token.\r\n    /// @param from Transfer tokens from.\r\n    /// @param to Transfer tokens to.\r\n    /// @param amount The token amount.\r\n    function safeTransferFrom(\r\n        IERC20 token,\r\n        address from,\r\n        address to,\r\n        uint256 amount\r\n    ) internal {\r\n        (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(SIG_TRANSFER_FROM, from, to, amount));\r\n        require(success && (data.length == 0 || abi.decode(data, (bool))), \"BoringERC20: TransferFrom failed\");\r\n    }\r\n}"
      },
      "/contracts/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.6.12;\r\n\r\ninterface IERC20 {\r\n    function totalSupply() external view returns (uint256);\r\n\r\n    function balanceOf(address account) external view returns (uint256);\r\n\r\n    function allowance(address owner, address spender) external view returns (uint256);\r\n\r\n    function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n    event Transfer(address indexed from, address indexed to, uint256 value);\r\n    event Approval(address indexed owner, address indexed spender, uint256 value);\r\n\r\n    /// @notice EIP 2612\r\n    function permit(\r\n        address owner,\r\n        address spender,\r\n        uint256 value,\r\n        uint256 deadline,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) external;\r\n}"
      },
      "@openzeppelin/contracts/utils/ReentrancyGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\ncontract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor () internal {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and make it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\ncontract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor () internal {\n        address msgSender = _msgSender();\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(_owner, newOwner);\n        _owner = newOwner;\n    }\n}\n"
      },
      "@openzeppelin/contracts/GSN/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "istanbul",
      "libraries": {},
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}