ETH Price: $2,799.87 (-5.38%)

Token

ERC20 ***

Overview

Max Total Supply

0.000000095250631027 ERC20 ***

Holders

18,467

Market

Price

$0.00 @ 0.000000 ETH

Onchain Market Cap

-

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
attapol.linea.eth
Balance
0.000000000000028652 ERC20 ***

Value
$0.00
0xDe6E0814AF98646fa9df7c64c5e0d943Bf0eCFF4
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
LToken

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/math/Math.sol";

import "../library/SafeToken.sol";

import "./Market.sol";

import "../interfaces/IWETH.sol";

contract LToken is Market {
  using SafeMath for uint256;
  using SafeToken for address;

  /* ========== STATE VARIABLES ========== */

  string public name;
  string public symbol;
  uint8 public decimals;

  // initializer
  bool public initialized;

  mapping(address => mapping(address => uint256)) private _transferAllowances;

  /* ========== EVENT ========== */

  event Mint(address minter, uint256 mintAmount);
  event Redeem(address account, uint underlyingAmount, uint lTokenAmount);

  event Borrow(address account, uint256 ammount, uint256 accountBorrow);
  event RepayBorrow(address payer, address borrower, uint256 amount, uint256 accountBorrow);
  event LiquidateBorrow(
    address liquidator,
    address borrower,
    uint256 amount,
    address lTokenCollateral,
    uint256 seizeAmount
  );

  event Transfer(address indexed from, address indexed to, uint256 amount);
  event Approval(address indexed owner, address indexed spender, uint256 amount);

  /* ========== INITIALIZER ========== */

  constructor() public {}

  function initialize(string memory _name, string memory _symbol, uint8 _decimals) external onlyOwner {
    require(initialized == false, "already initialized");
    __GMarket_init();

    name = _name;
    symbol = _symbol;
    decimals = _decimals;
    initialized = true;
  }

  /* ========== VIEWS ========== */

  function allowance(address account, address spender) external view override returns (uint256) {
    return _transferAllowances[account][spender];
  }

  function getOwner() external view returns (address) {
    return owner();
  }

  /* ========== MUTATIVE FUNCTIONS ========== */

  function transfer(address dst, uint256 amount) external override accrue nonReentrant returns (bool) {
    core.transferTokens(msg.sender, msg.sender, dst, amount);
    return true;
  }

  function transferFrom(address src, address dst, uint256 amount) external override accrue nonReentrant returns (bool) {
    core.transferTokens(msg.sender, src, dst, amount);
    return true;
  }

  function approve(address spender, uint256 amount) external override returns (bool) {
    _transferAllowances[msg.sender][spender] = amount;
    emit Approval(msg.sender, spender, amount);
    return true;
  }

  /* ========== RESTRICTED FUNCTIONS ========== */

  function supply(address account, uint256 uAmount) external payable override accrue onlyCore returns (uint256) {
    uint256 exchangeRate = exchangeRate();
    uAmount = underlying == address(ETH) ? msg.value : uAmount;
    uAmount = _doTransferIn(account, uAmount);
    uint256 lAmount = uAmount.mul(1e18).div(exchangeRate);
    require(lAmount > 0, "LToken: invalid lAmount");
    updateSupplyInfo(account, lAmount, 0);

    emit Mint(account, lAmount);
    emit Transfer(address(0), account, lAmount);
    return lAmount;
  }

  function supplyBehalf(address account, address supplier, uint256 uAmount) external payable override accrue onlyCore returns (uint256) {
    uint256 exchangeRate = exchangeRate();
    uAmount = underlying == address(ETH) ? msg.value : uAmount;
    uAmount = _doTransferIn(account, uAmount);
    uint256 lAmount = uAmount.mul(1e18).div(exchangeRate);
    require(lAmount > 0, "LToken: invalid lAmount");
    updateSupplyInfo(supplier, lAmount, 0);

    emit Mint(supplier, lAmount);
    emit Transfer(address(0), supplier, lAmount);
    return lAmount;
  }

  function redeemToken(address redeemer, uint256 lAmount) external override accrue onlyCore returns (uint256) {
    return _redeem(redeemer, lAmount, 0);
  }

  function redeemUnderlying(address redeemer, uint256 uAmount) external override accrue onlyCore returns (uint256) {
    return _redeem(redeemer, 0, uAmount);
  }

  function borrow(address account, uint256 amount) external override accrue onlyCore returns (uint256) {
    require(getCash() >= amount, "LToken: borrow amount exceeds cash");
    updateBorrowInfo(account, amount, 0);
    _doTransferOut(account, amount);

    emit Borrow(account, amount, borrowBalanceOf(account));
    return amount;
  }

  function borrowBehalf(address account, address borrower, uint256 amount) external override accrue onlyCore returns (uint256) {
    require(getCash() >= amount, "LToken: borrow amount exceeds cash");
    updateBorrowInfo(borrower, amount, 0);
    _doTransferOut(account, amount);

    emit Borrow(borrower, amount, borrowBalanceOf(borrower));
    return amount;
  }

  function repayBorrow(address account, uint256 amount) external payable override accrue onlyCore returns (uint256) {
    if (amount == uint256(-1)) {
      amount = borrowBalanceOf(account);
    }
    return _repay(account, account, underlying == address(ETH) ? msg.value : amount);
  }

  function liquidateBorrow(
    address lTokenCollateral,
    address liquidator,
    address borrower,
    uint256 amount
  )
    external
    payable
    override
    accrue
    onlyCore
    returns (uint256 seizeLAmount, uint256 rebateLAmount, uint256 liquidatorLAmount)
  {
    require(borrower != liquidator, "LToken: cannot liquidate yourself");
    amount = underlying == address(ETH) ? msg.value : amount;
    amount = _repay(liquidator, borrower, amount);
    require(amount > 0 && amount < uint256(-1), "LToken: invalid repay amount");

    (seizeLAmount, rebateLAmount, liquidatorLAmount) = IValidator(core.validator()).lTokenAmountToSeize(
      address(this),
      lTokenCollateral,
      amount
    );

    require(ILToken(payable(lTokenCollateral)).balanceOf(borrower) >= seizeLAmount, "LToken: too much seize amount");

    emit LiquidateBorrow(liquidator, borrower, amount, lTokenCollateral, seizeLAmount);
  }

  function seize(address liquidator, address borrower, uint256 lAmount) external override accrue onlyCore nonReentrant {
    accountBalances[borrower] = accountBalances[borrower].sub(lAmount);
    accountBalances[liquidator] = accountBalances[liquidator].add(lAmount);

    emit Transfer(borrower, liquidator, lAmount);
  }

  function withdrawReserves() external override accrue onlyRebateDistributor nonReentrant {
    if (getCash() >= totalReserve) {
      uint256 amount = totalReserve;

      if (amount > 0) {
        totalReserve = 0;
        _doTransferOut(address(rebateDistributor), amount);
      }
    }
  }

  function transferTokensInternal(
    address spender,
    address src,
    address dst,
    uint256 amount
  ) external override onlyCore {
    require(
      src != dst && IValidator(core.validator()).redeemAllowed(address(this), src, amount),
      "LToken: cannot transfer"
    );
    require(amount != 0, "LToken: zero amount");
    uint256 _allowance = spender == src ? uint256(-1) : _transferAllowances[src][spender];
    uint256 _allowanceNew = _allowance.sub(amount, "LToken: transfer amount exceeds allowance");

    accountBalances[src] = accountBalances[src].sub(amount);
    accountBalances[dst] = accountBalances[dst].add(amount);

    if (_allowance != uint256(-1)) {
      _transferAllowances[src][spender] = _allowanceNew;
    }
    emit Transfer(src, dst, amount);
  }

  /* ========== PRIVATE FUNCTIONS ========== */

  function _doTransferIn(address from, uint256 amount) private returns (uint256) {
    if (underlying == address(ETH)) {
      require(msg.value >= amount, "LToken: value mismatch");
      return Math.min(msg.value, amount);
    } else {
      uint256 balanceBefore = IBEP20(underlying).balanceOf(address(this));
      underlying.safeTransferFrom(from, address(this), amount);
      uint256 balanceAfter = IBEP20(underlying).balanceOf(address(this));
      require(balanceAfter.sub(balanceBefore) <= amount);
      return balanceAfter.sub(balanceBefore);
    }
  }

  function _doTransferOut(address to, uint256 amount) private {
    if (underlying == address(ETH)) {
      SafeToken.safeTransferETH(to, amount);
    } else {
      underlying.safeTransfer(to, amount);
    }
  }

  function _redeem(address account, uint256 lAmountIn, uint256 uAmountIn) private returns (uint256) {
    require(lAmountIn == 0 || uAmountIn == 0, "LToken: one of lAmountIn or uAmountIn must be zero");
    require(totalSupply >= lAmountIn, "LToken: not enough total supply");
    require(getCash() >= uAmountIn || uAmountIn == 0, "LToken: not enough underlying");
    require(getCash() >= lAmountIn.mul(exchangeRate()).div(1e18) || lAmountIn == 0, "LToken: not enough underlying");

    uint lAmountToRedeem = lAmountIn > 0 ? lAmountIn : uAmountIn.mul(1e18).div(exchangeRate());
    uint uAmountToRedeem = lAmountIn > 0 ? lAmountIn.mul(exchangeRate()).div(1e18) : uAmountIn;

    require(
      IValidator(core.validator()).redeemAllowed(address(this), account, lAmountToRedeem),
      "LToken: cannot redeem"
    );

    updateSupplyInfo(account, 0, lAmountToRedeem);
    _doTransferOut(account, uAmountToRedeem);

    emit Transfer(account, address(0), lAmountToRedeem);
    emit Redeem(account, uAmountToRedeem, lAmountToRedeem);
    return uAmountToRedeem;
  }

  function _repay(address payer, address borrower, uint256 amount) private returns (uint256) {
    uint256 borrowBalance = borrowBalanceOf(borrower);
    uint256 repayAmount = Math.min(borrowBalance, amount);
    repayAmount = _doTransferIn(payer, repayAmount);
    updateBorrowInfo(borrower, 0, repayAmount);

    if (underlying == address(ETH)) {
      uint256 refundAmount = amount > repayAmount ? amount.sub(repayAmount) : 0;
      if (refundAmount > 0) {
        _doTransferOut(payer, refundAmount);
      }
    }

    emit RepayBorrow(payer, borrower, repayAmount, borrowBalanceOf(borrower));
    return repayAmount;
  }
}

// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.6.12;

interface ERC20Interface {
  function balanceOf(address user) external view returns (uint256);
}

library SafeToken {
  function myBalance(address token) internal view returns (uint256) {
    return ERC20Interface(token).balanceOf(address(this));
  }

  function balanceOf(address token, address user) internal view returns (uint256) {
    return ERC20Interface(token).balanceOf(user);
  }

  function safeApprove(address token, address to, uint256 value) internal {
    // bytes4(keccak256(bytes('approve(address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
    require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeApprove");
  }

  function safeTransfer(address token, address to, uint256 value) internal {
    // bytes4(keccak256(bytes('transfer(address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
    require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeTransfer");
  }

  function safeTransferFrom(address token, address from, address to, uint256 value) internal {
    // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
    require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeTransferFrom");
  }

  function safeTransferETH(address to, uint256 value) internal {
    (bool success, ) = to.call{value: value}(new bytes(0));
    require(success, "!safeTransferETH");
  }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;

interface IWETH {
  function approve(address spender, uint256 value) external returns (bool);

  function transfer(address recipient, uint256 amount) external returns (bool);

  function deposit() external payable;

  function withdraw(uint256 amount) external;
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

import "../library/Constant.sol";

import "../interfaces/IBEP20.sol";
import "../interfaces/IValidator.sol";
import "../interfaces/IRateModel.sol";
import "../interfaces/ILToken.sol";
import "../interfaces/ICore.sol";
import "../interfaces/IRebateDistributor.sol";

abstract contract Market is ILToken, Ownable, ReentrancyGuard {
  using SafeMath for uint256;

  /* ========== CONSTANT VARIABLES ========== */

  uint256 internal constant RESERVE_FACTOR_MAX = 1e18;
  uint256 internal constant DUST = 1000;

  address internal constant ETH = 0x0000000000000000000000000000000000000000;

  /* ========== STATE VARIABLES ========== */

  ICore public core;
  IRateModel public rateModel;
  IRebateDistributor public rebateDistributor;
  address public override underlying;

  uint256 public override totalSupply; // Total supply of lToken
  uint256 public override totalReserve;
  uint256 public override _totalBorrow;

  mapping(address => uint256) internal accountBalances;
  mapping(address => Constant.BorrowInfo) internal accountBorrows;

  uint256 public override reserveFactor;
  uint256 public override lastAccruedTime;
  uint256 public override accInterestIndex;

  /* ========== INITIALIZER ========== */

  receive() external payable {}

  /// @dev Initialization
  function __GMarket_init() internal {
    lastAccruedTime = block.timestamp;
    accInterestIndex = 1e18;
  }

  /* ========== MODIFIERS ========== */

  /// @dev 아직 처리되지 않은 totalBorrow, totalReserve, accInterestIndex 계산 및 저장
  modifier accrue() {
    if (block.timestamp > lastAccruedTime && address(rateModel) != address(0)) {
      uint256 borrowRate = rateModel.getBorrowRate(getCashPrior(), _totalBorrow, totalReserve);
      uint256 interestFactor = borrowRate.mul(block.timestamp.sub(lastAccruedTime));
      uint256 pendingInterest = _totalBorrow.mul(interestFactor).div(1e18);

      _totalBorrow = _totalBorrow.add(pendingInterest);
      totalReserve = totalReserve.add(pendingInterest.mul(reserveFactor).div(1e18));
      accInterestIndex = accInterestIndex.add(interestFactor.mul(accInterestIndex).div(1e18));
      lastAccruedTime = block.timestamp;
    }
    _;
  }

  /// @dev msg.sender 가 core address 인지 검증
  modifier onlyCore() {
    require(msg.sender == address(core), "LToken: only Core Contract");
    _;
  }

  modifier onlyRebateDistributor() {
    require(msg.sender == address(rebateDistributor), "LToken: only RebateDistributor");
    _;
  }

  /* ========== RESTRICTED FUNCTIONS ========== */

  /// @notice core address 를 설정
  /// @dev ZERO ADDRESS 로 설정할 수 없음
  ///      설정 이후에는 다른 주소로 변경할 수 없음
  /// @param _core core contract address
  function setCore(address _core) public onlyOwner {
    require(_core != address(0), "GMarket: invalid core address");
    require(address(core) == address(0), "GMarket: core already set");
    core = ICore(_core);
  }

  /// @notice underlying asset 의 token 설정
  /// @dev ZERO ADDRESS 로 설정할 수 없음
  ///      설정 이후에는 다른 주소로 변경할 수 없음
  /// @param _underlying Underlying token contract address
  function setUnderlying(address _underlying) public onlyOwner {
    require(_underlying != address(0), "GMarket: invalid underlying address");
    require(underlying == address(0), "GMarket: set underlying already");
    underlying = _underlying;
  }

  /// @notice rateModel 설정
  /// @param _rateModel 새로운 RateModel contract address
  function setRateModel(address _rateModel) public accrue onlyOwner {
    require(_rateModel != address(0), "GMarket: invalid rate model address");
    rateModel = IRateModel(_rateModel);
  }

  /// @notice reserve factor 변경
  /// @dev RESERVE_FACTOR_MAX 를 초과할 수 없음
  /// @param _reserveFactor 새로운 reserveFactor 값
  function setReserveFactor(uint256 _reserveFactor) public accrue onlyOwner {
    require(_reserveFactor <= RESERVE_FACTOR_MAX, "GMarket: invalid reserve factor");
    reserveFactor = _reserveFactor;
  }

  function setRebateDistributor(address _rebateDistributor) public onlyOwner {
    require(_rebateDistributor != address(0), "GMarket: invalid rebate distributor address");
    rebateDistributor = IRebateDistributor(_rebateDistributor);
  }

  /* ========== VIEWS ========== */

  function balanceOf(address account) external view override returns (uint256) {
    return accountBalances[account];
  }

  /// @notice account 의 AccountSnapshot 조회
  /// @param account account address
  function accountSnapshot(address account) external view override returns (Constant.AccountSnapshot memory) {
    Constant.AccountSnapshot memory snapshot;
    snapshot.lTokenBalance = accountBalances[account];
    snapshot.borrowBalance = borrowBalanceOf(account);
    snapshot.exchangeRate = exchangeRate();
    return snapshot;
  }

  /// @notice account 의 supply 된 underlying token 의 amount 조회
  /// @dev 원금에 붙은 이자를 포함
  /// @param account account address
  function underlyingBalanceOf(address account) external view override returns (uint256) {
    return accountBalances[account].mul(exchangeRate()).div(1e18);
  }

  /// @notice 계정의 borrow amount 조회
  /// @dev 원금에 붙은 이자를 포함
  function borrowBalanceOf(address account) public view override returns (uint256) {
    Constant.AccrueSnapshot memory snapshot = pendingAccrueSnapshot();
    Constant.BorrowInfo storage info = accountBorrows[account];

    if (info.borrow == 0) return 0;
    return info.borrow.mul(snapshot.accInterestIndex).div(info.interestIndex);
  }

  function totalBorrow() public view override returns (uint256) {
    Constant.AccrueSnapshot memory snapshot = pendingAccrueSnapshot();
    return snapshot.totalBorrow;
  }

  function exchangeRate() public view override returns (uint256) {
    if (totalSupply == 0) return 1e18;
    Constant.AccrueSnapshot memory snapshot = pendingAccrueSnapshot();
    return getCashPrior().add(snapshot.totalBorrow).sub(snapshot.totalReserve).mul(1e18).div(totalSupply);
  }

  function getCash() public view override returns (uint256) {
    return getCashPrior();
  }

  function getRateModel() external view override returns (address) {
    return address(rateModel);
  }

  function getAccInterestIndex() public view override returns (uint256) {
    Constant.AccrueSnapshot memory snapshot = pendingAccrueSnapshot();
    return snapshot.accInterestIndex;
  }

  /* ========== MUTATIVE FUNCTIONS ========== */

  function accruedAccountSnapshot(address account) external override accrue returns (Constant.AccountSnapshot memory) {
    Constant.AccountSnapshot memory snapshot;
    Constant.BorrowInfo storage info = accountBorrows[account];
    if (info.interestIndex != 0) {
      info.borrow = info.borrow.mul(accInterestIndex).div(info.interestIndex);
      info.interestIndex = accInterestIndex;
    }

    snapshot.lTokenBalance = accountBalances[account];
    snapshot.borrowBalance = info.borrow;
    snapshot.exchangeRate = exchangeRate();
    return snapshot;
  }

  /// @notice View borrow balance amount after accure mutation
  function accruedBorrowBalanceOf(address account) external override accrue returns (uint256) {
    Constant.BorrowInfo storage info = accountBorrows[account];
    if (info.interestIndex != 0) {
      info.borrow = info.borrow.mul(accInterestIndex).div(info.interestIndex);
      info.interestIndex = accInterestIndex;
    }
    return info.borrow;
  }

  /// @notice View total borrow amount after accrue mutation
  function accruedTotalBorrow() external override accrue returns (uint256) {
    return _totalBorrow;
  }

  /// @notice View underlying token exchange rate after accure mutation
  function accruedExchangeRate() external override accrue returns (uint256) {
    return exchangeRate();
  }

  /* ========== INTERNAL FUNCTIONS ========== */

  /// @notice borrow info 업데이트
  /// @dev account 의 accountBorrows 를 변경하고, totalSupply 를 변경함
  /// @param account borrow 하는 address account
  /// @param addAmount 추가되는 borrow amount
  /// @param subAmount 제거되는 borrow amount
  function updateBorrowInfo(address account, uint256 addAmount, uint256 subAmount) internal {
    Constant.BorrowInfo storage info = accountBorrows[account];
    if (info.interestIndex == 0) {
      info.interestIndex = accInterestIndex;
    }

    info.borrow = info.borrow.mul(accInterestIndex).div(info.interestIndex).add(addAmount).sub(subAmount);
    info.interestIndex = accInterestIndex;
    _totalBorrow = _totalBorrow.add(addAmount).sub(subAmount);

    info.borrow = (info.borrow < DUST) ? 0 : info.borrow;
    _totalBorrow = (_totalBorrow < DUST) ? 0 : _totalBorrow;
  }

  /// @notice supply info 업데이트
  /// @dev account 의 accountBalances 를 변경하고, totalSupply 를 변경함
  /// @param account supply 하는 address account
  /// @param addAmount 추가되는 supply amount
  /// @param subAmount 제거되는 supply amount
  function updateSupplyInfo(address account, uint256 addAmount, uint256 subAmount) internal {
    accountBalances[account] = accountBalances[account].add(addAmount).sub(subAmount);
    totalSupply = totalSupply.add(addAmount).sub(subAmount);

    totalSupply = (totalSupply < DUST) ? 0 : totalSupply;
  }

  /// @notice contract 가 가지고 있는 underlying token amount 조회
  /// @dev underlying token 이 ETH 인 경우 msg.value 값을 빼서 계산함
  function getCashPrior() internal view returns (uint256) {
    return
      underlying == address(ETH) ? address(this).balance.sub(msg.value) : IBEP20(underlying).balanceOf(address(this));
  }

  /// @notice totalBorrow, totlaReserver, accInterestIdx 조회
  /// @dev 아직 계산되지 않은 pending interest 더한 값으로 조회
  ///      상태가 변겅되거나 저장되지는 않는다
  function pendingAccrueSnapshot() internal view returns (Constant.AccrueSnapshot memory) {
    Constant.AccrueSnapshot memory snapshot;
    snapshot.totalBorrow = _totalBorrow;
    snapshot.totalReserve = totalReserve;
    snapshot.accInterestIndex = accInterestIndex;

    if (block.timestamp > lastAccruedTime && _totalBorrow > 0) {
      uint256 borrowRate = rateModel.getBorrowRate(getCashPrior(), _totalBorrow, totalReserve);
      uint256 interestFactor = borrowRate.mul(block.timestamp.sub(lastAccruedTime));
      uint256 pendingInterest = _totalBorrow.mul(interestFactor).div(1e18);

      snapshot.totalBorrow = _totalBorrow.add(pendingInterest);
      snapshot.totalReserve = totalReserve.add(pendingInterest.mul(reserveFactor).div(1e18));
      snapshot.accInterestIndex = accInterestIndex.add(interestFactor.mul(accInterestIndex).div(1e18));
    }
    return snapshot;
  }
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

File 6 of 16 : Constant.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;

library Constant {
  uint256 public constant CLOSE_FACTOR_MIN = 5e16;
  uint256 public constant CLOSE_FACTOR_MAX = 9e17;
  uint256 public constant COLLATERAL_FACTOR_MAX = 9e17;
  uint256 public constant LIQUIDATION_THRESHOLD_MAX = 9e17;
  uint256 public constant LIQUIDATION_BONUS_MAX = 5e17;

  enum EcoScorePreviewOption {
    LOCK,
    CLAIM,
    EXTEND,
    LOCK_MORE
  }

  enum LoanState {
    None,
    Active,
    Auction,
    Repaid,
    Defaulted
  }

  struct MarketInfo {
    bool isListed;
    uint256 supplyCap;
    uint256 borrowCap;
    uint256 collateralFactor;
  }

  struct BorrowInfo {
    uint256 borrow;
    uint256 interestIndex;
  }

  struct AccountSnapshot {
    uint256 lTokenBalance;
    uint256 borrowBalance;
    uint256 exchangeRate;
  }

  struct AccrueSnapshot {
    uint256 totalBorrow;
    uint256 totalReserve;
    uint256 accInterestIndex;
  }

  struct AccrueLoanSnapshot {
    uint256 totalBorrow;
    uint256 accInterestIndex;
  }

  struct DistributionInfo {
    uint256 supplySpeed;
    uint256 borrowSpeed;
    uint256 totalBoostedSupply;
    uint256 totalBoostedBorrow;
    uint256 accPerShareSupply;
    uint256 accPerShareBorrow;
    uint256 accruedAt;
  }

  struct DistributionAccountInfo {
    uint256 accuredLAB; // Unclaimed LAB rewards amount
    uint256 boostedSupply; // effective(boosted) supply balance of user  (since last_action)
    uint256 boostedBorrow; // effective(boosted) borrow balance of user  (since last_action)
    uint256 accPerShareSupply; // Last integral value of LAB rewards per share. ∫(LABRate(t) / totalShare(t) dt) from 0 till (last_action)
    uint256 accPerShareBorrow; // Last integral value of LAB rewards per share. ∫(LABRate(t) / totalShare(t) dt) from 0 till (last_action)
  }

  struct DistributionAPY {
    uint256 apySupplyLab;
    uint256 apyBorrowLab;
    uint256 apyAccountSupplyLab;
    uint256 apyAccountBorrowLab;
  }

  struct RebateCheckpoint {
    uint256 timestamp;
    uint256 totalScore;
    uint256 adminFeeRate;
    uint256 weeklyLabSpeed;
    uint256 additionalLabAmount;
    mapping(address => uint256) marketFees;
  }

  struct LockInfo {
    uint256 timestamp;
    uint256 amount;
    uint256 expiry;
  }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

interface IValidator {
  function redeemAllowed(address lToken, address redeemer, uint256 redeemAmount) external returns (bool);

  function borrowAllowed(address lToken, address borrower, uint256 borrowAmount) external returns (bool);

  function liquidateAllowed(
    address lTokenBorrowed,
    address borrower,
    uint256 repayAmount,
    uint256 closeFactor
  ) external returns (bool);

  function lTokenAmountToSeize(
    address lTokenBorrowed,
    address lTokenCollateral,
    uint256 actualRepayAmount
  ) external returns (uint256 seizeLAmount, uint256 rebateLAmount, uint256 liquidatorLAmount);

  function getAccountLiquidity(
    address account
  ) external view returns (uint256 collateralInUSD, uint256 supplyInUSD, uint256 borrowInUSD);
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

import "../library/Constant.sol";

interface ICore {
  /* ========== Event ========== */
  event MarketSupply(address user, address lToken, uint256 uAmount);
  event MarketRedeem(address user, address lToken, uint256 uAmount);

  event MarketListed(address lToken);
  event MarketEntered(address lToken, address account);
  event MarketExited(address lToken, address account);

  event CloseFactorUpdated(uint256 newCloseFactor);
  event CollateralFactorUpdated(address lToken, uint256 newCollateralFactor);
  event LiquidationIncentiveUpdated(uint256 newLiquidationIncentive);
  event SupplyCapUpdated(address indexed lToken, uint256 newSupplyCap);
  event BorrowCapUpdated(address indexed lToken, uint256 newBorrowCap);
  event KeeperUpdated(address newKeeper);
  event ValidatorUpdated(address newValidator);
  event LABDistributorUpdated(address newLABDistributor);
  event RebateDistributorUpdated(address newRebateDistributor);
  event LeveragerUpdated(address newLeverager);
  event FlashLoan(
    address indexed target,
    address indexed initiator,
    address indexed asset,
    uint256 amount,
    uint256 premium
  );

  function validator() external view returns (address);

  function rebateDistributor() external view returns (address);

  function allMarkets() external view returns (address[] memory);

  function marketListOf(address account) external view returns (address[] memory);

  function marketInfoOf(address lToken) external view returns (Constant.MarketInfo memory);

  function checkMembership(address account, address lToken) external view returns (bool);

  function accountLiquidityOf(
    address account
  ) external view returns (uint256 collateralInUSD, uint256 supplyInUSD, uint256 borrowInUSD);

  function closeFactor() external view returns (uint256);

  function liquidationIncentive() external view returns (uint256);

  function enterMarkets(address[] memory lTokens) external;

  function exitMarket(address lToken) external;

  function supply(address lToken, uint256 underlyingAmount) external payable returns (uint256);

  function supplyBehalf(address account, address lToken, uint256 underlyingAmount) external payable returns (uint256);

  function redeemToken(address lToken, uint256 lTokenAmount) external returns (uint256 redeemed);

  function redeemUnderlying(address lToken, uint256 underlyingAmount) external returns (uint256 redeemed);

  function borrow(address lToken, uint256 amount) external;

  function borrowBehalf(address borrower, address lToken, uint256 amount) external;

  function repayBorrow(address lToken, uint256 amount) external payable;

  function liquidateBorrow(
    address lTokenBorrowed,
    address lTokenCollateral,
    address borrower,
    uint256 amount
  ) external payable;

  function claimLab() external;

  function claimLab(address market) external;

  function transferTokens(address spender, address src, address dst, uint256 amount) external;

  function compoundLab(uint256 lockDuration) external;
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;

interface IRateModel {
  function getBorrowRate(uint256 cash, uint256 borrows, uint256 reserves) external view returns (uint256);

  function getSupplyRate(
    uint256 cash,
    uint256 borrows,
    uint256 reserves,
    uint256 reserveFactor
  ) external view returns (uint256);
}

// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.4.0;

interface IBEP20 {
  /**
   * @dev Returns the amount of tokens in existence.
   */
  function totalSupply() external view returns (uint256);

  /**
   * @dev Returns the token decimals.
   */
  function decimals() external view returns (uint8);

  /**
   * @dev Returns the token symbol.
   */
  function symbol() external view returns (string memory);

  /**
   * @dev Returns the token name.
   */
  function name() external view returns (string memory);

  /**
   * @dev Returns the bep token owner.
   */
  function getOwner() external view returns (address);

  /**
   * @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: UNLICENSED
pragma solidity ^0.6.12;

interface IRebateDistributor {
  function setKeeper(address _keeper) external;

  function pause() external;

  function unpause() external;

  function updateAdminFeeRate(uint256 newAdminFeeRate) external;

  function checkpoint() external;

  function weeklyRebatePool() external view returns (uint256);

  function weeklyProfitOfVP(uint256 vp) external view returns (uint256);

  function weeklyProfitOf(address account) external view returns (uint256);

  function indicativeAPR() external view returns (uint256);

  function indicativeAPROf(uint256 amount, uint256 lockDuration) external view returns (uint256);

  function indicativeAPROfUser(address account) external view returns (uint256);

  function accruedRebates(address account) external view returns (uint256, uint256, uint256[] memory);

  function claimRebates() external returns (uint256, uint256, uint256[] memory);

  function claimAdminRebates() external returns (uint256, uint256[] memory);

  function addLABToRebatePool(uint256 amount) external;

  function addMarketUTokenToRebatePool(address lToken, uint256 uAmount) external payable;
}

File 12 of 16 : ILToken.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

import "../library/Constant.sol";

interface ILToken {
  function underlying() external view returns (address);

  function totalSupply() external view returns (uint256);

  function accountSnapshot(address account) external view returns (Constant.AccountSnapshot memory);

  function underlyingBalanceOf(address account) external view returns (uint256);

  function borrowBalanceOf(address account) external view returns (uint256);

  function totalBorrow() external view returns (uint256);

  function _totalBorrow() external view returns (uint256);

  function totalReserve() external view returns (uint256);

  function reserveFactor() external view returns (uint256);

  function lastAccruedTime() external view returns (uint256);

  function accInterestIndex() external view returns (uint256);

  function exchangeRate() external view returns (uint256);

  function getCash() external view returns (uint256);

  function getRateModel() external view returns (address);

  function getAccInterestIndex() external view returns (uint256);

  function accruedAccountSnapshot(address account) external returns (Constant.AccountSnapshot memory);

  function accruedBorrowBalanceOf(address account) external returns (uint256);

  function accruedTotalBorrow() external returns (uint256);

  function accruedExchangeRate() external returns (uint256);

  function approve(address spender, uint256 amount) external returns (bool);

  function allowance(address owner, address spender) external view returns (uint256);

  function balanceOf(address account) external view returns (uint256);

  function transfer(address dst, uint256 amount) external returns (bool);

  function transferFrom(address src, address dst, uint256 amount) external returns (bool);

  function supply(address account, uint256 underlyingAmount) external payable returns (uint256);

  function supplyBehalf(address account, address supplier, uint256 underlyingAmount) external payable returns (uint256);

  function redeemToken(address account, uint256 lTokenAmount) external returns (uint256);

  function redeemUnderlying(address account, uint256 underlyingAmount) external returns (uint256);

  function borrow(address account, uint256 amount) external returns (uint256);

  function borrowBehalf(address account, address borrower, uint256 amount) external returns (uint256);

  function repayBorrow(address account, uint256 amount) external payable returns (uint256);

  function liquidateBorrow(
    address lTokenCollateral,
    address liquidator,
    address borrower,
    uint256 amount
  ) external payable returns (uint256 seizeLAmount, uint256 rebateLAmount, uint256 liquidatorLAmount);

  function seize(address liquidator, address borrower, uint256 lTokenAmount) external;

  function withdrawReserves() external;

  function transferTokensInternal(address spender, address src, address dst, uint256 amount) external;
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../utils/Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 15 of 16 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"ammount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accountBorrow","type":"uint256"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"lTokenCollateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"seizeAmount","type":"uint256"}],"name":"LiquidateBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lTokenAmount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"payer","type":"address"},{"indexed":false,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accountBorrow","type":"uint256"}],"name":"RepayBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_totalBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accInterestIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"accountSnapshot","outputs":[{"components":[{"internalType":"uint256","name":"lTokenBalance","type":"uint256"},{"internalType":"uint256","name":"borrowBalance","type":"uint256"},{"internalType":"uint256","name":"exchangeRate","type":"uint256"}],"internalType":"struct Constant.AccountSnapshot","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"accruedAccountSnapshot","outputs":[{"components":[{"internalType":"uint256","name":"lTokenBalance","type":"uint256"},{"internalType":"uint256","name":"borrowBalance","type":"uint256"},{"internalType":"uint256","name":"exchangeRate","type":"uint256"}],"internalType":"struct Constant.AccountSnapshot","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"accruedBorrowBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accruedExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accruedTotalBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"borrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"borrowBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"borrowBehalf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"core","outputs":[{"internalType":"contract ICore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAccInterestIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRateModel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastAccruedTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lTokenCollateral","type":"address"},{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"liquidateBorrow","outputs":[{"internalType":"uint256","name":"seizeLAmount","type":"uint256"},{"internalType":"uint256","name":"rebateLAmount","type":"uint256"},{"internalType":"uint256","name":"liquidatorLAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rateModel","outputs":[{"internalType":"contract IRateModel","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebateDistributor","outputs":[{"internalType":"contract IRebateDistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"redeemer","type":"address"},{"internalType":"uint256","name":"lAmount","type":"uint256"}],"name":"redeemToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"redeemer","type":"address"},{"internalType":"uint256","name":"uAmount","type":"uint256"}],"name":"redeemUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"repayBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"reserveFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"liquidator","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"uint256","name":"lAmount","type":"uint256"}],"name":"seize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_core","type":"address"}],"name":"setCore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rateModel","type":"address"}],"name":"setRateModel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rebateDistributor","type":"address"}],"name":"setRebateDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reserveFactor","type":"uint256"}],"name":"setReserveFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_underlying","type":"address"}],"name":"setUnderlying","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"uAmount","type":"uint256"}],"name":"supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"supplier","type":"address"},{"internalType":"uint256","name":"uAmount","type":"uint256"}],"name":"supplyBehalf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferTokensInternal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"underlyingBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b5060006200001e62000072565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001805562000076565b3390565b614fce80620000866000396000f3fe6080604052600436106103035760003560e01c8063830cbbbd11610190578063b2a02ff1116100dc578063dd62ed3e11610095578063ecdaff7e1161006f578063ecdaff7e14610853578063f2b9fdb814610868578063f2f4eb261461087b578063f2fde38b146108905761030a565b8063dd62ed3e146107f1578063de02d64214610811578063e61604cf146108315761030a565b8063b2a02ff114610754578063bba6157814610774578063bdb2321f14610787578063c23379da146107a7578063d49187b3146107c7578063d88c3f22146107dc5761030a565b8063935a8b84116101495780639951c2cf116101235780639951c2cf146106f7578063a10884591461070c578063a9059cbb14610721578063abdb5ea8146107415761030a565b8063935a8b84146106a257806395d89b41146106c257806396294178146106d75761030a565b8063830cbbbd146106035780638399c0ba14610623578063893d20e8146106435780638b9db037146106585780638da5cb5b1461066d57806392fa4e8e146106825761030a565b80633ba0b9a91161024f5780636f307dc3116102085780637f9028c8116101e25780637f9028c8146105995780637ffc93b1146105b957806380009630146105ce5780638285ef40146105ee5761030a565b80636f307dc31461054f57806370a0823114610564578063715018a6146105845761030a565b80633ba0b9a9146104b95780634322b714146104ce5780634b8a3529146104e35780634c68df671461050357806352e97efd1461051857806359341a1a1461052d5761030a565b80631c446983116102bc578063313ce56711610296578063313ce5671461044257806333f9c87614610464578063374c49b4146104845780633b1d21a2146104a45761030a565b80631c446983146103ed57806323b872dd1461040d57806326d5f6411461042d5761030a565b8063014a296f1461030f57806306fdde0314610345578063095ea7b314610367578063158ef93e146103945780631624f6c6146103a957806318160ddd146103cb5761030a565b3661030a57005b600080fd5b34801561031b57600080fd5b5061032f61032a36600461443e565b6108b0565b60405161033c9190614eb9565b60405180910390f35b34801561035157600080fd5b5061035a6108fe565b60405161033c919061477f565b34801561037357600080fd5b5061038761038236600461453e565b61098c565b60405161033c9190614774565b3480156103a057600080fd5b506103876109f7565b3480156103b557600080fd5b506103c96103c4366004614589565b610a05565b005b3480156103d757600080fd5b506103e0610ac7565b60405161033c9190614eda565b3480156103f957600080fd5b506103c9610408366004614603565b610acd565b34801561041957600080fd5b506103876104283660046144fe565b610caa565b34801561043957600080fd5b506103c9610e9b565b34801561044e57600080fd5b5061045761107b565b60405161033c9190614ef9565b34801561047057600080fd5b506103e061047f3660046144fe565b611084565b34801561049057600080fd5b506103e061049f36600461443e565b611289565b3480156104b057600080fd5b506103e06112eb565b3480156104c557600080fd5b506103e06112fb565b3480156104da57600080fd5b506103e061136b565b3480156104ef57600080fd5b506103e06104fe36600461453e565b611371565b34801561050f57600080fd5b506103e0611575565b34801561052457600080fd5b506103e061157b565b34801561053957600080fd5b50610542611581565b60405161033c919061467c565b34801561055b57600080fd5b50610542611590565b34801561057057600080fd5b506103e061057f36600461443e565b61159f565b34801561059057600080fd5b506103c96115ba565b3480156105a557600080fd5b506103c96105b436600461443e565b611643565b3480156105c557600080fd5b506103e061181c565b3480156105da57600080fd5b506103c96105e936600461443e565b611822565b3480156105fa57600080fd5b506103e06118d2565b34801561060f57600080fd5b506103e061061e36600461453e565b6118eb565b34801561062f57600080fd5b506103e061063e36600461443e565b611a7c565b34801561064f57600080fd5b50610542611c1d565b34801561066457600080fd5b506103e0611c27565b34801561067957600080fd5b50610542611d83565b34801561068e57600080fd5b5061032f61069d36600461443e565b611d92565b3480156106ae57600080fd5b506103e06106bd36600461443e565b611f72565b3480156106ce57600080fd5b5061035a611faa565b3480156106e357600080fd5b506103e06106f236600461453e565b612005565b34801561070357600080fd5b506103e061218f565b34801561071857600080fd5b50610542612195565b34801561072d57600080fd5b5061038761073c36600461453e565b6121a4565b6103e061074f36600461453e565b612394565b34801561076057600080fd5b506103c961076f3660046144fe565b61254e565b6103e06107823660046144fe565b612795565b34801561079357600080fd5b506103c96107a236600461443e565b612a09565b3480156107b357600080fd5b506103c96107c23660046144ae565b612ab9565b3480156107d357600080fd5b50610542612d94565b3480156107e857600080fd5b506103e0612da3565b3480156107fd57600080fd5b506103e061080c366004614476565b612dbf565b34801561081d57600080fd5b506103c961082c36600461443e565b612dea565b61084461083f3660046144ae565b612e71565b60405161033c93929190614ee3565b34801561085f57600080fd5b506103e061326d565b6103e061087636600461453e565b6133c8565b34801561088757600080fd5b5061054261363b565b34801561089c57600080fd5b506103c96108ab36600461443e565b61364a565b6108b861430c565b6108c061430c565b6001600160a01b03831660009081526009602052604090205481526108e483611289565b60208201526108f16112fb565b604082015290505b919050565b600e805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109845780601f1061095957610100808354040283529160200191610984565b820191906000526020600020905b81548152906001019060200180831161096757829003601f168201915b505050505081565b3360008181526011602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906109e5908690614eda565b60405180910390a35060015b92915050565b601054610100900460ff1681565b610a0d61370a565b6001600160a01b0316610a1e611d83565b6001600160a01b031614610a4d5760405162461bcd60e51b8152600401610a4490614c15565b60405180910390fd5b601054610100900460ff1615610a755760405162461bcd60e51b8152600401610a4490614b1a565b610a7d61370e565b8251610a9090600e90602086019061432d565b508151610aa490600f90602085019061432d565b506010805461ff001960ff90931660ff1990911617919091166101001790555050565b60065481565b600c5442118015610ae857506003546001600160a01b031615155b15610c3e576003546000906001600160a01b03166315f24053610b09613720565b6008546007546040518463ffffffff1660e01b8152600401610b2d93929190614ee3565b60206040518083038186803b158015610b4557600080fd5b505afa158015610b59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7d919061461b565b90506000610ba0610b99600c54426137bf90919063ffffffff16565b83906137e7565b90506000610bcb670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b90613821565b600854909150610bdb9082613853565b600855600b54610c0790610bfe90670de0b6b3a764000090610bc59085906137e7565b60075490613853565b600755600d54610c3390610c2a90670de0b6b3a764000090610bc59086906137e7565b600d5490613853565b600d55505042600c55505b610c4661370a565b6001600160a01b0316610c57611d83565b6001600160a01b031614610c7d5760405162461bcd60e51b8152600401610a4490614c15565b670de0b6b3a7640000811115610ca55760405162461bcd60e51b8152600401610a4490614ddd565b600b55565b6000600c5442118015610cc757506003546001600160a01b031615155b15610dfe576003546000906001600160a01b03166315f24053610ce8613720565b6008546007546040518463ffffffff1660e01b8152600401610d0c93929190614ee3565b60206040518083038186803b158015610d2457600080fd5b505afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c919061461b565b90506000610d78610b99600c54426137bf90919063ffffffff16565b90506000610d9d670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150610dad9082613853565b600855600b54610dd090610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54610df390610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b60026001541415610e215760405162461bcd60e51b8152600401610a4490614e14565b60026001819055546040516368155ec160e01b81526001600160a01b03909116906368155ec190610e5c903390889088908890600401614690565b600060405180830381600087803b158015610e7657600080fd5b505af1158015610e8a573d6000803e3d6000fd5b505060018080559695505050505050565b600c5442118015610eb657506003546001600160a01b031615155b15610fed576003546000906001600160a01b03166315f24053610ed7613720565b6008546007546040518463ffffffff1660e01b8152600401610efb93929190614ee3565b60206040518083038186803b158015610f1357600080fd5b505afa158015610f27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4b919061461b565b90506000610f67610b99600c54426137bf90919063ffffffff16565b90506000610f8c670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150610f9c9082613853565b600855600b54610fbf90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54610fe290610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6004546001600160a01b031633146110175760405162461bcd60e51b8152600401610a4490614d51565b6002600154141561103a5760405162461bcd60e51b8152600401610a4490614e14565b600260015560075461104a6112eb565b10611075576007548015611073576000600755600454611073906001600160a01b031682613878565b505b60018055565b60105460ff1681565b6000600c54421180156110a157506003546001600160a01b031615155b156111d8576003546000906001600160a01b03166315f240536110c2613720565b6008546007546040518463ffffffff1660e01b81526004016110e693929190614ee3565b60206040518083038186803b1580156110fe57600080fd5b505afa158015611112573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611136919061461b565b90506000611152610b99600c54426137bf90919063ffffffff16565b90506000611177670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506111879082613853565b600855600b546111aa90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546111cd90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146112025760405162461bcd60e51b8152600401610a4490614e4b565b8161120b6112eb565b10156112295760405162461bcd60e51b8152600401610a4490614c4a565b611235838360006138b2565b61123f8483613878565b7fe1979fe4c35e0cef342fef5668e2c8e7a7e9f5d5d1ca8fee0ac6c427fa4153af838361126b86611289565b60405161127a93929190614753565b60405180910390a15092915050565b600061129361430c565b61129b61395a565b6001600160a01b0384166000908152600a602052604090208054919250906112c8576000925050506108f9565b6001810154604083015182546112e39291610bc591906137e7565b949350505050565b60006112f5613720565b90505b90565b6000600654600014156113175750670de0b6b3a76400006112f8565b61131f61430c565b61132761395a565b9050611365600654610bc5670de0b6b3a764000061135f85602001516113598760000151611353613720565b90613853565b906137bf565b906137e7565b91505090565b600b5481565b6000600c544211801561138e57506003546001600160a01b031615155b156114c5576003546000906001600160a01b03166315f240536113af613720565b6008546007546040518463ffffffff1660e01b81526004016113d393929190614ee3565b60206040518083038186803b1580156113eb57600080fd5b505afa1580156113ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611423919061461b565b9050600061143f610b99600c54426137bf90919063ffffffff16565b90506000611464670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506114749082613853565b600855600b5461149790610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546114ba90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146114ef5760405162461bcd60e51b8152600401610a4490614e4b565b816114f86112eb565b10156115165760405162461bcd60e51b8152600401610a4490614c4a565b611522838360006138b2565b61152c8383613878565b7fe1979fe4c35e0cef342fef5668e2c8e7a7e9f5d5d1ca8fee0ac6c427fa4153af838361155886611289565b60405161156793929190614753565b60405180910390a150919050565b60075481565b60085481565b6004546001600160a01b031681565b6005546001600160a01b031681565b6001600160a01b031660009081526009602052604090205490565b6115c261370a565b6001600160a01b03166115d3611d83565b6001600160a01b0316146115f95760405162461bcd60e51b8152600401610a4490614c15565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600c544211801561165e57506003546001600160a01b031615155b15611795576003546000906001600160a01b03166315f2405361167f613720565b6008546007546040518463ffffffff1660e01b81526004016116a393929190614ee3565b60206040518083038186803b1580156116bb57600080fd5b505afa1580156116cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f3919061461b565b9050600061170f610b99600c54426137bf90919063ffffffff16565b90506000611734670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506117449082613853565b600855600b5461176790610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461178a90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b61179d61370a565b6001600160a01b03166117ae611d83565b6001600160a01b0316146117d45760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b0381166117fa5760405162461bcd60e51b8152600401610a4490614cc3565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600c5481565b61182a61370a565b6001600160a01b031661183b611d83565b6001600160a01b0316146118615760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b0381166118875760405162461bcd60e51b8152600401610a4490614866565b6002546001600160a01b0316156118b05760405162461bcd60e51b8152600401610a44906148d4565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006118dc61430c565b6118e461395a565b5191505090565b6000600c544211801561190857506003546001600160a01b031615155b15611a3f576003546000906001600160a01b03166315f24053611929613720565b6008546007546040518463ffffffff1660e01b815260040161194d93929190614ee3565b60206040518083038186803b15801561196557600080fd5b505afa158015611979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199d919061461b565b905060006119b9610b99600c54426137bf90919063ffffffff16565b905060006119de670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506119ee9082613853565b600855600b54611a1190610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611a3490610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b03163314611a695760405162461bcd60e51b8152600401610a4490614e4b565b611a7583836000613acc565b9392505050565b6000600c5442118015611a9957506003546001600160a01b031615155b15611bd0576003546000906001600160a01b03166315f24053611aba613720565b6008546007546040518463ffffffff1660e01b8152600401611ade93929190614ee3565b60206040518083038186803b158015611af657600080fd5b505afa158015611b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2e919061461b565b90506000611b4a610b99600c54426137bf90919063ffffffff16565b90506000611b6f670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150611b7f9082613853565b600855600b54611ba290610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611bc590610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6001600160a01b0382166000908152600a60205260409020600181015415611c16576001810154600d548254611c0b9291610bc591906137e7565b8155600d5460018201555b5492915050565b60006112f5611d83565b6000600c5442118015611c4457506003546001600160a01b031615155b15611d7b576003546000906001600160a01b03166315f24053611c65613720565b6008546007546040518463ffffffff1660e01b8152600401611c8993929190614ee3565b60206040518083038186803b158015611ca157600080fd5b505afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd9919061461b565b90506000611cf5610b99600c54426137bf90919063ffffffff16565b90506000611d1a670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150611d2a9082613853565b600855600b54611d4d90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611d7090610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6112f56112fb565b6000546001600160a01b031690565b611d9a61430c565b600c5442118015611db557506003546001600160a01b031615155b15611eec576003546000906001600160a01b03166315f24053611dd6613720565b6008546007546040518463ffffffff1660e01b8152600401611dfa93929190614ee3565b60206040518083038186803b158015611e1257600080fd5b505afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a919061461b565b90506000611e66610b99600c54426137bf90919063ffffffff16565b90506000611e8b670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150611e9b9082613853565b600855600b54611ebe90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611ee190610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b611ef461430c565b6001600160a01b0383166000908152600a60205260409020600181015415611f3a576001810154600d548254611f2f9291610bc591906137e7565b8155600d5460018201555b6001600160a01b0384166000908152600960209081526040909120548352815490830152611f666112fb565b60408301525092915050565b60006109f1670de0b6b3a7640000610bc5611f8b6112fb565b6001600160a01b038616600090815260096020526040902054906137e7565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109845780601f1061095957610100808354040283529160200191610984565b6000600c544211801561202257506003546001600160a01b031615155b15612159576003546000906001600160a01b03166315f24053612043613720565b6008546007546040518463ffffffff1660e01b815260040161206793929190614ee3565b60206040518083038186803b15801561207f57600080fd5b505afa158015612093573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b7919061461b565b905060006120d3610b99600c54426137bf90919063ffffffff16565b905060006120f8670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506121089082613853565b600855600b5461212b90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461214e90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146121835760405162461bcd60e51b8152600401610a4490614e4b565b611a7583600084613acc565b600d5481565b6003546001600160a01b031681565b6000600c54421180156121c157506003546001600160a01b031615155b156122f8576003546000906001600160a01b03166315f240536121e2613720565b6008546007546040518463ffffffff1660e01b815260040161220693929190614ee3565b60206040518083038186803b15801561221e57600080fd5b505afa158015612232573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612256919061461b565b90506000612272610b99600c54426137bf90919063ffffffff16565b90506000612297670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506122a79082613853565b600855600b546122ca90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546122ed90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002600154141561231b5760405162461bcd60e51b8152600401610a4490614e14565b60026001819055546040516368155ec160e01b81526001600160a01b03909116906368155ec190612356903390819088908890600401614690565b600060405180830381600087803b15801561237057600080fd5b505af1158015612384573d6000803e3d6000fd5b5050600180805595945050505050565b6000600c54421180156123b157506003546001600160a01b031615155b156124e8576003546000906001600160a01b03166315f240536123d2613720565b6008546007546040518463ffffffff1660e01b81526004016123f693929190614ee3565b60206040518083038186803b15801561240e57600080fd5b505afa158015612422573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612446919061461b565b90506000612462610b99600c54426137bf90919063ffffffff16565b90506000612487670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506124979082613853565b600855600b546124ba90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546124dd90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146125125760405162461bcd60e51b8152600401610a4490614e4b565b6000198214156125285761252583611289565b91505b600554611a7590849081906001600160a01b0316156125475784612549565b345b613da9565b600c544211801561256957506003546001600160a01b031615155b156126a0576003546000906001600160a01b03166315f2405361258a613720565b6008546007546040518463ffffffff1660e01b81526004016125ae93929190614ee3565b60206040518083038186803b1580156125c657600080fd5b505afa1580156125da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125fe919061461b565b9050600061261a610b99600c54426137bf90919063ffffffff16565b9050600061263f670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b60085490915061264f9082613853565b600855600b5461267290610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461269590610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146126ca5760405162461bcd60e51b8152600401610a4490614e4b565b600260015414156126ed5760405162461bcd60e51b8152600401610a4490614e14565b60026001556001600160a01b03821660009081526009602052604090205461271590826137bf565b6001600160a01b0380841660009081526009602052604080822093909355908516815220546127449082613853565b6001600160a01b038085166000818152600960205260409081902093909355915190841690600080516020614f7983398151915290612784908590614eda565b60405180910390a350506001805550565b6000600c54421180156127b257506003546001600160a01b031615155b156128e9576003546000906001600160a01b03166315f240536127d3613720565b6008546007546040518463ffffffff1660e01b81526004016127f793929190614ee3565b60206040518083038186803b15801561280f57600080fd5b505afa158015612823573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612847919061461b565b90506000612863610b99600c54426137bf90919063ffffffff16565b90506000612888670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506128989082613853565b600855600b546128bb90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546128de90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146129135760405162461bcd60e51b8152600401610a4490614e4b565b600061291d6112fb565b6005549091506001600160a01b0316156129375782612939565b345b92506129458584613e58565b9250600061295f82610bc586670de0b6b3a76400006137e7565b9050600081116129815760405162461bcd60e51b8152600401610a4490614a75565b61298d85826000613fe4565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688585826040516129be92919061473a565b60405180910390a1846001600160a01b031660006001600160a01b0316600080516020614f79833981519152836040516129f89190614eda565b60405180910390a395945050505050565b612a1161370a565b6001600160a01b0316612a22611d83565b6001600160a01b031614612a485760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b038116612a6e5760405162461bcd60e51b8152600401610a44906149fb565b6005546001600160a01b031615612a975760405162461bcd60e51b8152600401610a4490614aac565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b03163314612ae35760405162461bcd60e51b8152600401610a4490614e4b565b816001600160a01b0316836001600160a01b031614158015612c075750600260009054906101000a90046001600160a01b03166001600160a01b0316633a5381b56040518163ffffffff1660e01b815260040160206040518083038186803b158015612b4e57600080fd5b505afa158015612b62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b86919061445a565b6001600160a01b031663eabe7d913085846040518463ffffffff1660e01b8152600401612bb5939291906146ba565b602060405180830381600087803b158015612bcf57600080fd5b505af1158015612be3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c079190614569565b612c235760405162461bcd60e51b8152600401610a449061490b565b80612c405760405162461bcd60e51b8152600401610a4490614839565b6000836001600160a01b0316856001600160a01b031614612c86576001600160a01b03808516600090815260116020908152604080832093891683529290522054612c8a565b6000195b90506000612cb383604051806060016040528060298152602001614f5060299139849190614059565b6001600160a01b038616600090815260096020526040902054909150612cd990846137bf565b6001600160a01b038087166000908152600960205260408082209390935590861681522054612d089084613853565b6001600160a01b0385166000908152600960205260409020556000198214612d53576001600160a01b038086166000908152601160209081526040808320938a168352929052208190555b836001600160a01b0316856001600160a01b0316600080516020614f7983398151915285604051612d849190614eda565b60405180910390a3505050505050565b6003546001600160a01b031690565b6000612dad61430c565b612db561395a565b6040015191505090565b6001600160a01b03918216600090815260116020908152604080832093909416825291909152205490565b612df261370a565b6001600160a01b0316612e03611d83565b6001600160a01b031614612e295760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b038116612e4f5760405162461bcd60e51b8152600401610a4490614d06565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000600c5442118015612e9157506003546001600160a01b031615155b15612fc8576003546000906001600160a01b03166315f24053612eb2613720565b6008546007546040518463ffffffff1660e01b8152600401612ed693929190614ee3565b60206040518083038186803b158015612eee57600080fd5b505afa158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f26919061461b565b90506000612f42610b99600c54426137bf90919063ffffffff16565b90506000612f67670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150612f779082613853565b600855600b54612f9a90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54612fbd90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b03163314612ff25760405162461bcd60e51b8152600401610a4490614e4b565b856001600160a01b0316856001600160a01b031614156130245760405162461bcd60e51b8152600401610a44906147b2565b6005546001600160a01b03161561303b578361303d565b345b935061304a868686613da9565b935060008411801561305d575060001984105b6130795760405162461bcd60e51b8152600401610a4490614e82565b600260009054906101000a90046001600160a01b03166001600160a01b0316633a5381b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156130c757600080fd5b505afa1580156130db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ff919061445a565b6001600160a01b031663f643b5df3089876040518463ffffffff1660e01b815260040161312e939291906146ba565b606060405180830381600087803b15801561314857600080fd5b505af115801561315c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131809190614633565b6040516370a0823160e01b8152929550909350915083906001600160a01b038916906370a08231906131b690899060040161467c565b60206040518083038186803b1580156131ce57600080fd5b505afa1580156131e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613206919061461b565b10156132245760405162461bcd60e51b8152600401610a4490614bb7565b7f298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb528686868a8760405161325b9594939291906146de565b60405180910390a19450945094915050565b6000600c544211801561328a57506003546001600160a01b031615155b156133c1576003546000906001600160a01b03166315f240536132ab613720565b6008546007546040518463ffffffff1660e01b81526004016132cf93929190614ee3565b60206040518083038186803b1580156132e757600080fd5b505afa1580156132fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331f919061461b565b9050600061333b610b99600c54426137bf90919063ffffffff16565b90506000613360670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506133709082613853565b600855600b5461339390610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546133b690610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b5060085490565b6000600c54421180156133e557506003546001600160a01b031615155b1561351c576003546000906001600160a01b03166315f24053613406613720565b6008546007546040518463ffffffff1660e01b815260040161342a93929190614ee3565b60206040518083038186803b15801561344257600080fd5b505afa158015613456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347a919061461b565b90506000613496610b99600c54426137bf90919063ffffffff16565b905060006134bb670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506134cb9082613853565b600855600b546134ee90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461351190610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146135465760405162461bcd60e51b8152600401610a4490614e4b565b60006135506112fb565b6005549091506001600160a01b03161561356a578261356c565b345b92506135788484613e58565b9250600061359282610bc586670de0b6b3a76400006137e7565b9050600081116135b45760405162461bcd60e51b8152600401610a4490614a75565b6135c085826000613fe4565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688585826040516135f192919061473a565b60405180910390a1846001600160a01b031660006001600160a01b0316600080516020614f798339815191528360405161362b9190614eda565b60405180910390a3949350505050565b6002546001600160a01b031681565b61365261370a565b6001600160a01b0316613663611d83565b6001600160a01b0316146136895760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b0381166136af5760405162461bcd60e51b8152600401610a44906147f3565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b42600c55670de0b6b3a7640000600d55565b6005546000906001600160a01b0316156137b9576005546040516370a0823160e01b81526001600160a01b03909116906370a082319061376490309060040161467c565b60206040518083038186803b15801561377c57600080fd5b505afa158015613790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137b4919061461b565b6112f5565b6112f547345b6000828211156137e15760405162461bcd60e51b8152600401610a44906149c4565b50900390565b6000826137f6575060006109f1565b8282028284828161380357fe5b0414611a755760405162461bcd60e51b8152600401610a4490614b76565b60008082116138425760405162461bcd60e51b8152600401610a4490614a3e565b81838161384b57fe5b049392505050565b600082820183811015611a755760405162461bcd60e51b8152600401610a449061489d565b6005546001600160a01b0316613897576138928282614085565b6138ae565b6005546138ae906001600160a01b03168383614117565b5050565b6001600160a01b0383166000908152600a6020526040902060018101546138dc57600d5460018201555b61390582611359856113538560010154610bc5600d5488600001546137e790919063ffffffff16565b8155600d5460018201556008546139229083906113599086613853565b60085580546103e811613936578054613939565b60005b81556008546103e81161394e57600854613951565b60005b60085550505050565b61396261430c565b61396a61430c565b60085481526007546020820152600d546040820152600c544211801561399257506000600854115b156112f5576003546000906001600160a01b03166315f240536139b3613720565b6008546007546040518463ffffffff1660e01b81526004016139d793929190614ee3565b60206040518083038186803b1580156139ef57600080fd5b505afa158015613a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a27919061461b565b90506000613a43610b99600c54426137bf90919063ffffffff16565b90506000613a68670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150613a789082613853565b8452600b54613a9a90610bfe90670de0b6b3a764000090610bc59085906137e7565b6020850152600d54613abf90610c2a90670de0b6b3a764000090610bc59086906137e7565b6040850152505050905090565b6000821580613ad9575081155b613af55760405162461bcd60e51b8152600401610a4490614942565b826006541015613b175760405162461bcd60e51b8152600401610a4490614ae3565b81613b206112eb565b101580613b2b575081155b613b475760405162461bcd60e51b8152600401610a4490614c8c565b613b65670de0b6b3a7640000610bc5613b5e6112fb565b86906137e7565b613b6d6112eb565b101580613b78575082155b613b945760405162461bcd60e51b8152600401610a4490614c8c565b6000808411613bbf57613bba613ba86112fb565b610bc585670de0b6b3a76400006137e7565b613bc1565b835b90506000808511613bd25783613bf0565b613bf0670de0b6b3a7640000610bc5613be96112fb565b88906137e7565b9050600260009054906101000a90046001600160a01b03166001600160a01b0316633a5381b56040518163ffffffff1660e01b815260040160206040518083038186803b158015613c4057600080fd5b505afa158015613c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c78919061445a565b6001600160a01b031663eabe7d913088856040518463ffffffff1660e01b8152600401613ca7939291906146ba565b602060405180830381600087803b158015613cc157600080fd5b505af1158015613cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cf99190614569565b613d155760405162461bcd60e51b8152600401610a4490614b47565b613d2186600084613fe4565b613d2b8682613878565b60006001600160a01b0316866001600160a01b0316600080516020614f7983398151915284604051613d5d9190614eda565b60405180910390a37fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929868284604051613d9893929190614753565b60405180910390a195945050505050565b600080613db584611289565b90506000613dc38285614205565b9050613dcf8682613e58565b9050613ddd856000836138b2565b6005546001600160a01b0316613e1b576000818511613dfd576000613e07565b613e0785836137bf565b90508015613e1957613e198782613878565b505b7fa9a154237a69922f8860321d1fec1624a5dbe8a8af89a3dd3d7a759f6c8080d8868683613e4889611289565b604051613d989493929190614711565b6005546000906001600160a01b0316613e9c5781341015613e8b5760405162461bcd60e51b8152600401610a4490614994565b613e953483614205565b90506109f1565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613ecd90309060040161467c565b60206040518083038186803b158015613ee557600080fd5b505afa158015613ef9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1d919061461b565b600554909150613f38906001600160a01b031685308661421b565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613f6990309060040161467c565b60206040518083038186803b158015613f8157600080fd5b505afa158015613f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb9919061461b565b905083613fc682846137bf565b1115613fd157600080fd5b613fdb81836137bf565b925050506109f1565b6001600160a01b03831660009081526009602052604090205461400d9082906113599085613853565b6001600160a01b0384166000908152600960205260409020556006546140399082906113599085613853565b60068190556103e81161404e57600654614051565b60005b600655505050565b6000818484111561407d5760405162461bcd60e51b8152600401610a44919061477f565b505050900390565b604080516000808252602082019092526001600160a01b0384169083906040516140af9190614660565b60006040518083038185875af1925050503d80600081146140ec576040519150601f19603f3d011682016040523d82523d6000602084013e6140f1565b606091505b50509050806141125760405162461bcd60e51b8152600401610a4490614d88565b505050565b60006060846001600160a01b031663a9059cbb858560405160240161413d92919061473a565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516141769190614660565b6000604051808303816000865af19150503d80600081146141b3576040519150601f19603f3d011682016040523d82523d6000602084013e6141b8565b606091505b50915091508180156141e25750805115806141e25750808060200190518101906141e29190614569565b6141fe5760405162461bcd60e51b8152600401610a4490614bee565b5050505050565b60008183106142145781611a75565b5090919050565b60006060856001600160a01b03166323b872dd868686604051602401614243939291906146ba565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161427c9190614660565b6000604051808303816000865af19150503d80600081146142b9576040519150601f19603f3d011682016040523d82523d6000602084013e6142be565b606091505b50915091508180156142e85750805115806142e85750808060200190518101906142e89190614569565b6143045760405162461bcd60e51b8152600401610a4490614db2565b505050505050565b60405180606001604052806000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061436e57805160ff191683800117855561439b565b8280016001018555821561439b579182015b8281111561439b578251825591602001919060010190614380565b506143a79291506143ab565b5090565b5b808211156143a757600081556001016143ac565b600082601f8301126143d0578081fd5b813567ffffffffffffffff808211156143e7578283fd5b604051601f8301601f191681016020018281118282101715614407578485fd5b60405282815292508284830160200186101561442257600080fd5b8260208601602083013760006020848301015250505092915050565b60006020828403121561444f578081fd5b8135611a7581614f37565b60006020828403121561446b578081fd5b8151611a7581614f37565b60008060408385031215614488578081fd5b823561449381614f37565b915060208301356144a381614f37565b809150509250929050565b600080600080608085870312156144c3578182fd5b84356144ce81614f37565b935060208501356144de81614f37565b925060408501356144ee81614f37565b9396929550929360600135925050565b600080600060608486031215614512578283fd5b833561451d81614f37565b9250602084013561452d81614f37565b929592945050506040919091013590565b60008060408385031215614550578182fd5b823561455b81614f37565b946020939093013593505050565b60006020828403121561457a578081fd5b81518015158114611a75578182fd5b60008060006060848603121561459d578283fd5b833567ffffffffffffffff808211156145b4578485fd5b6145c0878388016143c0565b945060208601359150808211156145d5578384fd5b506145e2868287016143c0565b925050604084013560ff811681146145f8578182fd5b809150509250925092565b600060208284031215614614578081fd5b5035919050565b60006020828403121561462c578081fd5b5051919050565b600080600060608486031215614647578283fd5b8351925060208401519150604084015190509250925092565b60008251614672818460208701614f07565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039586168152938516602085015260408401929092529092166060820152608081019190915260a00190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b600060208252825180602084015261479e816040850160208701614f07565b601f01601f19169190910160400192915050565b60208082526021908201527f4c546f6b656e3a2063616e6e6f74206c697175696461746520796f757273656c6040820152603360f91b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526013908201527213151bdad95b8e881e995c9bc8185b5bdd5b9d606a1b604082015260600190565b6020808252601d908201527f474d61726b65743a20696e76616c696420636f72652061646472657373000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526019908201527f474d61726b65743a20636f726520616c72656164792073657400000000000000604082015260600190565b60208082526017908201527f4c546f6b656e3a2063616e6e6f74207472616e73666572000000000000000000604082015260600190565b60208082526032908201527f4c546f6b656e3a206f6e65206f66206c416d6f756e74496e206f722075416d6f604082015271756e74496e206d757374206265207a65726f60701b606082015260800190565b602080825260169082015275098a8ded6cadc7440ecc2d8eaca40dad2e6dac2e8c6d60531b604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526023908201527f474d61726b65743a20696e76616c696420756e6465726c79696e67206164647260408201526265737360e81b606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526017908201527f4c546f6b656e3a20696e76616c6964206c416d6f756e74000000000000000000604082015260600190565b6020808252601f908201527f474d61726b65743a2073657420756e6465726c79696e6720616c726561647900604082015260600190565b6020808252601f908201527f4c546f6b656e3a206e6f7420656e6f75676820746f74616c20737570706c7900604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252601590820152744c546f6b656e3a2063616e6e6f742072656465656d60581b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601d908201527f4c546f6b656e3a20746f6f206d756368207365697a6520616d6f756e74000000604082015260600190565b6020808252600d908201526c10b9b0b332aa3930b739b332b960991b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f4c546f6b656e3a20626f72726f7720616d6f756e7420657863656564732063616040820152610e6d60f31b606082015260800190565b6020808252601d908201527f4c546f6b656e3a206e6f7420656e6f75676820756e6465726c79696e67000000604082015260600190565b60208082526023908201527f474d61726b65743a20696e76616c69642072617465206d6f64656c206164647260408201526265737360e81b606082015260800190565b6020808252602b908201527f474d61726b65743a20696e76616c69642072656261746520646973747269627560408201526a746f72206164647265737360a81b606082015260800190565b6020808252601e908201527f4c546f6b656e3a206f6e6c79205265626174654469737472696275746f720000604082015260600190565b60208082526010908201526f042e6c2cccaa8e4c2dce6cccae48aa8960831b604082015260600190565b60208082526011908201527021736166655472616e7366657246726f6d60781b604082015260600190565b6020808252601f908201527f474d61726b65743a20696e76616c6964207265736572766520666163746f7200604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601a908201527f4c546f6b656e3a206f6e6c7920436f726520436f6e7472616374000000000000604082015260600190565b6020808252601c908201527f4c546f6b656e3a20696e76616c696420726570617920616d6f756e7400000000604082015260600190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b9283526020830191909152604082015260600190565b60ff91909116815260200190565b60005b83811015614f22578181015183820152602001614f0a565b83811115614f31576000848401525b50505050565b6001600160a01b0381168114614f4c57600080fd5b5056fe4c546f6b656e3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220a620b1498c2e8c59ff692cc93f4c1b3d055e1596ab91b135450be21cd3237cf364736f6c634300060c0033

Deployed Bytecode

0x6080604052600436106103035760003560e01c8063830cbbbd11610190578063b2a02ff1116100dc578063dd62ed3e11610095578063ecdaff7e1161006f578063ecdaff7e14610853578063f2b9fdb814610868578063f2f4eb261461087b578063f2fde38b146108905761030a565b8063dd62ed3e146107f1578063de02d64214610811578063e61604cf146108315761030a565b8063b2a02ff114610754578063bba6157814610774578063bdb2321f14610787578063c23379da146107a7578063d49187b3146107c7578063d88c3f22146107dc5761030a565b8063935a8b84116101495780639951c2cf116101235780639951c2cf146106f7578063a10884591461070c578063a9059cbb14610721578063abdb5ea8146107415761030a565b8063935a8b84146106a257806395d89b41146106c257806396294178146106d75761030a565b8063830cbbbd146106035780638399c0ba14610623578063893d20e8146106435780638b9db037146106585780638da5cb5b1461066d57806392fa4e8e146106825761030a565b80633ba0b9a91161024f5780636f307dc3116102085780637f9028c8116101e25780637f9028c8146105995780637ffc93b1146105b957806380009630146105ce5780638285ef40146105ee5761030a565b80636f307dc31461054f57806370a0823114610564578063715018a6146105845761030a565b80633ba0b9a9146104b95780634322b714146104ce5780634b8a3529146104e35780634c68df671461050357806352e97efd1461051857806359341a1a1461052d5761030a565b80631c446983116102bc578063313ce56711610296578063313ce5671461044257806333f9c87614610464578063374c49b4146104845780633b1d21a2146104a45761030a565b80631c446983146103ed57806323b872dd1461040d57806326d5f6411461042d5761030a565b8063014a296f1461030f57806306fdde0314610345578063095ea7b314610367578063158ef93e146103945780631624f6c6146103a957806318160ddd146103cb5761030a565b3661030a57005b600080fd5b34801561031b57600080fd5b5061032f61032a36600461443e565b6108b0565b60405161033c9190614eb9565b60405180910390f35b34801561035157600080fd5b5061035a6108fe565b60405161033c919061477f565b34801561037357600080fd5b5061038761038236600461453e565b61098c565b60405161033c9190614774565b3480156103a057600080fd5b506103876109f7565b3480156103b557600080fd5b506103c96103c4366004614589565b610a05565b005b3480156103d757600080fd5b506103e0610ac7565b60405161033c9190614eda565b3480156103f957600080fd5b506103c9610408366004614603565b610acd565b34801561041957600080fd5b506103876104283660046144fe565b610caa565b34801561043957600080fd5b506103c9610e9b565b34801561044e57600080fd5b5061045761107b565b60405161033c9190614ef9565b34801561047057600080fd5b506103e061047f3660046144fe565b611084565b34801561049057600080fd5b506103e061049f36600461443e565b611289565b3480156104b057600080fd5b506103e06112eb565b3480156104c557600080fd5b506103e06112fb565b3480156104da57600080fd5b506103e061136b565b3480156104ef57600080fd5b506103e06104fe36600461453e565b611371565b34801561050f57600080fd5b506103e0611575565b34801561052457600080fd5b506103e061157b565b34801561053957600080fd5b50610542611581565b60405161033c919061467c565b34801561055b57600080fd5b50610542611590565b34801561057057600080fd5b506103e061057f36600461443e565b61159f565b34801561059057600080fd5b506103c96115ba565b3480156105a557600080fd5b506103c96105b436600461443e565b611643565b3480156105c557600080fd5b506103e061181c565b3480156105da57600080fd5b506103c96105e936600461443e565b611822565b3480156105fa57600080fd5b506103e06118d2565b34801561060f57600080fd5b506103e061061e36600461453e565b6118eb565b34801561062f57600080fd5b506103e061063e36600461443e565b611a7c565b34801561064f57600080fd5b50610542611c1d565b34801561066457600080fd5b506103e0611c27565b34801561067957600080fd5b50610542611d83565b34801561068e57600080fd5b5061032f61069d36600461443e565b611d92565b3480156106ae57600080fd5b506103e06106bd36600461443e565b611f72565b3480156106ce57600080fd5b5061035a611faa565b3480156106e357600080fd5b506103e06106f236600461453e565b612005565b34801561070357600080fd5b506103e061218f565b34801561071857600080fd5b50610542612195565b34801561072d57600080fd5b5061038761073c36600461453e565b6121a4565b6103e061074f36600461453e565b612394565b34801561076057600080fd5b506103c961076f3660046144fe565b61254e565b6103e06107823660046144fe565b612795565b34801561079357600080fd5b506103c96107a236600461443e565b612a09565b3480156107b357600080fd5b506103c96107c23660046144ae565b612ab9565b3480156107d357600080fd5b50610542612d94565b3480156107e857600080fd5b506103e0612da3565b3480156107fd57600080fd5b506103e061080c366004614476565b612dbf565b34801561081d57600080fd5b506103c961082c36600461443e565b612dea565b61084461083f3660046144ae565b612e71565b60405161033c93929190614ee3565b34801561085f57600080fd5b506103e061326d565b6103e061087636600461453e565b6133c8565b34801561088757600080fd5b5061054261363b565b34801561089c57600080fd5b506103c96108ab36600461443e565b61364a565b6108b861430c565b6108c061430c565b6001600160a01b03831660009081526009602052604090205481526108e483611289565b60208201526108f16112fb565b604082015290505b919050565b600e805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109845780601f1061095957610100808354040283529160200191610984565b820191906000526020600020905b81548152906001019060200180831161096757829003601f168201915b505050505081565b3360008181526011602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906109e5908690614eda565b60405180910390a35060015b92915050565b601054610100900460ff1681565b610a0d61370a565b6001600160a01b0316610a1e611d83565b6001600160a01b031614610a4d5760405162461bcd60e51b8152600401610a4490614c15565b60405180910390fd5b601054610100900460ff1615610a755760405162461bcd60e51b8152600401610a4490614b1a565b610a7d61370e565b8251610a9090600e90602086019061432d565b508151610aa490600f90602085019061432d565b506010805461ff001960ff90931660ff1990911617919091166101001790555050565b60065481565b600c5442118015610ae857506003546001600160a01b031615155b15610c3e576003546000906001600160a01b03166315f24053610b09613720565b6008546007546040518463ffffffff1660e01b8152600401610b2d93929190614ee3565b60206040518083038186803b158015610b4557600080fd5b505afa158015610b59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7d919061461b565b90506000610ba0610b99600c54426137bf90919063ffffffff16565b83906137e7565b90506000610bcb670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b90613821565b600854909150610bdb9082613853565b600855600b54610c0790610bfe90670de0b6b3a764000090610bc59085906137e7565b60075490613853565b600755600d54610c3390610c2a90670de0b6b3a764000090610bc59086906137e7565b600d5490613853565b600d55505042600c55505b610c4661370a565b6001600160a01b0316610c57611d83565b6001600160a01b031614610c7d5760405162461bcd60e51b8152600401610a4490614c15565b670de0b6b3a7640000811115610ca55760405162461bcd60e51b8152600401610a4490614ddd565b600b55565b6000600c5442118015610cc757506003546001600160a01b031615155b15610dfe576003546000906001600160a01b03166315f24053610ce8613720565b6008546007546040518463ffffffff1660e01b8152600401610d0c93929190614ee3565b60206040518083038186803b158015610d2457600080fd5b505afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c919061461b565b90506000610d78610b99600c54426137bf90919063ffffffff16565b90506000610d9d670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150610dad9082613853565b600855600b54610dd090610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54610df390610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b60026001541415610e215760405162461bcd60e51b8152600401610a4490614e14565b60026001819055546040516368155ec160e01b81526001600160a01b03909116906368155ec190610e5c903390889088908890600401614690565b600060405180830381600087803b158015610e7657600080fd5b505af1158015610e8a573d6000803e3d6000fd5b505060018080559695505050505050565b600c5442118015610eb657506003546001600160a01b031615155b15610fed576003546000906001600160a01b03166315f24053610ed7613720565b6008546007546040518463ffffffff1660e01b8152600401610efb93929190614ee3565b60206040518083038186803b158015610f1357600080fd5b505afa158015610f27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4b919061461b565b90506000610f67610b99600c54426137bf90919063ffffffff16565b90506000610f8c670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150610f9c9082613853565b600855600b54610fbf90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54610fe290610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6004546001600160a01b031633146110175760405162461bcd60e51b8152600401610a4490614d51565b6002600154141561103a5760405162461bcd60e51b8152600401610a4490614e14565b600260015560075461104a6112eb565b10611075576007548015611073576000600755600454611073906001600160a01b031682613878565b505b60018055565b60105460ff1681565b6000600c54421180156110a157506003546001600160a01b031615155b156111d8576003546000906001600160a01b03166315f240536110c2613720565b6008546007546040518463ffffffff1660e01b81526004016110e693929190614ee3565b60206040518083038186803b1580156110fe57600080fd5b505afa158015611112573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611136919061461b565b90506000611152610b99600c54426137bf90919063ffffffff16565b90506000611177670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506111879082613853565b600855600b546111aa90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546111cd90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146112025760405162461bcd60e51b8152600401610a4490614e4b565b8161120b6112eb565b10156112295760405162461bcd60e51b8152600401610a4490614c4a565b611235838360006138b2565b61123f8483613878565b7fe1979fe4c35e0cef342fef5668e2c8e7a7e9f5d5d1ca8fee0ac6c427fa4153af838361126b86611289565b60405161127a93929190614753565b60405180910390a15092915050565b600061129361430c565b61129b61395a565b6001600160a01b0384166000908152600a602052604090208054919250906112c8576000925050506108f9565b6001810154604083015182546112e39291610bc591906137e7565b949350505050565b60006112f5613720565b90505b90565b6000600654600014156113175750670de0b6b3a76400006112f8565b61131f61430c565b61132761395a565b9050611365600654610bc5670de0b6b3a764000061135f85602001516113598760000151611353613720565b90613853565b906137bf565b906137e7565b91505090565b600b5481565b6000600c544211801561138e57506003546001600160a01b031615155b156114c5576003546000906001600160a01b03166315f240536113af613720565b6008546007546040518463ffffffff1660e01b81526004016113d393929190614ee3565b60206040518083038186803b1580156113eb57600080fd5b505afa1580156113ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611423919061461b565b9050600061143f610b99600c54426137bf90919063ffffffff16565b90506000611464670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506114749082613853565b600855600b5461149790610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546114ba90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146114ef5760405162461bcd60e51b8152600401610a4490614e4b565b816114f86112eb565b10156115165760405162461bcd60e51b8152600401610a4490614c4a565b611522838360006138b2565b61152c8383613878565b7fe1979fe4c35e0cef342fef5668e2c8e7a7e9f5d5d1ca8fee0ac6c427fa4153af838361155886611289565b60405161156793929190614753565b60405180910390a150919050565b60075481565b60085481565b6004546001600160a01b031681565b6005546001600160a01b031681565b6001600160a01b031660009081526009602052604090205490565b6115c261370a565b6001600160a01b03166115d3611d83565b6001600160a01b0316146115f95760405162461bcd60e51b8152600401610a4490614c15565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600c544211801561165e57506003546001600160a01b031615155b15611795576003546000906001600160a01b03166315f2405361167f613720565b6008546007546040518463ffffffff1660e01b81526004016116a393929190614ee3565b60206040518083038186803b1580156116bb57600080fd5b505afa1580156116cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f3919061461b565b9050600061170f610b99600c54426137bf90919063ffffffff16565b90506000611734670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506117449082613853565b600855600b5461176790610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461178a90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b61179d61370a565b6001600160a01b03166117ae611d83565b6001600160a01b0316146117d45760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b0381166117fa5760405162461bcd60e51b8152600401610a4490614cc3565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600c5481565b61182a61370a565b6001600160a01b031661183b611d83565b6001600160a01b0316146118615760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b0381166118875760405162461bcd60e51b8152600401610a4490614866565b6002546001600160a01b0316156118b05760405162461bcd60e51b8152600401610a44906148d4565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006118dc61430c565b6118e461395a565b5191505090565b6000600c544211801561190857506003546001600160a01b031615155b15611a3f576003546000906001600160a01b03166315f24053611929613720565b6008546007546040518463ffffffff1660e01b815260040161194d93929190614ee3565b60206040518083038186803b15801561196557600080fd5b505afa158015611979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199d919061461b565b905060006119b9610b99600c54426137bf90919063ffffffff16565b905060006119de670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506119ee9082613853565b600855600b54611a1190610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611a3490610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b03163314611a695760405162461bcd60e51b8152600401610a4490614e4b565b611a7583836000613acc565b9392505050565b6000600c5442118015611a9957506003546001600160a01b031615155b15611bd0576003546000906001600160a01b03166315f24053611aba613720565b6008546007546040518463ffffffff1660e01b8152600401611ade93929190614ee3565b60206040518083038186803b158015611af657600080fd5b505afa158015611b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b2e919061461b565b90506000611b4a610b99600c54426137bf90919063ffffffff16565b90506000611b6f670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150611b7f9082613853565b600855600b54611ba290610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611bc590610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6001600160a01b0382166000908152600a60205260409020600181015415611c16576001810154600d548254611c0b9291610bc591906137e7565b8155600d5460018201555b5492915050565b60006112f5611d83565b6000600c5442118015611c4457506003546001600160a01b031615155b15611d7b576003546000906001600160a01b03166315f24053611c65613720565b6008546007546040518463ffffffff1660e01b8152600401611c8993929190614ee3565b60206040518083038186803b158015611ca157600080fd5b505afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd9919061461b565b90506000611cf5610b99600c54426137bf90919063ffffffff16565b90506000611d1a670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150611d2a9082613853565b600855600b54611d4d90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611d7090610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6112f56112fb565b6000546001600160a01b031690565b611d9a61430c565b600c5442118015611db557506003546001600160a01b031615155b15611eec576003546000906001600160a01b03166315f24053611dd6613720565b6008546007546040518463ffffffff1660e01b8152600401611dfa93929190614ee3565b60206040518083038186803b158015611e1257600080fd5b505afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a919061461b565b90506000611e66610b99600c54426137bf90919063ffffffff16565b90506000611e8b670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150611e9b9082613853565b600855600b54611ebe90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54611ee190610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b611ef461430c565b6001600160a01b0383166000908152600a60205260409020600181015415611f3a576001810154600d548254611f2f9291610bc591906137e7565b8155600d5460018201555b6001600160a01b0384166000908152600960209081526040909120548352815490830152611f666112fb565b60408301525092915050565b60006109f1670de0b6b3a7640000610bc5611f8b6112fb565b6001600160a01b038616600090815260096020526040902054906137e7565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109845780601f1061095957610100808354040283529160200191610984565b6000600c544211801561202257506003546001600160a01b031615155b15612159576003546000906001600160a01b03166315f24053612043613720565b6008546007546040518463ffffffff1660e01b815260040161206793929190614ee3565b60206040518083038186803b15801561207f57600080fd5b505afa158015612093573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b7919061461b565b905060006120d3610b99600c54426137bf90919063ffffffff16565b905060006120f8670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506121089082613853565b600855600b5461212b90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461214e90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146121835760405162461bcd60e51b8152600401610a4490614e4b565b611a7583600084613acc565b600d5481565b6003546001600160a01b031681565b6000600c54421180156121c157506003546001600160a01b031615155b156122f8576003546000906001600160a01b03166315f240536121e2613720565b6008546007546040518463ffffffff1660e01b815260040161220693929190614ee3565b60206040518083038186803b15801561221e57600080fd5b505afa158015612232573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612256919061461b565b90506000612272610b99600c54426137bf90919063ffffffff16565b90506000612297670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506122a79082613853565b600855600b546122ca90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546122ed90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002600154141561231b5760405162461bcd60e51b8152600401610a4490614e14565b60026001819055546040516368155ec160e01b81526001600160a01b03909116906368155ec190612356903390819088908890600401614690565b600060405180830381600087803b15801561237057600080fd5b505af1158015612384573d6000803e3d6000fd5b5050600180805595945050505050565b6000600c54421180156123b157506003546001600160a01b031615155b156124e8576003546000906001600160a01b03166315f240536123d2613720565b6008546007546040518463ffffffff1660e01b81526004016123f693929190614ee3565b60206040518083038186803b15801561240e57600080fd5b505afa158015612422573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612446919061461b565b90506000612462610b99600c54426137bf90919063ffffffff16565b90506000612487670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506124979082613853565b600855600b546124ba90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546124dd90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146125125760405162461bcd60e51b8152600401610a4490614e4b565b6000198214156125285761252583611289565b91505b600554611a7590849081906001600160a01b0316156125475784612549565b345b613da9565b600c544211801561256957506003546001600160a01b031615155b156126a0576003546000906001600160a01b03166315f2405361258a613720565b6008546007546040518463ffffffff1660e01b81526004016125ae93929190614ee3565b60206040518083038186803b1580156125c657600080fd5b505afa1580156125da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125fe919061461b565b9050600061261a610b99600c54426137bf90919063ffffffff16565b9050600061263f670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b60085490915061264f9082613853565b600855600b5461267290610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461269590610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146126ca5760405162461bcd60e51b8152600401610a4490614e4b565b600260015414156126ed5760405162461bcd60e51b8152600401610a4490614e14565b60026001556001600160a01b03821660009081526009602052604090205461271590826137bf565b6001600160a01b0380841660009081526009602052604080822093909355908516815220546127449082613853565b6001600160a01b038085166000818152600960205260409081902093909355915190841690600080516020614f7983398151915290612784908590614eda565b60405180910390a350506001805550565b6000600c54421180156127b257506003546001600160a01b031615155b156128e9576003546000906001600160a01b03166315f240536127d3613720565b6008546007546040518463ffffffff1660e01b81526004016127f793929190614ee3565b60206040518083038186803b15801561280f57600080fd5b505afa158015612823573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612847919061461b565b90506000612863610b99600c54426137bf90919063ffffffff16565b90506000612888670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506128989082613853565b600855600b546128bb90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546128de90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146129135760405162461bcd60e51b8152600401610a4490614e4b565b600061291d6112fb565b6005549091506001600160a01b0316156129375782612939565b345b92506129458584613e58565b9250600061295f82610bc586670de0b6b3a76400006137e7565b9050600081116129815760405162461bcd60e51b8152600401610a4490614a75565b61298d85826000613fe4565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688585826040516129be92919061473a565b60405180910390a1846001600160a01b031660006001600160a01b0316600080516020614f79833981519152836040516129f89190614eda565b60405180910390a395945050505050565b612a1161370a565b6001600160a01b0316612a22611d83565b6001600160a01b031614612a485760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b038116612a6e5760405162461bcd60e51b8152600401610a44906149fb565b6005546001600160a01b031615612a975760405162461bcd60e51b8152600401610a4490614aac565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b03163314612ae35760405162461bcd60e51b8152600401610a4490614e4b565b816001600160a01b0316836001600160a01b031614158015612c075750600260009054906101000a90046001600160a01b03166001600160a01b0316633a5381b56040518163ffffffff1660e01b815260040160206040518083038186803b158015612b4e57600080fd5b505afa158015612b62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b86919061445a565b6001600160a01b031663eabe7d913085846040518463ffffffff1660e01b8152600401612bb5939291906146ba565b602060405180830381600087803b158015612bcf57600080fd5b505af1158015612be3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c079190614569565b612c235760405162461bcd60e51b8152600401610a449061490b565b80612c405760405162461bcd60e51b8152600401610a4490614839565b6000836001600160a01b0316856001600160a01b031614612c86576001600160a01b03808516600090815260116020908152604080832093891683529290522054612c8a565b6000195b90506000612cb383604051806060016040528060298152602001614f5060299139849190614059565b6001600160a01b038616600090815260096020526040902054909150612cd990846137bf565b6001600160a01b038087166000908152600960205260408082209390935590861681522054612d089084613853565b6001600160a01b0385166000908152600960205260409020556000198214612d53576001600160a01b038086166000908152601160209081526040808320938a168352929052208190555b836001600160a01b0316856001600160a01b0316600080516020614f7983398151915285604051612d849190614eda565b60405180910390a3505050505050565b6003546001600160a01b031690565b6000612dad61430c565b612db561395a565b6040015191505090565b6001600160a01b03918216600090815260116020908152604080832093909416825291909152205490565b612df261370a565b6001600160a01b0316612e03611d83565b6001600160a01b031614612e295760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b038116612e4f5760405162461bcd60e51b8152600401610a4490614d06565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000600c5442118015612e9157506003546001600160a01b031615155b15612fc8576003546000906001600160a01b03166315f24053612eb2613720565b6008546007546040518463ffffffff1660e01b8152600401612ed693929190614ee3565b60206040518083038186803b158015612eee57600080fd5b505afa158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f26919061461b565b90506000612f42610b99600c54426137bf90919063ffffffff16565b90506000612f67670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150612f779082613853565b600855600b54612f9a90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d54612fbd90610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b03163314612ff25760405162461bcd60e51b8152600401610a4490614e4b565b856001600160a01b0316856001600160a01b031614156130245760405162461bcd60e51b8152600401610a44906147b2565b6005546001600160a01b03161561303b578361303d565b345b935061304a868686613da9565b935060008411801561305d575060001984105b6130795760405162461bcd60e51b8152600401610a4490614e82565b600260009054906101000a90046001600160a01b03166001600160a01b0316633a5381b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156130c757600080fd5b505afa1580156130db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ff919061445a565b6001600160a01b031663f643b5df3089876040518463ffffffff1660e01b815260040161312e939291906146ba565b606060405180830381600087803b15801561314857600080fd5b505af115801561315c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131809190614633565b6040516370a0823160e01b8152929550909350915083906001600160a01b038916906370a08231906131b690899060040161467c565b60206040518083038186803b1580156131ce57600080fd5b505afa1580156131e2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613206919061461b565b10156132245760405162461bcd60e51b8152600401610a4490614bb7565b7f298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb528686868a8760405161325b9594939291906146de565b60405180910390a19450945094915050565b6000600c544211801561328a57506003546001600160a01b031615155b156133c1576003546000906001600160a01b03166315f240536132ab613720565b6008546007546040518463ffffffff1660e01b81526004016132cf93929190614ee3565b60206040518083038186803b1580156132e757600080fd5b505afa1580156132fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061331f919061461b565b9050600061333b610b99600c54426137bf90919063ffffffff16565b90506000613360670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506133709082613853565b600855600b5461339390610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d546133b690610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b5060085490565b6000600c54421180156133e557506003546001600160a01b031615155b1561351c576003546000906001600160a01b03166315f24053613406613720565b6008546007546040518463ffffffff1660e01b815260040161342a93929190614ee3565b60206040518083038186803b15801561344257600080fd5b505afa158015613456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347a919061461b565b90506000613496610b99600c54426137bf90919063ffffffff16565b905060006134bb670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b6008549091506134cb9082613853565b600855600b546134ee90610bfe90670de0b6b3a764000090610bc59085906137e7565b600755600d5461351190610c2a90670de0b6b3a764000090610bc59086906137e7565b600d55505042600c55505b6002546001600160a01b031633146135465760405162461bcd60e51b8152600401610a4490614e4b565b60006135506112fb565b6005549091506001600160a01b03161561356a578261356c565b345b92506135788484613e58565b9250600061359282610bc586670de0b6b3a76400006137e7565b9050600081116135b45760405162461bcd60e51b8152600401610a4490614a75565b6135c085826000613fe4565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688585826040516135f192919061473a565b60405180910390a1846001600160a01b031660006001600160a01b0316600080516020614f798339815191528360405161362b9190614eda565b60405180910390a3949350505050565b6002546001600160a01b031681565b61365261370a565b6001600160a01b0316613663611d83565b6001600160a01b0316146136895760405162461bcd60e51b8152600401610a4490614c15565b6001600160a01b0381166136af5760405162461bcd60e51b8152600401610a44906147f3565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b42600c55670de0b6b3a7640000600d55565b6005546000906001600160a01b0316156137b9576005546040516370a0823160e01b81526001600160a01b03909116906370a082319061376490309060040161467c565b60206040518083038186803b15801561377c57600080fd5b505afa158015613790573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137b4919061461b565b6112f5565b6112f547345b6000828211156137e15760405162461bcd60e51b8152600401610a44906149c4565b50900390565b6000826137f6575060006109f1565b8282028284828161380357fe5b0414611a755760405162461bcd60e51b8152600401610a4490614b76565b60008082116138425760405162461bcd60e51b8152600401610a4490614a3e565b81838161384b57fe5b049392505050565b600082820183811015611a755760405162461bcd60e51b8152600401610a449061489d565b6005546001600160a01b0316613897576138928282614085565b6138ae565b6005546138ae906001600160a01b03168383614117565b5050565b6001600160a01b0383166000908152600a6020526040902060018101546138dc57600d5460018201555b61390582611359856113538560010154610bc5600d5488600001546137e790919063ffffffff16565b8155600d5460018201556008546139229083906113599086613853565b60085580546103e811613936578054613939565b60005b81556008546103e81161394e57600854613951565b60005b60085550505050565b61396261430c565b61396a61430c565b60085481526007546020820152600d546040820152600c544211801561399257506000600854115b156112f5576003546000906001600160a01b03166315f240536139b3613720565b6008546007546040518463ffffffff1660e01b81526004016139d793929190614ee3565b60206040518083038186803b1580156139ef57600080fd5b505afa158015613a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a27919061461b565b90506000613a43610b99600c54426137bf90919063ffffffff16565b90506000613a68670de0b6b3a7640000610bc5846008546137e790919063ffffffff16565b600854909150613a789082613853565b8452600b54613a9a90610bfe90670de0b6b3a764000090610bc59085906137e7565b6020850152600d54613abf90610c2a90670de0b6b3a764000090610bc59086906137e7565b6040850152505050905090565b6000821580613ad9575081155b613af55760405162461bcd60e51b8152600401610a4490614942565b826006541015613b175760405162461bcd60e51b8152600401610a4490614ae3565b81613b206112eb565b101580613b2b575081155b613b475760405162461bcd60e51b8152600401610a4490614c8c565b613b65670de0b6b3a7640000610bc5613b5e6112fb565b86906137e7565b613b6d6112eb565b101580613b78575082155b613b945760405162461bcd60e51b8152600401610a4490614c8c565b6000808411613bbf57613bba613ba86112fb565b610bc585670de0b6b3a76400006137e7565b613bc1565b835b90506000808511613bd25783613bf0565b613bf0670de0b6b3a7640000610bc5613be96112fb565b88906137e7565b9050600260009054906101000a90046001600160a01b03166001600160a01b0316633a5381b56040518163ffffffff1660e01b815260040160206040518083038186803b158015613c4057600080fd5b505afa158015613c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c78919061445a565b6001600160a01b031663eabe7d913088856040518463ffffffff1660e01b8152600401613ca7939291906146ba565b602060405180830381600087803b158015613cc157600080fd5b505af1158015613cd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cf99190614569565b613d155760405162461bcd60e51b8152600401610a4490614b47565b613d2186600084613fe4565b613d2b8682613878565b60006001600160a01b0316866001600160a01b0316600080516020614f7983398151915284604051613d5d9190614eda565b60405180910390a37fe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929868284604051613d9893929190614753565b60405180910390a195945050505050565b600080613db584611289565b90506000613dc38285614205565b9050613dcf8682613e58565b9050613ddd856000836138b2565b6005546001600160a01b0316613e1b576000818511613dfd576000613e07565b613e0785836137bf565b90508015613e1957613e198782613878565b505b7fa9a154237a69922f8860321d1fec1624a5dbe8a8af89a3dd3d7a759f6c8080d8868683613e4889611289565b604051613d989493929190614711565b6005546000906001600160a01b0316613e9c5781341015613e8b5760405162461bcd60e51b8152600401610a4490614994565b613e953483614205565b90506109f1565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613ecd90309060040161467c565b60206040518083038186803b158015613ee557600080fd5b505afa158015613ef9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1d919061461b565b600554909150613f38906001600160a01b031685308661421b565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613f6990309060040161467c565b60206040518083038186803b158015613f8157600080fd5b505afa158015613f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb9919061461b565b905083613fc682846137bf565b1115613fd157600080fd5b613fdb81836137bf565b925050506109f1565b6001600160a01b03831660009081526009602052604090205461400d9082906113599085613853565b6001600160a01b0384166000908152600960205260409020556006546140399082906113599085613853565b60068190556103e81161404e57600654614051565b60005b600655505050565b6000818484111561407d5760405162461bcd60e51b8152600401610a44919061477f565b505050900390565b604080516000808252602082019092526001600160a01b0384169083906040516140af9190614660565b60006040518083038185875af1925050503d80600081146140ec576040519150601f19603f3d011682016040523d82523d6000602084013e6140f1565b606091505b50509050806141125760405162461bcd60e51b8152600401610a4490614d88565b505050565b60006060846001600160a01b031663a9059cbb858560405160240161413d92919061473a565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516141769190614660565b6000604051808303816000865af19150503d80600081146141b3576040519150601f19603f3d011682016040523d82523d6000602084013e6141b8565b606091505b50915091508180156141e25750805115806141e25750808060200190518101906141e29190614569565b6141fe5760405162461bcd60e51b8152600401610a4490614bee565b5050505050565b60008183106142145781611a75565b5090919050565b60006060856001600160a01b03166323b872dd868686604051602401614243939291906146ba565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161427c9190614660565b6000604051808303816000865af19150503d80600081146142b9576040519150601f19603f3d011682016040523d82523d6000602084013e6142be565b606091505b50915091508180156142e85750805115806142e85750808060200190518101906142e89190614569565b6143045760405162461bcd60e51b8152600401610a4490614db2565b505050505050565b60405180606001604052806000815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061436e57805160ff191683800117855561439b565b8280016001018555821561439b579182015b8281111561439b578251825591602001919060010190614380565b506143a79291506143ab565b5090565b5b808211156143a757600081556001016143ac565b600082601f8301126143d0578081fd5b813567ffffffffffffffff808211156143e7578283fd5b604051601f8301601f191681016020018281118282101715614407578485fd5b60405282815292508284830160200186101561442257600080fd5b8260208601602083013760006020848301015250505092915050565b60006020828403121561444f578081fd5b8135611a7581614f37565b60006020828403121561446b578081fd5b8151611a7581614f37565b60008060408385031215614488578081fd5b823561449381614f37565b915060208301356144a381614f37565b809150509250929050565b600080600080608085870312156144c3578182fd5b84356144ce81614f37565b935060208501356144de81614f37565b925060408501356144ee81614f37565b9396929550929360600135925050565b600080600060608486031215614512578283fd5b833561451d81614f37565b9250602084013561452d81614f37565b929592945050506040919091013590565b60008060408385031215614550578182fd5b823561455b81614f37565b946020939093013593505050565b60006020828403121561457a578081fd5b81518015158114611a75578182fd5b60008060006060848603121561459d578283fd5b833567ffffffffffffffff808211156145b4578485fd5b6145c0878388016143c0565b945060208601359150808211156145d5578384fd5b506145e2868287016143c0565b925050604084013560ff811681146145f8578182fd5b809150509250925092565b600060208284031215614614578081fd5b5035919050565b60006020828403121561462c578081fd5b5051919050565b600080600060608486031215614647578283fd5b8351925060208401519150604084015190509250925092565b60008251614672818460208701614f07565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039586168152938516602085015260408401929092529092166060820152608081019190915260a00190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b039390931683526020830191909152604082015260600190565b901515815260200190565b600060208252825180602084015261479e816040850160208701614f07565b601f01601f19169190910160400192915050565b60208082526021908201527f4c546f6b656e3a2063616e6e6f74206c697175696461746520796f757273656c6040820152603360f91b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526013908201527213151bdad95b8e881e995c9bc8185b5bdd5b9d606a1b604082015260600190565b6020808252601d908201527f474d61726b65743a20696e76616c696420636f72652061646472657373000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526019908201527f474d61726b65743a20636f726520616c72656164792073657400000000000000604082015260600190565b60208082526017908201527f4c546f6b656e3a2063616e6e6f74207472616e73666572000000000000000000604082015260600190565b60208082526032908201527f4c546f6b656e3a206f6e65206f66206c416d6f756e74496e206f722075416d6f604082015271756e74496e206d757374206265207a65726f60701b606082015260800190565b602080825260169082015275098a8ded6cadc7440ecc2d8eaca40dad2e6dac2e8c6d60531b604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526023908201527f474d61726b65743a20696e76616c696420756e6465726c79696e67206164647260408201526265737360e81b606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526017908201527f4c546f6b656e3a20696e76616c6964206c416d6f756e74000000000000000000604082015260600190565b6020808252601f908201527f474d61726b65743a2073657420756e6465726c79696e6720616c726561647900604082015260600190565b6020808252601f908201527f4c546f6b656e3a206e6f7420656e6f75676820746f74616c20737570706c7900604082015260600190565b602080825260139082015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252601590820152744c546f6b656e3a2063616e6e6f742072656465656d60581b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601d908201527f4c546f6b656e3a20746f6f206d756368207365697a6520616d6f756e74000000604082015260600190565b6020808252600d908201526c10b9b0b332aa3930b739b332b960991b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526022908201527f4c546f6b656e3a20626f72726f7720616d6f756e7420657863656564732063616040820152610e6d60f31b606082015260800190565b6020808252601d908201527f4c546f6b656e3a206e6f7420656e6f75676820756e6465726c79696e67000000604082015260600190565b60208082526023908201527f474d61726b65743a20696e76616c69642072617465206d6f64656c206164647260408201526265737360e81b606082015260800190565b6020808252602b908201527f474d61726b65743a20696e76616c69642072656261746520646973747269627560408201526a746f72206164647265737360a81b606082015260800190565b6020808252601e908201527f4c546f6b656e3a206f6e6c79205265626174654469737472696275746f720000604082015260600190565b60208082526010908201526f042e6c2cccaa8e4c2dce6cccae48aa8960831b604082015260600190565b60208082526011908201527021736166655472616e7366657246726f6d60781b604082015260600190565b6020808252601f908201527f474d61726b65743a20696e76616c6964207265736572766520666163746f7200604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601a908201527f4c546f6b656e3a206f6e6c7920436f726520436f6e7472616374000000000000604082015260600190565b6020808252601c908201527f4c546f6b656e3a20696e76616c696420726570617920616d6f756e7400000000604082015260600190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b9283526020830191909152604082015260600190565b60ff91909116815260200190565b60005b83811015614f22578181015183820152602001614f0a565b83811115614f31576000848401525b50505050565b6001600160a01b0381168114614f4c57600080fd5b5056fe4c546f6b656e3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220a620b1498c2e8c59ff692cc93f4c1b3d055e1596ab91b135450be21cd3237cf364736f6c634300060c0033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.