ETH Price: $3,445.05 (-2.58%)
Gas: 2 Gwei

Contract

0xe1D71B60642d597e6e3DBF6d0Cd106AC3Cfa65FA
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Redeem172005182023-05-06 8:59:11443 days ago1683363551IN
Floor: Bond Depo
0 ETH0.00846675115.44215797
Redeem165651782023-02-05 21:09:59533 days ago1675631399IN
Floor: Bond Depo
0 ETH0.0017672327
Redeem164272992023-01-17 15:04:11552 days ago1673967851IN
Floor: Bond Depo
0 ETH0.0028566838.95024813
Redeem163006942022-12-30 22:54:11570 days ago1672440851IN
Floor: Bond Depo
0 ETH0.0025153834.29664244
Redeem157851702022-10-19 22:35:59642 days ago1666218959IN
Floor: Bond Depo
0 ETH0.0023241431.68910449
Redeem151042222022-07-08 20:50:00745 days ago1657313400IN
Floor: Bond Depo
0 ETH0.0013241923.53963815
Redeem148744882022-05-30 19:46:00784 days ago1653939960IN
Floor: Bond Depo
0 ETH0.0022012826.24517203
Redeem148192942022-05-21 20:20:32793 days ago1653164432IN
Floor: Bond Depo
0 ETH0.0007847513.95014486
Redeem147943142022-05-17 19:10:54797 days ago1652814654IN
Floor: Bond Depo
0 ETH0.0031872343.45711387
Redeem147713142022-05-14 3:25:43800 days ago1652498743IN
Floor: Bond Depo
0 ETH0.0020294131
Redeem147608122022-05-12 11:25:49802 days ago1652354749IN
Floor: Bond Depo
0 ETH0.00842266149.75755956
Redeem147490712022-05-10 14:24:34804 days ago1652192674IN
Floor: Bond Depo
0 ETH0.0040482254.21130837
Redeem147460892022-05-10 2:48:15804 days ago1652150895IN
Floor: Bond Depo
0 ETH0.0111750181.07710144
Redeem147460432022-05-10 2:35:41804 days ago1652150141IN
Floor: Bond Depo
0 ETH0.0064629257.95308456
Redeem147399602022-05-09 3:06:26805 days ago1652065586IN
Floor: Bond Depo
0 ETH0.0017162730.51592876
Redeem147345312022-05-08 6:35:44806 days ago1651991744IN
Floor: Bond Depo
0 ETH0.0019124323.16276815
Deposit147257452022-05-06 20:53:24808 days ago1651870404IN
Floor: Bond Depo
0 ETH0.0088317431
Deposit147255242022-05-06 20:05:27808 days ago1651867527IN
Floor: Bond Depo
0 ETH0.0248235146.97730045
Deposit147173832022-05-05 12:58:38809 days ago1651755518IN
Floor: Bond Depo
0 ETH0.0201183568.21262372
Deposit147170522022-05-05 11:40:35809 days ago1651750835IN
Floor: Bond Depo
0 ETH0.0105087936.88653935
Deposit147162652022-05-05 8:46:12809 days ago1651740372IN
Floor: Bond Depo
0 ETH0.0185916934.3827726
Redeem147129222022-05-04 20:01:14810 days ago1651694474IN
Floor: Bond Depo
0 ETH0.0037084365.92305507
Redeem147124782022-05-04 18:19:07810 days ago1651688347IN
Floor: Bond Depo
0 ETH0.0037154245
Deposit147124312022-05-04 18:08:21810 days ago1651687701IN
Floor: Bond Depo
0 ETH0.0215058869.31276657
Redeem147124222022-05-04 18:05:54810 days ago1651687554IN
Floor: Bond Depo
0 ETH0.0058742970.02716504
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FloorBondDepository

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 13 : BondDepository.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.10;

import "./types/NoteKeeper.sol";

import "./libraries/SafeERC20.sol";

import "./interfaces/IERC20Metadata.sol";
import "./interfaces/IBondDepository.sol";

/// @title Floor Bond Depository V2
/// @author Zeus, Indigo
/// Review by: JeffX

contract FloorBondDepository is IBondDepository, NoteKeeper {
/* ======== DEPENDENCIES ======== */

  using SafeERC20 for IERC20;

/* ======== EVENTS ======== */

  event CreateMarket(
    uint256 indexed id,
    address indexed quoteToken,
    uint256 initialPrice,
    uint256 capacity,
    bool capacityInQuote,
    uint256 conclusion,
    uint256 vestingPeriod
  );
  event CloseMarket(uint256 indexed id);
  event Tuned(uint256 indexed id, uint64 oldControlVariable, uint64 newControlVariable);
  event Bond(uint256 indexed id, uint256 amount, uint256 price, uint256 payout);

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

  // Storage
  Market[] public markets; // persistent market data
  Terms[] public terms; // deposit construction data
  Metadata[] public metadata; // extraneous market data
  mapping(uint256 => Adjustment) public adjustments; // control variable changes

  // Queries
  mapping(address => uint256[]) public marketsForQuote; // market IDs for quote token

/* ======== CONSTRUCTOR ======== */

  constructor(
    IFloorAuthority _authority,
    IERC20 _floor,
    IgFLOOR _gfloor,
    IStaking _staking,
    ITreasury _treasury
  ) NoteKeeper(_authority, _floor, _gfloor, _staking, _treasury) {
    // save gas for users by bulk approving stake() transactions
    _floor.approve(address(_staking), 1e45);
  }

/* ======== DEPOSIT ======== */

  /**
   * @notice             deposit quote tokens in exchange for a bond from a specified market
   * @param _id          the ID of the market
   * @param _amount      the amount of quote token to spend
   * @param _maxPrice    the maximum price at which to buy
   * @param _user        the recipient of the payout
   * @param _referral    the front end operator address
   * @return payout_     the amount of gFLOOR due
   * @return expiry_     the timestamp at which payout is redeemable
   * @return index_      the user index of the Note (used to redeem or query information)
   */
  function deposit(
    uint256 _id,
    uint256 _amount,
    uint256 _maxPrice,
    address _user,
    address _referral
  ) external override returns (
    uint256 payout_, 
    uint256 expiry_,
    uint256 index_
  ) {
    Market storage market = markets[_id];
    Terms memory term = terms[_id];
    uint48 currentTime = uint48(block.timestamp);

    // Markets end at a defined timestamp
    // |-------------------------------------| t
    require(currentTime < term.conclusion, "Depository: market concluded");

    // Debt and the control variable decay over time
    _decay(_id, currentTime);

    // Users input a maximum price, which protects them from price changes after
    // entering the mempool. max price is a slippage mitigation measure
    uint256 price = _marketPrice(_id);
    require(price <= _maxPrice, "Depository: more than max price"); 

    /**
     * payout for the deposit = amount / price
     *
     * where
     * payout = FLOOR out
     * amount = quote tokens in
     * price = quote tokens : floor (i.e. 42069 DAI : FLOOR)
     *
     * 1e18 = FLOOR decimals (9) + price decimals (9)
     */
    payout_ = (_amount * 1e18 / price) / (10 ** metadata[_id].quoteDecimals);

    // markets have a max payout amount, capping size because deposits
    // do not experience slippage. max payout is recalculated upon tuning
    require(payout_ <= market.maxPayout, "Depository: max size exceeded");
    
    /*
     * each market is initialized with a capacity
     *
     * this is either the number of FLOOR that the market can sell
     * (if capacity in quote is false), 
     *
     * or the number of quote tokens that the market can buy
     * (if capacity in quote is true)
     */
    market.capacity -= market.capacityInQuote
      ? _amount
      : payout_;

    /**
     * bonds mature with a cliff at a set timestamp
     * prior to the expiry timestamp, no payout tokens are accessible to the user
     * after the expiry timestamp, the entire payout can be redeemed
     *
     * there are two types of bonds: fixed-term and fixed-expiration
     *
     * fixed-term bonds mature in a set amount of time from deposit
     * i.e. term = 1 week. when alice deposits on day 1, her bond
     * expires on day 8. when bob deposits on day 2, his bond expires day 9.
     *
     * fixed-expiration bonds mature at a set timestamp
     * i.e. expiration = day 10. when alice deposits on day 1, her term
     * is 9 days. when bob deposits on day 2, his term is 8 days.
     */
    expiry_ = term.fixedTerm
      ? term.vesting + currentTime
      : term.vesting;

    // markets keep track of how many quote tokens have been
    // purchased, and how much FLOOR has been sold
    market.purchased += _amount;
    market.sold += uint64(payout_);

    // incrementing total debt raises the price of the next bond
    market.totalDebt += uint64(payout_);

    emit Bond(_id, _amount, price, payout_);

    /**
     * user data is stored as Notes. these are isolated array entries
     * storing the amount due, the time created, the time when payout
     * is redeemable, the time when payout was redeemed, and the ID
     * of the market deposited into
     */
    index_ = addNote(
      _user,
      payout_,
      uint48(expiry_),
      uint48(_id),
      _referral
    );

    // transfer payment to treasury
    market.quoteToken.safeTransferFrom(msg.sender, address(treasury), _amount);

    // if max debt is breached, the market is closed 
    // this a circuit breaker
    if (term.maxDebt < market.totalDebt) {
        market.capacity = 0;
        emit CloseMarket(_id);
    } else {
      // if market will continue, the control variable is tuned to hit targets on time
      _tune(_id, currentTime);
    }
  }

  /**
   * @notice             decay debt, and adjust control variable if there is an active change
   * @param _id          ID of market
   * @param _time        uint48 timestamp (saves gas when passed in)
   */
  function _decay(uint256 _id, uint48 _time) internal {

    // Debt decay

    /*
     * Debt is a time-decayed sum of tokens spent in a market
     * Debt is added when deposits occur and removed over time
     * |
     * |    debt falls with
     * |   / \  inactivity       / \
     * | /     \              /\/    \
     * |         \           /         \
     * |           \      /\/            \
     * |             \  /  and rises       \
     * |                with deposits
     * |
     * |------------------------------------| t
     */
    markets[_id].totalDebt -= debtDecay(_id);
    metadata[_id].lastDecay = _time;


    // Control variable decay

    // The bond control variable is continually tuned. When it is lowered (which
    // lowers the market price), the change is carried out smoothly over time.
    if (adjustments[_id].active) {
      Adjustment storage adjustment = adjustments[_id];

      (uint64 adjustBy, uint48 secondsSince, bool stillActive) = _controlDecay(_id);
      terms[_id].controlVariable -= adjustBy;

      if (stillActive) {
        adjustment.change -= adjustBy;
        adjustment.timeToAdjusted -= secondsSince;
        adjustment.lastAdjustment = _time;
      } else {
        adjustment.active = false;
      }
    }
  }

  /**
   * @notice             auto-adjust control variable to hit capacity/spend target
   * @param _id          ID of market
   * @param _time        uint48 timestamp (saves gas when passed in)
   */
  function _tune(uint256 _id, uint48 _time) internal {
    Metadata memory meta = metadata[_id];

    if (_time >= meta.lastTune + meta.tuneInterval) {
      Market memory market = markets[_id];
      
      // compute seconds remaining until market will conclude
      uint256 timeRemaining = terms[_id].conclusion - _time;
      uint256 price = _marketPrice(_id);

      // standardize capacity into an base token amount
      // floor decimals (9) + price decimals (9)
      uint256 capacity = market.capacityInQuote
        ? (market.capacity * 1e18 / price) / (10 ** meta.quoteDecimals)
        : market.capacity;

      /**
       * calculate the correct payout to complete on time assuming each bond
       * will be max size in the desired deposit interval for the remaining time
       *
       * i.e. market has 10 days remaining. deposit interval is 1 day. capacity
       * is 10,000 FLOOR. max payout would be 1,000 FLOOR (10,000 * 1 / 10).
       */  
      markets[_id].maxPayout = uint64(capacity * meta.depositInterval / timeRemaining);

      // calculate the ideal total debt to satisfy capacity in the remaining time
      uint256 targetDebt = capacity * meta.length / timeRemaining;

      // derive a new control variable from the target debt and current supply
      uint64 newControlVariable = uint64(price * treasury.baseSupply() / targetDebt);

      emit Tuned(_id, terms[_id].controlVariable, newControlVariable);

      if (newControlVariable >= terms[_id].controlVariable) {
        terms[_id].controlVariable = newControlVariable;
      } else {
        // if decrease, control variable change will be carried out over the tune interval
        // this is because price will be lowered
        uint64 change = terms[_id].controlVariable - newControlVariable;
        adjustments[_id] = Adjustment(change, _time, meta.tuneInterval, true);
      }
      metadata[_id].lastTune = _time;
    }
  }

/* ======== CREATE ======== */

  /**
   * @notice             creates a new market type
   * @dev                current price should be in 9 decimals.
   * @param _quoteToken  token used to deposit
   * @param _market      [capacity (in FLOOR or quote), initial price / FLOOR (9 decimals), debt buffer (3 decimals)]
   * @param _booleans    [capacity in quote, fixed term]
   * @param _terms       [(seconds) vesting length (if fixed term) or vested timestamp, conclusion timestamp]
   * @param _intervals   [deposit interval (seconds), tune interval (seconds)]
   * @return id_         ID of new bond market
   */
  function create(
    IERC20 _quoteToken,
    uint256[3] memory _market,
    bool[2] memory _booleans,
    uint256[2] memory _terms,
    uint32[2] memory _intervals
  ) external override onlyPolicy returns (uint256 id_) {

    // the length of the program, in seconds
    uint256 secondsToConclusion = _terms[1] - block.timestamp;

    // the decimal count of the quote token
    uint256 decimals = IERC20Metadata(address(_quoteToken)).decimals();

    /* 
     * initial target debt is equal to capacity (this is the amount of debt
     * that will decay over in the length of the program if price remains the same).
     * it is converted into base token terms if passed in in quote token terms.
     *
     * 1e18 = floor decimals (9) + initial price decimals (9)
     */
    uint64 targetDebt = uint64(_booleans[0]
      ? (_market[0] * 1e18 / _market[1]) / 10 ** decimals
      : _market[0]
    );

    /*
     * max payout is the amount of capacity that should be utilized in a deposit
     * interval. for example, if capacity is 1,000 FLOOR, there are 10 days to conclusion, 
     * and the preferred deposit interval is 1 day, max payout would be 100 FLOOR.
     */
    uint64 maxPayout = uint64(targetDebt * _intervals[0] / secondsToConclusion);

    /*
     * max debt serves as a circuit breaker for the market. let's say the quote
     * token is a stablecoin, and that stablecoin depegs. without max debt, the
     * market would continue to buy until it runs out of capacity. this is
     * configurable with a 3 decimal buffer (1000 = 1% above initial price).
     * note that its likely advisable to keep this buffer wide.
     * note that the buffer is above 100%. i.e. 10% buffer = initial debt * 1.1
     */
    uint256 maxDebt = targetDebt + (targetDebt * _market[2] / 1e5); // 1e5 = 100,000. 10,000 / 100,000 = 10%.

    /*
     * the control variable is set so that initial price equals the desired
     * initial price. the control variable is the ultimate determinant of price,
     * so we compute this last.
     *
     * price = control variable * debt ratio
     * debt ratio = total debt / supply
     * therefore, control variable = price / debt ratio
     */
    uint256 controlVariable = _market[1] * treasury.baseSupply() / targetDebt;

    // depositing into, or getting info for, the created market uses this ID
    id_ = markets.length;

    markets.push(Market({
      quoteToken: _quoteToken, 
      capacityInQuote: _booleans[0],
      capacity: _market[0],
      totalDebt: targetDebt, 
      maxPayout: maxPayout,
      purchased: 0,
      sold: 0
    }));

    terms.push(Terms({
      fixedTerm: _booleans[1], 
      controlVariable: uint64(controlVariable),
      vesting: uint48(_terms[0]), 
      conclusion: uint48(_terms[1]), 
      maxDebt: uint64(maxDebt) 
    }));

    metadata.push(Metadata({
      lastTune: uint48(block.timestamp),
      lastDecay: uint48(block.timestamp),
      length: uint48(secondsToConclusion),
      depositInterval: _intervals[0],
      tuneInterval: _intervals[1],
      quoteDecimals: uint8(decimals)
    }));

    marketsForQuote[address(_quoteToken)].push(id_);

    emit CreateMarket(id_, address(_quoteToken), _market[1], _market[0], _booleans[0], _terms[1], _terms[0]);
  }

  /**
   * @notice             disable existing market
   * @param _id          ID of market to close
   */
  function close(uint256 _id) external override onlyPolicy {
    terms[_id].conclusion = uint48(block.timestamp);
    markets[_id].capacity = 0;
    emit CloseMarket(_id);
  }

/* ======== EXTERNAL VIEW ======== */

  /**
   * @notice             calculate current market price of quote token in base token
   * @dev                accounts for debt and control variable decay since last deposit (vs _marketPrice())
   * @param _id          ID of market
   * @return             price for market in FLOOR decimals
   *
   * price is derived from the equation
   *
   * p = cv * dr
   *
   * where
   * p = price
   * cv = control variable
   * dr = debt ratio
   *
   * dr = d / s
   * 
   * where
   * d = debt
   * s = supply of token at market creation
   *
   * d -= ( d * (dt / l) )
   * 
   * where
   * dt = change in time
   * l = length of program
   */
  function marketPrice(uint256 _id) public view override returns (uint256) {
    return 
      currentControlVariable(_id)
      * debtRatio(_id)
      / (10 ** metadata[_id].quoteDecimals);
  }

  /**
   * @notice             payout due for amount of quote tokens
   * @dev                accounts for debt and control variable decay so it is up to date
   * @param _amount      amount of quote tokens to spend
   * @param _id          ID of market
   * @return             amount of FLOOR to be paid in FLOOR decimals
   *
   * @dev 1e18 = floor decimals (9) + market price decimals (9)
   */
  function payoutFor(uint256 _amount, uint256 _id) external view override returns (uint256) {
    Metadata memory meta = metadata[_id];
    return 
      _amount
      * 1e18 
      / marketPrice(_id)
      / 10 ** meta.quoteDecimals;
  }

  /**
   * @notice             calculate current ratio of debt to supply
   * @dev                uses current debt, which accounts for debt decay since last deposit (vs _debtRatio())
   * @param _id          ID of market
   * @return             debt ratio for market in quote decimals
   */
  function debtRatio(uint256 _id) public view override returns (uint256) {
    return 
      currentDebt(_id)
      * (10 ** metadata[_id].quoteDecimals)
      / treasury.baseSupply(); 
  }

  /**
   * @notice             calculate debt factoring in decay
   * @dev                accounts for debt decay since last deposit
   * @param _id          ID of market
   * @return             current debt for market in FLOOR decimals
   */
  function currentDebt(uint256 _id) public view override returns (uint256) {
    return markets[_id].totalDebt - debtDecay(_id);
  }

  /**
   * @notice             amount of debt to decay from total debt for market ID
   * @param _id          ID of market
   * @return             amount of debt to decay
   */
  function debtDecay(uint256 _id) public view override returns (uint64) {
    Metadata memory meta = metadata[_id];

    uint256 secondsSince = block.timestamp - meta.lastDecay;

    return uint64(markets[_id].totalDebt * secondsSince / meta.length);
  }

  /**
   * @notice             up to date control variable
   * @dev                accounts for control variable adjustment
   * @param _id          ID of market
   * @return             control variable for market in FLOOR decimals
   */
  function currentControlVariable(uint256 _id) public view returns (uint256) {
    (uint64 decay,,) = _controlDecay(_id);
    return terms[_id].controlVariable - decay;
  }

  /**
   * @notice             is a given market accepting deposits
   * @param _id          ID of market
   */
  function isLive(uint256 _id) public view override returns (bool) {
    return (markets[_id].capacity != 0 && terms[_id].conclusion > block.timestamp);
  }

  /**
   * @notice returns an array of all active market IDs
   */
  function liveMarkets() external view override returns (uint256[] memory) {
    uint256 num;
    for (uint256 i = 0; i < markets.length; i++) {
      if (isLive(i)) num++;
    }

    uint256[] memory ids = new uint256[](num);
    uint256 nonce;
    for (uint256 i = 0; i < markets.length; i++) {
      if (isLive(i)) {
        ids[nonce] = i;
        nonce++;
      }
    }
    return ids;
  }

  /**
   * @notice             returns an array of all active market IDs for a given quote token
   * @param _token       quote token to check for
   */
  function liveMarketsFor(address _token) external view override returns (uint256[] memory) {
    uint256[] memory mkts = marketsForQuote[_token];
    uint256 num;

    for (uint256 i = 0; i < mkts.length; i++) {
      if (isLive(mkts[i])) num++;
    }

    uint256[] memory ids = new uint256[](num);
    uint256 nonce;

    for (uint256 i = 0; i < mkts.length; i++) {
      if (isLive(mkts[i])) {
        ids[nonce] = mkts[i];
        nonce++;
      }
    }
    return ids;
  }

/* ======== INTERNAL VIEW ======== */

  /**
   * @notice                  calculate current market price of quote token in base token
   * @dev                     see marketPrice() for explanation of price computation
   * @dev                     uses info from storage because data has been updated before call (vs marketPrice())
   * @param _id               market ID
   * @return                  price for market in FLOOR decimals
   */ 
  function _marketPrice(uint256 _id) internal view returns (uint256) {
    return 
      terms[_id].controlVariable 
      * _debtRatio(_id) 
      / (10 ** metadata[_id].quoteDecimals);
  }
  
  /**
   * @notice                  calculate debt factoring in decay
   * @dev                     uses info from storage because data has been updated before call (vs debtRatio())
   * @param _id               market ID
   * @return                  current debt for market in quote decimals
   */ 
  function _debtRatio(uint256 _id) internal view returns (uint256) {
    return 
      markets[_id].totalDebt
      * (10 ** metadata[_id].quoteDecimals)
      / treasury.baseSupply(); 
  }

  /**
   * @notice                  amount to decay control variable by
   * @param _id               ID of market
   * @return decay_           change in control variable
   * @return secondsSince_    seconds since last change in control variable
   * @return active_          whether or not change remains active
   */ 
  function _controlDecay(uint256 _id) internal view returns (uint64 decay_, uint48 secondsSince_, bool active_) {
    Adjustment memory info = adjustments[_id];
    if (!info.active) return (0, 0, false);

    secondsSince_ = uint48(block.timestamp) - info.lastAdjustment;

    active_ = secondsSince_ < info.timeToAdjusted;
    decay_ = active_ 
      ? info.change * secondsSince_ / info.timeToAdjusted
      : info.change;
  }
}

File 2 of 13 : NoteKeeper.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.10;

import "../types/FrontEndRewarder.sol";

import "../interfaces/IgFLOOR.sol";
import "../interfaces/IStaking.sol";
import "../interfaces/ITreasury.sol";
import "../interfaces/INoteKeeper.sol";

abstract contract NoteKeeper is INoteKeeper, FrontEndRewarder {

  event CreateNote(address user, uint48 bondId, uint256 index, uint256 payout, uint48 expiry);
  event PushNote(address oldUser, address newUser, uint256 oldIndex, uint256 newIndex);
  event RedeemNote(address user, uint256[] indexes);

  mapping(address => Note[]) public notes; // user deposit data
  mapping(address => mapping(uint256 => address)) private noteTransfers; // change note ownership

  IgFLOOR internal immutable gFLOOR;
  IStaking internal immutable staking;
  ITreasury internal treasury;

  constructor (
    IFloorAuthority _authority,
    IERC20 _floor,
    IgFLOOR _gfloor, 
    IStaking _staking,
    ITreasury _treasury
  ) FrontEndRewarder(_authority, _floor) {
    gFLOOR = _gfloor;
    staking = _staking;
    treasury = _treasury;
  }

  // if treasury address changes on authority, update it
  function updateTreasury() external {
    require(
      msg.sender == authority.governor() ||
      msg.sender == authority.guardian() ||
      msg.sender == authority.policy(),
      "Only authorized"
    );
    treasury = ITreasury(authority.vault());
  }

/* ========== ADD ========== */

  /**
   * @notice             adds a new Note for a user, stores the front end & DAO rewards, and mints & stakes payout & rewards
   * @param _user        the user that owns the Note
   * @param _payout      the amount of FLOOR due to the user
   * @param _expiry      the timestamp when the Note is redeemable
   * @param _marketID    the ID of the market deposited into
   * @return index_      the index of the Note in the user's array
   */
  function addNote(
    address _user, 
    uint256 _payout, 
    uint48 _expiry, 
    uint48 _marketID,
    address _referral
  ) internal returns (uint256 index_) {
    // the index of the note is the next in the user's array
    index_ = notes[_user].length;

    // the new note is pushed to the user's array
    notes[_user].push(
      Note({
        payout: gFLOOR.balanceTo(_payout),
        created: uint48(block.timestamp),
        matured: _expiry,
        redeemed: 0,
        marketID: _marketID
      })
    );

    emit CreateNote(_user, _marketID, index_, gFLOOR.balanceTo(_payout), _expiry);

    // front end operators can earn rewards by referring users
    uint256 rewards = _giveRewards(_payout, _referral);

    // mint and stake payout
    treasury.mint(address(this), _payout + rewards);

    // note that only the payout gets staked (front end rewards are in FLOOR)
    staking.stake(address(this), _payout, false, true);
  }

/* ========== REDEEM ========== */

  /**
   * @notice             redeem notes for user
   * @param _user        the user to redeem for
   * @param _indexes     the note indexes to redeem
   * @param _sendgFLOOR  send payout as gFLOOR or sFLOOR
   * @return payout_     sum of payout sent, in gFLOOR
   */
  function redeem(address _user, uint256[] memory _indexes, bool _sendgFLOOR) external override returns (uint256 payout_) {
    uint48 time = uint48(block.timestamp);

    for (uint256 i = 0; i < _indexes.length; i++) {
      (uint256 pay, bool matured) = pendingFor(_user, _indexes[i]);
      require(matured, "Depository: note not matured");
      if (matured) {
        notes[_user][_indexes[i]].redeemed = time; // mark as redeemed
        payout_ += pay;
      }
    }

    if (_sendgFLOOR) {
      gFLOOR.transfer(_user, payout_); // send payout as gFLOOR
    } else {
      staking.unwrap(_user, payout_); // unwrap and send payout as sFLOOR
    }

    emit RedeemNote(_user, _indexes);
  }

/* ========== TRANSFER ========== */

  /**
   * @notice             approve an address to transfer a note
   * @param _to          address to approve note transfer for
   * @param _index       index of note to approve transfer for
   */ 
  function pushNote(address _to, uint256 _index) external override {
    require(notes[msg.sender][_index].created != 0, "Depository: note not found");
    noteTransfers[msg.sender][_index] = _to;
  }

  /**
   * @notice             transfer a note that has been approved by an address
   * @param _from        the address that approved the note transfer
   * @param _index       the index of the note to transfer (in the sender's array)
   */ 
  function pullNote(address _from, uint256 _index) external override returns (uint256 newIndex_) {
    require(noteTransfers[_from][_index] == msg.sender, "Depository: transfer not found");
    require(notes[_from][_index].redeemed == 0, "Depository: note redeemed");

    newIndex_ = notes[msg.sender].length;
    notes[msg.sender].push(notes[_from][_index]);

    delete notes[_from][_index];

    emit PushNote(_from, msg.sender, _index, newIndex_);
  }

/* ========== VIEW ========== */

  // Note info

  /**
   * @notice             all pending notes for user
   * @param _user        the user to query notes for
   * @return             the pending notes for the user
   */
  function indexesFor(address _user) public view override returns (uint256[] memory) {
    Note[] memory info = notes[_user];

    uint256 length;
    for (uint256 i = 0; i < info.length; i++) {
        if (info[i].redeemed == 0 && info[i].payout != 0) length++;
    }

    uint256[] memory indexes = new uint256[](length);
    uint256 position;

    for (uint256 i = 0; i < info.length; i++) {
        if (info[i].redeemed == 0 && info[i].payout != 0) {
            indexes[position] = i;
            position++;
        }
    }

    return indexes;
  }

  /**
   * @notice             calculate amount available for claim for a single note
   * @param _user        the user that the note belongs to
   * @param _index       the index of the note in the user's array
   * @return payout_     the payout due, in gFLOOR
   * @return matured_    if the payout can be redeemed
   */
  function pendingFor(address _user, uint256 _index) public view override returns (uint256 payout_, bool matured_) {
    Note memory note = notes[_user][_index];

    payout_ = note.payout;
    matured_ = note.redeemed == 0 && note.matured <= block.timestamp && note.payout != 0;
  }
}

File 3 of 13 : SafeERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.7.5;

import {IERC20} from "../interfaces/IERC20.sol";

/// @notice Safe IERC20 and ETH transfer library that safely handles missing return values.
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/libraries/TransferHelper.sol)
/// Taken from Solmate
library SafeERC20 {
    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        (bool success, bytes memory data) = address(token).call(
            abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount)
        );

        require(success && (data.length == 0 || abi.decode(data, (bool))), "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        (bool success, bytes memory data) = address(token).call(
            abi.encodeWithSelector(IERC20.transfer.selector, to, amount)
        );

        require(success && (data.length == 0 || abi.decode(data, (bool))), "TRANSFER_FAILED");
    }

    function safeApprove(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        (bool success, bytes memory data) = address(token).call(
            abi.encodeWithSelector(IERC20.approve.selector, to, amount)
        );

        require(success && (data.length == 0 || abi.decode(data, (bool))), "APPROVE_FAILED");
    }

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

        require(success, "ETH_TRANSFER_FAILED");
    }
}

File 4 of 13 : IERC20Metadata.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.7.5;

import "./IERC20.sol";

interface IERC20Metadata is IERC20 {

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);
}

File 5 of 13 : IBondDepository.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.7.5;

import "./IERC20.sol";

interface IBondDepository {

  // Info about each type of market
  struct Market {
    uint256 capacity; // capacity remaining
    IERC20 quoteToken; // token to accept as payment
    bool capacityInQuote; // capacity limit is in payment token (true) or in FLOOR (false, default)
    uint64 totalDebt; // total debt from market
    uint64 maxPayout; // max tokens in/out (determined by capacityInQuote false/true, respectively)
    uint64 sold; // base tokens out
    uint256 purchased; // quote tokens in
  }

  // Info for creating new markets
  struct Terms {
    bool fixedTerm; // fixed term or fixed expiration
    uint64 controlVariable; // scaling variable for price
    uint48 vesting; // length of time from deposit to maturity if fixed-term
    uint48 conclusion; // timestamp when market no longer offered (doubles as time when market matures if fixed-expiry)
    uint64 maxDebt; // 9 decimal debt maximum in FLOOR
  }

  // Additional info about market.
  struct Metadata {
    uint48 lastTune; // last timestamp when control variable was tuned
    uint48 lastDecay; // last timestamp when market was created and debt was decayed
    uint48 length; // time from creation to conclusion. used as speed to decay debt.
    uint48 depositInterval; // target frequency of deposits
    uint48 tuneInterval; // frequency of tuning
    uint8 quoteDecimals; // decimals of quote token
  }

  // Control variable adjustment data
  struct Adjustment {
    uint64 change;
    uint48 lastAdjustment;
    uint48 timeToAdjusted;
    bool active;
  }


  /**
   * @notice deposit market
   * @param _bid uint256
   * @param _amount uint256
   * @param _maxPrice uint256
   * @param _user address
   * @param _referral address
   * @return payout_ uint256
   * @return expiry_ uint256
   * @return index_ uint256
   */
  function deposit(
    uint256 _bid,
    uint256 _amount,
    uint256 _maxPrice,
    address _user,
    address _referral
  ) external returns (
    uint256 payout_, 
    uint256 expiry_,
    uint256 index_
  );

  function create (
    IERC20 _quoteToken, // token used to deposit
    uint256[3] memory _market, // [capacity, initial price]
    bool[2] memory _booleans, // [capacity in quote, fixed term]
    uint256[2] memory _terms, // [vesting, conclusion]
    uint32[2] memory _intervals // [deposit interval, tune interval]
  ) external returns (uint256 id_);
  function close(uint256 _id) external;

  function isLive(uint256 _bid) external view returns (bool);
  function liveMarkets() external view returns (uint256[] memory);
  function liveMarketsFor(address _quoteToken) external view returns (uint256[] memory);
  function payoutFor(uint256 _amount, uint256 _bid) external view returns (uint256);
  function marketPrice(uint256 _bid) external view returns (uint256);
  function currentDebt(uint256 _bid) external view returns (uint256);
  function debtRatio(uint256 _bid) external view returns (uint256);
  function debtDecay(uint256 _bid) external view returns (uint64);
}

File 6 of 13 : FrontEndRewarder.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.10;

import "../types/FloorAccessControlled.sol";
import "../interfaces/IERC20.sol";

abstract contract FrontEndRewarder is FloorAccessControlled {

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

  uint256 public daoReward; // % reward for dao (3 decimals: 100 = 1%)
  uint256 public refReward; // % reward for referrer (3 decimals: 100 = 1%)
  mapping(address => uint256) public rewards; // front end operator rewards
  mapping(address => bool) public whitelisted; // whitelisted status for operators

  IERC20 internal immutable floor; // reward token

  constructor(
    IFloorAuthority _authority, 
    IERC20 _floor
  ) FloorAccessControlled(_authority) {
    floor = _floor;
  }

  /* ========= EXTERNAL FUNCTIONS ========== */

  // pay reward to front end operator
  function getReward() external {
    uint256 reward = rewards[msg.sender];

    rewards[msg.sender] = 0;
    floor.transfer(msg.sender, reward);
  }

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

  /** 
   * @notice add new market payout to user data
   */
  function _giveRewards(
    uint256 _payout,
    address _referral
  ) internal returns (uint256) {
    // first we calculate rewards paid to the DAO and to the front end operator (referrer)
    uint256 toDAO = _payout * daoReward / 1e4;
    uint256 toRef = _payout * refReward / 1e4;

    // and store them in our rewards mapping
    if (whitelisted[_referral]) {
      rewards[_referral] += toRef;
      rewards[authority.guardian()] += toDAO;
    } else { // the DAO receives both rewards if referrer is not whitelisted
      rewards[authority.guardian()] += toDAO + toRef;
    }
    return toDAO + toRef;
  }

  /**
   * @notice set rewards for front end operators and DAO
   */
  function setRewards(uint256 _toFrontEnd, uint256 _toDAO) external onlyGovernor {
    refReward = _toFrontEnd;
    daoReward = _toDAO;
  }

  /**
   * @notice add or remove addresses from the reward whitelist
   */
  function whitelist(address _operator) external onlyPolicy {
    whitelisted[_operator] = !whitelisted[_operator];
  }
}

File 7 of 13 : IgFLOOR.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.7.5;

import "./IERC20.sol";

interface IgFLOOR is IERC20 {
  function mint(address _to, uint256 _amount) external;

  function burn(address _from, uint256 _amount) external;

  function index() external view returns (uint256);

  function balanceFrom(uint256 _amount) external view returns (uint256);

  function balanceTo(uint256 _amount) external view returns (uint256);
}

File 8 of 13 : IStaking.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.7.5;

interface IStaking {
    function stake(
        address _to,
        uint256 _amount,
        bool _rebasing,
        bool _claim
    ) external returns (uint256);

    function claim(address _recipient, bool _rebasing) external returns (uint256);

    function forfeit() external returns (uint256);

    function toggleLock() external;

    function unstake(
        address _to,
        uint256 _amount,
        bool _trigger,
        bool _rebasing
    ) external returns (uint256);

    function wrap(address _to, uint256 _amount) external returns (uint256 gBalance_);

    function unwrap(address _to, uint256 _amount) external returns (uint256 sBalance_);

    function rebase() external;

    function index() external view returns (uint256);

    function contractBalance() external view returns (uint256);

    function totalStaked() external view returns (uint256);

    function supplyInWarmup() external view returns (uint256);
}

File 9 of 13 : ITreasury.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.7.5;

interface ITreasury {
    function bondCalculator(address _address) external view returns (address);

    function deposit(uint256 _amount, address _token, uint256 _profit) external returns (uint256);

    function withdraw(uint256 _amount, address _token) external;

    function depositERC721(address _token, uint256 _tokenId) external;

    function withdrawERC721(address _token, uint256 _tokenId) external;

    function tokenValue(address _token, uint256 _amount) external view returns (uint256 value_);

    function mint(address _recipient, uint256 _amount) external;

    function manage(address _token, uint256 _amount) external;

    function allocatorManage(address _token, uint256 _amount) external;

    function claimNFTXRewards(address _liquidityStaking, uint256 _vaultId, address _rewardToken) external;

    function incurDebt(uint256 amount_, address token_) external;

    function repayDebtWithReserve(uint256 amount_, address token_) external;

    function excessReserves() external view returns (uint256);
    
    function riskOffValuation(address _token) external view returns (uint256);

    function baseSupply() external view returns (uint256);
}

File 10 of 13 : INoteKeeper.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.7.5;

interface INoteKeeper {
  // Info for market note
  struct Note {
    uint256 payout; // gFLOOR remaining to be paid
    uint48 created; // time market was created
    uint48 matured; // timestamp when market is matured
    uint48 redeemed; // time market was redeemed
    uint48 marketID; // market ID of deposit. uint48 to avoid adding a slot.
  }

  function redeem(address _user, uint256[] memory _indexes, bool _sendgFLOOR) external returns (uint256);
  function pushNote(address to, uint256 index) external;
  function pullNote(address from, uint256 index) external returns (uint256 newIndex_);

  function indexesFor(address _user) external view returns (uint256[] memory);
  function pendingFor(address _user, uint256 _index) external view returns (uint256 payout_, bool matured_);
}

File 11 of 13 : FloorAccessControlled.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.7.5;

import "../interfaces/IFloorAuthority.sol";

abstract contract FloorAccessControlled {

    /* ========== EVENTS ========== */

    event AuthorityUpdated(IFloorAuthority indexed authority);

    string UNAUTHORIZED = "UNAUTHORIZED"; // save gas

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

    IFloorAuthority public authority;


    /* ========== Constructor ========== */

    constructor(IFloorAuthority _authority) {
        authority = _authority;
        emit AuthorityUpdated(_authority);
    }
    

    /* ========== MODIFIERS ========== */
    
    modifier onlyGovernor() {
        require(msg.sender == authority.governor(), UNAUTHORIZED);
        _;
    }
    
    modifier onlyGuardian() {
        require(msg.sender == authority.guardian(), UNAUTHORIZED);
        _;
    }
    
    modifier onlyPolicy() {
        require(msg.sender == authority.policy(), UNAUTHORIZED);
        _;
    }

    modifier onlyVault() {
        require(msg.sender == authority.vault(), UNAUTHORIZED);
        _;
    }
    
    /* ========== GOV ONLY ========== */
    
    function setAuthority(IFloorAuthority _newAuthority) external onlyGovernor {
        authority = _newAuthority;
        emit AuthorityUpdated(_newAuthority);
    }
}

File 12 of 13 : IERC20.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.7.5;

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

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

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

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

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

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

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

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

File 13 of 13 : IFloorAuthority.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity >=0.7.5;

interface IFloorAuthority {
    /* ========== EVENTS ========== */
    
    event GovernorPushed(address indexed from, address indexed to, bool _effectiveImmediately);
    event GuardianPushed(address indexed from, address indexed to, bool _effectiveImmediately);    
    event PolicyPushed(address indexed from, address indexed to, bool _effectiveImmediately);    
    event VaultPushed(address indexed from, address indexed to, bool _effectiveImmediately);    

    event GovernorPulled(address indexed from, address indexed to);
    event GuardianPulled(address indexed from, address indexed to);
    event PolicyPulled(address indexed from, address indexed to);
    event VaultPulled(address indexed from, address indexed to);

    /* ========== VIEW ========== */
    
    function governor() external view returns (address);
    function guardian() external view returns (address);
    function policy() external view returns (address);
    function vault() external view returns (address);
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IFloorAuthority","name":"_authority","type":"address"},{"internalType":"contract IERC20","name":"_floor","type":"address"},{"internalType":"contract IgFLOOR","name":"_gfloor","type":"address"},{"internalType":"contract IStaking","name":"_staking","type":"address"},{"internalType":"contract ITreasury","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IFloorAuthority","name":"authority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"}],"name":"Bond","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"CloseMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"quoteToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"initialPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"capacity","type":"uint256"},{"indexed":false,"internalType":"bool","name":"capacityInQuote","type":"bool"},{"indexed":false,"internalType":"uint256","name":"conclusion","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"vestingPeriod","type":"uint256"}],"name":"CreateMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint48","name":"bondId","type":"uint48"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint48","name":"expiry","type":"uint48"}],"name":"CreateNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUser","type":"address"},{"indexed":false,"internalType":"address","name":"newUser","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newIndex","type":"uint256"}],"name":"PushNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"indexes","type":"uint256[]"}],"name":"RedeemNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"oldControlVariable","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"newControlVariable","type":"uint64"}],"name":"Tuned","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"adjustments","outputs":[{"internalType":"uint64","name":"change","type":"uint64"},{"internalType":"uint48","name":"lastAdjustment","type":"uint48"},{"internalType":"uint48","name":"timeToAdjusted","type":"uint48"},{"internalType":"bool","name":"active","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract IFloorAuthority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"close","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_quoteToken","type":"address"},{"internalType":"uint256[3]","name":"_market","type":"uint256[3]"},{"internalType":"bool[2]","name":"_booleans","type":"bool[2]"},{"internalType":"uint256[2]","name":"_terms","type":"uint256[2]"},{"internalType":"uint32[2]","name":"_intervals","type":"uint32[2]"}],"name":"create","outputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"currentControlVariable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"currentDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"debtDecay","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_maxPrice","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_referral","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"payout_","type":"uint256"},{"internalType":"uint256","name":"expiry_","type":"uint256"},{"internalType":"uint256","name":"index_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"indexesFor","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"isLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liveMarkets","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"liveMarketsFor","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"marketPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"markets","outputs":[{"internalType":"uint256","name":"capacity","type":"uint256"},{"internalType":"contract IERC20","name":"quoteToken","type":"address"},{"internalType":"bool","name":"capacityInQuote","type":"bool"},{"internalType":"uint64","name":"totalDebt","type":"uint64"},{"internalType":"uint64","name":"maxPayout","type":"uint64"},{"internalType":"uint64","name":"sold","type":"uint64"},{"internalType":"uint256","name":"purchased","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"marketsForQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"metadata","outputs":[{"internalType":"uint48","name":"lastTune","type":"uint48"},{"internalType":"uint48","name":"lastDecay","type":"uint48"},{"internalType":"uint48","name":"length","type":"uint48"},{"internalType":"uint48","name":"depositInterval","type":"uint48"},{"internalType":"uint48","name":"tuneInterval","type":"uint48"},{"internalType":"uint8","name":"quoteDecimals","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"notes","outputs":[{"internalType":"uint256","name":"payout","type":"uint256"},{"internalType":"uint48","name":"created","type":"uint48"},{"internalType":"uint48","name":"matured","type":"uint48"},{"internalType":"uint48","name":"redeemed","type":"uint48"},{"internalType":"uint48","name":"marketID","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"payoutFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"pendingFor","outputs":[{"internalType":"uint256","name":"payout_","type":"uint256"},{"internalType":"bool","name":"matured_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"pullNote","outputs":[{"internalType":"uint256","name":"newIndex_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"pushNote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256[]","name":"_indexes","type":"uint256[]"},{"internalType":"bool","name":"_sendgFLOOR","type":"bool"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"payout_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IFloorAuthority","name":"_newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_toFrontEnd","type":"uint256"},{"internalType":"uint256","name":"_toDAO","type":"uint256"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"terms","outputs":[{"internalType":"bool","name":"fixedTerm","type":"bool"},{"internalType":"uint64","name":"controlVariable","type":"uint64"},{"internalType":"uint48","name":"vesting","type":"uint48"},{"internalType":"uint48","name":"conclusion","type":"uint48"},{"internalType":"uint64","name":"maxDebt","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

610120604052600c60e08190526b15539055551213d49256915160a21b6101009081526200003191600091906200017b565b503480156200003f57600080fd5b50604051620046723803806200467283398101604081905262000062916200023a565b600180546001600160a01b0319166001600160a01b038716908117909155604051869186918691869186918691869183917f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad90600090a2506001600160a01b0390811660805293841660a0525090821660c052600880546001600160a01b03191691831691909117905560405163095ea7b360e01b81528582166004820152722cd76fe086b93ce2f768a00b22a000000000006024820152908716925063095ea7b391506044016020604051808303816000875af115801562000149573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016f9190620002ba565b50505050505062000322565b8280546200018990620002e5565b90600052602060002090601f016020900481019282620001ad5760008555620001f8565b82601f10620001c857805160ff1916838001178555620001f8565b82800160010185558215620001f8579182015b82811115620001f8578251825591602001919060010190620001db565b50620002069291506200020a565b5090565b5b808211156200020657600081556001016200020b565b6001600160a01b03811681146200023757600080fd5b50565b600080600080600060a086880312156200025357600080fd5b8551620002608162000221565b6020870151909550620002738162000221565b6040870151909450620002868162000221565b6060870151909350620002998162000221565b6080870151909250620002ac8162000221565b809150509295509295909350565b600060208284031215620002cd57600080fd5b81518015158114620002de57600080fd5b9392505050565b600181811c90821680620002fa57607f821691505b602082108114156200031c57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05161430b62000367600039600081816124fb015261309701526000818161246201528181612dc40152612f2f0152600061106f015261430b6000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063abbf4b171161011a578063c9b67af5116100ad578063e0b117ff1161007c578063e0b117ff14610598578063e3684e39146105e0578063e481b26514610637578063f1b7dc781461064a578063f3191a461461065d57600080fd5b8063c9b67af514610547578063d62fbdd31461054f578063d6db4df814610562578063d936547e1461057557600080fd5b8063bf7e214f116100e9578063bf7e214f14610492578063c0680e20146104bd578063c0aa0e8a146104d0578063c3e0fb1c1461051f57600080fd5b8063abbf4b171461036a578063b1283e7714610395578063bc3b2b12146103f5578063bcb296671461047f57600080fd5b806364914439116101925780637c770aae116101615780637c770aae1461030e5780639b19251a1461033c5780639c7697871461034f578063a42206101461035757600080fd5b806364914439146102b5578063654e51e7146102d55780636a6c575d146102e85780637a9e5e4b146102fb57600080fd5b806321a7d29b116101ce57806321a7d29b1461026457806327507458146102775780633adec5a71461029a5780633d18b912146102ad57600080fd5b80630700037d146102005780630a9d85eb146102335780630aebeb4e146102465780631885f5801461025b575b600080fd5b61022061020e366004613a9a565b60046020526000908152604090205481565b6040519081526020015b60405180910390f35b610220610241366004613abe565b610666565b610259610254366004613abe565b6106be565b005b61022060025481565b610220610272366004613c5e565b610809565b61028a610285366004613abe565b610f6f565b604051901515815260200161022a565b6102206102a8366004613abe565b610fd8565b610259611034565b6102c86102c3366004613a9a565b6110e0565b60405161022a9190613d5a565b6102596102e3366004613d6d565b61126e565b6102206102f6366004613d6d565b611325565b610259610309366004613a9a565b6113f5565b61032161031c366004613d8f565b6114eb565b6040805193845260208401929092529082015260600161022a565b61025961034a366004613a9a565b611906565b6102596119db565b610220610365366004613de5565b611c61565b61037d610378366004613abe565b611f21565b6040516001600160401b03909116815260200161022a565b6103a86103a3366004613abe565b612005565b604080519788526001600160a01b039096166020880152931515948601949094526001600160401b0391821660608601528116608085015290911660a083015260c082015260e00161022a565b610447610403366004613abe565b600c602052600090815260409020546001600160401b0381169065ffffffffffff600160401b8204811691600160701b81049091169060ff600160a01b9091041684565b604080516001600160401b0395909516855265ffffffffffff938416602086015291909216908301521515606082015260800161022a565b61022061048d366004613abe565b612073565b6001546104a5906001600160a01b031681565b6040516001600160a01b03909116815260200161022a565b6102206104cb366004613de5565b6120cf565b6104e36104de366004613abe565b612100565b6040805195151586526001600160401b03948516602087015265ffffffffffff938416908601529116606084015216608082015260a00161022a565b61053261052d366004613de5565b612159565b6040805192835290151560208301520161022a565b6102c8612224565b61022061055d366004613e11565b61230c565b610259610570366004613de5565b6125ab565b61028a610583366004613a9a565b60056020526000908152604090205460ff1681565b6105ab6105a6366004613de5565b61266d565b6040805195865265ffffffffffff9485166020870152928416928501929092528216606084015216608082015260a00161022a565b6105f36105ee366004613abe565b6126d0565b6040805165ffffffffffff97881681529587166020870152938616938501939093529084166060840152909216608082015260ff90911660a082015260c00161022a565b6102c8610645366004613a9a565b61272e565b610220610658366004613abe565b612952565b61022060035481565b600080610672836129fd565b5050905080600a848154811061068a5761068a613edb565b6000918252602090912001546106ae919061010090046001600160401b0316613f07565b6001600160401b03169392505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630505c8c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610711573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107359190613f2f565b6001600160a01b0316336001600160a01b0316146000906107725760405162461bcd60e51b81526004016107699190613f4c565b60405180910390fd5b5042600a828154811061078757610787613edb565b90600052602060002001600001600f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506000600982815481106107cb576107cb613edb565b6000918252602082206004909102019190915560405182917f8401d05adbea6548a6999cc1540766e6d2ff919292142862893d0e62ec79fbe591a250565b60015460408051630505c8c960e01b815290516000926001600160a01b031691630505c8c99160048083019260209291908290030181865afa158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190613f2f565b6001600160a01b0316336001600160a01b0316146000906108ab5760405162461bcd60e51b81526004016107699190613f4c565b5060208301516000906108bf904290613ff4565b90506000876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610901573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610925919061400b565b60ff16905060008681602002015161093e578751610976565b61094982600a614112565b6020890151895161096290670de0b6b3a764000061411e565b61096c9190614153565b6109769190614153565b855190915060009084906109909063ffffffff1684614167565b6001600160401b03166109a39190614153565b90506000620186a08a600260200201516109c6906001600160401b03861661411e565b6109d09190614153565b6109e3906001600160401b038516614196565b90506000836001600160401b0316600860009054906101000a90046001600160a01b03166001600160a01b031663860f50486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6891906141ae565b60208d0151610a77919061411e565b610a819190614153565b600980546040805160e0810190915290995091925090808d6000602002015181526020018e6001600160a01b031681526020018c600060028110610ac757610ac7613edb565b60209081029190910151151582526001600160401b0380891683830152878116604080850191909152600060608086018290526080958601829052875460018181018a5598835291859020875160049093020191825593860151818801805488850151968901518616600160a81b0267ffffffffffffffff60a81b19971515600160a01b026001600160a81b03199092166001600160a01b03909416939093171795909516179093559284015160028301805460a0808801518516600160401b026fffffffffffffffffffffffffffffffff19909216939094169290921791909117905560c09093015160039091015580519182019052600a9181908d90602002015115158152602001836001600160401b031681526020018b600060028110610bf357610bf3613edb565b602002015165ffffffffffff1681526020018b600160028110610c1857610c18613edb565b6020908102919091015165ffffffffffff90811683526001600160401b038088169383019390935284546001810186556000958652828620855191018054868501516040808901516060808b01516080909b01518a16600160a81b0267ffffffffffffffff60a81b199b8916600160781b0265ffffffffffff60781b19938a16600160481b029390931674ffffffffffffffffffffffff0000000000000000001995909b166101000268ffffffffffffffff00199815159890981668ffffffffffffffffff1990961695909517969096179290921697909717179690961695909517909455825160c081018452428216808252928101929092528a1691810191909152600b9290918201908b906020908102919091015163ffffffff168252018a6001602002015163ffffffff1665ffffffffffff1681526020018760ff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548165ffffffffffff021916908365ffffffffffff160217905550604082015181600001600c6101000a81548165ffffffffffff021916908365ffffffffffff16021790555060608201518160000160126101000a81548165ffffffffffff021916908365ffffffffffff16021790555060808201518160000160186101000a81548165ffffffffffff021916908365ffffffffffff16021790555060a082015181600001601e6101000a81548160ff021916908360ff1602179055505050600d60008d6001600160a01b03166001600160a01b031681526020019081526020016000208790806001815401808255809150506001900390600052602060002001600090919091909150558b6001600160a01b0316877fb2d2d229227861ab44a51447b9eb227b7191d1cfb2046d5c3f340c30569e6e9e8d600160038110610f0457610f04613edb565b60200201518e600060200201518e600060200201518e600160200201518f60006020020151604051610f58959493929190948552602085019390935290151560408401526060830152608082015260a00190565b60405180910390a350505050505095945050505050565b600060098281548110610f8457610f84613edb565b906000526020600020906004020160000154600014158015610fd2575042600a8381548110610fb557610fb5613edb565b600091825260209091200154600160781b900465ffffffffffff16115b92915050565b6000600b8281548110610fed57610fed613edb565b60009182526020909120015461100e90600160f01b900460ff16600a6141c7565b61101783612952565b61102084610666565b61102a919061411e565b610fd29190614153565b33600081815260046020819052604080832080549390555163a9059cbb60e01b81529081019290925260248201819052906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156110b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dc91906141d6565b5050565b6001600160a01b0381166000908152600d6020908152604080832080548251818502810185019093528083526060949383018282801561113f57602002820191906000526020600020905b81548152602001906001019080831161112b575b50505050509050600080600090505b825181101561119e5761117983828151811061116c5761116c613edb565b6020026020010151610f6f565b1561118c5781611188816141f3565b9250505b80611196816141f3565b91505061114e565b506000816001600160401b038111156111b9576111b9613ad7565b6040519080825280602002602001820160405280156111e2578160200160208202803683370190505b5090506000805b84518110156112635761120785828151811061116c5761116c613edb565b156112515784818151811061121e5761121e613edb565b602002602001015183838151811061123857611238613edb565b60209081029190910101528161124d816141f3565b9250505b8061125b816141f3565b9150506111e9565b509095945050505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e59190613f2f565b6001600160a01b0316336001600160a01b0316146000906113195760405162461bcd60e51b81526004016107699190613f4c565b50600391909155600255565b600080600b838154811061133b5761133b613edb565b60009182526020918290206040805160c081018252919092015465ffffffffffff8082168352600160301b8204811694830194909452600160601b8104841692820192909252600160901b820483166060820152600160c01b8204909216608083015260ff600160f01b9091041660a082018190529091506113be90600a6141c7565b6113c784610fd8565b6113d986670de0b6b3a764000061411e565b6113e39190614153565b6113ed9190614153565b949350505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015611448573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146c9190613f2f565b6001600160a01b0316336001600160a01b0316146000906114a05760405162461bcd60e51b81526004016107699190613f4c565b50600180546001600160a01b0319166001600160a01b0383169081179091556040517f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad90600090a250565b6000806000806009898154811061150457611504613edb565b906000526020600020906004020190506000600a8a8154811061152957611529613edb565b60009182526020918290206040805160a081018252919092015460ff8116151582526001600160401b03610100820481169483019490945265ffffffffffff600160481b8204811693830193909352600160781b8104831660608301819052600160a81b909104909316608082015292504291908216106115ec5760405162461bcd60e51b815260206004820152601c60248201527f4465706f7369746f72793a206d61726b657420636f6e636c75646564000000006044820152606401610769565b6115f68b82612aea565b60006116018c612d0d565b9050898111156116535760405162461bcd60e51b815260206004820152601f60248201527f4465706f7369746f72793a206d6f7265207468616e206d6178207072696365006044820152606401610769565b600b8c8154811061166657611666613edb565b60009182526020909120015461168790600160f01b900460ff16600a6141c7565b8161169a8d670de0b6b3a764000061411e565b6116a49190614153565b6116ae9190614153565b60028501549097506001600160401b031687111561170e5760405162461bcd60e51b815260206004820152601d60248201527f4465706f7369746f72793a206d61782073697a652065786365656465640000006044820152606401610769565b6001840154600160a01b900460ff166117275786611729565b8a5b84600001600082825461173c9190613ff4565b90915550508251611751578260400151611761565b818360400151611761919061420e565b65ffffffffffff1695508a84600301600082825461177f9190614196565b90915550506002840180548891906008906117ab908490600160401b90046001600160401b0316614238565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550868460010160158282829054906101000a90046001600160401b03166117f59190614238565b92506101000a8154816001600160401b0302191690836001600160401b031602179055508b7f8f81d43253aa8fe80c98ec1a0b2e10f8c0fb0f24cf3c4a5e582e56de3aa7178e8c838a60405161185e939291909283526020830191909152604082015260600190565b60405180910390a26118738988888f8c612d83565b6008546001860154919650611897916001600160a01b03908116913391168e613119565b600184015460808401516001600160401b03600160a81b9092048216911610156118ed5760008085556040518d917f8401d05adbea6548a6999cc1540766e6d2ff919292142862893d0e62ec79fbe591a26118f7565b6118f78c8361322c565b50505050955095509592505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630505c8c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197d9190613f2f565b6001600160a01b0316336001600160a01b0316146000906119b15760405162461bcd60e51b81526004016107699190613f4c565b506001600160a01b03166000908152600560205260409020805460ff19811660ff90911615179055565b600160009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a529190613f2f565b6001600160a01b0316336001600160a01b03161480611af85750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611abf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae39190613f2f565b6001600160a01b0316336001600160a01b0316145b80611b8a5750600160009054906101000a90046001600160a01b03166001600160a01b0316630505c8c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b759190613f2f565b6001600160a01b0316336001600160a01b0316145b611bc85760405162461bcd60e51b815260206004820152600f60248201526e13db9b1e48185d5d1a1bdc9a5e9959608a1b6044820152606401610769565b600160009054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3f9190613f2f565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382811660009081526007602090815260408083208584529091528120549091163314611cd75760405162461bcd60e51b815260206004820152601e60248201527f4465706f7369746f72793a207472616e73666572206e6f7420666f756e6400006044820152606401610769565b6001600160a01b0383166000908152600660205260409020805483908110611d0157611d01613edb565b6000918252602090912060029091020160010154600160601b900465ffffffffffff1615611d715760405162461bcd60e51b815260206004820152601960248201527f4465706f7369746f72793a206e6f74652072656465656d6564000000000000006044820152606401610769565b503360009081526006602052604080822080546001600160a01b038616845291909220805491929184908110611da957611da9613edb565b600091825260208083208454600181810187559585528285206002948502909201805491909402909101908155918401805492909401805465ffffffffffff19811665ffffffffffff94851690811783558654600160301b908190048616026bffffffffffffffffffffffff1990921617178082558554600160601b9081900485160265ffffffffffff60601b198216811783559554600160901b9081900490941690930265ffffffffffff60901b199095166bffffffffffffffffffffffff60601b19909316929092179390931790556001600160a01b0385168152600690915260409020805483908110611ea157611ea1613edb565b60009182526020808320600292909202909101918255600190910180546001600160c01b0319169055604080516001600160a01b038616815233928101929092528101839052606081018290527f706f2211bcf8c95f0be5018c3ddd4a13ed3aef954937f21655b9e3d3854eae579060800160405180910390a192915050565b600080600b8381548110611f3757611f37613edb565b600091825260208083206040805160c081018252939091015465ffffffffffff8082168552600160301b82048116938501849052600160601b8204811692850192909252600160901b810482166060850152600160c01b81049091166080840152600160f01b900460ff1660a0830152909250611fb49042613ff4565b9050816040015165ffffffffffff168160098681548110611fd757611fd7613edb565b60009182526020909120600490910201600101546113e39190600160a81b90046001600160401b031661411e565b6009818154811061201557600080fd5b600091825260209091206004909102018054600182015460028301546003909301549193506001600160a01b0381169260ff600160a01b830416926001600160401b03600160a81b90930483169282811692600160401b9004169087565b600061207e82611f21565b6009838154811061209157612091613edb565b906000526020600020906004020160010160159054906101000a90046001600160401b03166120c09190613f07565b6001600160401b031692915050565b600d60205281600052604060002081815481106120eb57600080fd5b90600052602060002001600091509150505481565b600a818154811061211057600080fd5b60009182526020909120015460ff811691506001600160401b03610100820481169165ffffffffffff600160481b8204811692600160781b830490911691600160a81b90041685565b6001600160a01b03821660009081526006602052604081208054829182918590811061218757612187613edb565b60009182526020918290206040805160a0810182526002909302909101805480845260019091015465ffffffffffff80821695850195909552600160301b8104851692840192909252600160601b8204841660608401819052600160901b9092049093166080830152919450915015801561220e575042816040015165ffffffffffff1611155b801561221a5750805115155b9150509250929050565b60606000805b6009548110156122625761223d81610f6f565b15612250578161224c816141f3565b9250505b8061225a816141f3565b91505061222a565b506000816001600160401b0381111561227d5761227d613ad7565b6040519080825280602002602001820160405280156122a6578160200160208202803683370190505b5090506000805b600954811015612303576122c081610f6f565b156122f157808383815181106122d8576122d8613edb565b6020908102919091010152816122ed816141f3565b9250505b806122fb816141f3565b9150506122ad565b50909392505050565b600042815b8451811015612435576000806123408888858151811061233357612333613edb565b6020026020010151612159565b91509150806123915760405162461bcd60e51b815260206004820152601c60248201527f4465706f7369746f72793a206e6f7465206e6f74206d617475726564000000006044820152606401610769565b8015612420576001600160a01b038816600090815260066020526040902087518591908990869081106123c6576123c6613edb565b6020026020010151815481106123de576123de613edb565b9060005260206000209060020201600101600c6101000a81548165ffffffffffff021916908365ffffffffffff160217905550818561241d9190614196565b94505b5050808061242d906141f3565b915050612311565b5082156124d55760405163a9059cbb60e01b81526001600160a01b038681166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156124ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124cf91906141d6565b5061256a565b6040516339f4769360e01b81526001600160a01b038681166004830152602482018490527f000000000000000000000000000000000000000000000000000000000000000016906339f47693906044016020604051808303816000875af1158015612544573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256891906141ae565b505b7fc23d625f7a5488c9b6dc65d24695ee2302b430809ea4e6c46793aab8b059cbdb858560405161259b92919061425a565b60405180910390a1509392505050565b3360009081526006602052604090208054829081106125cc576125cc613edb565b600091825260209091206001600290920201015465ffffffffffff166126345760405162461bcd60e51b815260206004820152601a60248201527f4465706f7369746f72793a206e6f7465206e6f7420666f756e640000000000006044820152606401610769565b3360009081526007602090815260408083209383529290522080546001600160a01b0319166001600160a01b0392909216919091179055565b6006602052816000526040600020818154811061268957600080fd5b60009182526020909120600290910201805460019091015490925065ffffffffffff8082169250600160301b8204811691600160601b8104821691600160901b9091041685565b600b81815481106126e057600080fd5b60009182526020909120015465ffffffffffff8082169250600160301b8204811691600160601b8104821691600160901b8204811691600160c01b810490911690600160f01b900460ff1686565b6001600160a01b0381166000908152600660209081526040808320805482518185028101850190935280835260609493849084015b828210156127d95760008481526020908190206040805160a081018252600286029092018054835260019081015465ffffffffffff80821685870152600160301b8204811693850193909352600160601b810483166060850152600160901b900490911660808301529083529092019101612763565b505050509050600080600090505b82518110156128685782818151811061280257612802613edb565b60200260200101516060015165ffffffffffff166000148015612843575082818151811061283257612832613edb565b602002602001015160000151600014155b156128565781612852816141f3565b9250505b80612860816141f3565b9150506127e7565b506000816001600160401b0381111561288357612883613ad7565b6040519080825280602002602001820160405280156128ac578160200160208202803683370190505b5090506000805b8451811015611263578481815181106128ce576128ce613edb565b60200260200101516060015165ffffffffffff16600014801561290f57508481815181106128fe576128fe613edb565b602002602001015160000151600014155b15612940578083838151811061292757612927613edb565b60209081029190910101528161293c816141f3565b9250505b8061294a816141f3565b9150506128b3565b600854604080516310c1ea0960e31b815290516000926001600160a01b03169163860f50489160048083019260209291908290030181865afa15801561299c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c091906141ae565b600b83815481106129d3576129d3613edb565b6000918252602090912001546129f490600160f01b900460ff16600a6141c7565b61102084612073565b6000818152600c60209081526040808320815160808101835290546001600160401b0381168252600160401b810465ffffffffffff90811694830194909452600160701b810490931691810191909152600160a01b90910460ff1615156060820181905282918291612a7a57600080600093509350935050612ae3565b6020810151612a89904261427e565b9250806040015165ffffffffffff168365ffffffffffff1610915081612ab0578051612adf565b806040015165ffffffffffff168365ffffffffffff168260000151612ad59190614167565b612adf919061429d565b9350505b9193909250565b612af382611f21565b60098381548110612b0657612b06613edb565b906000526020600020906004020160010160158282829054906101000a90046001600160401b0316612b389190613f07565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555080600b8381548110612b7057612b70613edb565b60009182526020808320909101805465ffffffffffff94909416600160301b026bffffffffffff0000000000001990941693909317909255838152600c909152604090205460ff600160a01b90910416156110dc576000828152600c60205260408120908080612bdf866129fd565b92509250925082600a8781548110612bf957612bf9613edb565b60009182526020909120018054600190612c2290849061010090046001600160401b0316613f07565b92506101000a8154816001600160401b0302191690836001600160401b031602179055508015612cf957835483908590600090612c699084906001600160401b0316613f07565b92506101000a8154816001600160401b0302191690836001600160401b031602179055508184600001600e8282829054906101000a900465ffffffffffff16612cb2919061427e565b82546101009290920a65ffffffffffff81810219909316918316021790915585546dffffffffffff00000000000000001916600160401b9188169190910217855550612d05565b835460ff60a01b191684555b505050505050565b6000600b8281548110612d2257612d22613edb565b600091825260209091200154612d4390600160f01b900460ff16600a6141c7565b612d4c836137a3565b600a8481548110612d5f57612d5f613edb565b60009182526020909120015461102a919061010090046001600160401b031661411e565b6001600160a01b03858116600090815260066020526040908190208054825160a08101938490526319a948db60e21b90935260a483018890529290919081907f0000000000000000000000000000000000000000000000000000000000000000166366a5236c60c48301602060405180830381865afa158015612e0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2e91906141ae565b815265ffffffffffff428116602080840191909152888216604080850191909152600060608086018290528a8516608096870152875460018181018a559883529184902087516002909302019182559286015196018054868301519387015196909501518416600160901b0265ffffffffffff60901b19968516600160601b02969096166bffffffffffffffffffffffff60601b19938516600160301b026bffffffffffffffffffffffff19909616979094169690961793909317161791909117909155516319a948db60e21b81527f1f58724e9d5598976a9faf8e2e354dbc7d54ab2d81e09e0c682e2893881e1aa7908790859084906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906366a5236c90612f68908c9060040190815260200190565b602060405180830381865afa158015612f85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa991906141ae565b604080516001600160a01b03909516855265ffffffffffff938416602086015284019190915260608301528616608082015260a00160405180910390a16000612ff28684613886565b6008549091506001600160a01b03166340c10f1930613011848a614196565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561305757600080fd5b505af115801561306b573d6000803e3d6000fd5b5050604051631b0cd93b60e31b81523060048201526024810189905260006044820152600160648201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316925063d866c9d891506084016020604051808303816000875af11580156130ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310e91906141ae565b505095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161317d91906142c3565b6000604051808303816000865af19150503d80600081146131ba576040519150601f19603f3d011682016040523d82523d6000602084013e6131bf565b606091505b50915091508180156131e95750805115806131e95750808060200190518101906131e991906141d6565b612d055760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610769565b6000600b838154811061324157613241613edb565b60009182526020918290206040805160c081018252929091015465ffffffffffff808216808552600160301b8304821695850195909552600160601b8204811692840192909252600160901b810482166060840152600160c01b810490911660808301819052600160f01b90910460ff1660a08301529092506132c39161420e565b65ffffffffffff168265ffffffffffff161061379e576000600984815481106132ee576132ee613edb565b600091825260208083206040805160e08101825260049094029091018054845260018101546001600160a01b0381169385019390935260ff600160a01b8404161515918401919091526001600160401b03600160a81b9092048216606084015260028101548083166080850152600160401b900490911660a08301526003015460c0820152600a805491935085918790811061338c5761338c613edb565b6000918252602090912001546133b19190600160781b900465ffffffffffff1661427e565b65ffffffffffff16905060006133c686612d0d565b9050600083604001516133da578351613414565b60a08501516133ea90600a6141c7565b8451839061340090670de0b6b3a764000061411e565b61340a9190614153565b6134149190614153565b905082856060015165ffffffffffff168261342f919061411e565b6134399190614153565b6009888154811061344c5761344c613edb565b906000526020600020906004020160020160006101000a8154816001600160401b0302191690836001600160401b03160217905550600083866040015165ffffffffffff168361349c919061411e565b6134a69190614153565b9050600081600860009054906101000a90046001600160a01b03166001600160a01b031663860f50486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352291906141ae565b61352c908661411e565b6135369190614153565b9050887f3070b0e3e52b8713c7489d32604ea4b0970024f74c6e05319269a19bc1e3a9d9600a8b8154811061356d5761356d613edb565b60009182526020918290200154604080516101009092046001600160401b0390811683528616928201929092520160405180910390a2600a89815481106135b6576135b6613edb565b6000918252602090912001546001600160401b036101009091048116908216106136245780600a8a815481106135ee576135ee613edb565b9060005260206000200160000160016101000a8154816001600160401b0302191690836001600160401b0316021790555061375c565b600081600a8b8154811061363a5761363a613edb565b60009182526020909120015461365e919061010090046001600160401b0316613f07565b90506040518060800160405280826001600160401b031681526020018a65ffffffffffff168152602001896080015165ffffffffffff16815260200160011515815250600c60008c815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a81548165ffffffffffff021916908365ffffffffffff160217905550604082015181600001600e6101000a81548165ffffffffffff021916908365ffffffffffff16021790555060608201518160000160146101000a81548160ff021916908315150217905550905050505b87600b8a8154811061377057613770613edb565b6000918252602090912001805465ffffffffffff191665ffffffffffff929092169190911790555050505050505b505050565b600854604080516310c1ea0960e31b815290516000926001600160a01b03169163860f50489160048083019260209291908290030181865afa1580156137ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381191906141ae565b600b838154811061382457613824613edb565b60009182526020909120015461384590600160f01b900460ff16600a6141c7565b6009848154811061385857613858613edb565b600091825260209091206004909102016001015461102a9190600160a81b90046001600160401b031661411e565b6000806127106002548561389a919061411e565b6138a49190614153565b90506000612710600354866138b9919061411e565b6138c39190614153565b6001600160a01b03851660009081526005602052604090205490915060ff16156139c0576001600160a01b0384166000908152600460205260408120805483929061390f908490614196565b909155505060015460408051630229549960e51b8152905184926004926000926001600160a01b039092169163452a93209180860191602091819003870181865afa158015613962573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139869190613f2f565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008282546139b59190614196565b90915550613a6f9050565b6139ca8183614196565b60015460408051630229549960e51b815290516004926000926001600160a01b039091169163452a93209180860191602091819003870181865afa158015613a16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3a9190613f2f565b6001600160a01b03166001600160a01b031681526020019081526020016000206000828254613a699190614196565b90915550505b613a798183614196565b95945050505050565b6001600160a01b0381168114613a9757600080fd5b50565b600060208284031215613aac57600080fd5b8135613ab781613a82565b9392505050565b600060208284031215613ad057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715613b0f57613b0f613ad7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613b3d57613b3d613ad7565b604052919050565b6000604051606081018181106001600160401b0382111715613b6957613b69613ad7565b6040529050806060830184811115613b8057600080fd5b835b81811015613b9a578035835260209283019201613b82565b50505092915050565b8015158114613a9757600080fd5b8035613bbc81613ba3565b919050565b600082601f830112613bd257600080fd5b613bda613aed565b806040840185811115613bec57600080fd5b845b81811015611263578035845260209384019301613bee565b600082601f830112613c1757600080fd5b613c1f613aed565b806040840185811115613c3157600080fd5b845b8181101561126357803563ffffffff81168114613c505760008081fd5b845260209384019301613c33565b60008060008060006101408688031215613c7757600080fd5b8535613c8281613a82565b94506020603f87018813613c9557600080fd5b613ca188828901613b45565b945087609f880112613cb257600080fd5b613cba613aed565b8060c089018a811115613ccc57600080fd5b60808a015b81811015613cf1578035613ce481613ba3565b8452928401928401613cd1565b50819650613cff8b82613bc1565b955050505050613d13876101008801613c06565b90509295509295909350565b600081518084526020808501945080840160005b83811015613d4f57815187529582019590820190600101613d33565b509495945050505050565b602081526000613ab76020830184613d1f565b60008060408385031215613d8057600080fd5b50508035926020909101359150565b600080600080600060a08688031215613da757600080fd5b8535945060208601359350604086013592506060860135613dc781613a82565b91506080860135613dd781613a82565b809150509295509295909350565b60008060408385031215613df857600080fd5b8235613e0381613a82565b946020939093013593505050565b600080600060608486031215613e2657600080fd5b8335613e3181613a82565b92506020848101356001600160401b0380821115613e4e57600080fd5b818701915087601f830112613e6257600080fd5b813581811115613e7457613e74613ad7565b8060051b9150613e85848301613b15565b818152918301840191848101908a841115613e9f57600080fd5b938501935b83851015613ebd57843582529385019390850190613ea4565b809750505050505050613ed260408501613bb1565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001600160401b0383811690831681811015613f2757613f27613ef1565b039392505050565b600060208284031215613f4157600080fd5b8151613ab781613a82565b600060208083526000845481600182811c915080831680613f6e57607f831692505b858310811415613f8c57634e487b7160e01b85526022600452602485fd5b878601838152602001818015613fa95760018114613fba57613fe5565b60ff19861682528782019650613fe5565b60008b81526020902060005b86811015613fdf57815484820152908501908901613fc6565b83019750505b50949998505050505050505050565b60008282101561400657614006613ef1565b500390565b60006020828403121561401d57600080fd5b815160ff81168114613ab757600080fd5b600181815b8085111561406957816000190482111561404f5761404f613ef1565b8085161561405c57918102915b93841c9390800290614033565b509250929050565b60008261408057506001610fd2565b8161408d57506000610fd2565b81600181146140a357600281146140ad576140c9565b6001915050610fd2565b60ff8411156140be576140be613ef1565b50506001821b610fd2565b5060208310610133831016604e8410600b84101617156140ec575081810a610fd2565b6140f6838361402e565b806000190482111561410a5761410a613ef1565b029392505050565b6000613ab78383614071565b600081600019048311821515161561413857614138613ef1565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826141625761416261413d565b500490565b60006001600160401b038083168185168183048111821515161561418d5761418d613ef1565b02949350505050565b600082198211156141a9576141a9613ef1565b500190565b6000602082840312156141c057600080fd5b5051919050565b6000613ab760ff841683614071565b6000602082840312156141e857600080fd5b8151613ab781613ba3565b600060001982141561420757614207613ef1565b5060010190565b600065ffffffffffff80831681851680830382111561422f5761422f613ef1565b01949350505050565b60006001600160401b0380831681851680830382111561422f5761422f613ef1565b6001600160a01b03831681526040602082018190526000906113ed90830184613d1f565b600065ffffffffffff83811690831681811015613f2757613f27613ef1565b60006001600160401b03808416806142b7576142b761413d565b92169190910492915050565b6000825160005b818110156142e457602081860181015185830152016142ca565b818111156142f3576000828501525b50919091019291505056fea164736f6c634300080a000a000000000000000000000000618907e21898d0357f0a0bf0b112949b1530cbc1000000000000000000000000f59257e961883636290411c11ec5ae622d19455e000000000000000000000000b1cc59fc717b8d4783d41f952725177298b5619d000000000000000000000000759c6de5bca9ade8a1a2719a31553c4b7de0253900000000000000000000000091e453f442d25523f42063e1695390e325076ca2

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063abbf4b171161011a578063c9b67af5116100ad578063e0b117ff1161007c578063e0b117ff14610598578063e3684e39146105e0578063e481b26514610637578063f1b7dc781461064a578063f3191a461461065d57600080fd5b8063c9b67af514610547578063d62fbdd31461054f578063d6db4df814610562578063d936547e1461057557600080fd5b8063bf7e214f116100e9578063bf7e214f14610492578063c0680e20146104bd578063c0aa0e8a146104d0578063c3e0fb1c1461051f57600080fd5b8063abbf4b171461036a578063b1283e7714610395578063bc3b2b12146103f5578063bcb296671461047f57600080fd5b806364914439116101925780637c770aae116101615780637c770aae1461030e5780639b19251a1461033c5780639c7697871461034f578063a42206101461035757600080fd5b806364914439146102b5578063654e51e7146102d55780636a6c575d146102e85780637a9e5e4b146102fb57600080fd5b806321a7d29b116101ce57806321a7d29b1461026457806327507458146102775780633adec5a71461029a5780633d18b912146102ad57600080fd5b80630700037d146102005780630a9d85eb146102335780630aebeb4e146102465780631885f5801461025b575b600080fd5b61022061020e366004613a9a565b60046020526000908152604090205481565b6040519081526020015b60405180910390f35b610220610241366004613abe565b610666565b610259610254366004613abe565b6106be565b005b61022060025481565b610220610272366004613c5e565b610809565b61028a610285366004613abe565b610f6f565b604051901515815260200161022a565b6102206102a8366004613abe565b610fd8565b610259611034565b6102c86102c3366004613a9a565b6110e0565b60405161022a9190613d5a565b6102596102e3366004613d6d565b61126e565b6102206102f6366004613d6d565b611325565b610259610309366004613a9a565b6113f5565b61032161031c366004613d8f565b6114eb565b6040805193845260208401929092529082015260600161022a565b61025961034a366004613a9a565b611906565b6102596119db565b610220610365366004613de5565b611c61565b61037d610378366004613abe565b611f21565b6040516001600160401b03909116815260200161022a565b6103a86103a3366004613abe565b612005565b604080519788526001600160a01b039096166020880152931515948601949094526001600160401b0391821660608601528116608085015290911660a083015260c082015260e00161022a565b610447610403366004613abe565b600c602052600090815260409020546001600160401b0381169065ffffffffffff600160401b8204811691600160701b81049091169060ff600160a01b9091041684565b604080516001600160401b0395909516855265ffffffffffff938416602086015291909216908301521515606082015260800161022a565b61022061048d366004613abe565b612073565b6001546104a5906001600160a01b031681565b6040516001600160a01b03909116815260200161022a565b6102206104cb366004613de5565b6120cf565b6104e36104de366004613abe565b612100565b6040805195151586526001600160401b03948516602087015265ffffffffffff938416908601529116606084015216608082015260a00161022a565b61053261052d366004613de5565b612159565b6040805192835290151560208301520161022a565b6102c8612224565b61022061055d366004613e11565b61230c565b610259610570366004613de5565b6125ab565b61028a610583366004613a9a565b60056020526000908152604090205460ff1681565b6105ab6105a6366004613de5565b61266d565b6040805195865265ffffffffffff9485166020870152928416928501929092528216606084015216608082015260a00161022a565b6105f36105ee366004613abe565b6126d0565b6040805165ffffffffffff97881681529587166020870152938616938501939093529084166060840152909216608082015260ff90911660a082015260c00161022a565b6102c8610645366004613a9a565b61272e565b610220610658366004613abe565b612952565b61022060035481565b600080610672836129fd565b5050905080600a848154811061068a5761068a613edb565b6000918252602090912001546106ae919061010090046001600160401b0316613f07565b6001600160401b03169392505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630505c8c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015610711573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107359190613f2f565b6001600160a01b0316336001600160a01b0316146000906107725760405162461bcd60e51b81526004016107699190613f4c565b60405180910390fd5b5042600a828154811061078757610787613edb565b90600052602060002001600001600f6101000a81548165ffffffffffff021916908365ffffffffffff1602179055506000600982815481106107cb576107cb613edb565b6000918252602082206004909102019190915560405182917f8401d05adbea6548a6999cc1540766e6d2ff919292142862893d0e62ec79fbe591a250565b60015460408051630505c8c960e01b815290516000926001600160a01b031691630505c8c99160048083019260209291908290030181865afa158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190613f2f565b6001600160a01b0316336001600160a01b0316146000906108ab5760405162461bcd60e51b81526004016107699190613f4c565b5060208301516000906108bf904290613ff4565b90506000876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610901573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610925919061400b565b60ff16905060008681602002015161093e578751610976565b61094982600a614112565b6020890151895161096290670de0b6b3a764000061411e565b61096c9190614153565b6109769190614153565b855190915060009084906109909063ffffffff1684614167565b6001600160401b03166109a39190614153565b90506000620186a08a600260200201516109c6906001600160401b03861661411e565b6109d09190614153565b6109e3906001600160401b038516614196565b90506000836001600160401b0316600860009054906101000a90046001600160a01b03166001600160a01b031663860f50486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6891906141ae565b60208d0151610a77919061411e565b610a819190614153565b600980546040805160e0810190915290995091925090808d6000602002015181526020018e6001600160a01b031681526020018c600060028110610ac757610ac7613edb565b60209081029190910151151582526001600160401b0380891683830152878116604080850191909152600060608086018290526080958601829052875460018181018a5598835291859020875160049093020191825593860151818801805488850151968901518616600160a81b0267ffffffffffffffff60a81b19971515600160a01b026001600160a81b03199092166001600160a01b03909416939093171795909516179093559284015160028301805460a0808801518516600160401b026fffffffffffffffffffffffffffffffff19909216939094169290921791909117905560c09093015160039091015580519182019052600a9181908d90602002015115158152602001836001600160401b031681526020018b600060028110610bf357610bf3613edb565b602002015165ffffffffffff1681526020018b600160028110610c1857610c18613edb565b6020908102919091015165ffffffffffff90811683526001600160401b038088169383019390935284546001810186556000958652828620855191018054868501516040808901516060808b01516080909b01518a16600160a81b0267ffffffffffffffff60a81b199b8916600160781b0265ffffffffffff60781b19938a16600160481b029390931674ffffffffffffffffffffffff0000000000000000001995909b166101000268ffffffffffffffff00199815159890981668ffffffffffffffffff1990961695909517969096179290921697909717179690961695909517909455825160c081018452428216808252928101929092528a1691810191909152600b9290918201908b906020908102919091015163ffffffff168252018a6001602002015163ffffffff1665ffffffffffff1681526020018760ff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548165ffffffffffff021916908365ffffffffffff16021790555060208201518160000160066101000a81548165ffffffffffff021916908365ffffffffffff160217905550604082015181600001600c6101000a81548165ffffffffffff021916908365ffffffffffff16021790555060608201518160000160126101000a81548165ffffffffffff021916908365ffffffffffff16021790555060808201518160000160186101000a81548165ffffffffffff021916908365ffffffffffff16021790555060a082015181600001601e6101000a81548160ff021916908360ff1602179055505050600d60008d6001600160a01b03166001600160a01b031681526020019081526020016000208790806001815401808255809150506001900390600052602060002001600090919091909150558b6001600160a01b0316877fb2d2d229227861ab44a51447b9eb227b7191d1cfb2046d5c3f340c30569e6e9e8d600160038110610f0457610f04613edb565b60200201518e600060200201518e600060200201518e600160200201518f60006020020151604051610f58959493929190948552602085019390935290151560408401526060830152608082015260a00190565b60405180910390a350505050505095945050505050565b600060098281548110610f8457610f84613edb565b906000526020600020906004020160000154600014158015610fd2575042600a8381548110610fb557610fb5613edb565b600091825260209091200154600160781b900465ffffffffffff16115b92915050565b6000600b8281548110610fed57610fed613edb565b60009182526020909120015461100e90600160f01b900460ff16600a6141c7565b61101783612952565b61102084610666565b61102a919061411e565b610fd29190614153565b33600081815260046020819052604080832080549390555163a9059cbb60e01b81529081019290925260248201819052906001600160a01b037f000000000000000000000000f59257e961883636290411c11ec5ae622d19455e169063a9059cbb906044016020604051808303816000875af11580156110b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dc91906141d6565b5050565b6001600160a01b0381166000908152600d6020908152604080832080548251818502810185019093528083526060949383018282801561113f57602002820191906000526020600020905b81548152602001906001019080831161112b575b50505050509050600080600090505b825181101561119e5761117983828151811061116c5761116c613edb565b6020026020010151610f6f565b1561118c5781611188816141f3565b9250505b80611196816141f3565b91505061114e565b506000816001600160401b038111156111b9576111b9613ad7565b6040519080825280602002602001820160405280156111e2578160200160208202803683370190505b5090506000805b84518110156112635761120785828151811061116c5761116c613edb565b156112515784818151811061121e5761121e613edb565b602002602001015183838151811061123857611238613edb565b60209081029190910101528161124d816141f3565b9250505b8061125b816141f3565b9150506111e9565b509095945050505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e59190613f2f565b6001600160a01b0316336001600160a01b0316146000906113195760405162461bcd60e51b81526004016107699190613f4c565b50600391909155600255565b600080600b838154811061133b5761133b613edb565b60009182526020918290206040805160c081018252919092015465ffffffffffff8082168352600160301b8204811694830194909452600160601b8104841692820192909252600160901b820483166060820152600160c01b8204909216608083015260ff600160f01b9091041660a082018190529091506113be90600a6141c7565b6113c784610fd8565b6113d986670de0b6b3a764000061411e565b6113e39190614153565b6113ed9190614153565b949350505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015611448573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146c9190613f2f565b6001600160a01b0316336001600160a01b0316146000906114a05760405162461bcd60e51b81526004016107699190613f4c565b50600180546001600160a01b0319166001600160a01b0383169081179091556040517f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad90600090a250565b6000806000806009898154811061150457611504613edb565b906000526020600020906004020190506000600a8a8154811061152957611529613edb565b60009182526020918290206040805160a081018252919092015460ff8116151582526001600160401b03610100820481169483019490945265ffffffffffff600160481b8204811693830193909352600160781b8104831660608301819052600160a81b909104909316608082015292504291908216106115ec5760405162461bcd60e51b815260206004820152601c60248201527f4465706f7369746f72793a206d61726b657420636f6e636c75646564000000006044820152606401610769565b6115f68b82612aea565b60006116018c612d0d565b9050898111156116535760405162461bcd60e51b815260206004820152601f60248201527f4465706f7369746f72793a206d6f7265207468616e206d6178207072696365006044820152606401610769565b600b8c8154811061166657611666613edb565b60009182526020909120015461168790600160f01b900460ff16600a6141c7565b8161169a8d670de0b6b3a764000061411e565b6116a49190614153565b6116ae9190614153565b60028501549097506001600160401b031687111561170e5760405162461bcd60e51b815260206004820152601d60248201527f4465706f7369746f72793a206d61782073697a652065786365656465640000006044820152606401610769565b6001840154600160a01b900460ff166117275786611729565b8a5b84600001600082825461173c9190613ff4565b90915550508251611751578260400151611761565b818360400151611761919061420e565b65ffffffffffff1695508a84600301600082825461177f9190614196565b90915550506002840180548891906008906117ab908490600160401b90046001600160401b0316614238565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550868460010160158282829054906101000a90046001600160401b03166117f59190614238565b92506101000a8154816001600160401b0302191690836001600160401b031602179055508b7f8f81d43253aa8fe80c98ec1a0b2e10f8c0fb0f24cf3c4a5e582e56de3aa7178e8c838a60405161185e939291909283526020830191909152604082015260600190565b60405180910390a26118738988888f8c612d83565b6008546001860154919650611897916001600160a01b03908116913391168e613119565b600184015460808401516001600160401b03600160a81b9092048216911610156118ed5760008085556040518d917f8401d05adbea6548a6999cc1540766e6d2ff919292142862893d0e62ec79fbe591a26118f7565b6118f78c8361322c565b50505050955095509592505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630505c8c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197d9190613f2f565b6001600160a01b0316336001600160a01b0316146000906119b15760405162461bcd60e51b81526004016107699190613f4c565b506001600160a01b03166000908152600560205260409020805460ff19811660ff90911615179055565b600160009054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a529190613f2f565b6001600160a01b0316336001600160a01b03161480611af85750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611abf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae39190613f2f565b6001600160a01b0316336001600160a01b0316145b80611b8a5750600160009054906101000a90046001600160a01b03166001600160a01b0316630505c8c96040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b759190613f2f565b6001600160a01b0316336001600160a01b0316145b611bc85760405162461bcd60e51b815260206004820152600f60248201526e13db9b1e48185d5d1a1bdc9a5e9959608a1b6044820152606401610769565b600160009054906101000a90046001600160a01b03166001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3f9190613f2f565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382811660009081526007602090815260408083208584529091528120549091163314611cd75760405162461bcd60e51b815260206004820152601e60248201527f4465706f7369746f72793a207472616e73666572206e6f7420666f756e6400006044820152606401610769565b6001600160a01b0383166000908152600660205260409020805483908110611d0157611d01613edb565b6000918252602090912060029091020160010154600160601b900465ffffffffffff1615611d715760405162461bcd60e51b815260206004820152601960248201527f4465706f7369746f72793a206e6f74652072656465656d6564000000000000006044820152606401610769565b503360009081526006602052604080822080546001600160a01b038616845291909220805491929184908110611da957611da9613edb565b600091825260208083208454600181810187559585528285206002948502909201805491909402909101908155918401805492909401805465ffffffffffff19811665ffffffffffff94851690811783558654600160301b908190048616026bffffffffffffffffffffffff1990921617178082558554600160601b9081900485160265ffffffffffff60601b198216811783559554600160901b9081900490941690930265ffffffffffff60901b199095166bffffffffffffffffffffffff60601b19909316929092179390931790556001600160a01b0385168152600690915260409020805483908110611ea157611ea1613edb565b60009182526020808320600292909202909101918255600190910180546001600160c01b0319169055604080516001600160a01b038616815233928101929092528101839052606081018290527f706f2211bcf8c95f0be5018c3ddd4a13ed3aef954937f21655b9e3d3854eae579060800160405180910390a192915050565b600080600b8381548110611f3757611f37613edb565b600091825260208083206040805160c081018252939091015465ffffffffffff8082168552600160301b82048116938501849052600160601b8204811692850192909252600160901b810482166060850152600160c01b81049091166080840152600160f01b900460ff1660a0830152909250611fb49042613ff4565b9050816040015165ffffffffffff168160098681548110611fd757611fd7613edb565b60009182526020909120600490910201600101546113e39190600160a81b90046001600160401b031661411e565b6009818154811061201557600080fd5b600091825260209091206004909102018054600182015460028301546003909301549193506001600160a01b0381169260ff600160a01b830416926001600160401b03600160a81b90930483169282811692600160401b9004169087565b600061207e82611f21565b6009838154811061209157612091613edb565b906000526020600020906004020160010160159054906101000a90046001600160401b03166120c09190613f07565b6001600160401b031692915050565b600d60205281600052604060002081815481106120eb57600080fd5b90600052602060002001600091509150505481565b600a818154811061211057600080fd5b60009182526020909120015460ff811691506001600160401b03610100820481169165ffffffffffff600160481b8204811692600160781b830490911691600160a81b90041685565b6001600160a01b03821660009081526006602052604081208054829182918590811061218757612187613edb565b60009182526020918290206040805160a0810182526002909302909101805480845260019091015465ffffffffffff80821695850195909552600160301b8104851692840192909252600160601b8204841660608401819052600160901b9092049093166080830152919450915015801561220e575042816040015165ffffffffffff1611155b801561221a5750805115155b9150509250929050565b60606000805b6009548110156122625761223d81610f6f565b15612250578161224c816141f3565b9250505b8061225a816141f3565b91505061222a565b506000816001600160401b0381111561227d5761227d613ad7565b6040519080825280602002602001820160405280156122a6578160200160208202803683370190505b5090506000805b600954811015612303576122c081610f6f565b156122f157808383815181106122d8576122d8613edb565b6020908102919091010152816122ed816141f3565b9250505b806122fb816141f3565b9150506122ad565b50909392505050565b600042815b8451811015612435576000806123408888858151811061233357612333613edb565b6020026020010151612159565b91509150806123915760405162461bcd60e51b815260206004820152601c60248201527f4465706f7369746f72793a206e6f7465206e6f74206d617475726564000000006044820152606401610769565b8015612420576001600160a01b038816600090815260066020526040902087518591908990869081106123c6576123c6613edb565b6020026020010151815481106123de576123de613edb565b9060005260206000209060020201600101600c6101000a81548165ffffffffffff021916908365ffffffffffff160217905550818561241d9190614196565b94505b5050808061242d906141f3565b915050612311565b5082156124d55760405163a9059cbb60e01b81526001600160a01b038681166004830152602482018490527f000000000000000000000000b1cc59fc717b8d4783d41f952725177298b5619d169063a9059cbb906044016020604051808303816000875af11580156124ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124cf91906141d6565b5061256a565b6040516339f4769360e01b81526001600160a01b038681166004830152602482018490527f000000000000000000000000759c6de5bca9ade8a1a2719a31553c4b7de0253916906339f47693906044016020604051808303816000875af1158015612544573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256891906141ae565b505b7fc23d625f7a5488c9b6dc65d24695ee2302b430809ea4e6c46793aab8b059cbdb858560405161259b92919061425a565b60405180910390a1509392505050565b3360009081526006602052604090208054829081106125cc576125cc613edb565b600091825260209091206001600290920201015465ffffffffffff166126345760405162461bcd60e51b815260206004820152601a60248201527f4465706f7369746f72793a206e6f7465206e6f7420666f756e640000000000006044820152606401610769565b3360009081526007602090815260408083209383529290522080546001600160a01b0319166001600160a01b0392909216919091179055565b6006602052816000526040600020818154811061268957600080fd5b60009182526020909120600290910201805460019091015490925065ffffffffffff8082169250600160301b8204811691600160601b8104821691600160901b9091041685565b600b81815481106126e057600080fd5b60009182526020909120015465ffffffffffff8082169250600160301b8204811691600160601b8104821691600160901b8204811691600160c01b810490911690600160f01b900460ff1686565b6001600160a01b0381166000908152600660209081526040808320805482518185028101850190935280835260609493849084015b828210156127d95760008481526020908190206040805160a081018252600286029092018054835260019081015465ffffffffffff80821685870152600160301b8204811693850193909352600160601b810483166060850152600160901b900490911660808301529083529092019101612763565b505050509050600080600090505b82518110156128685782818151811061280257612802613edb565b60200260200101516060015165ffffffffffff166000148015612843575082818151811061283257612832613edb565b602002602001015160000151600014155b156128565781612852816141f3565b9250505b80612860816141f3565b9150506127e7565b506000816001600160401b0381111561288357612883613ad7565b6040519080825280602002602001820160405280156128ac578160200160208202803683370190505b5090506000805b8451811015611263578481815181106128ce576128ce613edb565b60200260200101516060015165ffffffffffff16600014801561290f57508481815181106128fe576128fe613edb565b602002602001015160000151600014155b15612940578083838151811061292757612927613edb565b60209081029190910101528161293c816141f3565b9250505b8061294a816141f3565b9150506128b3565b600854604080516310c1ea0960e31b815290516000926001600160a01b03169163860f50489160048083019260209291908290030181865afa15801561299c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c091906141ae565b600b83815481106129d3576129d3613edb565b6000918252602090912001546129f490600160f01b900460ff16600a6141c7565b61102084612073565b6000818152600c60209081526040808320815160808101835290546001600160401b0381168252600160401b810465ffffffffffff90811694830194909452600160701b810490931691810191909152600160a01b90910460ff1615156060820181905282918291612a7a57600080600093509350935050612ae3565b6020810151612a89904261427e565b9250806040015165ffffffffffff168365ffffffffffff1610915081612ab0578051612adf565b806040015165ffffffffffff168365ffffffffffff168260000151612ad59190614167565b612adf919061429d565b9350505b9193909250565b612af382611f21565b60098381548110612b0657612b06613edb565b906000526020600020906004020160010160158282829054906101000a90046001600160401b0316612b389190613f07565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555080600b8381548110612b7057612b70613edb565b60009182526020808320909101805465ffffffffffff94909416600160301b026bffffffffffff0000000000001990941693909317909255838152600c909152604090205460ff600160a01b90910416156110dc576000828152600c60205260408120908080612bdf866129fd565b92509250925082600a8781548110612bf957612bf9613edb565b60009182526020909120018054600190612c2290849061010090046001600160401b0316613f07565b92506101000a8154816001600160401b0302191690836001600160401b031602179055508015612cf957835483908590600090612c699084906001600160401b0316613f07565b92506101000a8154816001600160401b0302191690836001600160401b031602179055508184600001600e8282829054906101000a900465ffffffffffff16612cb2919061427e565b82546101009290920a65ffffffffffff81810219909316918316021790915585546dffffffffffff00000000000000001916600160401b9188169190910217855550612d05565b835460ff60a01b191684555b505050505050565b6000600b8281548110612d2257612d22613edb565b600091825260209091200154612d4390600160f01b900460ff16600a6141c7565b612d4c836137a3565b600a8481548110612d5f57612d5f613edb565b60009182526020909120015461102a919061010090046001600160401b031661411e565b6001600160a01b03858116600090815260066020526040908190208054825160a08101938490526319a948db60e21b90935260a483018890529290919081907f000000000000000000000000b1cc59fc717b8d4783d41f952725177298b5619d166366a5236c60c48301602060405180830381865afa158015612e0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2e91906141ae565b815265ffffffffffff428116602080840191909152888216604080850191909152600060608086018290528a8516608096870152875460018181018a559883529184902087516002909302019182559286015196018054868301519387015196909501518416600160901b0265ffffffffffff60901b19968516600160601b02969096166bffffffffffffffffffffffff60601b19938516600160301b026bffffffffffffffffffffffff19909616979094169690961793909317161791909117909155516319a948db60e21b81527f1f58724e9d5598976a9faf8e2e354dbc7d54ab2d81e09e0c682e2893881e1aa7908790859084906001600160a01b037f000000000000000000000000b1cc59fc717b8d4783d41f952725177298b5619d16906366a5236c90612f68908c9060040190815260200190565b602060405180830381865afa158015612f85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa991906141ae565b604080516001600160a01b03909516855265ffffffffffff938416602086015284019190915260608301528616608082015260a00160405180910390a16000612ff28684613886565b6008549091506001600160a01b03166340c10f1930613011848a614196565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561305757600080fd5b505af115801561306b573d6000803e3d6000fd5b5050604051631b0cd93b60e31b81523060048201526024810189905260006044820152600160648201527f000000000000000000000000759c6de5bca9ade8a1a2719a31553c4b7de025396001600160a01b0316925063d866c9d891506084016020604051808303816000875af11580156130ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310e91906141ae565b505095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161317d91906142c3565b6000604051808303816000865af19150503d80600081146131ba576040519150601f19603f3d011682016040523d82523d6000602084013e6131bf565b606091505b50915091508180156131e95750805115806131e95750808060200190518101906131e991906141d6565b612d055760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610769565b6000600b838154811061324157613241613edb565b60009182526020918290206040805160c081018252929091015465ffffffffffff808216808552600160301b8304821695850195909552600160601b8204811692840192909252600160901b810482166060840152600160c01b810490911660808301819052600160f01b90910460ff1660a08301529092506132c39161420e565b65ffffffffffff168265ffffffffffff161061379e576000600984815481106132ee576132ee613edb565b600091825260208083206040805160e08101825260049094029091018054845260018101546001600160a01b0381169385019390935260ff600160a01b8404161515918401919091526001600160401b03600160a81b9092048216606084015260028101548083166080850152600160401b900490911660a08301526003015460c0820152600a805491935085918790811061338c5761338c613edb565b6000918252602090912001546133b19190600160781b900465ffffffffffff1661427e565b65ffffffffffff16905060006133c686612d0d565b9050600083604001516133da578351613414565b60a08501516133ea90600a6141c7565b8451839061340090670de0b6b3a764000061411e565b61340a9190614153565b6134149190614153565b905082856060015165ffffffffffff168261342f919061411e565b6134399190614153565b6009888154811061344c5761344c613edb565b906000526020600020906004020160020160006101000a8154816001600160401b0302191690836001600160401b03160217905550600083866040015165ffffffffffff168361349c919061411e565b6134a69190614153565b9050600081600860009054906101000a90046001600160a01b03166001600160a01b031663860f50486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156134fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352291906141ae565b61352c908661411e565b6135369190614153565b9050887f3070b0e3e52b8713c7489d32604ea4b0970024f74c6e05319269a19bc1e3a9d9600a8b8154811061356d5761356d613edb565b60009182526020918290200154604080516101009092046001600160401b0390811683528616928201929092520160405180910390a2600a89815481106135b6576135b6613edb565b6000918252602090912001546001600160401b036101009091048116908216106136245780600a8a815481106135ee576135ee613edb565b9060005260206000200160000160016101000a8154816001600160401b0302191690836001600160401b0316021790555061375c565b600081600a8b8154811061363a5761363a613edb565b60009182526020909120015461365e919061010090046001600160401b0316613f07565b90506040518060800160405280826001600160401b031681526020018a65ffffffffffff168152602001896080015165ffffffffffff16815260200160011515815250600c60008c815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a81548165ffffffffffff021916908365ffffffffffff160217905550604082015181600001600e6101000a81548165ffffffffffff021916908365ffffffffffff16021790555060608201518160000160146101000a81548160ff021916908315150217905550905050505b87600b8a8154811061377057613770613edb565b6000918252602090912001805465ffffffffffff191665ffffffffffff929092169190911790555050505050505b505050565b600854604080516310c1ea0960e31b815290516000926001600160a01b03169163860f50489160048083019260209291908290030181865afa1580156137ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381191906141ae565b600b838154811061382457613824613edb565b60009182526020909120015461384590600160f01b900460ff16600a6141c7565b6009848154811061385857613858613edb565b600091825260209091206004909102016001015461102a9190600160a81b90046001600160401b031661411e565b6000806127106002548561389a919061411e565b6138a49190614153565b90506000612710600354866138b9919061411e565b6138c39190614153565b6001600160a01b03851660009081526005602052604090205490915060ff16156139c0576001600160a01b0384166000908152600460205260408120805483929061390f908490614196565b909155505060015460408051630229549960e51b8152905184926004926000926001600160a01b039092169163452a93209180860191602091819003870181865afa158015613962573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139869190613f2f565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008282546139b59190614196565b90915550613a6f9050565b6139ca8183614196565b60015460408051630229549960e51b815290516004926000926001600160a01b039091169163452a93209180860191602091819003870181865afa158015613a16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3a9190613f2f565b6001600160a01b03166001600160a01b031681526020019081526020016000206000828254613a699190614196565b90915550505b613a798183614196565b95945050505050565b6001600160a01b0381168114613a9757600080fd5b50565b600060208284031215613aac57600080fd5b8135613ab781613a82565b9392505050565b600060208284031215613ad057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715613b0f57613b0f613ad7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715613b3d57613b3d613ad7565b604052919050565b6000604051606081018181106001600160401b0382111715613b6957613b69613ad7565b6040529050806060830184811115613b8057600080fd5b835b81811015613b9a578035835260209283019201613b82565b50505092915050565b8015158114613a9757600080fd5b8035613bbc81613ba3565b919050565b600082601f830112613bd257600080fd5b613bda613aed565b806040840185811115613bec57600080fd5b845b81811015611263578035845260209384019301613bee565b600082601f830112613c1757600080fd5b613c1f613aed565b806040840185811115613c3157600080fd5b845b8181101561126357803563ffffffff81168114613c505760008081fd5b845260209384019301613c33565b60008060008060006101408688031215613c7757600080fd5b8535613c8281613a82565b94506020603f87018813613c9557600080fd5b613ca188828901613b45565b945087609f880112613cb257600080fd5b613cba613aed565b8060c089018a811115613ccc57600080fd5b60808a015b81811015613cf1578035613ce481613ba3565b8452928401928401613cd1565b50819650613cff8b82613bc1565b955050505050613d13876101008801613c06565b90509295509295909350565b600081518084526020808501945080840160005b83811015613d4f57815187529582019590820190600101613d33565b509495945050505050565b602081526000613ab76020830184613d1f565b60008060408385031215613d8057600080fd5b50508035926020909101359150565b600080600080600060a08688031215613da757600080fd5b8535945060208601359350604086013592506060860135613dc781613a82565b91506080860135613dd781613a82565b809150509295509295909350565b60008060408385031215613df857600080fd5b8235613e0381613a82565b946020939093013593505050565b600080600060608486031215613e2657600080fd5b8335613e3181613a82565b92506020848101356001600160401b0380821115613e4e57600080fd5b818701915087601f830112613e6257600080fd5b813581811115613e7457613e74613ad7565b8060051b9150613e85848301613b15565b818152918301840191848101908a841115613e9f57600080fd5b938501935b83851015613ebd57843582529385019390850190613ea4565b809750505050505050613ed260408501613bb1565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001600160401b0383811690831681811015613f2757613f27613ef1565b039392505050565b600060208284031215613f4157600080fd5b8151613ab781613a82565b600060208083526000845481600182811c915080831680613f6e57607f831692505b858310811415613f8c57634e487b7160e01b85526022600452602485fd5b878601838152602001818015613fa95760018114613fba57613fe5565b60ff19861682528782019650613fe5565b60008b81526020902060005b86811015613fdf57815484820152908501908901613fc6565b83019750505b50949998505050505050505050565b60008282101561400657614006613ef1565b500390565b60006020828403121561401d57600080fd5b815160ff81168114613ab757600080fd5b600181815b8085111561406957816000190482111561404f5761404f613ef1565b8085161561405c57918102915b93841c9390800290614033565b509250929050565b60008261408057506001610fd2565b8161408d57506000610fd2565b81600181146140a357600281146140ad576140c9565b6001915050610fd2565b60ff8411156140be576140be613ef1565b50506001821b610fd2565b5060208310610133831016604e8410600b84101617156140ec575081810a610fd2565b6140f6838361402e565b806000190482111561410a5761410a613ef1565b029392505050565b6000613ab78383614071565b600081600019048311821515161561413857614138613ef1565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826141625761416261413d565b500490565b60006001600160401b038083168185168183048111821515161561418d5761418d613ef1565b02949350505050565b600082198211156141a9576141a9613ef1565b500190565b6000602082840312156141c057600080fd5b5051919050565b6000613ab760ff841683614071565b6000602082840312156141e857600080fd5b8151613ab781613ba3565b600060001982141561420757614207613ef1565b5060010190565b600065ffffffffffff80831681851680830382111561422f5761422f613ef1565b01949350505050565b60006001600160401b0380831681851680830382111561422f5761422f613ef1565b6001600160a01b03831681526040602082018190526000906113ed90830184613d1f565b600065ffffffffffff83811690831681811015613f2757613f27613ef1565b60006001600160401b03808416806142b7576142b761413d565b92169190910492915050565b6000825160005b818110156142e457602081860181015185830152016142ca565b818111156142f3576000828501525b50919091019291505056fea164736f6c634300080a000a

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000618907e21898d0357f0a0bf0b112949b1530cbc1000000000000000000000000f59257e961883636290411c11ec5ae622d19455e000000000000000000000000b1cc59fc717b8d4783d41f952725177298b5619d000000000000000000000000759c6de5bca9ade8a1a2719a31553c4b7de0253900000000000000000000000091e453f442d25523f42063e1695390e325076ca2

-----Decoded View---------------
Arg [0] : _authority (address): 0x618907E21898D0357f0a0BF0B112949b1530Cbc1
Arg [1] : _floor (address): 0xf59257E961883636290411c11ec5Ae622d19455e
Arg [2] : _gfloor (address): 0xb1Cc59Fc717b8D4783D41F952725177298B5619d
Arg [3] : _staking (address): 0x759c6De5bcA9ADE8A1a2719a31553c4B7DE02539
Arg [4] : _treasury (address): 0x91E453f442d25523F42063E1695390e325076ca2

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000618907e21898d0357f0a0bf0b112949b1530cbc1
Arg [1] : 000000000000000000000000f59257e961883636290411c11ec5ae622d19455e
Arg [2] : 000000000000000000000000b1cc59fc717b8d4783d41f952725177298b5619d
Arg [3] : 000000000000000000000000759c6de5bca9ade8a1a2719a31553c4b7de02539
Arg [4] : 00000000000000000000000091e453f442d25523f42063e1695390e325076ca2


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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