ETH Price: $2,955.77 (+0.83%)
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

> 10 Internal Transactions found.

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580422023-07-30 11:01:01909 days ago1690714861
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075580122023-07-30 11:00:01909 days ago1690714801
KyberSwap: ElasticLM Helper
0 ETH
1075574842023-07-30 10:42:25909 days ago1690713745
KyberSwap: ElasticLM Helper
0 ETH
1075574842023-07-30 10:42:25909 days ago1690713745
KyberSwap: ElasticLM Helper
0 ETH
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
KSElasticLMHelper

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';

import {MathConstants as C} from '../libraries/MathConstants.sol';
import {FullMath} from '../libraries/FullMath.sol';
import {ReinvestmentMath} from '../libraries/ReinvestmentMath.sol';

import {IKSElasticLMHelper} from '../interfaces/liquidityMining/IKSElasticLMHelper.sol';
import {IBasePositionManager} from '../interfaces/liquidityMining/IBasePositionManager.sol';
import {IPoolStorage} from '../interfaces/liquidityMining/IPoolStorage.sol';

import {KSAdmin} from './base/KSAdmin.sol';

contract KSElasticLMHelper is IKSElasticLMHelper, KSAdmin {
  using SafeERC20 for IERC20;

  event RescueFund(address token, uint256 amount);

  function rescueFund(IERC20 token, uint256 amount) external isAdmin {
    if (address(token) == address(0)) {
      (bool success, ) = payable(msg.sender).call{value: amount}('');
      require(success, 'rescueFund: failed to collect native');
    } else {
      token.safeTransfer(msg.sender, amount);
    }
    emit RescueFund(address(token), amount);
  }

  function checkPool(
    address pAddress,
    address nftContract,
    uint256 nftId
  ) external view override returns (bool) {
    IBasePositionManager.Position memory pData = _getPositionFromNFT(nftContract, nftId);
    return IBasePositionManager(nftContract).addressToPoolId(pAddress) == pData.poolId;
  }

  /// @dev use virtual to be overrided to mock data for fuzz tests
  function getActiveTime(
    address pAddr,
    address nftContract,
    uint256 nftId
  ) external view override returns (uint128) {
    IBasePositionManager.Position memory pData = _getPositionFromNFT(nftContract, nftId);
    return IPoolStorage(pAddr).getSecondsPerLiquidityInside(pData.tickLower, pData.tickUpper);
  }

  function getSignedFee(
    address nftContract,
    uint256 nftId
  ) external view override returns (int256) {
    uint256 feeGrowthInsideLast = _getFee(nftContract, nftId);
    return int256(feeGrowthInsideLast);
  }

  function getSignedFeePool(
    address poolAddress,
    address nftContract,
    uint256 nftId
  ) external view override returns (int256) {
    uint256 feeGrowthInside = _getFeePool(poolAddress, nftContract, nftId);
    return int256(feeGrowthInside);
  }

  function getLiq(address nftContract, uint256 nftId) external view override returns (uint128) {
    IBasePositionManager.Position memory pData = _getPositionFromNFT(nftContract, nftId);
    return pData.liquidity;
  }

  function getPair(
    address nftContract,
    uint256 nftId
  ) external view override returns (address, address) {
    (, IBasePositionManager.PoolInfo memory poolInfo) = IBasePositionManager(nftContract)
      .positions(nftId);

    return (poolInfo.token0, poolInfo.token1);
  }

  function _getPositionFromNFT(
    address nftContract,
    uint256 nftId
  ) internal view returns (IBasePositionManager.Position memory) {
    (IBasePositionManager.Position memory pData, ) = IBasePositionManager(nftContract).positions(
      nftId
    );
    return pData;
  }

  function _getFee(address nftContract, uint256 nftId) internal view virtual returns (uint256) {
    IBasePositionManager.Position memory pData = _getPositionFromNFT(nftContract, nftId);
    return pData.feeGrowthInsideLast;
  }

  function _getFeePool(
    address poolAddress,
    address nftContract,
    uint256 nftId
  ) internal view virtual returns (uint256 feeGrowthInside) {
    IBasePositionManager.Position memory position = _getPositionFromNFT(nftContract, nftId);
    (, , uint256 lowerValue, ) = IPoolStorage(poolAddress).ticks(position.tickLower);
    (, , uint256 upperValue, ) = IPoolStorage(poolAddress).ticks(position.tickUpper);
    (, int24 currentTick, , ) = IPoolStorage(poolAddress).getPoolState();
    uint256 feeGrowthGlobal = IPoolStorage(poolAddress).getFeeGrowthGlobal();

    {
      (uint128 baseL, uint128 reinvestL, uint128 reinvestLLast) = IPoolStorage(poolAddress)
        .getLiquidityState();
      uint256 rTotalSupply = IERC20(poolAddress).totalSupply();
      // logic ported from Pool._syncFeeGrowth()
      uint256 rMintQty = ReinvestmentMath.calcrMintQty(
        uint256(reinvestL),
        uint256(reinvestLLast),
        baseL,
        rTotalSupply
      );

      if (rMintQty != 0) {
        // fetch governmentFeeUnits
        (, uint24 governmentFeeUnits) = IPoolStorage(poolAddress).factory().feeConfiguration();
        unchecked {
          if (governmentFeeUnits != 0) {
            uint256 rGovtQty = (rMintQty * governmentFeeUnits) / C.FEE_UNITS;
            rMintQty -= rGovtQty;
          }
          feeGrowthGlobal += FullMath.mulDivFloor(rMintQty, C.TWO_POW_96, baseL);
        }
      }
    }
    unchecked {
      if (currentTick < position.tickLower) {
        feeGrowthInside = lowerValue - upperValue;
      } else if (currentTick >= position.tickUpper) {
        feeGrowthInside = upperValue - lowerValue;
      } else {
        feeGrowthInside = feeGrowthGlobal - (lowerValue + upperValue);
      }
    }
  }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 4 of 12 : MathConstants.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity >=0.8.0;

/// @title Contains constants needed for math libraries
library MathConstants {
  uint256 internal constant TWO_POW_96 = 2**96;
  uint128 internal constant MIN_LIQUIDITY = 100_000;
  uint24 internal constant FEE_UNITS = 100_000;
  uint8 internal constant RES_96 = 96;
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @title Contains 512-bit math functions
/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision
/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits
/// @dev Code has been modified to be compatible with sol 0.8
library FullMath {
  /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
  /// @param a The multiplicand
  /// @param b The multiplier
  /// @param denominator The divisor
  /// @return result The 256-bit result
  /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv
  function mulDivFloor(
    uint256 a,
    uint256 b,
    uint256 denominator
  ) internal pure returns (uint256 result) {
    // 512-bit multiply [prod1 prod0] = a * b
    // Compute the product mod 2**256 and mod 2**256 - 1
    // then use the Chinese Remainder Theorem to reconstruct
    // the 512 bit result. The result is stored in two 256
    // variables such that product = prod1 * 2**256 + prod0
    uint256 prod0; // Least significant 256 bits of the product
    uint256 prod1; // Most significant 256 bits of the product
    assembly {
      let mm := mulmod(a, b, not(0))
      prod0 := mul(a, b)
      prod1 := sub(sub(mm, prod0), lt(mm, prod0))
    }

    // Handle non-overflow cases, 256 by 256 division
    if (prod1 == 0) {
      require(denominator > 0, '0 denom');
      assembly {
        result := div(prod0, denominator)
      }
      return result;
    }

    // Make sure the result is less than 2**256.
    // Also prevents denominator == 0
    require(denominator > prod1, 'denom <= prod1');

    ///////////////////////////////////////////////
    // 512 by 256 division.
    ///////////////////////////////////////////////

    // Make division exact by subtracting the remainder from [prod1 prod0]
    // Compute remainder using mulmod
    uint256 remainder;
    assembly {
      remainder := mulmod(a, b, denominator)
    }
    // Subtract 256 bit number from 512 bit number
    assembly {
      prod1 := sub(prod1, gt(remainder, prod0))
      prod0 := sub(prod0, remainder)
    }

    // Factor powers of two out of denominator
    // Compute largest power of two divisor of denominator.
    // Always >= 1.
    uint256 twos = denominator & (~denominator + 1);
    // Divide denominator by power of two
    assembly {
      denominator := div(denominator, twos)
    }

    // Divide [prod1 prod0] by the factors of two
    assembly {
      prod0 := div(prod0, twos)
    }
    // Shift in bits from prod1 into prod0. For this we need
    // to flip `twos` such that it is 2**256 / twos.
    // If twos is zero, then it becomes one
    assembly {
      twos := add(div(sub(0, twos), twos), 1)
    }
    unchecked {
      prod0 |= prod1 * twos;

      // Invert denominator mod 2**256
      // Now that denominator is an odd number, it has an inverse
      // modulo 2**256 such that denominator * inv = 1 mod 2**256.
      // Compute the inverse by starting with a seed that is correct
      // correct for four bits. That is, denominator * inv = 1 mod 2**4
      uint256 inv = (3 * denominator) ^ 2;

      // Now use Newton-Raphson iteration to improve the precision.
      // Thanks to Hensel's lifting lemma, this also works in modular
      // arithmetic, doubling the correct bits in each step.
      inv *= 2 - denominator * inv; // inverse mod 2**8
      inv *= 2 - denominator * inv; // inverse mod 2**16
      inv *= 2 - denominator * inv; // inverse mod 2**32
      inv *= 2 - denominator * inv; // inverse mod 2**64
      inv *= 2 - denominator * inv; // inverse mod 2**128
      inv *= 2 - denominator * inv; // inverse mod 2**256

      // Because the division is now exact we can divide by multiplying
      // with the modular inverse of denominator. This will give us the
      // correct result modulo 2**256. Since the precoditions guarantee
      // that the outcome is less than 2**256, this is the final result.
      // We don't need to compute the high bits of the result and prod1
      // is no longer required.
      result = prod0 * inv;
    }
    return result;
  }

  /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
  /// @param a The multiplicand
  /// @param b The multiplier
  /// @param denominator The divisor
  /// @return result The 256-bit result
  function mulDivCeiling(
    uint256 a,
    uint256 b,
    uint256 denominator
  ) internal pure returns (uint256 result) {
    result = mulDivFloor(a, b, denominator);
    if (mulmod(a, b, denominator) > 0) {
      result++;
    }
  }
}

File 6 of 12 : ReinvestmentMath.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity >=0.8.0;

import {FullMath} from './FullMath.sol';

/// @title Contains helper function to calculate the number of reinvestment tokens to be minted
library ReinvestmentMath {
  /// @dev calculate the mint amount with given reinvestL, reinvestLLast, baseL and rTotalSupply
  /// contribution of lp to the increment is calculated by the proportion of baseL with reinvestL + baseL
  /// then rMintQty is calculated by mutiplying this with the liquidity per reinvestment token
  /// rMintQty = rTotalSupply * (reinvestL - reinvestLLast) / reinvestLLast * baseL / (baseL + reinvestL)
  function calcrMintQty(
    uint256 reinvestL,
    uint256 reinvestLLast,
    uint128 baseL,
    uint256 rTotalSupply
  ) internal pure returns (uint256 rMintQty) {
    uint256 lpContribution = FullMath.mulDivFloor(
      baseL,
      reinvestL - reinvestLLast,
      baseL + reinvestL
    );
    rMintQty = FullMath.mulDivFloor(rTotalSupply, lpContribution, reinvestLLast);
  }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IKSElasticLMHelper {
  function checkPool(
    address pAddress,
    address nftContract,
    uint256 nftId
  ) external view returns (bool);

  /// @dev use virtual to be overrided to mock data for fuzz tests
  function getActiveTime(
    address pAddr,
    address nftContract,
    uint256 nftId
  ) external view returns (uint128);

  function getSignedFee(address nftContract, uint256 nftId) external view returns (int256);

  function getSignedFeePool(
    address poolAddress,
    address nftContract,
    uint256 nftId
  ) external view returns (int256);

  function getLiq(address nftContract, uint256 nftId) external view returns (uint128);

  function getPair(address nftContract, uint256 nftId) external view returns (address, address);
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.8.0;

interface IBasePositionManager {
  struct Position {
    // the nonce for permits
    uint96 nonce;
    // the address that is approved for spending this token
    address operator;
    // the ID of the pool with which this token is connected
    uint80 poolId;
    // the tick range of the position
    int24 tickLower;
    int24 tickUpper;
    // the liquidity of the position
    uint128 liquidity;
    // the current rToken that the position owed
    uint256 rTokenOwed;
    // fee growth per unit of liquidity as of the last update to liquidity
    uint256 feeGrowthInsideLast;
  }

  struct PoolInfo {
    address token0;
    uint16 fee;
    address token1;
  }

  struct MintParams {
    address token0;
    address token1;
    uint24 fee;
    int24 tickLower;
    int24 tickUpper;
    int24[2] ticksPrevious;
    uint256 amount0Desired;
    uint256 amount1Desired;
    uint256 amount0Min;
    uint256 amount1Min;
    address recipient;
    uint256 deadline;
  }

  struct IncreaseLiquidityParams {
    uint256 tokenId;
    uint256 amount0Desired;
    uint256 amount1Desired;
    uint256 amount0Min;
    uint256 amount1Min;
    uint256 deadline;
  }

  struct RemoveLiquidityParams {
    uint256 tokenId;
    uint128 liquidity;
    uint256 amount0Min;
    uint256 amount1Min;
    uint256 deadline;
  }

  struct BurnRTokenParams {
    uint256 tokenId;
    uint256 amount0Min;
    uint256 amount1Min;
    uint256 deadline;
  }

  function positions(
    uint256 tokenId
  ) external view returns (Position memory pos, PoolInfo memory info);

  function addressToPoolId(address pool) external view returns (uint80);

  function WETH() external view returns (address);

  function mint(
    MintParams calldata params
  )
    external
    payable
    returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);

  function addLiquidity(
    IncreaseLiquidityParams calldata params
  )
    external
    payable
    returns (uint128 liquidity, uint256 amount0, uint256 amount1, uint256 additionalRTokenOwed);

  function removeLiquidity(
    RemoveLiquidityParams calldata params
  ) external returns (uint256 amount0, uint256 amount1, uint256 additionalRTokenOwed);

  function syncFeeGrowth(uint256 tokenId) external returns (uint256 additionalRTokenOwed);

  function burnRTokens(
    BurnRTokenParams calldata params
  ) external returns (uint256 rTokenQty, uint256 amount0, uint256 amount1);

  function transferAllTokens(address token, uint256 minAmount, address recipient) external payable;

  function unwrapWeth(uint256 minAmount, address recipient) external payable;
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity >=0.8.0;

import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';

import {IFactory} from './IFactory.sol';

interface IPoolStorage {
  struct PoolData {
    uint160 sqrtP;
    int24 nearestCurrentTick;
    int24 currentTick;
    bool locked;
    uint128 baseL;
    uint128 reinvestL;
    uint128 reinvestLLast;
    uint256 feeGrowthGlobal;
    uint128 secondsPerLiquidityGlobal;
    uint32 secondsPerLiquidityUpdateTime;
  }

  // data stored for each initialized individual tick
  struct TickData {
    // gross liquidity of all positions in tick
    uint128 liquidityGross;
    // liquidity quantity to be added | removed when tick is crossed up | down
    int128 liquidityNet;
    // fee growth per unit of liquidity on the other side of this tick (relative to current tick)
    // only has relative meaning, not absolute — the value depends on when the tick is initialized
    uint256 feeGrowthOutside;
    // seconds spent on the other side of this tick (relative to current tick)
    // only has relative meaning, not absolute — the value depends on when the tick is initialized
    uint128 secondsPerLiquidityOutside;
  }

  /// @notice The contract that deployed the pool, which must adhere to the IFactory interface
  /// @return The contract address
  function factory() external view returns (IFactory);

  /// @notice The first of the two tokens of the pool, sorted by address
  /// @return The token contract address
  function token0() external view returns (IERC20);

  /// @notice The second of the two tokens of the pool, sorted by address
  /// @return The token contract address
  function token1() external view returns (IERC20);

  /// @notice The fee to be charged for a swap in basis points
  /// @return The swap fee in basis points
  function swapFeeBps() external view returns (uint16);

  /// @notice The pool tick distance
  /// @dev Ticks can only be initialized and used at multiples of this value
  /// It remains an int24 to avoid casting even though it is >= 1.
  /// e.g: a tickDistance of 5 means ticks can be initialized every 5th tick, i.e., ..., -10, -5, 0, 5, 10, ...
  /// @return The tick distance
  function tickDistance() external view returns (int24);

  /// @notice Maximum gross liquidity that an initialized tick can have
  /// @dev This is to prevent overflow the pool's active base liquidity (uint128)
  /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool
  /// @return The max amount of liquidity per tick
  function maxTickLiquidity() external view returns (uint128);

  /// @notice Look up information about a specific tick in the pool
  /// @param tick The tick to look up
  /// @return liquidityGross total liquidity amount from positions that uses this tick as a lower or upper tick
  /// liquidityNet how much liquidity changes when the pool tick crosses above the tick
  /// feeGrowthOutside the fee growth on the other side of the tick relative to the current tick
  /// secondsPerLiquidityOutside the seconds spent on the other side of the tick relative to the current tick
  function ticks(int24 tick)
    external
    view
    returns (
      uint128 liquidityGross,
      int128 liquidityNet,
      uint256 feeGrowthOutside,
      uint128 secondsPerLiquidityOutside
    );

  /// @notice Returns the previous and next initialized ticks of a specific tick
  /// @dev If specified tick is uninitialized, the returned values are zero.
  /// @param tick The tick to look up
  function initializedTicks(int24 tick) external view returns (int24 previous, int24 next);

  /// @notice Returns the information about a position by the position's key
  /// @return liquidity the liquidity quantity of the position
  /// @return feeGrowthInsideLast fee growth inside the tick range as of the last mint / burn action performed
  function getPositions(
    address owner,
    int24 tickLower,
    int24 tickUpper
  ) external view returns (uint128 liquidity, uint256 feeGrowthInsideLast);

  /// @notice Fetches the pool's prices, ticks and lock status
  /// @return sqrtP sqrt of current price: sqrt(token1/token0)
  /// @return currentTick pool's current tick
  /// @return nearestCurrentTick pool's nearest initialized tick that is <= currentTick
  /// @return locked true if pool is locked, false otherwise
  function getPoolState()
    external
    view
    returns (
      uint160 sqrtP,
      int24 currentTick,
      int24 nearestCurrentTick,
      bool locked
    );

  /// @notice Fetches the pool's liquidity values
  /// @return baseL pool's base liquidity without reinvest liqudity
  /// @return reinvestL the liquidity is reinvested into the pool
  /// @return reinvestLLast last cached value of reinvestL, used for calculating reinvestment token qty
  function getLiquidityState()
    external
    view
    returns (
      uint128 baseL,
      uint128 reinvestL,
      uint128 reinvestLLast
    );

  /// @return feeGrowthGlobal All-time fee growth per unit of liquidity of the pool
  function getFeeGrowthGlobal() external view returns (uint256);

  /// @return secondsPerLiquidityGlobal All-time seconds per unit of liquidity of the pool
  /// @return lastUpdateTime The timestamp in which secondsPerLiquidityGlobal was last updated
  function getSecondsPerLiquidityData()
    external
    view
    returns (uint128 secondsPerLiquidityGlobal, uint32 lastUpdateTime);

  /// @notice Calculates and returns the active time per unit of liquidity until current block.timestamp
  /// @param tickLower The lower tick (of a position)
  /// @param tickUpper The upper tick (of a position)
  /// @return secondsPerLiquidityInside active time (multiplied by 2^96)
  /// between the 2 ticks, per unit of liquidity.
  function getSecondsPerLiquidityInside(int24 tickLower, int24 tickUpper)
    external
    view
    returns (uint128 secondsPerLiquidityInside);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

abstract contract KSAdmin {
  address public admin;
  mapping(address => bool) public operators; // address => bool

  event TransferAdmin(address indexed admin);
  event UpdateOperator(address indexed user, bool grantOrRevoke);

  modifier isAdmin() {
    require(msg.sender == admin, 'forbidden');
    _;
  }

  modifier isOperator() {
    require(operators[msg.sender], 'forbidden');
    _;
  }

  constructor() {
    admin = msg.sender;
    operators[msg.sender] = true;
  }

  function transferAdmin(address _admin) external virtual isAdmin {
    require(_admin != address(0), 'forbidden');

    admin = _admin;

    emit TransferAdmin(_admin);
  }

  function updateOperator(address user, bool grantOrRevoke) external isAdmin {
    operators[user] = grantOrRevoke;

    emit UpdateOperator(user, grantOrRevoke);
  }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// SPDX-License-Identifier: agpl-3.0
pragma solidity >=0.8.0;

/// @title KyberSwap v2 factory
/// @notice Deploys KyberSwap v2 pools and manages control over government fees
interface IFactory {
  /// @notice Emitted when a pool is created
  /// @param token0 First pool token by address sort order
  /// @param token1 Second pool token by address sort order
  /// @param swapFeeBps Fee to be collected upon every swap in the pool, in basis points
  /// @param tickDistance Minimum number of ticks between initialized ticks
  /// @param pool The address of the created pool
  event PoolCreated(
    address indexed token0,
    address indexed token1,
    uint16 indexed swapFeeBps,
    int24 tickDistance,
    address pool
  );

  /// @notice Emitted when a new fee is enabled for pool creation via the factory
  /// @param swapFeeBps Fee to be collected upon every swap in the pool, in basis points
  /// @param tickDistance Minimum number of ticks between initialized ticks for pools created with the given fee
  event SwapFeeEnabled(uint16 indexed swapFeeBps, int24 indexed tickDistance);

  /// @notice Emitted when vesting period changes
  /// @param vestingPeriod The maximum time duration for which LP fees
  /// are proportionally burnt upon LP removals
  event VestingPeriodUpdated(uint32 vestingPeriod);

  /// @notice Emitted when configMaster changes
  /// @param oldConfigMaster configMaster before the update
  /// @param newConfigMaster configMaster after the update
  event ConfigMasterUpdated(address oldConfigMaster, address newConfigMaster);

  /// @notice Emitted when fee configuration changes
  /// @param feeTo Recipient of government fees
  /// @param governmentFeeBps Fee amount, in basis points,
  /// to be collected out of the fee charged for a pool swap
  event FeeConfigurationUpdated(address feeTo, uint16 governmentFeeBps);

  /// @notice Emitted when whitelist feature is enabled
  event WhitelistEnabled();

  /// @notice Emitted when whitelist feature is disabled
  event WhitelistDisabled();

  /// @notice Returns the maximum time duration for which LP fees
  /// are proportionally burnt upon LP removals
  function vestingPeriod() external view returns (uint32);

  /// @notice Returns the tick distance for a specified fee.
  /// @dev Once added, cannot be updated or removed.
  /// @param swapFeeBps Swap fee, in basis points.
  /// @return The tick distance. Returns 0 if fee has not been added.
  function feeAmountTickDistance(uint16 swapFeeBps) external view returns (int24);

  /// @notice Returns the address which can update the fee configuration
  function configMaster() external view returns (address);

  /// @notice Returns the keccak256 hash of the Pool creation code
  /// This is used for pre-computation of pool addresses
  function poolInitHash() external view returns (bytes32);

  /// @notice Fetches the recipient of government fees
  /// and current government fee charged in basis points
  function feeConfiguration() external view returns (address _feeTo, uint16 _governmentFeeBps);

  /// @notice Returns the status of whitelisting feature of NFT managers
  /// If true, anyone can mint liquidity tokens
  /// Otherwise, only whitelisted NFT manager(s) are allowed to mint liquidity tokens
  function whitelistDisabled() external view returns (bool);

  //// @notice Returns all whitelisted NFT managers
  /// If the whitelisting feature is turned on,
  /// only whitelisted NFT manager(s) are allowed to mint liquidity tokens
  function getWhitelistedNFTManagers() external view returns (address[] memory);

  /// @notice Checks if sender is a whitelisted NFT manager
  /// If the whitelisting feature is turned on,
  /// only whitelisted NFT manager(s) are allowed to mint liquidity tokens
  /// @param sender address to be checked
  /// @return true if sender is a whistelisted NFT manager, false otherwise
  function isWhitelistedNFTManager(address sender) external view returns (bool);

  /// @notice Returns the pool address for a given pair of tokens and a swap fee
  /// @dev Token order does not matter
  /// @param tokenA Contract address of either token0 or token1
  /// @param tokenB Contract address of the other token
  /// @param swapFeeBps Fee to be collected upon every swap in the pool, in basis points
  /// @return pool The pool address. Returns null address if it does not exist
  function getPool(
    address tokenA,
    address tokenB,
    uint16 swapFeeBps
  ) external view returns (address pool);

  /// @notice Fetch parameters to be used for pool creation
  /// @dev Called by the pool constructor to fetch the parameters of the pool
  /// @return factory The factory address
  /// @return token0 First pool token by address sort order
  /// @return token1 Second pool token by address sort order
  /// @return swapFeeBps Fee to be collected upon every swap in the pool, in basis points
  /// @return tickDistance Minimum number of ticks between initialized ticks
  function parameters()
    external
    view
    returns (
      address factory,
      address token0,
      address token1,
      uint16 swapFeeBps,
      int24 tickDistance
    );

  /// @notice Creates a pool for the given two tokens and fee
  /// @param tokenA One of the two tokens in the desired pool
  /// @param tokenB The other of the two tokens in the desired pool
  /// @param swapFeeBps Desired swap fee for the pool, in basis points
  /// @dev Token order does not matter. tickDistance is determined from the fee.
  /// Call will revert under any of these conditions:
  ///     1) pool already exists
  ///     2) invalid swap fee
  ///     3) invalid token arguments
  /// @return pool The address of the newly created pool
  function createPool(
    address tokenA,
    address tokenB,
    uint16 swapFeeBps
  ) external returns (address pool);

  /// @notice Enables a fee amount with the given tickDistance
  /// @dev Fee amounts may never be removed once enabled
  /// @param swapFeeBps The fee amount to enable, in basis points
  /// @param tickDistance The distance between ticks to be enforced for all pools created with the given fee amount
  function enableSwapFee(uint16 swapFeeBps, int24 tickDistance) external;

  /// @notice Updates the address which can update the fee configuration
  /// @dev Must be called by the current configMaster
  function updateConfigMaster(address) external;

  /// @notice Updates the vesting period
  /// @dev Must be called by the current configMaster
  function updateVestingPeriod(uint32) external;

  /// @notice Updates the address receiving government fees and fee quantity
  /// @dev Only configMaster is able to perform the update
  /// @param feeTo Address to receive government fees collected from pools
  /// @param governmentFeeBps Fee amount, in basis points,
  /// to be collected out of the fee charged for a pool swap
  function updateFeeConfiguration(address feeTo, uint16 governmentFeeBps) external;

  /// @notice Enables the whitelisting feature
  /// @dev Only configMaster is able to perform the update
  function enableWhitelist() external;

  /// @notice Disables the whitelisting feature
  /// @dev Only configMaster is able to perform the update
  function disableWhitelist() external;
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RescueFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"TransferAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"grantOrRevoke","type":"bool"}],"name":"UpdateOperator","type":"event"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pAddress","type":"address"},{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"checkPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pAddr","type":"address"},{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"getActiveTime","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"getLiq","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"getSignedFee","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"getSignedFeePool","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"operators","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"grantOrRevoke","type":"bool"}],"name":"updateOperator","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50600080546001600160a01b0319163390811782558152600160208190526040909120805460ff191690911790556115288061004d6000396000f3fe608060405234801561001057600080fd5b50600436106100a85760003560e01c80636e261df1116100715780636e261df11461016b57806373770cd61461017e57806375829def1461019f578063a51dc8f2146101b2578063d7aee3bd146101c5578063f851a440146101d857600080fd5b80626349fb146100ad57806313e7c9d8146100e5578063420c52f2146101185780635c6d96a9146101435780636d44a3b214610156575b600080fd5b6100c06100bb366004610fc3565b610203565b604080516001600160a01b039384168152929091166020830152015b60405180910390f35b6101086100f3366004610fef565b60016020526000908152604090205460ff1681565b60405190151581526020016100dc565b61012b61012636600461100c565b61029c565b6040516001600160801b0390911681526020016100dc565b61012b610151366004610fc3565b610343565b61016961016436600461105b565b61035c565b005b610169610179366004610fc3565b6103ee565b61019161018c36600461100c565b61052a565b6040519081526020016100dc565b6101696101ad366004610fef565b610538565b6101916101c0366004610fc3565b6105d0565b6101086101d336600461100c565b6105e5565b6000546101eb906001600160a01b031681565b6040516001600160a01b0390911681526020016100dc565b6000806000846001600160a01b03166399fbab88856040518263ffffffff1660e01b815260040161023691815260200190565b6101606040518083038186803b15801561024f57600080fd5b505afa158015610263573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028791906111b5565b80516040909101519097909650945050505050565b6000806102a98484610698565b60608101516080820151604051631646347760e31b8152600292830b6004820152910b60248201529091506001600160a01b0386169063b231a3b89060440160206040518083038186803b15801561030057600080fd5b505afa158015610314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103389190611285565b9150505b9392505050565b6000806103508484610698565b60a00151949350505050565b6000546001600160a01b0316331461038f5760405162461bcd60e51b8152600401610386906112a0565b60405180910390fd5b6001600160a01b038216600081815260016020908152604091829020805460ff191685151590811790915591519182527f2ee52be9d342458b3d25e07faada7ff9bc06723b4aa24edb6321ac1316b8a9dd910160405180910390a25050565b6000546001600160a01b031633146104185760405162461bcd60e51b8152600401610386906112a0565b6001600160a01b0382166104d057604051600090339083908381818185875af1925050503d8060008114610468576040519150601f19603f3d011682016040523d82523d6000602084013e61046d565b606091505b50509050806104ca5760405162461bcd60e51b8152602060048201526024808201527f72657363756546756e643a206661696c656420746f20636f6c6c656374206e616044820152637469766560e01b6064820152608401610386565b506104e4565b6104e46001600160a01b038316338361075e565b604080516001600160a01b0384168152602081018390527f125fbdbcf3a7becd38f03d012558074dc0f2dbf28942defd577fea7832369872910160405180910390a15050565b6000806103388585856107b5565b6000546001600160a01b031633146105625760405162461bcd60e51b8152600401610386906112a0565b6001600160a01b0381166105885760405162461bcd60e51b8152600401610386906112a0565b600080546001600160a01b0319166001600160a01b038316908117825560405190917fda7b0a7bc965abdec8a1a995575a891838264c2968e14bd456c5391827b7aa3091a250565b6000806105dd8484610c4d565b949350505050565b6000806105f28484610698565b604080820151905163097fc67360e31b81526001600160a01b03888116600483015292935069ffffffffffffffffffff90911691861690634bfe33989060240160206040518083038186803b15801561064a57600080fd5b505afa15801561065e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068291906112c3565b69ffffffffffffffffffff161495945050505050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260405163133f757160e31b8152600481018390526000906001600160a01b038516906399fbab88906024016101606040518083038186803b15801561071d57600080fd5b505afa158015610731573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075591906111b5565b50949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526107b0908490610c66565b505050565b6000806107c28484610698565b606081015160405163f30dba9360e01b815260029190910b60048201529091506000906001600160a01b0387169063f30dba939060240160806040518083038186803b15801561081157600080fd5b505afa158015610825573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084991906112de565b50608085015160405163f30dba9360e01b815260029190910b6004820152909350600092506001600160a01b038916915063f30dba939060240160806040518083038186803b15801561089b57600080fd5b505afa1580156108af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d391906112de565b50925050506000876001600160a01b031663217ac2376040518163ffffffff1660e01b815260040160806040518083038186803b15801561091357600080fd5b505afa158015610927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094b9190611334565b50509150506000886001600160a01b03166372cc51486040518163ffffffff1660e01b815260040160206040518083038186803b15801561098b57600080fd5b505afa15801561099f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c3919061138c565b905060008060008b6001600160a01b031663ab612f2b6040518163ffffffff1660e01b815260040160606040518083038186803b158015610a0357600080fd5b505afa158015610a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3b91906113a5565b92509250925060008c6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a7c57600080fd5b505afa158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab4919061138c565b90506000610ad6846001600160801b0316846001600160801b03168785610d38565b90508015610bfd5760008e6001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1957600080fd5b505afa158015610b2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5191906113e8565b6001600160a01b03166398c47e8c6040518163ffffffff1660e01b8152600401604080518083038186803b158015610b8857600080fd5b505afa158015610b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190611405565b61ffff169150508015610bdf57620186a062ffffff8216830204909103905b610bf782600160601b886001600160801b0316610d81565b87019650505b5050505050846060015160020b8260020b1215610c1e578284039550610c41565b846080015160020b8260020b12610c39578383039550610c41565b828401810395505b50505050509392505050565b600080610c5a8484610698565b60e00151949350505050565b6000610cbb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ea09092919063ffffffff16565b8051909150156107b05780806020019051810190610cd9919061143a565b6107b05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610386565b600080610d6a6001600160801b038516610d52878961146d565b610d65896001600160801b038916611484565b610d81565b9050610d77838287610d81565b9695505050505050565b600080806000198587098587029250828110838203039150508060001415610de85760008411610ddd5760405162461bcd60e51b8152602060048201526007602482015266302064656e6f6d60c81b6044820152606401610386565b50829004905061033c565b808411610e285760405162461bcd60e51b815260206004820152600e60248201526d64656e6f6d203c3d2070726f643160901b6044820152606401610386565b6000848688098084039381119092039190506000610e4886196001611484565b8616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030260008290038290046001019490940294049390931791909102925050509392505050565b60606105dd848460008585843b610ef95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610386565b600080866001600160a01b03168587604051610f1591906114cc565b60006040518083038185875af1925050503d8060008114610f52576040519150601f19603f3d011682016040523d82523d6000602084013e610f57565b606091505b5091509150610f67828286610f72565b979650505050505050565b60608315610f8157508161033c565b825115610f915782518084602001fd5b8160405162461bcd60e51b815260040161038691906114e8565b6001600160a01b0381168114610fc057600080fd5b50565b60008060408385031215610fd657600080fd5b8235610fe181610fab565b946020939093013593505050565b60006020828403121561100157600080fd5b813561033c81610fab565b60008060006060848603121561102157600080fd5b833561102c81610fab565b9250602084013561103c81610fab565b929592945050506040919091013590565b8015158114610fc057600080fd5b6000806040838503121561106e57600080fd5b823561107981610fab565b915060208301356110898161104d565b809150509250929050565b604051610100810167ffffffffffffffff811182821017156110c657634e487b7160e01b600052604160045260246000fd5b60405290565b80516110d781610fab565b919050565b805169ffffffffffffffffffff811681146110d757600080fd5b8051600281900b81146110d757600080fd5b80516001600160801b03811681146110d757600080fd5b805161ffff811681146110d757600080fd5b60006060828403121561114357600080fd5b6040516060810181811067ffffffffffffffff8211171561117457634e487b7160e01b600052604160045260246000fd5b8060405250809150825161118781610fab565b81526111956020840161111f565b602082015260408301516111a881610fab565b6040919091015292915050565b6000808284036101608112156111ca57600080fd5b610100808212156111da57600080fd5b6111e2611094565b915084516bffffffffffffffffffffffff8116811461120057600080fd5b825261120e602086016110cc565b602083015261121f604086016110dc565b6040830152611230606086016110f6565b6060830152611241608086016110f6565b608083015261125260a08601611108565b60a083015260c085015160c083015260e085015160e083015281935061127a86828701611131565b925050509250929050565b60006020828403121561129757600080fd5b61033c82611108565b6020808252600990820152683337b93134b23232b760b91b604082015260600190565b6000602082840312156112d557600080fd5b61033c826110dc565b600080600080608085870312156112f457600080fd5b6112fd85611108565b9350602085015180600f0b811461131357600080fd5b6040860151909350915061132960608601611108565b905092959194509250565b6000806000806080858703121561134a57600080fd5b845161135581610fab565b9350611363602086016110f6565b9250611371604086016110f6565b915060608501516113818161104d565b939692955090935050565b60006020828403121561139e57600080fd5b5051919050565b6000806000606084860312156113ba57600080fd5b6113c384611108565b92506113d160208501611108565b91506113df60408501611108565b90509250925092565b6000602082840312156113fa57600080fd5b815161033c81610fab565b6000806040838503121561141857600080fd5b825161142381610fab565b91506114316020840161111f565b90509250929050565b60006020828403121561144c57600080fd5b815161033c8161104d565b634e487b7160e01b600052601160045260246000fd5b60008282101561147f5761147f611457565b500390565b6000821982111561149757611497611457565b500190565b60005b838110156114b757818101518382015260200161149f565b838111156114c6576000848401525b50505050565b600082516114de81846020870161149c565b9190910192915050565b602081526000825180602084015261150781604085016020870161149c565b601f01601f1916919091016040019291505056fea164736f6c6343000809000a

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100a85760003560e01c80636e261df1116100715780636e261df11461016b57806373770cd61461017e57806375829def1461019f578063a51dc8f2146101b2578063d7aee3bd146101c5578063f851a440146101d857600080fd5b80626349fb146100ad57806313e7c9d8146100e5578063420c52f2146101185780635c6d96a9146101435780636d44a3b214610156575b600080fd5b6100c06100bb366004610fc3565b610203565b604080516001600160a01b039384168152929091166020830152015b60405180910390f35b6101086100f3366004610fef565b60016020526000908152604090205460ff1681565b60405190151581526020016100dc565b61012b61012636600461100c565b61029c565b6040516001600160801b0390911681526020016100dc565b61012b610151366004610fc3565b610343565b61016961016436600461105b565b61035c565b005b610169610179366004610fc3565b6103ee565b61019161018c36600461100c565b61052a565b6040519081526020016100dc565b6101696101ad366004610fef565b610538565b6101916101c0366004610fc3565b6105d0565b6101086101d336600461100c565b6105e5565b6000546101eb906001600160a01b031681565b6040516001600160a01b0390911681526020016100dc565b6000806000846001600160a01b03166399fbab88856040518263ffffffff1660e01b815260040161023691815260200190565b6101606040518083038186803b15801561024f57600080fd5b505afa158015610263573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061028791906111b5565b80516040909101519097909650945050505050565b6000806102a98484610698565b60608101516080820151604051631646347760e31b8152600292830b6004820152910b60248201529091506001600160a01b0386169063b231a3b89060440160206040518083038186803b15801561030057600080fd5b505afa158015610314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103389190611285565b9150505b9392505050565b6000806103508484610698565b60a00151949350505050565b6000546001600160a01b0316331461038f5760405162461bcd60e51b8152600401610386906112a0565b60405180910390fd5b6001600160a01b038216600081815260016020908152604091829020805460ff191685151590811790915591519182527f2ee52be9d342458b3d25e07faada7ff9bc06723b4aa24edb6321ac1316b8a9dd910160405180910390a25050565b6000546001600160a01b031633146104185760405162461bcd60e51b8152600401610386906112a0565b6001600160a01b0382166104d057604051600090339083908381818185875af1925050503d8060008114610468576040519150601f19603f3d011682016040523d82523d6000602084013e61046d565b606091505b50509050806104ca5760405162461bcd60e51b8152602060048201526024808201527f72657363756546756e643a206661696c656420746f20636f6c6c656374206e616044820152637469766560e01b6064820152608401610386565b506104e4565b6104e46001600160a01b038316338361075e565b604080516001600160a01b0384168152602081018390527f125fbdbcf3a7becd38f03d012558074dc0f2dbf28942defd577fea7832369872910160405180910390a15050565b6000806103388585856107b5565b6000546001600160a01b031633146105625760405162461bcd60e51b8152600401610386906112a0565b6001600160a01b0381166105885760405162461bcd60e51b8152600401610386906112a0565b600080546001600160a01b0319166001600160a01b038316908117825560405190917fda7b0a7bc965abdec8a1a995575a891838264c2968e14bd456c5391827b7aa3091a250565b6000806105dd8484610c4d565b949350505050565b6000806105f28484610698565b604080820151905163097fc67360e31b81526001600160a01b03888116600483015292935069ffffffffffffffffffff90911691861690634bfe33989060240160206040518083038186803b15801561064a57600080fd5b505afa15801561065e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068291906112c3565b69ffffffffffffffffffff161495945050505050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260405163133f757160e31b8152600481018390526000906001600160a01b038516906399fbab88906024016101606040518083038186803b15801561071d57600080fd5b505afa158015610731573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075591906111b5565b50949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526107b0908490610c66565b505050565b6000806107c28484610698565b606081015160405163f30dba9360e01b815260029190910b60048201529091506000906001600160a01b0387169063f30dba939060240160806040518083038186803b15801561081157600080fd5b505afa158015610825573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084991906112de565b50608085015160405163f30dba9360e01b815260029190910b6004820152909350600092506001600160a01b038916915063f30dba939060240160806040518083038186803b15801561089b57600080fd5b505afa1580156108af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d391906112de565b50925050506000876001600160a01b031663217ac2376040518163ffffffff1660e01b815260040160806040518083038186803b15801561091357600080fd5b505afa158015610927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094b9190611334565b50509150506000886001600160a01b03166372cc51486040518163ffffffff1660e01b815260040160206040518083038186803b15801561098b57600080fd5b505afa15801561099f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c3919061138c565b905060008060008b6001600160a01b031663ab612f2b6040518163ffffffff1660e01b815260040160606040518083038186803b158015610a0357600080fd5b505afa158015610a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3b91906113a5565b92509250925060008c6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a7c57600080fd5b505afa158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab4919061138c565b90506000610ad6846001600160801b0316846001600160801b03168785610d38565b90508015610bfd5760008e6001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1957600080fd5b505afa158015610b2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5191906113e8565b6001600160a01b03166398c47e8c6040518163ffffffff1660e01b8152600401604080518083038186803b158015610b8857600080fd5b505afa158015610b9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190611405565b61ffff169150508015610bdf57620186a062ffffff8216830204909103905b610bf782600160601b886001600160801b0316610d81565b87019650505b5050505050846060015160020b8260020b1215610c1e578284039550610c41565b846080015160020b8260020b12610c39578383039550610c41565b828401810395505b50505050509392505050565b600080610c5a8484610698565b60e00151949350505050565b6000610cbb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ea09092919063ffffffff16565b8051909150156107b05780806020019051810190610cd9919061143a565b6107b05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610386565b600080610d6a6001600160801b038516610d52878961146d565b610d65896001600160801b038916611484565b610d81565b9050610d77838287610d81565b9695505050505050565b600080806000198587098587029250828110838203039150508060001415610de85760008411610ddd5760405162461bcd60e51b8152602060048201526007602482015266302064656e6f6d60c81b6044820152606401610386565b50829004905061033c565b808411610e285760405162461bcd60e51b815260206004820152600e60248201526d64656e6f6d203c3d2070726f643160901b6044820152606401610386565b6000848688098084039381119092039190506000610e4886196001611484565b8616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030260008290038290046001019490940294049390931791909102925050509392505050565b60606105dd848460008585843b610ef95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610386565b600080866001600160a01b03168587604051610f1591906114cc565b60006040518083038185875af1925050503d8060008114610f52576040519150601f19603f3d011682016040523d82523d6000602084013e610f57565b606091505b5091509150610f67828286610f72565b979650505050505050565b60608315610f8157508161033c565b825115610f915782518084602001fd5b8160405162461bcd60e51b815260040161038691906114e8565b6001600160a01b0381168114610fc057600080fd5b50565b60008060408385031215610fd657600080fd5b8235610fe181610fab565b946020939093013593505050565b60006020828403121561100157600080fd5b813561033c81610fab565b60008060006060848603121561102157600080fd5b833561102c81610fab565b9250602084013561103c81610fab565b929592945050506040919091013590565b8015158114610fc057600080fd5b6000806040838503121561106e57600080fd5b823561107981610fab565b915060208301356110898161104d565b809150509250929050565b604051610100810167ffffffffffffffff811182821017156110c657634e487b7160e01b600052604160045260246000fd5b60405290565b80516110d781610fab565b919050565b805169ffffffffffffffffffff811681146110d757600080fd5b8051600281900b81146110d757600080fd5b80516001600160801b03811681146110d757600080fd5b805161ffff811681146110d757600080fd5b60006060828403121561114357600080fd5b6040516060810181811067ffffffffffffffff8211171561117457634e487b7160e01b600052604160045260246000fd5b8060405250809150825161118781610fab565b81526111956020840161111f565b602082015260408301516111a881610fab565b6040919091015292915050565b6000808284036101608112156111ca57600080fd5b610100808212156111da57600080fd5b6111e2611094565b915084516bffffffffffffffffffffffff8116811461120057600080fd5b825261120e602086016110cc565b602083015261121f604086016110dc565b6040830152611230606086016110f6565b6060830152611241608086016110f6565b608083015261125260a08601611108565b60a083015260c085015160c083015260e085015160e083015281935061127a86828701611131565b925050509250929050565b60006020828403121561129757600080fd5b61033c82611108565b6020808252600990820152683337b93134b23232b760b91b604082015260600190565b6000602082840312156112d557600080fd5b61033c826110dc565b600080600080608085870312156112f457600080fd5b6112fd85611108565b9350602085015180600f0b811461131357600080fd5b6040860151909350915061132960608601611108565b905092959194509250565b6000806000806080858703121561134a57600080fd5b845161135581610fab565b9350611363602086016110f6565b9250611371604086016110f6565b915060608501516113818161104d565b939692955090935050565b60006020828403121561139e57600080fd5b5051919050565b6000806000606084860312156113ba57600080fd5b6113c384611108565b92506113d160208501611108565b91506113df60408501611108565b90509250925092565b6000602082840312156113fa57600080fd5b815161033c81610fab565b6000806040838503121561141857600080fd5b825161142381610fab565b91506114316020840161111f565b90509250929050565b60006020828403121561144c57600080fd5b815161033c8161104d565b634e487b7160e01b600052601160045260246000fd5b60008282101561147f5761147f611457565b500390565b6000821982111561149757611497611457565b500190565b60005b838110156114b757818101518382015260200161149f565b838111156114c6576000848401525b50505050565b600082516114de81846020870161149c565b9190910192915050565b602081526000825180602084015261150781604085016020870161149c565b601f01601f1916919091016040019291505056fea164736f6c6343000809000a

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.