ETH Price: $3,915.89 (+6.70%)

Contract

0x9fC9ae5c87FD07368e87D1EA0970a6fC1E6dD6Cb
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Buy Collateral149591202022-06-14 1:20:40912 days ago1655169640IN
0x9fC9ae5c...C1E6dD6Cb
0 ETH0.0077848561.7512591

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
126846002021-06-22 14:40:491268 days ago1624372849  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
IncreasingDiscountCollateralAuctionHouse

Compiler Version
v0.6.7+commit.b8d736ae

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-06-22
*/

pragma solidity 0.6.7;

abstract contract SAFEEngineLike {
    function transferInternalCoins(address,address,uint256) virtual external;
    function transferCollateral(bytes32,address,address,uint256) virtual external;
}
abstract contract OracleRelayerLike {
    function redemptionPrice() virtual public returns (uint256);
}
abstract contract OracleLike {
    function priceSource() virtual public view returns (address);
    function getResultWithValidity() virtual public view returns (uint256, bool);
}
abstract contract LiquidationEngineLike {
    function removeCoinsFromAuction(uint256) virtual public;
    function addAuthorization(address) external virtual;
    function removeAuthorization(address) external virtual;
    function modifyParameters(bytes32,bytes32,address) external virtual;
    function collateralTypes(bytes32) virtual public view returns (
        IncreasingDiscountCollateralAuctionHouse collateralAuctionHouse,
        uint256 liquidationPenalty,     // [wad]
        uint256 liquidationQuantity     // [rad]
    );
}

/// IncreasingDiscountCollateralAuctionHouse.sol

// Copyright (C) 2018 Rain <[email protected]>, 2020 Reflexer Labs, INC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

/*
   This thing lets you sell some collateral at an increasing discount in order to instantly recapitalize the system
*/

contract IncreasingDiscountCollateralAuctionHouse {
    // --- Auth ---
    mapping (address => uint256) public authorizedAccounts;
    /**
     * @notice Add auth to an account
     * @param account Account to add auth to
     */
    function addAuthorization(address account) external isAuthorized {
        authorizedAccounts[account] = 1;
        emit AddAuthorization(account);
    }
    /**
     * @notice Remove auth from an account
     * @param account Account to remove auth from
     */
    function removeAuthorization(address account) external isAuthorized {
        authorizedAccounts[account] = 0;
        emit RemoveAuthorization(account);
    }
    /**
    * @notice Checks whether msg.sender can call an authed function
    **/
    modifier isAuthorized {
        require(authorizedAccounts[msg.sender] == 1, "IncreasingDiscountCollateralAuctionHouse/account-not-authorized");
        _;
    }

    // --- Data ---
    struct Bid {
        // How much collateral is sold in an auction
        uint256 amountToSell;                                                                                         // [wad]
        // Total/max amount of coins to raise
        uint256 amountToRaise;                                                                                        // [rad]
        // Current discount
        uint256 currentDiscount;                                                                                      // [wad]
        // Max possibe discount
        uint256 maxDiscount;                                                                                          // [wad]
        // Rate at which the discount is updated every second
        uint256 perSecondDiscountUpdateRate;                                                                          // [ray]
        // Last time when the current discount was updated
        uint256 latestDiscountUpdateTime;                                                                             // [unix timestamp]
        // Deadline after which the discount cannot increase anymore
        uint48  discountIncreaseDeadline;                                                                             // [unix epoch time]
        // Who (which SAFE) receives leftover collateral that is not sold in the auction; usually the liquidated SAFE
        address forgoneCollateralReceiver;
        // Who receives the coins raised by the auction; usually the accounting engine
        address auctionIncomeRecipient;
    }

    // Bid data for each separate auction
    mapping (uint256 => Bid) public bids;

    // SAFE database
    SAFEEngineLike public safeEngine;
    // Collateral type name
    bytes32        public collateralType;

    // Minimum acceptable bid
    uint256  public   minimumBid = 5 * WAD;                                                                           // [wad]
    // Total length of the auction. Kept to adhere to the same interface as the English auction but redundant
    uint48   public   totalAuctionLength = uint48(-1);                                                                // [seconds]
    // Number of auctions started up until now
    uint256  public   auctionsStarted = 0;
    // The last read redemption price
    uint256  public   lastReadRedemptionPrice;
    // Minimum discount (compared to the system coin's current redemption price) at which collateral is being sold
    uint256  public   minDiscount = 0.95E18;                      // 5% discount                                      // [wad]
    // Maximum discount (compared to the system coin's current redemption price) at which collateral is being sold
    uint256  public   maxDiscount = 0.95E18;                      // 5% discount                                      // [wad]
    // Rate at which the discount will be updated in an auction
    uint256  public   perSecondDiscountUpdateRate = RAY;                                                              // [ray]
    // Max time over which the discount can be updated
    uint256  public   maxDiscountUpdateRateTimeline  = 1 hours;                                                       // [seconds]
    // Max lower bound deviation that the collateral median can have compared to the FSM price
    uint256  public   lowerCollateralMedianDeviation = 0.90E18;   // 10% deviation                                    // [wad]
    // Max upper bound deviation that the collateral median can have compared to the FSM price
    uint256  public   upperCollateralMedianDeviation = 0.95E18;   // 5% deviation                                     // [wad]
    // Max lower bound deviation that the system coin oracle price feed can have compared to the systemCoinOracle price
    uint256  public   lowerSystemCoinMedianDeviation = WAD;       // 0% deviation                                     // [wad]
    // Max upper bound deviation that the system coin oracle price feed can have compared to the systemCoinOracle price
    uint256  public   upperSystemCoinMedianDeviation = WAD;       // 0% deviation                                     // [wad]
    // Min deviation for the system coin median result compared to the redemption price in order to take the median into account
    uint256  public   minSystemCoinMedianDeviation   = 0.999E18;                                                      // [wad]

    OracleRelayerLike     public oracleRelayer;
    OracleLike            public collateralFSM;
    OracleLike            public systemCoinOracle;
    LiquidationEngineLike public liquidationEngine;

    bytes32 public constant AUCTION_HOUSE_TYPE = bytes32("COLLATERAL");
    bytes32 public constant AUCTION_TYPE       = bytes32("INCREASING_DISCOUNT");

    // --- Events ---
    event AddAuthorization(address account);
    event RemoveAuthorization(address account);
    event StartAuction(
        uint256 id,
        uint256 auctionsStarted,
        uint256 amountToSell,
        uint256 initialBid,
        uint256 indexed amountToRaise,
        uint256 startingDiscount,
        uint256 maxDiscount,
        uint256 perSecondDiscountUpdateRate,
        uint48  discountIncreaseDeadline,
        address indexed forgoneCollateralReceiver,
        address indexed auctionIncomeRecipient
    );
    event ModifyParameters(bytes32 parameter, uint256 data);
    event ModifyParameters(bytes32 parameter, address data);
    event BuyCollateral(uint256 indexed id, uint256 wad, uint256 boughtCollateral);
    event SettleAuction(uint256 indexed id, uint256 leftoverCollateral);
    event TerminateAuctionPrematurely(uint256 indexed id, address sender, uint256 collateralAmount);

    // --- Init ---
    constructor(address safeEngine_, address liquidationEngine_, bytes32 collateralType_) public {
        safeEngine = SAFEEngineLike(safeEngine_);
        liquidationEngine = LiquidationEngineLike(liquidationEngine_);
        collateralType = collateralType_;
        authorizedAccounts[msg.sender] = 1;
        emit AddAuthorization(msg.sender);
    }

    // --- Math ---
    function addUint48(uint48 x, uint48 y) internal pure returns (uint48 z) {
        require((z = x + y) >= x, "IncreasingDiscountCollateralAuctionHouse/add-uint48-overflow");
    }
    function addUint256(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "IncreasingDiscountCollateralAuctionHouse/add-uint256-overflow");
    }
    function subtract(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "IncreasingDiscountCollateralAuctionHouse/sub-underflow");
    }
    function multiply(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "IncreasingDiscountCollateralAuctionHouse/mul-overflow");
    }
    uint256 constant WAD = 10 ** 18;
    function wmultiply(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = multiply(x, y) / WAD;
    }
    uint256 constant RAY = 10 ** 27;
    function rdivide(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y > 0, "IncreasingDiscountCollateralAuctionHouse/rdiv-by-zero");
        z = multiply(x, RAY) / y;
    }
    function rmultiply(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x * y;
        require(y == 0 || z / y == x, "IncreasingDiscountCollateralAuctionHouse/rmul-overflow");
        z = z / RAY;
    }
    function wdivide(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y > 0, "IncreasingDiscountCollateralAuctionHouse/wdiv-by-zero");
        z = multiply(x, WAD) / y;
    }
    function minimum(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = (x <= y) ? x : y;
    }
    function maximum(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = (x >= y) ? x : y;
    }
    function rpower(uint256 x, uint256 n, uint256 b) internal pure returns (uint256 z) {
      assembly {
        switch x case 0 {switch n case 0 {z := b} default {z := 0}}
        default {
          switch mod(n, 2) case 0 { z := b } default { z := x }
          let half := div(b, 2)  // for rounding.
          for { n := div(n, 2) } n { n := div(n,2) } {
            let xx := mul(x, x)
            if iszero(eq(div(xx, x), x)) { revert(0,0) }
            let xxRound := add(xx, half)
            if lt(xxRound, xx) { revert(0,0) }
            x := div(xxRound, b)
            if mod(n,2) {
              let zx := mul(z, x)
              if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
              let zxRound := add(zx, half)
              if lt(zxRound, zx) { revert(0,0) }
              z := div(zxRound, b)
            }
          }
        }
      }
    }

    // --- General Utils ---
    function either(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := or(x, y)}
    }
    function both(bool x, bool y) internal pure returns (bool z) {
        assembly{ z := and(x, y)}
    }

    // --- Admin ---
    /**
     * @notice Modify an uint256 parameter
     * @param parameter The name of the parameter to modify
     * @param data New value for the parameter
     */
    function modifyParameters(bytes32 parameter, uint256 data) external isAuthorized {
        if (parameter == "minDiscount") {
            require(both(data >= maxDiscount, data < WAD), "IncreasingDiscountCollateralAuctionHouse/invalid-min-discount");
            minDiscount = data;
        }
        else if (parameter == "maxDiscount") {
            require(both(both(data <= minDiscount, data < WAD), data > 0), "IncreasingDiscountCollateralAuctionHouse/invalid-max-discount");
            maxDiscount = data;
        }
        else if (parameter == "perSecondDiscountUpdateRate") {
            require(data <= RAY, "IncreasingDiscountCollateralAuctionHouse/invalid-discount-update-rate");
            perSecondDiscountUpdateRate = data;
        }
        else if (parameter == "maxDiscountUpdateRateTimeline") {
            require(both(data > 0, uint256(uint48(-1)) > addUint256(now, data)), "IncreasingDiscountCollateralAuctionHouse/invalid-update-rate-time");
            maxDiscountUpdateRateTimeline = data;
        }
        else if (parameter == "lowerCollateralMedianDeviation") {
            require(data <= WAD, "IncreasingDiscountCollateralAuctionHouse/invalid-lower-collateral-median-deviation");
            lowerCollateralMedianDeviation = data;
        }
        else if (parameter == "upperCollateralMedianDeviation") {
            require(data <= WAD, "IncreasingDiscountCollateralAuctionHouse/invalid-upper-collateral-median-deviation");
            upperCollateralMedianDeviation = data;
        }
        else if (parameter == "lowerSystemCoinMedianDeviation") {
            require(data <= WAD, "IncreasingDiscountCollateralAuctionHouse/invalid-lower-system-coin-median-deviation");
            lowerSystemCoinMedianDeviation = data;
        }
        else if (parameter == "upperSystemCoinMedianDeviation") {
            require(data <= WAD, "IncreasingDiscountCollateralAuctionHouse/invalid-upper-system-coin-median-deviation");
            upperSystemCoinMedianDeviation = data;
        }
        else if (parameter == "minSystemCoinMedianDeviation") {
            minSystemCoinMedianDeviation = data;
        }
        else if (parameter == "minimumBid") {
            minimumBid = data;
        }
        else revert("IncreasingDiscountCollateralAuctionHouse/modify-unrecognized-param");
        emit ModifyParameters(parameter, data);
    }
    /**
     * @notice Modify an addres parameter
     * @param parameter The parameter name
     * @param data New address for the parameter
     */
    function modifyParameters(bytes32 parameter, address data) external isAuthorized {
        if (parameter == "oracleRelayer") oracleRelayer = OracleRelayerLike(data);
        else if (parameter == "collateralFSM") {
          collateralFSM = OracleLike(data);
          // Check that priceSource() is implemented
          collateralFSM.priceSource();
        }
        else if (parameter == "systemCoinOracle") systemCoinOracle = OracleLike(data);
        else if (parameter == "liquidationEngine") liquidationEngine = LiquidationEngineLike(data);
        else revert("IncreasingDiscountCollateralAuctionHouse/modify-unrecognized-param");
        emit ModifyParameters(parameter, data);
    }

    // --- Private Auction Utils ---
    /*
    * @notify Get the amount of bought collateral from a specific auction using custom collateral price feeds, a system
    *         coin price feed and a custom discount
    * @param id The ID of the auction to bid in and get collateral from
    * @param collateralFsmPriceFeedValue The collateral price fetched from the FSM
    * @param collateralMedianPriceFeedValue The collateral price fetched from the oracle median
    * @param systemCoinPriceFeedValue The system coin market price fetched from the oracle
    * @param adjustedBid The system coin bid
    * @param customDiscount The discount offered
    */
    function getBoughtCollateral(
        uint256 id,
        uint256 collateralFsmPriceFeedValue,
        uint256 collateralMedianPriceFeedValue,
        uint256 systemCoinPriceFeedValue,
        uint256 adjustedBid,
        uint256 customDiscount
    ) private view returns (uint256) {
        // calculate the collateral price in relation to the latest system coin price and apply the discount
        uint256 discountedCollateralPrice =
          getDiscountedCollateralPrice(
            collateralFsmPriceFeedValue,
            collateralMedianPriceFeedValue,
            systemCoinPriceFeedValue,
            customDiscount
          );
        // calculate the amount of collateral bought
        uint256 boughtCollateral = wdivide(adjustedBid, discountedCollateralPrice);
        // if the calculated collateral amount exceeds the amount still up for sale, adjust it to the remaining amount
        boughtCollateral = (boughtCollateral > bids[id].amountToSell) ? bids[id].amountToSell : boughtCollateral;

        return boughtCollateral;
    }
    /*
    * @notice Update the discount used in a particular auction
    * @param id The id of the auction to update the discount for
    * @returns The newly computed currentDiscount for the targeted auction
    */
    function updateCurrentDiscount(uint256 id) private returns (uint256) {
        // Work directly with storage
        Bid storage auctionBidData              = bids[id];
        auctionBidData.currentDiscount          = getNextCurrentDiscount(id);
        auctionBidData.latestDiscountUpdateTime = now;
        return auctionBidData.currentDiscount;
    }

    // --- Public Auction Utils ---
    /*
    * @notice Fetch the collateral median price (from the oracle, not FSM)
    * @returns The collateral price from the oracle median; zero if the address of the collateralMedian (as fetched from the FSM) is null
    */
    function getCollateralMedianPrice() public view returns (uint256 priceFeed) {
        // Fetch the collateral median address from the collateral FSM
        address collateralMedian;
        try collateralFSM.priceSource() returns (address median) {
          collateralMedian = median;
        } catch (bytes memory revertReason) {}

        if (collateralMedian == address(0)) return 0;

        // wrapped call toward the collateral median
        try OracleLike(collateralMedian).getResultWithValidity()
          returns (uint256 price, bool valid) {
          if (valid) {
            priceFeed = uint256(price);
          }
        } catch (bytes memory revertReason) {
          return 0;
        }
    }
    /*
    * @notice Fetch the system coin market price
    * @returns The system coin market price fetch from the oracle
    */
    function getSystemCoinMarketPrice() public view returns (uint256 priceFeed) {
        if (address(systemCoinOracle) == address(0)) return 0;

        // wrapped call toward the system coin oracle
        try systemCoinOracle.getResultWithValidity()
          returns (uint256 price, bool valid) {
          if (valid) {
            priceFeed = uint256(price) * 10 ** 9; // scale to RAY
          }
        } catch (bytes memory revertReason) {
          return 0;
        }
    }
    /*
    * @notice Get the smallest possible price that's at max lowerSystemCoinMedianDeviation deviated from the redemption price and at least
    *         minSystemCoinMedianDeviation deviated
    */
    function getSystemCoinFloorDeviatedPrice(uint256 redemptionPrice) public view returns (uint256 floorPrice) {
        uint256 minFloorDeviatedPrice = wmultiply(redemptionPrice, minSystemCoinMedianDeviation);
        floorPrice = wmultiply(redemptionPrice, lowerSystemCoinMedianDeviation);
        floorPrice = (floorPrice <= minFloorDeviatedPrice) ? floorPrice : redemptionPrice;
    }
    /*
    * @notice Get the highest possible price that's at max upperSystemCoinMedianDeviation deviated from the redemption price and at least
    *         minSystemCoinMedianDeviation deviated
    */
    function getSystemCoinCeilingDeviatedPrice(uint256 redemptionPrice) public view returns (uint256 ceilingPrice) {
        uint256 minCeilingDeviatedPrice = wmultiply(redemptionPrice, subtract(2 * WAD, minSystemCoinMedianDeviation));
        ceilingPrice = wmultiply(redemptionPrice, subtract(2 * WAD, upperSystemCoinMedianDeviation));
        ceilingPrice = (ceilingPrice >= minCeilingDeviatedPrice) ? ceilingPrice : redemptionPrice;
    }
    /*
    * @notice Get the collateral price from the FSM and the final system coin price that will be used when bidding in an auction
    * @param systemCoinRedemptionPrice The system coin redemption price
    * @returns The collateral price from the FSM and the final system coin price used for bidding (picking between redemption and market prices)
    */
    function getCollateralFSMAndFinalSystemCoinPrices(uint256 systemCoinRedemptionPrice) public view returns (uint256, uint256) {
        require(systemCoinRedemptionPrice > 0, "IncreasingDiscountCollateralAuctionHouse/invalid-redemption-price-provided");
        (uint256 collateralFsmPriceFeedValue, bool collateralFsmHasValidValue) = collateralFSM.getResultWithValidity();
        if (!collateralFsmHasValidValue) {
          return (0, 0);
        }

        uint256 systemCoinAdjustedPrice  = systemCoinRedemptionPrice;
        uint256 systemCoinPriceFeedValue = getSystemCoinMarketPrice();

        if (systemCoinPriceFeedValue > 0) {
          uint256 floorPrice   = getSystemCoinFloorDeviatedPrice(systemCoinAdjustedPrice);
          uint256 ceilingPrice = getSystemCoinCeilingDeviatedPrice(systemCoinAdjustedPrice);

          if (uint(systemCoinPriceFeedValue) < systemCoinAdjustedPrice) {
            systemCoinAdjustedPrice = maximum(uint256(systemCoinPriceFeedValue), floorPrice);
          } else {
            systemCoinAdjustedPrice = minimum(uint256(systemCoinPriceFeedValue), ceilingPrice);
          }
        }

        return (uint256(collateralFsmPriceFeedValue), systemCoinAdjustedPrice);
    }
    /*
    * @notice Get the collateral price used in bidding by picking between the raw FSM and the oracle median price and taking into account
    *         deviation limits
    * @param collateralFsmPriceFeedValue The collateral price fetched from the FSM
    * @param collateralMedianPriceFeedValue The collateral price fetched from the median attached to the FSM
    */
    function getFinalBaseCollateralPrice(
        uint256 collateralFsmPriceFeedValue,
        uint256 collateralMedianPriceFeedValue
    ) public view returns (uint256) {
        uint256 floorPrice   = wmultiply(collateralFsmPriceFeedValue, lowerCollateralMedianDeviation);
        uint256 ceilingPrice = wmultiply(collateralFsmPriceFeedValue, subtract(2 * WAD, upperCollateralMedianDeviation));

        uint256 adjustedMedianPrice = (collateralMedianPriceFeedValue == 0) ?
          collateralFsmPriceFeedValue : collateralMedianPriceFeedValue;

        if (adjustedMedianPrice < collateralFsmPriceFeedValue) {
          return maximum(adjustedMedianPrice, floorPrice);
        } else {
          return minimum(adjustedMedianPrice, ceilingPrice);
        }
    }
    /*
    * @notice Get the discounted collateral price (using a custom discount)
    * @param collateralFsmPriceFeedValue The collateral price fetched from the FSM
    * @param collateralMedianPriceFeedValue The collateral price fetched from the oracle median
    * @param systemCoinPriceFeedValue The system coin price fetched from the oracle
    * @param customDiscount The custom discount used to calculate the collateral price offered
    */
    function getDiscountedCollateralPrice(
        uint256 collateralFsmPriceFeedValue,
        uint256 collateralMedianPriceFeedValue,
        uint256 systemCoinPriceFeedValue,
        uint256 customDiscount
    ) public view returns (uint256) {
        // calculate the collateral price in relation to the latest system coin price and apply the discount
        return wmultiply(
          rdivide(getFinalBaseCollateralPrice(collateralFsmPriceFeedValue, collateralMedianPriceFeedValue), systemCoinPriceFeedValue),
          customDiscount
        );
    }
    /*
    * @notice Get the upcoming discount that will be used in a specific auction
    * @param id The ID of the auction to calculate the upcoming discount for
    * @returns The upcoming discount that will be used in the targeted auction
    */
    function getNextCurrentDiscount(uint256 id) public view returns (uint256) {
        if (bids[id].forgoneCollateralReceiver == address(0)) return RAY;
        uint256 nextDiscount = bids[id].currentDiscount;

        // If the increase deadline hasn't been passed yet and the current discount is not at or greater than max
        if (both(uint48(now) < bids[id].discountIncreaseDeadline, bids[id].currentDiscount > bids[id].maxDiscount)) {
            // Calculate the new current discount
            nextDiscount = rmultiply(
              rpower(bids[id].perSecondDiscountUpdateRate, subtract(now, bids[id].latestDiscountUpdateTime), RAY),
              bids[id].currentDiscount
            );

            // If the new discount is greater than the max one
            if (nextDiscount <= bids[id].maxDiscount) {
              nextDiscount = bids[id].maxDiscount;
            }
        } else {
            // Determine the conditions when we can instantly set the current discount to max
            bool currentZeroMaxNonZero = both(bids[id].currentDiscount == 0, bids[id].maxDiscount > 0);
            bool doneUpdating          = both(uint48(now) >= bids[id].discountIncreaseDeadline, bids[id].currentDiscount != bids[id].maxDiscount);

            if (either(currentZeroMaxNonZero, doneUpdating)) {
              nextDiscount = bids[id].maxDiscount;
            }
        }

        return nextDiscount;
    }
    /*
    * @notice Get the actual bid that will be used in an auction (taking into account the bidder input)
    * @param id The id of the auction to calculate the adjusted bid for
    * @param wad The initial bid submitted
    * @returns Whether the bid is valid or not and the adjusted bid
    */
    function getAdjustedBid(
        uint256 id, uint256 wad
    ) public view returns (bool, uint256) {
        if (either(
          either(bids[id].amountToSell == 0, bids[id].amountToRaise == 0),
          either(wad == 0, wad < minimumBid)
        )) {
          return (false, wad);
        }

        uint256 remainingToRaise = bids[id].amountToRaise;

        // bound max amount offered in exchange for collateral
        uint256 adjustedBid = wad;
        if (multiply(adjustedBid, RAY) > remainingToRaise) {
            adjustedBid = addUint256(remainingToRaise / RAY, 1);
        }

        remainingToRaise = (multiply(adjustedBid, RAY) > remainingToRaise) ? 0 : subtract(bids[id].amountToRaise, multiply(adjustedBid, RAY));
        if (both(remainingToRaise > 0, remainingToRaise < RAY)) {
            return (false, adjustedBid);
        }

        return (true, adjustedBid);
    }

    // --- Core Auction Logic ---
    /**
     * @notice Start a new collateral auction
     * @param forgoneCollateralReceiver Who receives leftover collateral that is not auctioned
     * @param auctionIncomeRecipient Who receives the amount raised in the auction
     * @param amountToRaise Total amount of coins to raise (rad)
     * @param amountToSell Total amount of collateral available to sell (wad)
     * @param initialBid Unused
     */
    function startAuction(
        address forgoneCollateralReceiver,
        address auctionIncomeRecipient,
        uint256 amountToRaise,
        uint256 amountToSell,
        uint256 initialBid
    ) public isAuthorized returns (uint256 id) {
        require(auctionsStarted < uint256(-1), "IncreasingDiscountCollateralAuctionHouse/overflow");
        require(amountToSell > 0, "IncreasingDiscountCollateralAuctionHouse/no-collateral-for-sale");
        require(amountToRaise > 0, "IncreasingDiscountCollateralAuctionHouse/nothing-to-raise");
        require(amountToRaise >= RAY, "IncreasingDiscountCollateralAuctionHouse/dusty-auction");
        id = ++auctionsStarted;

        uint48 discountIncreaseDeadline      = addUint48(uint48(now), uint48(maxDiscountUpdateRateTimeline));

        bids[id].currentDiscount             = minDiscount;
        bids[id].maxDiscount                 = maxDiscount;
        bids[id].perSecondDiscountUpdateRate = perSecondDiscountUpdateRate;
        bids[id].discountIncreaseDeadline    = discountIncreaseDeadline;
        bids[id].latestDiscountUpdateTime    = now;
        bids[id].amountToSell                = amountToSell;
        bids[id].forgoneCollateralReceiver   = forgoneCollateralReceiver;
        bids[id].auctionIncomeRecipient      = auctionIncomeRecipient;
        bids[id].amountToRaise               = amountToRaise;

        safeEngine.transferCollateral(collateralType, msg.sender, address(this), amountToSell);

        emit StartAuction(
          id,
          auctionsStarted,
          amountToSell,
          initialBid,
          amountToRaise,
          minDiscount,
          maxDiscount,
          perSecondDiscountUpdateRate,
          discountIncreaseDeadline,
          forgoneCollateralReceiver,
          auctionIncomeRecipient
        );
    }
    /**
     * @notice Calculate how much collateral someone would buy from an auction using the last read redemption price and the old current
     *         discount associated with the auction
     * @param id ID of the auction to buy collateral from
     * @param wad New bid submitted
     */
    function getApproximateCollateralBought(uint256 id, uint256 wad) external view returns (uint256, uint256) {
        if (lastReadRedemptionPrice == 0) return (0, wad);

        (bool validAuctionAndBid, uint256 adjustedBid) = getAdjustedBid(id, wad);
        if (!validAuctionAndBid) {
            return (0, adjustedBid);
        }

        // check that the oracle doesn't return an invalid value
        (uint256 collateralFsmPriceFeedValue, uint256 systemCoinPriceFeedValue) = getCollateralFSMAndFinalSystemCoinPrices(lastReadRedemptionPrice);
        if (collateralFsmPriceFeedValue == 0) {
          return (0, adjustedBid);
        }

        return (getBoughtCollateral(
          id,
          collateralFsmPriceFeedValue,
          getCollateralMedianPrice(),
          systemCoinPriceFeedValue,
          adjustedBid,
          bids[id].currentDiscount
        ), adjustedBid);
    }
    /**
     * @notice Calculate how much collateral someone would buy from an auction using the latest redemption price fetched from the
     *         OracleRelayer and the latest updated discount associated with the auction
     * @param id ID of the auction to buy collateral from
     * @param wad New bid submitted
     */
    function getCollateralBought(uint256 id, uint256 wad) external returns (uint256, uint256) {
        (bool validAuctionAndBid, uint256 adjustedBid) = getAdjustedBid(id, wad);
        if (!validAuctionAndBid) {
            return (0, adjustedBid);
        }

        // Read the redemption price
        lastReadRedemptionPrice = oracleRelayer.redemptionPrice();

        // check that the oracle doesn't return an invalid value
        (uint256 collateralFsmPriceFeedValue, uint256 systemCoinPriceFeedValue) = getCollateralFSMAndFinalSystemCoinPrices(lastReadRedemptionPrice);
        if (collateralFsmPriceFeedValue == 0) {
          return (0, adjustedBid);
        }

        return (getBoughtCollateral(
          id,
          collateralFsmPriceFeedValue,
          getCollateralMedianPrice(),
          systemCoinPriceFeedValue,
          adjustedBid,
          updateCurrentDiscount(id)
        ), adjustedBid);
    }
    /**
     * @notice Buy collateral from an auction at an increasing discount
     * @param id ID of the auction to buy collateral from
     * @param wad New bid submitted (as a WAD which has 18 decimals)
     */
    function buyCollateral(uint256 id, uint256 wad) external {
        require(both(bids[id].amountToSell > 0, bids[id].amountToRaise > 0), "IncreasingDiscountCollateralAuctionHouse/inexistent-auction");
        require(both(wad > 0, wad >= minimumBid), "IncreasingDiscountCollateralAuctionHouse/invalid-bid");

        // bound max amount offered in exchange for collateral (in case someone offers more than it's necessary)
        uint256 adjustedBid = wad;
        if (multiply(adjustedBid, RAY) > bids[id].amountToRaise) {
            adjustedBid = addUint256(bids[id].amountToRaise / RAY, 1);
        }

        // Read the redemption price
        lastReadRedemptionPrice = oracleRelayer.redemptionPrice();

        // check that the collateral FSM doesn't return an invalid value
        (uint256 collateralFsmPriceFeedValue, uint256 systemCoinPriceFeedValue) = getCollateralFSMAndFinalSystemCoinPrices(lastReadRedemptionPrice);
        require(collateralFsmPriceFeedValue > 0, "IncreasingDiscountCollateralAuctionHouse/collateral-fsm-invalid-value");

        // get the amount of collateral bought
        uint256 boughtCollateral = getBoughtCollateral(
            id, collateralFsmPriceFeedValue, getCollateralMedianPrice(), systemCoinPriceFeedValue, adjustedBid, updateCurrentDiscount(id)
        );
        // check that the calculated amount is greater than zero
        require(boughtCollateral > 0, "IncreasingDiscountCollateralAuctionHouse/null-bought-amount");
        // update the amount of collateral to sell
        bids[id].amountToSell = subtract(bids[id].amountToSell, boughtCollateral);

        // update remainingToRaise in case amountToSell is zero (everything has been sold)
        uint256 remainingToRaise = (either(multiply(wad, RAY) >= bids[id].amountToRaise, bids[id].amountToSell == 0)) ?
            bids[id].amountToRaise : subtract(bids[id].amountToRaise, multiply(wad, RAY));

        // update leftover amount to raise in the bid struct
        bids[id].amountToRaise = (multiply(adjustedBid, RAY) > bids[id].amountToRaise) ?
            0 : subtract(bids[id].amountToRaise, multiply(adjustedBid, RAY));

        // check that the remaining amount to raise is either zero or higher than RAY
        require(
          either(bids[id].amountToRaise == 0, bids[id].amountToRaise >= RAY),
          "IncreasingDiscountCollateralAuctionHouse/invalid-left-to-raise"
        );

        // transfer the bid to the income recipient and the collateral to the bidder
        safeEngine.transferInternalCoins(msg.sender, bids[id].auctionIncomeRecipient, multiply(adjustedBid, RAY));
        safeEngine.transferCollateral(collateralType, address(this), msg.sender, boughtCollateral);

        // Emit the buy event
        emit BuyCollateral(id, adjustedBid, boughtCollateral);

        // Remove coins from the liquidation buffer
        bool soldAll = either(bids[id].amountToRaise == 0, bids[id].amountToSell == 0);
        if (soldAll) {
            liquidationEngine.removeCoinsFromAuction(remainingToRaise);
        } else {
            liquidationEngine.removeCoinsFromAuction(multiply(adjustedBid, RAY));
        }

        // If the auction raised the whole amount or all collateral was sold,
        // send remaining collateral to the forgone receiver
        if (soldAll) {
            safeEngine.transferCollateral(collateralType, address(this), bids[id].forgoneCollateralReceiver, bids[id].amountToSell);
            delete bids[id];
            emit SettleAuction(id, bids[id].amountToSell);
        }
    }
    /**
     * @notice Settle/finish an auction
     * @param id ID of the auction to settle
     */
    function settleAuction(uint256 id) external {
        return;
    }
    /**
     * @notice Terminate an auction prematurely. Usually called by Global Settlement.
     * @param id ID of the auction to settle
     */
    function terminateAuctionPrematurely(uint256 id) external isAuthorized {
        require(both(bids[id].amountToSell > 0, bids[id].amountToRaise > 0), "IncreasingDiscountCollateralAuctionHouse/inexistent-auction");
        liquidationEngine.removeCoinsFromAuction(bids[id].amountToRaise);
        safeEngine.transferCollateral(collateralType, address(this), msg.sender, bids[id].amountToSell);
        delete bids[id];
        emit TerminateAuctionPrematurely(id, msg.sender, bids[id].amountToSell);
    }

    // --- Getters ---
    function bidAmount(uint256 id) public view returns (uint256) {
        return 0;
    }
    function remainingAmountToSell(uint256 id) public view returns (uint256) {
        return bids[id].amountToSell;
    }
    function forgoneCollateralReceiver(uint256 id) public view returns (address) {
        return bids[id].forgoneCollateralReceiver;
    }
    function raisedAmount(uint256 id) public view returns (uint256) {
        return 0;
    }
    function amountToRaise(uint256 id) public view returns (uint256) {
        return bids[id].amountToRaise;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"safeEngine_","type":"address"},{"internalType":"address","name":"liquidationEngine_","type":"address"},{"internalType":"bytes32","name":"collateralType_","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"AddAuthorization","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wad","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boughtCollateral","type":"uint256"}],"name":"BuyCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"address","name":"data","type":"address"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"RemoveAuthorization","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leftoverCollateral","type":"uint256"}],"name":"SettleAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"auctionsStarted","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountToSell","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"initialBid","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amountToRaise","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startingDiscount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxDiscount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"perSecondDiscountUpdateRate","type":"uint256"},{"indexed":false,"internalType":"uint48","name":"discountIncreaseDeadline","type":"uint48"},{"indexed":true,"internalType":"address","name":"forgoneCollateralReceiver","type":"address"},{"indexed":true,"internalType":"address","name":"auctionIncomeRecipient","type":"address"}],"name":"StartAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"TerminateAuctionPrematurely","type":"event"},{"inputs":[],"name":"AUCTION_HOUSE_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AUCTION_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"amountToRaise","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auctionsStarted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorizedAccounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"bidAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bids","outputs":[{"internalType":"uint256","name":"amountToSell","type":"uint256"},{"internalType":"uint256","name":"amountToRaise","type":"uint256"},{"internalType":"uint256","name":"currentDiscount","type":"uint256"},{"internalType":"uint256","name":"maxDiscount","type":"uint256"},{"internalType":"uint256","name":"perSecondDiscountUpdateRate","type":"uint256"},{"internalType":"uint256","name":"latestDiscountUpdateTime","type":"uint256"},{"internalType":"uint48","name":"discountIncreaseDeadline","type":"uint48"},{"internalType":"address","name":"forgoneCollateralReceiver","type":"address"},{"internalType":"address","name":"auctionIncomeRecipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"buyCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collateralFSM","outputs":[{"internalType":"contract OracleLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralType","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"forgoneCollateralReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"getAdjustedBid","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"getApproximateCollateralBought","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"getCollateralBought","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"systemCoinRedemptionPrice","type":"uint256"}],"name":"getCollateralFSMAndFinalSystemCoinPrices","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCollateralMedianPrice","outputs":[{"internalType":"uint256","name":"priceFeed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collateralFsmPriceFeedValue","type":"uint256"},{"internalType":"uint256","name":"collateralMedianPriceFeedValue","type":"uint256"},{"internalType":"uint256","name":"systemCoinPriceFeedValue","type":"uint256"},{"internalType":"uint256","name":"customDiscount","type":"uint256"}],"name":"getDiscountedCollateralPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"collateralFsmPriceFeedValue","type":"uint256"},{"internalType":"uint256","name":"collateralMedianPriceFeedValue","type":"uint256"}],"name":"getFinalBaseCollateralPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getNextCurrentDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"redemptionPrice","type":"uint256"}],"name":"getSystemCoinCeilingDeviatedPrice","outputs":[{"internalType":"uint256","name":"ceilingPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"redemptionPrice","type":"uint256"}],"name":"getSystemCoinFloorDeviatedPrice","outputs":[{"internalType":"uint256","name":"floorPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSystemCoinMarketPrice","outputs":[{"internalType":"uint256","name":"priceFeed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastReadRedemptionPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidationEngine","outputs":[{"internalType":"contract LiquidationEngineLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lowerCollateralMedianDeviation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lowerSystemCoinMedianDeviation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDiscountUpdateRateTimeline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minSystemCoinMedianDeviation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumBid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracleRelayer","outputs":[{"internalType":"contract OracleRelayerLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"perSecondDiscountUpdateRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"raisedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"remainingAmountToSell","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"safeEngine","outputs":[{"internalType":"contract SAFEEngineLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"settleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forgoneCollateralReceiver","type":"address"},{"internalType":"address","name":"auctionIncomeRecipient","type":"address"},{"internalType":"uint256","name":"amountToRaise","type":"uint256"},{"internalType":"uint256","name":"amountToSell","type":"uint256"},{"internalType":"uint256","name":"initialBid","type":"uint256"}],"name":"startAuction","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemCoinOracle","outputs":[{"internalType":"contract OracleLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"terminateAuctionPrematurely","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAuctionLength","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"upperCollateralMedianDeviation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"upperSystemCoinMedianDeviation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6080604052674563918244f400006004556005805465ffffffffffff191665ffffffffffff1790556000600655670d2f13f7789f0000600881905560098190556b033b2e3c9fd0803ce8000000600a55610e10600b55670c7d713b49da0000600c55600d55670de0b6b3a7640000600e819055600f55670ddd2935029d800060105534801561008d57600080fd5b50604051613399380380613399833981810160405260608110156100b057600080fd5b508051602080830151604093840151600280546001600160a01b038087166001600160a01b0319928316179092556014805492851692909116919091179055600381905533600081815280855286902060019055855190815294519394919390927f599a298163e1678bb1c676052a8930bf0b8a1261ed6e01b8a2391e55f7000102928290030190a150505061324e8061014b6000396000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c80635e3a02cb11610167578063b64c1d55116100ce578063e934323b11610087578063e934323b146106d7578063f16e0fc1146106df578063f32abfac146106fc578063fe36543914610704578063fe4f58901461070c578063ff8dad751461072f57610295565b8063b64c1d5514610677578063b8b89e1b14610694578063ca8481491461069c578063d3a86386146106bf578063e818ac21146106c7578063e824600f146106cf57610295565b80638d68836c116101205780638d68836c146105e4578063933f76081461060757806394f3f81d146106245780639b056afb1461064a578063acb4cd2614610652578063b261c39a1461065a57610295565b80635e3a02cb146105415780636614f0101461055e57806367aea3131461058a57806373c0a3671461059257806376353627146104d457806383ba1afc146105b557610295565b80633d6f49111161020b57806346585f61116101c457806346585f611461049657806348d9be16146104d45780634a71b469146104f15780634faf61ab1461050e57806354ece2d314610516578063551cb3b11461053957610295565b80633d6f4911146103c55780634423c5f1146103cd57806344bf3c721461044557806344f5b11014610469578063455018e11461047157806345edd29b1461047957610295565b806325ebc2741161025d57806325ebc274146102f25780632e9936111461033457806334f36bb814610353578063355a47531461035b57806335b2815314610363578063394e954d1461038957610295565b806303a613031461029a5780630b73771f146102b45780631266fb94146102bc5780631fcf3810146102c457806324ba5884146102cc575b600080fd5b6102a261074c565b60408051918252519081900360200190f35b6102a26108cb565b6102a26108d1565b6102a26108e2565b6102a2600480360360208110156102e257600080fd5b50356001600160a01b03166108e8565b6102a2600480360360a081101561030857600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608001356108fa565b6103516004803603602081101561034a57600080fd5b5035610d0c565b005b6102a2610d0f565b6102a2610d15565b6103516004803603602081101561037957600080fd5b50356001600160a01b0316610d2f565b6103ac6004803603604081101561039f57600080fd5b5080359060200135610dcf565b6040805192835260208301919091528051918290030190f35b6102a2610ece565b6103ea600480360360208110156103e357600080fd5b5035610faa565b60408051998a5260208a0198909852888801969096526060880194909452608087019290925260a086015265ffffffffffff1660c08501526001600160a01b0390811660e08501521661010083015251908190036101200190f35b61044d61100b565b604080516001600160a01b039092168252519081900360200190f35b6102a261101a565b6102a2611020565b61044d6004803603602081101561048f57600080fd5b5035611026565b6104b9600480360360408110156104ac57600080fd5b508035906020013561104e565b60408051921515835260208301919091528051918290030190f35b6102a2600480360360208110156104ea57600080fd5b5035611176565b6102a26004803603602081101561050757600080fd5b503561117c565b61044d6111d5565b6103516004803603604081101561052c57600080fd5b50803590602001356111e4565b6102a2611944565b6102a26004803603602081101561055757600080fd5b503561194a565b6103516004803603604081101561057457600080fd5b50803590602001356001600160a01b0316611960565b61044d611b81565b61059a611b90565b6040805165ffffffffffff9092168252519081900360200190f35b6102a2600480360360808110156105cb57600080fd5b5080359060208101359060408101359060600135611b9e565b6103ac600480360360408110156105fa57600080fd5b5080359060200135611bc5565b6103516004803603602081101561061d57600080fd5b5035611c54565b6103516004803603602081101561063a57600080fd5b50356001600160a01b0316611e92565b6102a2611f31565b6102a2611f37565b6102a26004803603602081101561067057600080fd5b5035611f3d565b6103ac6004803603602081101561068d57600080fd5b50356120d4565b6102a261220b565b6102a2600480360360408110156106b257600080fd5b5080359060200135612211565b6102a2612279565b61044d61227f565b6102a261228e565b6102a2612294565b6102a2600480360360208110156106f557600080fd5b503561229a565b61044d6122ac565b6102a26122bb565b6103516004803603604081101561072257600080fd5b50803590602001356122c1565b6102a26004803603602081101561074557600080fd5b503561277a565b600080601260009054906101000a90046001600160a01b03166001600160a01b03166320531bc96040518163ffffffff1660e01b815260040160206040518083038186803b15801561079d57600080fd5b505afa9250505080156107c257506040513d60208110156107bd57600080fd5b505160015b6107fc573d8080156107f0576040519150601f19603f3d011682016040523d82523d6000602084013e6107f5565b606091505b50506107ff565b90505b6001600160a01b0381166108175760009150506108c8565b806001600160a01b0316634fd0ada86040518163ffffffff1660e01b8152600401604080518083038186803b15801561084f57600080fd5b505afa92505050801561087b57506040513d604081101561086f57600080fd5b50805160209091015160015b6108ba573d8080156108a9576040519150601f19603f3d011682016040523d82523d6000602084013e6108ae565b606091505b506000925050506108c8565b80156108c4578193505b5050505b90565b600f5481565b6910d3d31310551154905360b21b81565b600c5481565b60006020819052908152604090205481565b336000908152602081905260408120546001146109485760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b6000196006541061098a5760405162461bcd60e51b8152600401808060200182810382526031815260200180612e036031913960400191505060405180910390fd5b600083116109c95760405162461bcd60e51b815260040180806020018281038252603f81526020018061304a603f913960400191505060405180910390fd5b60008411610a085760405162461bcd60e51b8152600401808060200182810382526039815260200180612d776039913960400191505060405180910390fd5b676765c793fa10079d601b1b841015610a525760405162461bcd60e51b8152600401808060200182810382526036815260200180612fa26036913960400191505060405180910390fd5b506006805460010190819055600b54600090610a6f9042906127a7565b905060085460016000848152602001908152602001600020600201819055506009546001600084815260200190815260200160002060030181905550600a546001600084815260200190815260200160002060040181905550806001600084815260200190815260200160002060060160006101000a81548165ffffffffffff021916908365ffffffffffff160217905550426001600084815260200190815260200160002060050181905550836001600084815260200190815260200160002060000181905550866001600084815260200190815260200160002060060160066101000a8154816001600160a01b0302191690836001600160a01b03160217905550856001600084815260200190815260200160002060070160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550846001600084815260200190815260200160002060010181905550600260009054906101000a90046001600160a01b03166001600160a01b0316634e5111a66003543330886040518563ffffffff1660e01b815260040180858152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050600060405180830381600087803b158015610c6157600080fd5b505af1158015610c75573d6000803e3d6000fd5b5050600654600854600954600a546040805189815260208101959095528481018b9052606085018a9052608085019390935260a084019190915260c083015265ffffffffffff851660e0830152516001600160a01b03808b1694508b16925088917feeef9cc8b762ca3069593e765824d4986b3666db6287f9d6418789eda72cfe3791908190036101000190a45095945050505050565b50565b60075481565b72125390d4915054d25391d7d11254d0d3d55395606a1b81565b33600090815260208190526040902054600114610d7d5760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b6001600160a01b0381166000818152602081815260409182902060019055815192835290517f599a298163e1678bb1c676052a8930bf0b8a1261ed6e01b8a2391e55f70001029281900390910190a150565b600080600080610ddf868661104e565b9150915081610df557600093509150610ec79050565b601160009054906101000a90046001600160a01b03166001600160a01b031663c5b748c06040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e4557600080fd5b505af1158015610e59573d6000803e3d6000fd5b505050506040513d6020811015610e6f57600080fd5b505160078190556000908190610e84906120d4565b915091508160001415610ea1575060009450909250610ec7915050565b610ebe8883610eae61074c565b8487610eb98e6127f4565b612822565b95509193505050505b9250929050565b6013546000906001600160a01b0316610ee9575060006108c8565b601354604080516309fa15b560e31b815281516001600160a01b0390931692634fd0ada892600480840193919291829003018186803b158015610f2b57600080fd5b505afa925050508015610f5757506040513d6040811015610f4b57600080fd5b50805160209091015160015b610f95573d808015610f85576040519150601f19603f3d011682016040523d82523d6000602084013e610f8a565b606091505b5060009150506108c8565b8015610fa55781633b9aca000292505b505090565b6001602081905260009182526040909120805491810154600282015460038301546004840154600585015460068601546007909601549495939492939192909165ffffffffffff8116916001600160a01b03600160301b9092048216911689565b6014546001600160a01b031681565b600d5481565b600e5481565b600081815260016020526040902060060154600160301b90046001600160a01b03165b919050565b600082815260016020819052604082208054910154829161108b916110759115901561287a565b61108685600014600454871061287a565b61287a565b1561109b57506000905081610ec7565b6000848152600160208190526040909120015483816110c582676765c793fa10079d601b1b61287e565b11156110e7576110e4676765c793fa10079d601b1b835b0460016128d4565b90505b816110fd82676765c793fa10079d601b1b61287e565b1161113857600086815260016020819052604090912001546111339061112e83676765c793fa10079d601b1b61287e565b612916565b61113b565b60005b915061115760008311676765c793fa10079d601b1b8410612958565b1561116957600093509150610ec79050565b6001969095509350505050565b50600090565b60008061119f8361119a670de0b6b3a7640000600202601054612916565b61295c565b90506111bc8361119a670de0b6b3a7640000600202600f54612916565b9150808210156111cc57826111ce565b815b9392505050565b6011546001600160a01b031681565b60008281526001602081905260409091208054910154611208911515901515612958565b6112435760405162461bcd60e51b815260040180806020018281038252603b8152602001806131a0603b913960400191505060405180910390fd5b61125560008211600454831015612958565b6112905760405162461bcd60e51b8152600401808060200182810382526034815260200180612f2c6034913960400191505060405180910390fd5b6000828152600160208190526040909120015481906112ba82676765c793fa10079d601b1b61287e565b11156112ec57600083815260016020819052604090912001546112e990676765c793fa10079d601b1b906110dc565b90505b601160009054906101000a90046001600160a01b03166001600160a01b031663c5b748c06040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561133c57600080fd5b505af1158015611350573d6000803e3d6000fd5b505050506040513d602081101561136657600080fd5b50516007819055600090819061137b906120d4565b91509150600082116113be5760405162461bcd60e51b8152600401808060200182810382526045815260200180612b746045913960600191505060405180910390fd5b60006113d886846113cd61074c565b8588610eb98c6127f4565b9050600081116114195760405162461bcd60e51b815260040180806020018281038252603b815260200180612ef1603b913960400191505060405180910390fd5b6000868152600160205260409020546114329082612916565b60008781526001602081905260408220928355919091015461147c9061146388676765c793fa10079d601b1b61287e565b60008a815260016020526040902054911115901561287a565b6114b157600087815260016020819052604090912001546114ac9061112e88676765c793fa10079d601b1b61287e565b6114c5565b600087815260016020819052604090912001545b600088815260016020819052604090912001549091506114f086676765c793fa10079d601b1b61287e565b1161152657600087815260016020819052604090912001546115219061112e87676765c793fa10079d601b1b61287e565b611529565b60005b60008881526001602081905260409091200181905561155890801590676765c793fa10079d601b1b111561287a565b6115935760405162461bcd60e51b815260040180806020018281038252603e8152602001806131db603e913960400191505060405180910390fd5b6002546000888152600160205260409020600701546001600160a01b039182169163efabcadc913391166115d289676765c793fa10079d601b1b61287e565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561163a57600080fd5b505af115801561164e573d6000803e3d6000fd5b50506002546003546040805163272888d360e11b8152600481019290925230602483015233604483015260648201879052516001600160a01b039092169350634e5111a6925060848082019260009290919082900301818387803b1580156116b557600080fd5b505af11580156116c9573d6000803e3d6000fd5b5050604080518881526020810186905281518b94507fa4a1133e32fac37643a1fe1db4631daadb462c8662ae16004e67f0b8bb60838393509081900390910190a26000878152600160208190526040822090810154905461172c9115901561287a565b9050801561179e576014546040805163332bef1160e01b81526004810185905290516001600160a01b039092169163332bef119160248082019260009290919082900301818387803b15801561178157600080fd5b505af1158015611795573d6000803e3d6000fd5b50505050611813565b6014546001600160a01b031663332bef116117c488676765c793fa10079d601b1b61287e565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156117fa57600080fd5b505af115801561180e573d6000803e3d6000fd5b505050505b801561193a5760025460035460008a81526001602052604080822060068101549054825163272888d360e11b815260048101959095523060248601526001600160a01b03600160301b9092048216604486015260648501529051931692634e5111a692608480820193929182900301818387803b15801561189357600080fd5b505af11580156118a7573d6000803e3d6000fd5b5050506000898152600160208181526040808420848155928301849055600283018490556003830184905560048301849055600583018490556006830180546001600160d01b0319169055600790920180546001600160a01b0319169055815192835290518b93507fef063949eb6ef5abef19139d9c75a558424ffa759302cfe445f8d2d327376fe49281900390910190a25b5050505050505050565b60065481565b6000908152600160208190526040909120015490565b336000908152602081905260409020546001146119ae5760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b816c37b930b1b632a932b630bcb2b960991b14156119e657601180546001600160a01b0319166001600160a01b038316179055611b3a565b816c636f6c6c61746572616c46534d60981b1415611a8c57601280546001600160a01b0319166001600160a01b038381169190911791829055604080516320531bc960e01b8152905192909116916320531bc991600480820192602092909190829003018186803b158015611a5a57600080fd5b505afa158015611a6e573d6000803e3d6000fd5b505050506040513d6020811015611a8457600080fd5b50611b3a9050565b816f73797374656d436f696e4f7261636c6560801b1415611ac757601380546001600160a01b0319166001600160a01b038316179055611b3a565b81706c69717569646174696f6e456e67696e6560781b1415611b0357601480546001600160a01b0319166001600160a01b038316179055611b3a565b60405162461bcd60e51b8152600401808060200182810382526042815260200180612f606042913960600191505060405180910390fd5b604080518381526001600160a01b038316602082015281517fd91f38cf03346b5dc15fb60f9076f866295231ad3c3841a1051f8443f25170d1929181900390910190a15050565b6002546001600160a01b031681565b60055465ffffffffffff1681565b6000611bbc611bb6611bb08787612211565b85612980565b8361295c565b95945050505050565b60008060075460001415611bde57506000905081610ec7565b600080611beb868661104e565b9150915081611c0157600093509150610ec79050565b600080611c0f6007546120d4565b915091508160001415611c2c575060009450909250610ec7915050565b610ebe8883611c3961074c565b60008c81526001602052604090206002015485908890612822565b33600090815260208190526040902054600114611ca25760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b60008181526001602081905260409091208054910154611cc6911515901515612958565b611d015760405162461bcd60e51b815260040180806020018281038252603b8152602001806131a0603b913960400191505060405180910390fd5b601454600082815260016020819052604080832090910154815163332bef1160e01b8152600481019190915290516001600160a01b039093169263332bef119260248084019391929182900301818387803b158015611d5f57600080fd5b505af1158015611d73573d6000803e3d6000fd5b505060025460035460008581526001602052604080822054815163272888d360e11b815260048101949094523060248501523360448501526064840152516001600160a01b039093169450634e5111a69350608480830193919282900301818387803b158015611de257600080fd5b505af1158015611df6573d6000803e3d6000fd5b5050506000828152600160208181526040808420848155928301849055600283018490556003830184905560048301849055600583018490556006830180546001600160d01b0319169055600790920180546001600160a01b031916905581513381529081019290925280518493507fc34559e2a8e75127b58d4776333fd647f36849c478fb02e4e069d7501ac004159281900390910190a250565b33600090815260208190526040902054600114611ee05760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b6001600160a01b03811660008181526020818152604080832092909255815192835290517f8834a87e641e9716be4f34527af5d23e11624f1ddeefede6ad75a9acfc31b9039281900390910190a150565b60085481565b60105481565b600081815260016020526040812060060154600160301b90046001600160a01b0316611f755750676765c793fa10079d601b1b611049565b6000828152600160205260409020600281015460068201546003909201549091611fb39165ffffffffffff9182164290921691909110908311612958565b15612040576000838152600160205260409020600481015460059091015461200c91611ff591611fe4904290612916565b676765c793fa10079d601b1b6129d6565b600085815260016020526040902060020154612a94565b600084815260016020526040902060030154909150811161203b57506000828152600160205260409020600301545b6120ce565b600083815260016020526040812060028101546003909101546120669115901515612958565b60008581526001602052604081206006810154600382015460029092015493945091926120a59265ffffffffffff908116429091161015911415612958565b90506120b1828261287a565b156120cb5760008581526001602052604090206003015492505b50505b92915050565b600080600083116121165760405162461bcd60e51b815260040180806020018281038252604a815260200180612e34604a913960600191505060405180910390fd5b601254604080516309fa15b560e31b8152815160009384936001600160a01b0390911692634fd0ada89260048083019392829003018186803b15801561215b57600080fd5b505afa15801561216f573d6000803e3d6000fd5b505050506040513d604081101561218557600080fd5b5080516020909101519092509050806121a75750600092508291506122069050565b8460006121b2610ece565b905080156121fd5760006121c58361277a565b905060006121d28461117c565b9050838310156121ed576121e68383612af9565b93506121fa565b6121f78382612b10565b93505b50505b50919350909150505b915091565b60095481565b60008061222084600c5461295c565b9050600061223f8561119a670de0b6b3a7640000600202600d54612916565b90506000841561224f5784612251565b855b90508581101561226f576122658184612af9565b93505050506120ce565b6122658183612b10565b60045481565b6013546001600160a01b031681565b60035481565b600b5481565b60009081526001602052604090205490565b6012546001600160a01b031681565b600a5481565b3360009081526020819052604090205460011461230f5760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b816a1b5a5b911a5cd8dbdd5b9d60aa1b14156123835761233e600954821015670de0b6b3a76400008310612958565b6123795760405162461bcd60e51b815260040180806020018281038252603d815260200180613111603d913960400191505060405180910390fd5b600881905561273b565b816a1b585e111a5cd8dbdd5b9d60aa1b1415612403576123be6123b5600854831115670de0b6b3a76400008410612958565b60008311612958565b6123f95760405162461bcd60e51b815260040180806020018281038252603d815260200180612e7e603d913960400191505060405180910390fd5b600981905561273b565b817f7065725365636f6e64446973636f756e74557064617465526174650000000000141561247f57676765c793fa10079d601b1b8111156124755760405162461bcd60e51b8152600401808060200182810382526045815260200180612c476045913960600191505060405180910390fd5b600a81905561273b565b817f6d6178446973636f756e745570646174655261746554696d656c696e65000000141561250a576124c5600082116124b842846128d4565b65ffffffffffff11612958565b6125005760405162461bcd60e51b8152600401808060200182810382526041815260200180612cc26041913960600191505060405180910390fd5b600b81905561273b565b817f6c6f776572436f6c6c61746572616c4d656469616e446576696174696f6e0000141561258357670de0b6b3a76400008111156125795760405162461bcd60e51b8152600401808060200182810382526052815260200180612bf56052913960600191505060405180910390fd5b600c81905561273b565b817f7570706572436f6c6c61746572616c4d656469616e446576696174696f6e000014156125fc57670de0b6b3a76400008111156125f25760405162461bcd60e51b815260040180806020018281038252605281526020018061314e6052913960600191505060405180910390fd5b600d81905561273b565b817f6c6f77657253797374656d436f696e4d656469616e446576696174696f6e0000141561267557670de0b6b3a764000081111561266b5760405162461bcd60e51b8152600401808060200182810382526053815260200180612db06053913960600191505060405180910390fd5b600e81905561273b565b817f757070657253797374656d436f696e4d656469616e446576696174696f6e000014156126ee57670de0b6b3a76400008111156126e45760405162461bcd60e51b81526004018080602001828103825260538152602001806130896053913960600191505060405180910390fd5b600f81905561273b565b817f6d696e53797374656d436f696e4d656469616e446576696174696f6e00000000141561272057601081905561273b565b81691b5a5b9a5b5d5b509a5960b21b1415611b035760048190555b604080518381526020810183905281517fac7c5c1afaef770ec56ac6268cd3f2fbb1035858ead2601d6553157c33036c3a929181900390910190a15050565b6000806127898360105461295c565b905061279783600e5461295c565b9150808211156111cc57826111ce565b80820165ffffffffffff80841690821610156120ce5760405162461bcd60e51b815260040180806020018281038252603c815260200180612bb9603c913960400191505060405180910390fd5b600081815260016020526040812061280b83611f3d565b600282018190554260059092019190915592915050565b60008061283187878786611b9e565b9050600061283f8583612b20565b60008a815260016020526040902054909150811161285d578061286d565b6000898152600160205260409020545b9998505050505050505050565b1790565b60008115806128995750508082028282828161289657fe5b04145b6120ce5760405162461bcd60e51b81526004018080602001828103825260358152602001806130156035913960400191505060405180910390fd5b808201828110156120ce5760405162461bcd60e51b815260040180806020018281038252603d815260200180612fd8603d913960400191505060405180910390fd5b808203828111156120ce5760405162461bcd60e51b8152600401808060200182810382526036815260200180612ebb6036913960400191505060405180910390fd5b1690565b6000670de0b6b3a7640000612971848461287e565b8161297857fe5b049392505050565b60008082116129c05760405162461bcd60e51b81526004018080602001828103825260358152602001806130dc6035913960400191505060405180910390fd5b8161297184676765c793fa10079d601b1b61287e565b6000838015612a76576001841680156129f1578592506129f5565b8392505b50600283046002850494505b8415612a70578586028687820414612a1857600080fd5b81810181811015612a2857600080fd5b8590049650506001851615612a65578583028387820414158715151615612a4e57600080fd5b81810181811015612a5e57600080fd5b8590049350505b600285049450612a01565b50612a8c565b838015612a865760009250612a8a565b8392505b505b509392505050565b818102811580612aac575082828281612aa957fe5b04145b612ae75760405162461bcd60e51b8152600401808060200182810382526036815260200180612c8c6036913960400191505060405180910390fd5b676765c793fa10079d601b1b81612978565b600081831015612b0957816111ce565b5090919050565b600081831115612b0957816111ce565b6000808211612b605760405162461bcd60e51b8152600401808060200182810382526035815260200180612d036035913960400191505060405180910390fd5b8161297184670de0b6b3a764000061287e56fe496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f636f6c6c61746572616c2d66736d2d696e76616c69642d76616c7565496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6164642d75696e7434382d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6c6f7765722d636f6c6c61746572616c2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d646973636f756e742d7570646174652d72617465496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f726d756c2d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d7570646174652d726174652d74696d65496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f776469762d62792d7a65726f496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6163636f756e742d6e6f742d617574686f72697a6564496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6e6f7468696e672d746f2d7261697365496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6c6f7765722d73797374656d2d636f696e2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d726564656d7074696f6e2d70726963652d70726f7669646564496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6d61782d646973636f756e74496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f7375622d756e646572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6e756c6c2d626f756768742d616d6f756e74496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d626964496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6d6f646966792d756e7265636f676e697a65642d706172616d496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f64757374792d61756374696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6164642d75696e743235362d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6d756c2d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6e6f2d636f6c6c61746572616c2d666f722d73616c65496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d75707065722d73797374656d2d636f696e2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f726469762d62792d7a65726f496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6d696e2d646973636f756e74496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d75707065722d636f6c6c61746572616c2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e6578697374656e742d61756374696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6c6566742d746f2d7261697365a264697066735822122022066dba05c697ae11a7f5a343ce8b3c19f3e9b76d50c7f0bd8541f42cc8fe4164736f6c63430006070033000000000000000000000000cc88a9d330da1133df3a7bd823b95e52511a696200000000000000000000000027efc6ffe79692e0521e7e27657cf228240a06c24554482d41000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102955760003560e01c80635e3a02cb11610167578063b64c1d55116100ce578063e934323b11610087578063e934323b146106d7578063f16e0fc1146106df578063f32abfac146106fc578063fe36543914610704578063fe4f58901461070c578063ff8dad751461072f57610295565b8063b64c1d5514610677578063b8b89e1b14610694578063ca8481491461069c578063d3a86386146106bf578063e818ac21146106c7578063e824600f146106cf57610295565b80638d68836c116101205780638d68836c146105e4578063933f76081461060757806394f3f81d146106245780639b056afb1461064a578063acb4cd2614610652578063b261c39a1461065a57610295565b80635e3a02cb146105415780636614f0101461055e57806367aea3131461058a57806373c0a3671461059257806376353627146104d457806383ba1afc146105b557610295565b80633d6f49111161020b57806346585f61116101c457806346585f611461049657806348d9be16146104d45780634a71b469146104f15780634faf61ab1461050e57806354ece2d314610516578063551cb3b11461053957610295565b80633d6f4911146103c55780634423c5f1146103cd57806344bf3c721461044557806344f5b11014610469578063455018e11461047157806345edd29b1461047957610295565b806325ebc2741161025d57806325ebc274146102f25780632e9936111461033457806334f36bb814610353578063355a47531461035b57806335b2815314610363578063394e954d1461038957610295565b806303a613031461029a5780630b73771f146102b45780631266fb94146102bc5780631fcf3810146102c457806324ba5884146102cc575b600080fd5b6102a261074c565b60408051918252519081900360200190f35b6102a26108cb565b6102a26108d1565b6102a26108e2565b6102a2600480360360208110156102e257600080fd5b50356001600160a01b03166108e8565b6102a2600480360360a081101561030857600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608001356108fa565b6103516004803603602081101561034a57600080fd5b5035610d0c565b005b6102a2610d0f565b6102a2610d15565b6103516004803603602081101561037957600080fd5b50356001600160a01b0316610d2f565b6103ac6004803603604081101561039f57600080fd5b5080359060200135610dcf565b6040805192835260208301919091528051918290030190f35b6102a2610ece565b6103ea600480360360208110156103e357600080fd5b5035610faa565b60408051998a5260208a0198909852888801969096526060880194909452608087019290925260a086015265ffffffffffff1660c08501526001600160a01b0390811660e08501521661010083015251908190036101200190f35b61044d61100b565b604080516001600160a01b039092168252519081900360200190f35b6102a261101a565b6102a2611020565b61044d6004803603602081101561048f57600080fd5b5035611026565b6104b9600480360360408110156104ac57600080fd5b508035906020013561104e565b60408051921515835260208301919091528051918290030190f35b6102a2600480360360208110156104ea57600080fd5b5035611176565b6102a26004803603602081101561050757600080fd5b503561117c565b61044d6111d5565b6103516004803603604081101561052c57600080fd5b50803590602001356111e4565b6102a2611944565b6102a26004803603602081101561055757600080fd5b503561194a565b6103516004803603604081101561057457600080fd5b50803590602001356001600160a01b0316611960565b61044d611b81565b61059a611b90565b6040805165ffffffffffff9092168252519081900360200190f35b6102a2600480360360808110156105cb57600080fd5b5080359060208101359060408101359060600135611b9e565b6103ac600480360360408110156105fa57600080fd5b5080359060200135611bc5565b6103516004803603602081101561061d57600080fd5b5035611c54565b6103516004803603602081101561063a57600080fd5b50356001600160a01b0316611e92565b6102a2611f31565b6102a2611f37565b6102a26004803603602081101561067057600080fd5b5035611f3d565b6103ac6004803603602081101561068d57600080fd5b50356120d4565b6102a261220b565b6102a2600480360360408110156106b257600080fd5b5080359060200135612211565b6102a2612279565b61044d61227f565b6102a261228e565b6102a2612294565b6102a2600480360360208110156106f557600080fd5b503561229a565b61044d6122ac565b6102a26122bb565b6103516004803603604081101561072257600080fd5b50803590602001356122c1565b6102a26004803603602081101561074557600080fd5b503561277a565b600080601260009054906101000a90046001600160a01b03166001600160a01b03166320531bc96040518163ffffffff1660e01b815260040160206040518083038186803b15801561079d57600080fd5b505afa9250505080156107c257506040513d60208110156107bd57600080fd5b505160015b6107fc573d8080156107f0576040519150601f19603f3d011682016040523d82523d6000602084013e6107f5565b606091505b50506107ff565b90505b6001600160a01b0381166108175760009150506108c8565b806001600160a01b0316634fd0ada86040518163ffffffff1660e01b8152600401604080518083038186803b15801561084f57600080fd5b505afa92505050801561087b57506040513d604081101561086f57600080fd5b50805160209091015160015b6108ba573d8080156108a9576040519150601f19603f3d011682016040523d82523d6000602084013e6108ae565b606091505b506000925050506108c8565b80156108c4578193505b5050505b90565b600f5481565b6910d3d31310551154905360b21b81565b600c5481565b60006020819052908152604090205481565b336000908152602081905260408120546001146109485760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b6000196006541061098a5760405162461bcd60e51b8152600401808060200182810382526031815260200180612e036031913960400191505060405180910390fd5b600083116109c95760405162461bcd60e51b815260040180806020018281038252603f81526020018061304a603f913960400191505060405180910390fd5b60008411610a085760405162461bcd60e51b8152600401808060200182810382526039815260200180612d776039913960400191505060405180910390fd5b676765c793fa10079d601b1b841015610a525760405162461bcd60e51b8152600401808060200182810382526036815260200180612fa26036913960400191505060405180910390fd5b506006805460010190819055600b54600090610a6f9042906127a7565b905060085460016000848152602001908152602001600020600201819055506009546001600084815260200190815260200160002060030181905550600a546001600084815260200190815260200160002060040181905550806001600084815260200190815260200160002060060160006101000a81548165ffffffffffff021916908365ffffffffffff160217905550426001600084815260200190815260200160002060050181905550836001600084815260200190815260200160002060000181905550866001600084815260200190815260200160002060060160066101000a8154816001600160a01b0302191690836001600160a01b03160217905550856001600084815260200190815260200160002060070160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550846001600084815260200190815260200160002060010181905550600260009054906101000a90046001600160a01b03166001600160a01b0316634e5111a66003543330886040518563ffffffff1660e01b815260040180858152602001846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001945050505050600060405180830381600087803b158015610c6157600080fd5b505af1158015610c75573d6000803e3d6000fd5b5050600654600854600954600a546040805189815260208101959095528481018b9052606085018a9052608085019390935260a084019190915260c083015265ffffffffffff851660e0830152516001600160a01b03808b1694508b16925088917feeef9cc8b762ca3069593e765824d4986b3666db6287f9d6418789eda72cfe3791908190036101000190a45095945050505050565b50565b60075481565b72125390d4915054d25391d7d11254d0d3d55395606a1b81565b33600090815260208190526040902054600114610d7d5760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b6001600160a01b0381166000818152602081815260409182902060019055815192835290517f599a298163e1678bb1c676052a8930bf0b8a1261ed6e01b8a2391e55f70001029281900390910190a150565b600080600080610ddf868661104e565b9150915081610df557600093509150610ec79050565b601160009054906101000a90046001600160a01b03166001600160a01b031663c5b748c06040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610e4557600080fd5b505af1158015610e59573d6000803e3d6000fd5b505050506040513d6020811015610e6f57600080fd5b505160078190556000908190610e84906120d4565b915091508160001415610ea1575060009450909250610ec7915050565b610ebe8883610eae61074c565b8487610eb98e6127f4565b612822565b95509193505050505b9250929050565b6013546000906001600160a01b0316610ee9575060006108c8565b601354604080516309fa15b560e31b815281516001600160a01b0390931692634fd0ada892600480840193919291829003018186803b158015610f2b57600080fd5b505afa925050508015610f5757506040513d6040811015610f4b57600080fd5b50805160209091015160015b610f95573d808015610f85576040519150601f19603f3d011682016040523d82523d6000602084013e610f8a565b606091505b5060009150506108c8565b8015610fa55781633b9aca000292505b505090565b6001602081905260009182526040909120805491810154600282015460038301546004840154600585015460068601546007909601549495939492939192909165ffffffffffff8116916001600160a01b03600160301b9092048216911689565b6014546001600160a01b031681565b600d5481565b600e5481565b600081815260016020526040902060060154600160301b90046001600160a01b03165b919050565b600082815260016020819052604082208054910154829161108b916110759115901561287a565b61108685600014600454871061287a565b61287a565b1561109b57506000905081610ec7565b6000848152600160208190526040909120015483816110c582676765c793fa10079d601b1b61287e565b11156110e7576110e4676765c793fa10079d601b1b835b0460016128d4565b90505b816110fd82676765c793fa10079d601b1b61287e565b1161113857600086815260016020819052604090912001546111339061112e83676765c793fa10079d601b1b61287e565b612916565b61113b565b60005b915061115760008311676765c793fa10079d601b1b8410612958565b1561116957600093509150610ec79050565b6001969095509350505050565b50600090565b60008061119f8361119a670de0b6b3a7640000600202601054612916565b61295c565b90506111bc8361119a670de0b6b3a7640000600202600f54612916565b9150808210156111cc57826111ce565b815b9392505050565b6011546001600160a01b031681565b60008281526001602081905260409091208054910154611208911515901515612958565b6112435760405162461bcd60e51b815260040180806020018281038252603b8152602001806131a0603b913960400191505060405180910390fd5b61125560008211600454831015612958565b6112905760405162461bcd60e51b8152600401808060200182810382526034815260200180612f2c6034913960400191505060405180910390fd5b6000828152600160208190526040909120015481906112ba82676765c793fa10079d601b1b61287e565b11156112ec57600083815260016020819052604090912001546112e990676765c793fa10079d601b1b906110dc565b90505b601160009054906101000a90046001600160a01b03166001600160a01b031663c5b748c06040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561133c57600080fd5b505af1158015611350573d6000803e3d6000fd5b505050506040513d602081101561136657600080fd5b50516007819055600090819061137b906120d4565b91509150600082116113be5760405162461bcd60e51b8152600401808060200182810382526045815260200180612b746045913960600191505060405180910390fd5b60006113d886846113cd61074c565b8588610eb98c6127f4565b9050600081116114195760405162461bcd60e51b815260040180806020018281038252603b815260200180612ef1603b913960400191505060405180910390fd5b6000868152600160205260409020546114329082612916565b60008781526001602081905260408220928355919091015461147c9061146388676765c793fa10079d601b1b61287e565b60008a815260016020526040902054911115901561287a565b6114b157600087815260016020819052604090912001546114ac9061112e88676765c793fa10079d601b1b61287e565b6114c5565b600087815260016020819052604090912001545b600088815260016020819052604090912001549091506114f086676765c793fa10079d601b1b61287e565b1161152657600087815260016020819052604090912001546115219061112e87676765c793fa10079d601b1b61287e565b611529565b60005b60008881526001602081905260409091200181905561155890801590676765c793fa10079d601b1b111561287a565b6115935760405162461bcd60e51b815260040180806020018281038252603e8152602001806131db603e913960400191505060405180910390fd5b6002546000888152600160205260409020600701546001600160a01b039182169163efabcadc913391166115d289676765c793fa10079d601b1b61287e565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b15801561163a57600080fd5b505af115801561164e573d6000803e3d6000fd5b50506002546003546040805163272888d360e11b8152600481019290925230602483015233604483015260648201879052516001600160a01b039092169350634e5111a6925060848082019260009290919082900301818387803b1580156116b557600080fd5b505af11580156116c9573d6000803e3d6000fd5b5050604080518881526020810186905281518b94507fa4a1133e32fac37643a1fe1db4631daadb462c8662ae16004e67f0b8bb60838393509081900390910190a26000878152600160208190526040822090810154905461172c9115901561287a565b9050801561179e576014546040805163332bef1160e01b81526004810185905290516001600160a01b039092169163332bef119160248082019260009290919082900301818387803b15801561178157600080fd5b505af1158015611795573d6000803e3d6000fd5b50505050611813565b6014546001600160a01b031663332bef116117c488676765c793fa10079d601b1b61287e565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156117fa57600080fd5b505af115801561180e573d6000803e3d6000fd5b505050505b801561193a5760025460035460008a81526001602052604080822060068101549054825163272888d360e11b815260048101959095523060248601526001600160a01b03600160301b9092048216604486015260648501529051931692634e5111a692608480820193929182900301818387803b15801561189357600080fd5b505af11580156118a7573d6000803e3d6000fd5b5050506000898152600160208181526040808420848155928301849055600283018490556003830184905560048301849055600583018490556006830180546001600160d01b0319169055600790920180546001600160a01b0319169055815192835290518b93507fef063949eb6ef5abef19139d9c75a558424ffa759302cfe445f8d2d327376fe49281900390910190a25b5050505050505050565b60065481565b6000908152600160208190526040909120015490565b336000908152602081905260409020546001146119ae5760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b816c37b930b1b632a932b630bcb2b960991b14156119e657601180546001600160a01b0319166001600160a01b038316179055611b3a565b816c636f6c6c61746572616c46534d60981b1415611a8c57601280546001600160a01b0319166001600160a01b038381169190911791829055604080516320531bc960e01b8152905192909116916320531bc991600480820192602092909190829003018186803b158015611a5a57600080fd5b505afa158015611a6e573d6000803e3d6000fd5b505050506040513d6020811015611a8457600080fd5b50611b3a9050565b816f73797374656d436f696e4f7261636c6560801b1415611ac757601380546001600160a01b0319166001600160a01b038316179055611b3a565b81706c69717569646174696f6e456e67696e6560781b1415611b0357601480546001600160a01b0319166001600160a01b038316179055611b3a565b60405162461bcd60e51b8152600401808060200182810382526042815260200180612f606042913960600191505060405180910390fd5b604080518381526001600160a01b038316602082015281517fd91f38cf03346b5dc15fb60f9076f866295231ad3c3841a1051f8443f25170d1929181900390910190a15050565b6002546001600160a01b031681565b60055465ffffffffffff1681565b6000611bbc611bb6611bb08787612211565b85612980565b8361295c565b95945050505050565b60008060075460001415611bde57506000905081610ec7565b600080611beb868661104e565b9150915081611c0157600093509150610ec79050565b600080611c0f6007546120d4565b915091508160001415611c2c575060009450909250610ec7915050565b610ebe8883611c3961074c565b60008c81526001602052604090206002015485908890612822565b33600090815260208190526040902054600114611ca25760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b60008181526001602081905260409091208054910154611cc6911515901515612958565b611d015760405162461bcd60e51b815260040180806020018281038252603b8152602001806131a0603b913960400191505060405180910390fd5b601454600082815260016020819052604080832090910154815163332bef1160e01b8152600481019190915290516001600160a01b039093169263332bef119260248084019391929182900301818387803b158015611d5f57600080fd5b505af1158015611d73573d6000803e3d6000fd5b505060025460035460008581526001602052604080822054815163272888d360e11b815260048101949094523060248501523360448501526064840152516001600160a01b039093169450634e5111a69350608480830193919282900301818387803b158015611de257600080fd5b505af1158015611df6573d6000803e3d6000fd5b5050506000828152600160208181526040808420848155928301849055600283018490556003830184905560048301849055600583018490556006830180546001600160d01b0319169055600790920180546001600160a01b031916905581513381529081019290925280518493507fc34559e2a8e75127b58d4776333fd647f36849c478fb02e4e069d7501ac004159281900390910190a250565b33600090815260208190526040902054600114611ee05760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b6001600160a01b03811660008181526020818152604080832092909255815192835290517f8834a87e641e9716be4f34527af5d23e11624f1ddeefede6ad75a9acfc31b9039281900390910190a150565b60085481565b60105481565b600081815260016020526040812060060154600160301b90046001600160a01b0316611f755750676765c793fa10079d601b1b611049565b6000828152600160205260409020600281015460068201546003909201549091611fb39165ffffffffffff9182164290921691909110908311612958565b15612040576000838152600160205260409020600481015460059091015461200c91611ff591611fe4904290612916565b676765c793fa10079d601b1b6129d6565b600085815260016020526040902060020154612a94565b600084815260016020526040902060030154909150811161203b57506000828152600160205260409020600301545b6120ce565b600083815260016020526040812060028101546003909101546120669115901515612958565b60008581526001602052604081206006810154600382015460029092015493945091926120a59265ffffffffffff908116429091161015911415612958565b90506120b1828261287a565b156120cb5760008581526001602052604090206003015492505b50505b92915050565b600080600083116121165760405162461bcd60e51b815260040180806020018281038252604a815260200180612e34604a913960600191505060405180910390fd5b601254604080516309fa15b560e31b8152815160009384936001600160a01b0390911692634fd0ada89260048083019392829003018186803b15801561215b57600080fd5b505afa15801561216f573d6000803e3d6000fd5b505050506040513d604081101561218557600080fd5b5080516020909101519092509050806121a75750600092508291506122069050565b8460006121b2610ece565b905080156121fd5760006121c58361277a565b905060006121d28461117c565b9050838310156121ed576121e68383612af9565b93506121fa565b6121f78382612b10565b93505b50505b50919350909150505b915091565b60095481565b60008061222084600c5461295c565b9050600061223f8561119a670de0b6b3a7640000600202600d54612916565b90506000841561224f5784612251565b855b90508581101561226f576122658184612af9565b93505050506120ce565b6122658183612b10565b60045481565b6013546001600160a01b031681565b60035481565b600b5481565b60009081526001602052604090205490565b6012546001600160a01b031681565b600a5481565b3360009081526020819052604090205460011461230f5760405162461bcd60e51b815260040180806020018281038252603f815260200180612d38603f913960400191505060405180910390fd5b816a1b5a5b911a5cd8dbdd5b9d60aa1b14156123835761233e600954821015670de0b6b3a76400008310612958565b6123795760405162461bcd60e51b815260040180806020018281038252603d815260200180613111603d913960400191505060405180910390fd5b600881905561273b565b816a1b585e111a5cd8dbdd5b9d60aa1b1415612403576123be6123b5600854831115670de0b6b3a76400008410612958565b60008311612958565b6123f95760405162461bcd60e51b815260040180806020018281038252603d815260200180612e7e603d913960400191505060405180910390fd5b600981905561273b565b817f7065725365636f6e64446973636f756e74557064617465526174650000000000141561247f57676765c793fa10079d601b1b8111156124755760405162461bcd60e51b8152600401808060200182810382526045815260200180612c476045913960600191505060405180910390fd5b600a81905561273b565b817f6d6178446973636f756e745570646174655261746554696d656c696e65000000141561250a576124c5600082116124b842846128d4565b65ffffffffffff11612958565b6125005760405162461bcd60e51b8152600401808060200182810382526041815260200180612cc26041913960600191505060405180910390fd5b600b81905561273b565b817f6c6f776572436f6c6c61746572616c4d656469616e446576696174696f6e0000141561258357670de0b6b3a76400008111156125795760405162461bcd60e51b8152600401808060200182810382526052815260200180612bf56052913960600191505060405180910390fd5b600c81905561273b565b817f7570706572436f6c6c61746572616c4d656469616e446576696174696f6e000014156125fc57670de0b6b3a76400008111156125f25760405162461bcd60e51b815260040180806020018281038252605281526020018061314e6052913960600191505060405180910390fd5b600d81905561273b565b817f6c6f77657253797374656d436f696e4d656469616e446576696174696f6e0000141561267557670de0b6b3a764000081111561266b5760405162461bcd60e51b8152600401808060200182810382526053815260200180612db06053913960600191505060405180910390fd5b600e81905561273b565b817f757070657253797374656d436f696e4d656469616e446576696174696f6e000014156126ee57670de0b6b3a76400008111156126e45760405162461bcd60e51b81526004018080602001828103825260538152602001806130896053913960600191505060405180910390fd5b600f81905561273b565b817f6d696e53797374656d436f696e4d656469616e446576696174696f6e00000000141561272057601081905561273b565b81691b5a5b9a5b5d5b509a5960b21b1415611b035760048190555b604080518381526020810183905281517fac7c5c1afaef770ec56ac6268cd3f2fbb1035858ead2601d6553157c33036c3a929181900390910190a15050565b6000806127898360105461295c565b905061279783600e5461295c565b9150808211156111cc57826111ce565b80820165ffffffffffff80841690821610156120ce5760405162461bcd60e51b815260040180806020018281038252603c815260200180612bb9603c913960400191505060405180910390fd5b600081815260016020526040812061280b83611f3d565b600282018190554260059092019190915592915050565b60008061283187878786611b9e565b9050600061283f8583612b20565b60008a815260016020526040902054909150811161285d578061286d565b6000898152600160205260409020545b9998505050505050505050565b1790565b60008115806128995750508082028282828161289657fe5b04145b6120ce5760405162461bcd60e51b81526004018080602001828103825260358152602001806130156035913960400191505060405180910390fd5b808201828110156120ce5760405162461bcd60e51b815260040180806020018281038252603d815260200180612fd8603d913960400191505060405180910390fd5b808203828111156120ce5760405162461bcd60e51b8152600401808060200182810382526036815260200180612ebb6036913960400191505060405180910390fd5b1690565b6000670de0b6b3a7640000612971848461287e565b8161297857fe5b049392505050565b60008082116129c05760405162461bcd60e51b81526004018080602001828103825260358152602001806130dc6035913960400191505060405180910390fd5b8161297184676765c793fa10079d601b1b61287e565b6000838015612a76576001841680156129f1578592506129f5565b8392505b50600283046002850494505b8415612a70578586028687820414612a1857600080fd5b81810181811015612a2857600080fd5b8590049650506001851615612a65578583028387820414158715151615612a4e57600080fd5b81810181811015612a5e57600080fd5b8590049350505b600285049450612a01565b50612a8c565b838015612a865760009250612a8a565b8392505b505b509392505050565b818102811580612aac575082828281612aa957fe5b04145b612ae75760405162461bcd60e51b8152600401808060200182810382526036815260200180612c8c6036913960400191505060405180910390fd5b676765c793fa10079d601b1b81612978565b600081831015612b0957816111ce565b5090919050565b600081831115612b0957816111ce565b6000808211612b605760405162461bcd60e51b8152600401808060200182810382526035815260200180612d036035913960400191505060405180910390fd5b8161297184670de0b6b3a764000061287e56fe496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f636f6c6c61746572616c2d66736d2d696e76616c69642d76616c7565496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6164642d75696e7434382d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6c6f7765722d636f6c6c61746572616c2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d646973636f756e742d7570646174652d72617465496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f726d756c2d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d7570646174652d726174652d74696d65496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f776469762d62792d7a65726f496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6163636f756e742d6e6f742d617574686f72697a6564496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6e6f7468696e672d746f2d7261697365496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6c6f7765722d73797374656d2d636f696e2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d726564656d7074696f6e2d70726963652d70726f7669646564496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6d61782d646973636f756e74496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f7375622d756e646572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6e756c6c2d626f756768742d616d6f756e74496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d626964496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6d6f646966792d756e7265636f676e697a65642d706172616d496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f64757374792d61756374696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6164642d75696e743235362d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6d756c2d6f766572666c6f77496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f6e6f2d636f6c6c61746572616c2d666f722d73616c65496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d75707065722d73797374656d2d636f696e2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f726469762d62792d7a65726f496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6d696e2d646973636f756e74496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d75707065722d636f6c6c61746572616c2d6d656469616e2d646576696174696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e6578697374656e742d61756374696f6e496e6372656173696e67446973636f756e74436f6c6c61746572616c41756374696f6e486f7573652f696e76616c69642d6c6566742d746f2d7261697365a264697066735822122022066dba05c697ae11a7f5a343ce8b3c19f3e9b76d50c7f0bd8541f42cc8fe4164736f6c63430006070033

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

000000000000000000000000cc88a9d330da1133df3a7bd823b95e52511a696200000000000000000000000027efc6ffe79692e0521e7e27657cf228240a06c24554482d41000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : safeEngine_ (address): 0xCC88a9d330da1133Df3A7bD823B95e52511A6962
Arg [1] : liquidationEngine_ (address): 0x27Efc6FFE79692E0521E7e27657cF228240A06c2
Arg [2] : collateralType_ (bytes32): 0x4554482d41000000000000000000000000000000000000000000000000000000

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000cc88a9d330da1133df3a7bd823b95e52511a6962
Arg [1] : 00000000000000000000000027efc6ffe79692e0521e7e27657cf228240a06c2
Arg [2] : 4554482d41000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

2016:35707:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;2016:35707:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;18246:730:0;;;:::i;:::-;;;;;;;;;;;;;;;;7066:54;;;:::i;7659:66::-;;;:::i;6344:58::-;;;:::i;2094:54::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;2094:54:0;-1:-1:-1;;;;;2094:54:0;;:::i;28063:1857::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;;;;;;28063:1857:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;36379:69::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;36379:69:0;;:::i;:::-;;5331:41;;;:::i;7732:75::-;;;:::i;2258:156::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;2258:156:0;-1:-1:-1;;;;;2258:156:0;;:::i;31486:946::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;31486:946:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;19115:491;;;:::i;4618:36::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;4618:36:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4618:36:0;;;;;;;;;;;;;;;;;;;;;7604:46;;;:::i;:::-;;;;-1:-1:-1;;;;;7604:46:0;;;;;;;;;;;;;;6568:58;;;:::i;6817:54::-;;;:::i;37367:137::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;37367:137:0;;:::i;26680:917::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;26680:917:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;37147:88;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;37147:88:0;;:::i;20423:442::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;20423:442:0;;:::i;7454:42::-;;;:::i;32658:3610::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32658:3610:0;;;;;;;:::i;5248:37::-;;;:::i;37607:113::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;37607:113:0;;:::i;14930:703::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;14930:703:0;;;;;;-1:-1:-1;;;;;14930:703:0;;:::i;4685:32::-;;;:::i;5068:49::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;24096:565;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;24096:565:0;;;;;;;;;;;;;;;;;:::i;30230:915::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;30230:915:0;;;;;;;:::i;36605:510::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;36605:510:0;;:::i;2533:162::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;2533:162:0;-1:-1:-1;;;;;2533:162:0;;:::i;5495:39::-;;;:::i;7324:59::-;;;:::i;24922:1445::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;24922:1445:0;;:::i;21236:1235::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;21236:1235:0;;:::i;5739:39::-;;;:::i;22858:777::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;22858:777:0;;;;;;;:::i;4829:38::-;;;:::i;7552:45::-;;;:::i;4753:36::-;;;:::i;6116:58::-;;;:::i;37241:120::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;37241:120:0;;:::i;7503:42::-;;;:::i;5932:51::-;;;:::i;12358:2411::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;12358:2411:0;;;;;;;:::i;19821:388::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;19821:388:0;;:::i;18246:730::-;18303:17;18405:24;18444:13;;;;;;;;;-1:-1:-1;;;;;18444:13:0;-1:-1:-1;;;;;18444:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;18444:27:0;;;;;;;;;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;18444:27:0;;;18440:144;;;;14:27:-1;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;18548:36:0;18440:144;;;18529:6;-1:-1:-1;18440:144:0;-1:-1:-1;;;;;18600:30:0;;18596:44;;18639:1;18632:8;;;;;18596:44;18722:16;-1:-1:-1;;;;;18711:50:0;;:52;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;18711:52:0;;;;;;;;;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;18711:52:0;;;;;;;;;18707:262;;;;14:27:-1;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;18956:1:0;18949:8;;;;;;18707:262;18828:5;18824:66;;;18870:5;18850:26;;18824:66;18775:126;;18246:730;;;:::o;7066:54::-;;;;:::o;7659:66::-;-1:-1:-1;;;7659:66:0;:::o;6344:58::-;;;;:::o;2094:54::-;;;;;;;;;;;;;;:::o;28063:1857::-;2848:10;28298;2829:30;;;;;;;;;;;2863:1;2829:35;2821:111;;;;-1:-1:-1;;;2821:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;28329:15:0::1;;:29;28321:91;;;;-1:-1:-1::0;;;28321:91:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28446:1;28431:12;:16;28423:92;;;;-1:-1:-1::0;;;28423:92:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28550:1;28534:13;:17;28526:87;;;;-1:-1:-1::0;;;28526:87:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;28632:13:0::1;:20;;28624:87;;;;-1:-1:-1::0;;;28624:87:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;28729:15:0::1;28727:17:::0;;::::1;;::::0;;;;28826:29:::1;::::0;28729:15:::1;::::0;28796:61:::1;::::0;28813:3:::1;::::0;28796:9:::1;:61::i;:::-;28757:100;;28909:11;;28870:4;:8;28875:2;28870:8;;;;;;;;;;;:24;;:50;;;;28970:11;;28931:4;:8;28936:2;28931:8;;;;;;;;;;;:20;;:50;;;;29031:27;;28992:4;:8;28997:2;28992:8;;;;;;;;;;;:36;;:66;;;;29108:24;29069:4;:8;29074:2;29069:8;;;;;;;;;;;:33;;;:63;;;;;;;;;;;;;;;;;;29182:3;29143:4;:8;29148:2;29143:8;;;;;;;;;;;:33;;:42;;;;29235:12;29196:4;:8;29201:2;29196:8;;;;;;;;;;;:21;;:51;;;;29297:25;29258:4;:8;29263:2;29258:8;;;;;;;;;;;:34;;;:64;;;;;-1:-1:-1::0;;;;;29258:64:0::1;;;;;-1:-1:-1::0;;;;;29258:64:0::1;;;;;;29372:22;29333:4;:8;29338:2;29333:8;;;;;;;;;;;:31;;;:61;;;;;-1:-1:-1::0;;;;;29333:61:0::1;;;;;-1:-1:-1::0;;;;;29333:61:0::1;;;;;;29444:13;29405:4;:8;29410:2;29405:8;;;;;;;;;;;:22;;:52;;;;29470:10;;;;;;;;;-1:-1:-1::0;;;;;29470:10:0::1;-1:-1:-1::0;;;;;29470:29:0::1;;29500:14;;29516:10;29536:4;29543:12;29470:86;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;29470:86:0::1;-1:-1:-1::0;;;;;29470:86:0::1;;;;;;-1:-1:-1::0;;;;;29470:86:0::1;-1:-1:-1::0;;;;;29470:86:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;29470:86:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;;29614:15:0::1;::::0;29716:11:::1;::::0;29740::::1;::::0;29764:27:::1;::::0;29574:338:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::1;::::0;::::1;::::0;;;;;-1:-1:-1;;;;;29574:338:0;;::::1;::::0;-1:-1:-1;29574:338:0;::::1;::::0;-1:-1:-1;29690:13:0;;29574:338:::1;::::0;;;;;;;;::::1;2943:1;28063:1857:::0;;;;;;;:::o;36379:69::-;;:::o;5331:41::-;;;;:::o;7732:75::-;-1:-1:-1;;;7732:75:0;:::o;2258:156::-;2848:10;2829:18;:30;;;;;;;;;;;2863:1;2829:35;2821:111;;;;-1:-1:-1;;;2821:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2334:27:0;::::1;:18;:27:::0;;;::::1;::::0;;;;;;;;2364:1:::1;2334:31:::0;;2381:25;;;;;;;::::1;::::0;;;;;;;;::::1;2258:156:::0;:::o;31486:946::-;31558:7;31567;31588:23;31613:19;31636:23;31651:2;31655:3;31636:14;:23::i;:::-;31587:72;;;;31675:18;31670:75;;31718:1;;-1:-1:-1;31721:11:0;-1:-1:-1;31710:23:0;;-1:-1:-1;31710:23:0;31670:75;31821:13;;;;;;;;;-1:-1:-1;;;;;31821:13:0;-1:-1:-1;;;;;31821:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;31821:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31821:31:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;31821:31:0;31795:23;:57;;;31932:35;;;;32005:65;;:40;:65::i;:::-;31931:139;;;;32085:27;32116:1;32085:32;32081:86;;;-1:-1:-1;32140:1:0;;-1:-1:-1;32143:11:0;;-1:-1:-1;32132:23:0;;-1:-1:-1;;32132:23:0;32081:86;32187:223;32219:2;32234:27;32274:26;:24;:26::i;:::-;32313:24;32350:11;32374:25;32396:2;32374:21;:25::i;:::-;32187:19;:223::i;:::-;32179:245;-1:-1:-1;32412:11:0;;-1:-1:-1;;;;31486:946:0;;;;;;:::o;19115:491::-;19214:16;;19172:17;;-1:-1:-1;;;;;19214:16:0;19202:53;;-1:-1:-1;19254:1:0;19247:8;;19202:53;19327:16;;:40;;;-1:-1:-1;;;19327:40:0;;;;-1:-1:-1;;;;;19327:16:0;;;;:38;;:40;;;;;;;;;;;;;:16;:40;;;2:2:-1;;;;27:1;24;17:12;2:2;19327:40:0;;;;;;;;;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;19327:40:0;;;;;;;;;19323:276;;;;14:27:-1;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;19586:1:0;19579:8;;;;;19323:276;19432:5;19428:92;;;19474:5;19483:7;19466:24;19454:36;;19428:92;19379:152;;19115:491;:::o;4618:36::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;4618:36:0;;;;;;;;:::o;7604:46::-;;;-1:-1:-1;;;;;7604:46:0;;:::o;6568:58::-;;;;:::o;6817:54::-;;;;:::o;37367:137::-;37435:7;37462:8;;;:4;:8;;;;;:34;;;-1:-1:-1;;;37462:34:0;;-1:-1:-1;;;;;37462:34:0;37367:137;;;;:::o;26680:917::-;26766:4;26822:8;;;:4;:8;;;;;;;:21;;26850:22;;;26766:4;;26796:140;;26815:63;;26822:26;;26850:27;26815:6;:63::i;:::-;26891:34;26898:3;26905:1;26898:8;26914:10;;26908:3;:16;26891:6;:34::i;:::-;26796:6;:140::i;:::-;26792:190;;;-1:-1:-1;26959:5:0;;-1:-1:-1;26966:3:0;26951:19;;26792:190;26994:24;27021:8;;;:4;:8;;;;;;;;:22;;27142:3;27021:22;27160:26;27142:3;-1:-1:-1;;;27160:8:0;:26::i;:::-;:45;27156:129;;;27236:37;-1:-1:-1;;;27247:16:0;:22;;27271:1;27236:10;:37::i;:::-;27222:51;;27156:129;27346:16;27317:26;27326:11;-1:-1:-1;;;27317:8:0;:26::i;:::-;:45;27316:114;;27379:8;;;;:4;:8;;;;;;;;:22;;27370:60;;27403:26;27412:11;-1:-1:-1;;;27403:8:0;:26::i;:::-;27370:8;:60::i;:::-;27316:114;;;27366:1;27316:114;27297:133;;27445:50;27469:1;27450:16;:20;-1:-1:-1;;;27472:16:0;:22;27445:4;:50::i;:::-;27441:110;;;27520:5;;-1:-1:-1;27527:11:0;-1:-1:-1;27512:27:0;;-1:-1:-1;27512:27:0;27441:110;27571:4;;27577:11;;-1:-1:-1;26680:917:0;-1:-1:-1;;;;26680:917:0:o;37147:88::-;-1:-1:-1;37199:7:0;;37147:88::o;20423:442::-;20512:20;20545:31;20579:75;20589:15;20606:47;9946:8;20615:1;:7;20624:28;;20606:8;:47::i;:::-;20579:9;:75::i;:::-;20545:109;;20680:77;20690:15;20707:49;9946:8;20716:1;:7;20725:30;;20707:8;:49::i;20680:77::-;20665:92;;20800:23;20784:12;:39;;20783:74;;20842:15;20783:74;;;20827:12;20783:74;20768:89;20423:442;-1:-1:-1;;;20423:442:0:o;7454:42::-;;;-1:-1:-1;;;;;7454:42:0;;:::o;32658:3610::-;32763:1;32739:8;;;:4;:8;;;;;;;;:21;;32766:22;;;32734:59;;32739:25;;;32766:26;;32734:4;:59::i;:::-;32726:131;;;;-1:-1:-1;;;32726:131:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32876:32;32887:1;32881:3;:7;32897:10;;32890:3;:17;;32876:4;:32::i;:::-;32868:97;;;;-1:-1:-1;;;32868:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33092:19;33161:8;;;:4;:8;;;;;;;;:22;;33114:3;;33132:26;33114:3;-1:-1:-1;;;33132:8:0;:26::i;:::-;:51;33128:141;;;33225:8;;;;:4;:8;;;;;;;;:22;;33214:43;;-1:-1:-1;;;10108:8:0;33225:28;;33214:43;33200:57;;33128:141;33345:13;;;;;;;;;-1:-1:-1;;;;;33345:13:0;-1:-1:-1;;;;;33345:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;33345:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33345:31:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;33345:31:0;33319:23;:57;;;33464:35;;;;33537:65;;:40;:65::i;:::-;33463:139;;;;33651:1;33621:27;:31;33613:113;;;;-1:-1:-1;;;33613:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33787:24;33814:170;33848:2;33852:27;33881:26;:24;:26::i;:::-;33909:24;33935:11;33948:25;33970:2;33948:21;:25::i;33814:170::-;33787:197;;34088:1;34069:16;:20;34061:92;;;;-1:-1:-1;;;34061:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34249:8;;;;:4;:8;;;;;:21;34240:49;;34272:16;34240:8;:49::i;:::-;34216:8;;;;:4;:8;;;;;;;:73;;;34451:22;;;;;34422:80;;34429:18;34438:3;-1:-1:-1;;;34429:8:0;:18::i;:::-;34475:8;;;;:4;:8;;;;;:21;34429:44;-1:-1:-1;34429:44:0;;34475:26;34422:6;:80::i;:::-;34421:175;;34553:8;;;;:4;:8;;;;;;;;:22;;34544:52;;34577:18;34586:3;-1:-1:-1;;;34577:8:0;:18::i;34544:52::-;34421:175;;;34519:8;;;;:4;:8;;;;;;;;:22;;34421:175;34726:8;;;;:4;:8;;;;;;;;:22;;34394:202;;-1:-1:-1;34697:26:0;34706:11;-1:-1:-1;;;34697:8:0;:26::i;:::-;:51;34696:133;;34778:8;;;;:4;:8;;;;;;;;:22;;34769:60;;34802:26;34811:11;-1:-1:-1;;;34802:8:0;:26::i;34769:60::-;34696:133;;;34765:1;34696:133;34671:8;;;;:4;:8;;;;;;;;:22;:158;;;34949:66;;34956:27;;;-1:-1:-1;;;;34985:29:0;34949:6;:66::i;:::-;34929:174;;;;-1:-1:-1;;;34929:174:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35202:10;;;35247:8;;;35202:10;35247:8;;;;;:31;;;-1:-1:-1;;;;;35202:10:0;;;;:32;;35235:10;;35247:31;35280:26;35289:11;-1:-1:-1;;;35280:8:0;:26::i;:::-;35202:105;;;;;;;;;;;;;-1:-1:-1;;;;;35202:105:0;-1:-1:-1;;;;;35202:105:0;;;;;;-1:-1:-1;;;;;35202:105:0;-1:-1:-1;;;;;35202:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;35202:105:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;35318:10:0;;35348:14;;35318:90;;;-1:-1:-1;;;35318:90:0;;;;;;;;;35372:4;35318:90;;;;35379:10;35318:90;;;;;;;;;;;-1:-1:-1;;;;;35318:10:0;;;;-1:-1:-1;35318:29:0;;-1:-1:-1;35318:90:0;;;;;:10;;:90;;;;;;;;:10;;:90;;;2:2:-1;;;;27:1;24;17:12;2:2;35318:90:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;35457:48:0;;;;;;;;;;;;;;35471:2;;-1:-1:-1;35457:48:0;;-1:-1:-1;35457:48:0;;;;;;;;;35571:12;35593:8;;;:4;:8;;;;;;;:22;;;;35622:21;;35586:63;;35593:27;;35622:26;35586:6;:63::i;:::-;35571:78;;35664:7;35660:199;;;35688:17;;:58;;;-1:-1:-1;;;35688:58:0;;;;;;;;;;-1:-1:-1;;;;;35688:17:0;;;;:40;;:58;;;;;:17;;:58;;;;;;;;:17;;:58;;;2:2:-1;;;;27:1;24;17:12;2:2;35688:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;35688:58:0;;;;35660:199;;;35779:17;;-1:-1:-1;;;;;35779:17:0;:40;35820:26;35829:11;-1:-1:-1;;;35820:8:0;:26::i;:::-;35779:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;35779:68:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;35779:68:0;;;;35660:199;36016:7;36012:249;;;36040:10;;36070:14;;36040:10;36101:8;;;36040:10;36101:8;;;;;;:34;;;;36137:21;;36040:119;;-1:-1:-1;;;36040:119:0;;;;;;;;;36094:4;36040:119;;;;-1:-1:-1;;;;;;;;36101:34:0;;;;;36040:119;;;;;;;;;;:10;;;:29;;:119;;;;;:10;:119;;;;;;:10;;:119;;;2:2:-1;;;;27:1;24;17:12;2:2;36040:119:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;36181:8:0;;;;:4;:8;;;;;;;;36174:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;36174:15:0;;;;;;;;;-1:-1:-1;;;;;;36174:15:0;;;36209:40;;;;;;;36186:2;;-1:-1:-1;36209:40:0;;;;;;;;;;36012:249;32658:3610;;;;;;;;:::o;5248:37::-;;;;:::o;37607:113::-;37663:7;37690:8;;;:4;:8;;;;;;;;:22;;;37607:113::o;14930:703::-;2848:10;2829:18;:30;;;;;;;;;;;2863:1;2829:35;2821:111;;;;-1:-1:-1;;;2821:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15026:9:::1;-1:-1:-1::0;;;15026:28:0::1;15022:554;;;15056:13;:39:::0;;-1:-1:-1;;;;;;15056:39:0::1;-1:-1:-1::0;;;;;15056:39:0;::::1;;::::0;;15022:554:::1;;;15115:9;-1:-1:-1::0;;;15115:28:0::1;15111:465;;;15158:13;:32:::0;;-1:-1:-1;;;;;;15158:32:0::1;-1:-1:-1::0;;;;;15158:32:0;;::::1;::::0;;;::::1;::::0;;;;15257:27:::1;::::0;;-1:-1:-1;;;15257:27:0;;;;:13;;;::::1;::::0;:25:::1;::::0;:27:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;:13;:27;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;15257:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;15257:27:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;15111:465:0::1;::::0;-1:-1:-1;15111:465:0::1;;15315:9;-1:-1:-1::0;;;15315:31:0::1;15311:265;;;15348:16;:35:::0;;-1:-1:-1;;;;;;15348:35:0::1;-1:-1:-1::0;;;;;15348:35:0;::::1;;::::0;;15311:265:::1;;;15403:9;-1:-1:-1::0;;;15403:32:0::1;15399:177;;;15437:17;:47:::0;;-1:-1:-1;;;;;;15437:47:0::1;-1:-1:-1::0;;;;;15437:47:0;::::1;;::::0;;15399:177:::1;;;15500:76;;-1:-1:-1::0;;;15500:76:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15399:177;15592:33;::::0;;;;;-1:-1:-1;;;;;15592:33:0;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;;::::1;14930:703:::0;;:::o;4685:32::-;;;-1:-1:-1;;;;;4685:32:0;;:::o;5068:49::-;;;;;;:::o;24096:565::-;24333:7;24470:183;24492:123;24500:88;24528:27;24557:30;24500:27;:88::i;:::-;24590:24;24492:7;:123::i;:::-;24628:14;24470:9;:183::i;:::-;24463:190;24096:565;-1:-1:-1;;;;;24096:565:0:o;30230:915::-;30318:7;30327;30351:23;;30378:1;30351:28;30347:49;;;-1:-1:-1;30389:1:0;;-1:-1:-1;30392:3:0;30381:15;;30347:49;30410:23;30435:19;30458:23;30473:2;30477:3;30458:14;:23::i;:::-;30409:72;;;;30497:18;30492:75;;30540:1;;-1:-1:-1;30543:11:0;-1:-1:-1;30532:23:0;;-1:-1:-1;30532:23:0;30492:75;30646:35;30683:32;30719:65;30760:23;;30719:40;:65::i;:::-;30645:139;;;;30799:27;30830:1;30799:32;30795:86;;;-1:-1:-1;30854:1:0;;-1:-1:-1;30857:11:0;;-1:-1:-1;30846:23:0;;-1:-1:-1;;30846:23:0;30795:86;30901:222;30933:2;30948:27;30988:26;:24;:26::i;:::-;31088:8;;;;:4;:8;;;;;:24;;;31027;;31064:11;;30901:19;:222::i;36605:510::-;2848:10;2829:18;:30;;;;;;;;;;;2863:1;2829:35;2821:111;;;;-1:-1:-1;;;2821:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36724:1:::1;36700:8:::0;;;:4:::1;:8;::::0;;;;;;;:21;;36727:22;::::1;::::0;36695:59:::1;::::0;36700:25;;;36727:26;;36695:4:::1;:59::i;:::-;36687:131;;;;-1:-1:-1::0;;;36687:131:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36829:17;::::0;::::1;36870:8:::0;;;36829:17;36870:8:::1;::::0;;;;;;;:22;;::::1;::::0;36829:64;;-1:-1:-1;;;36829:64:0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;;;;;36829:17:0;;::::1;::::0;:40:::1;::::0;:64;;;;;:17;;:64;;;;;;:17;;:64;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;36829:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;;36904:10:0::1;::::0;36934:14:::1;::::0;36904:10:::1;36977:8:::0;;;36904:10;36977:8:::1;::::0;;;;;:21;36904:95;;-1:-1:-1;;;36904:95:0;;::::1;::::0;::::1;::::0;;;;36958:4:::1;36904:95:::0;;;;36965:10:::1;36904:95:::0;;;;;;;;;-1:-1:-1;;;;;36904:10:0;;::::1;::::0;-1:-1:-1;36904:29:0::1;::::0;-1:-1:-1;36904:95:0;;;;;:10;;:95;;;;;:10;;:95;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;36904:95:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;;;37017:8:0::1;::::0;;;:4:::1;:8;::::0;;;;;;;37010:15;;;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;;37010:15:0;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;;;;;37010:15:0::1;::::0;;37041:66;;37073:10:::1;37041:66:::0;;;;::::1;::::0;;;;;;37022:2;;-1:-1:-1;37041:66:0::1;::::0;;;;;;;;::::1;36605:510:::0;:::o;2533:162::-;2848:10;2829:18;:30;;;;;;;;;;;2863:1;2829:35;2821:111;;;;-1:-1:-1;;;2821:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2612:27:0;::::1;2642:1;2612:27:::0;;;::::1;::::0;;;;;;;:31;;;;2659:28;;;;;;;::::1;::::0;;;;;;;;::::1;2533:162:::0;:::o;5495:39::-;;;;:::o;7324:59::-;;;;:::o;24922:1445::-;24987:7;25011:8;;;:4;:8;;;;;:34;;;-1:-1:-1;;;25011:34:0;;-1:-1:-1;;;;;25011:34:0;25007:64;;-1:-1:-1;;;;25061:10:0;;25007:64;25082:20;25105:8;;;:4;:8;;;;;:24;;;;25280:33;;;;25342:20;;;;;25105:24;;25261:102;;25280:33;;;;25273:3;25266:47;;;;;;;;25315;;25261:4;:102::i;:::-;25257:1071;;;25479:8;;;;:4;:8;;;;;:36;;;;25531:33;;;;;25446:181;;25472:99;;25517:48;;25526:3;;25517:8;:48::i;:::-;-1:-1:-1;;;25472:6:0;:99::i;:::-;25588:8;;;;:4;:8;;;;;:24;;;25446:9;:181::i;:::-;25728:8;;;;:4;:8;;;;;:20;;;25431:196;;-1:-1:-1;25712:36:0;;25708:110;;-1:-1:-1;25782:8:0;;;;:4;:8;;;;;:20;;;25708:110;25257:1071;;;25945:26;25979:8;;;:4;:8;;;;;:24;;;;26010:20;;;;;25974:61;;25979:29;;26010:24;;25974:4;:61::i;:::-;26050:17;26099:8;;;:4;:8;;;;;:33;;;;26162:20;;;;26134:24;;;;;25945:90;;-1:-1:-1;26050:17:0;;26079:104;;26099:33;;;;26091:3;26084:48;;;;;;26134;;26079:4;:104::i;:::-;26050:133;;26204:43;26211:21;26234:12;26204:6;:43::i;:::-;26200:117;;;26281:8;;;;:4;:8;;;;;:20;;;;-1:-1:-1;26200:117:0;25257:1071;;;26347:12;24922:1445;-1:-1:-1;;24922:1445:0:o;21236:1235::-;21342:7;21351;21407:1;21379:25;:29;21371:116;;;;-1:-1:-1;;;21371:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21571:13;;:37;;;-1:-1:-1;;;21571:37:0;;;;21499:35;;;;-1:-1:-1;;;;;21571:13:0;;;;:35;;:37;;;;;;;;;;;:13;:37;;;2:2:-1;;;;27:1;24;17:12;2:2;21571:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21571:37:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;21571:37:0;;;;;;;;;-1:-1:-1;21571:37:0;-1:-1:-1;21571:37:0;21619:71;;-1:-1:-1;21673:1:0;;-1:-1:-1;21673:1:0;;-1:-1:-1;21665:13:0;;-1:-1:-1;21665:13:0;21619:71;21737:25;21702:31;21808:26;:24;:26::i;:::-;21773:61;-1:-1:-1;21851:28:0;;21847:534;;21894:18;21917:56;21949:23;21917:31;:56::i;:::-;21894:79;;21986:20;22009:58;22043:23;22009:33;:58::i;:::-;21986:81;;22119:23;22091:24;22086:56;22082:288;;;22185:54;22201:24;22228:10;22185:7;:54::i;:::-;22159:80;;22082:288;;;22300:56;22316:24;22343:12;22300:7;:56::i;:::-;22274:82;;22082:288;21847:534;;;-1:-1:-1;22409:27:0;;-1:-1:-1;22439:23:0;;-1:-1:-1;;21236:1235:0;;;;:::o;5739:39::-;;;;:::o;22858:777::-;23018:7;23038:18;23061:70;23071:27;23100:30;;23061:9;:70::i;:::-;23038:93;;23142:20;23165:89;23175:27;23204:49;9946:8;23213:1;:7;23222:30;;23204:8;:49::i;23165:89::-;23142:112;-1:-1:-1;23267:27:0;23298:35;;23297:111;;23378:30;23297:111;;;23348:27;23297:111;23267:141;;23447:27;23425:19;:49;23421:207;;;23496:40;23504:19;23525:10;23496:7;:40::i;:::-;23489:47;;;;;;;23421:207;23574:42;23582:19;23603:12;23574:7;:42::i;4829:38::-;;;;:::o;7552:45::-;;;-1:-1:-1;;;;;7552:45:0;;:::o;4753:36::-;;;;:::o;6116:58::-;;;;:::o;37241:120::-;37305:7;37332:8;;;:4;:8;;;;;:21;;37241:120::o;7503:42::-;;;-1:-1:-1;;;;;7503:42:0;;:::o;5932:51::-;;;;:::o;12358:2411::-;2848:10;2829:18;:30;;;;;;;;;;;2863:1;2829:35;2821:111;;;;-1:-1:-1;;;2821:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12454:9:::1;-1:-1:-1::0;;;12454:26:0::1;12450:2262;;;12505:37;12518:11;;12510:4;:19;;9946:8;12531:4;:10;12505:4;:37::i;:::-;12497:111;;;;-1:-1:-1::0;;;12497:111:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12623:11;:18:::0;;;12450:2262:::1;;;12672:9;-1:-1:-1::0;;;12672:26:0::1;12668:2044;;;12723:53;12728:37;12741:11;;12733:4;:19;;9946:8;12754:4;:10;12728:4;:37::i;:::-;12774:1;12767:4;:8;12723:4;:53::i;:::-;12715:127;;;;-1:-1:-1::0;;;12715:127:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12857:11;:18:::0;;;12668:2044:::1;;;12906:9;:42;;12902:1810;;;-1:-1:-1::0;;;12973:4:0::1;:11;;12965:93;;;;-1:-1:-1::0;;;12965:93:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13073:27;:34:::0;;;12902:1810:::1;;;13138:9;:44;;13134:1578;;;13207:59;13219:1;13212:4;:8;13244:21;13255:3;13260:4;13244:10;:21::i;:::-;13222:19;:43;13207:4;:59::i;:::-;13199:137;;;;-1:-1:-1::0;;;13199:137:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13351:29;:36:::0;;;13134:1578:::1;;;13418:9;:45;;13414:1298;;;9946:8;13488:4;:11;;13480:106;;;;-1:-1:-1::0;;;13480:106:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13601:30;:37:::0;;;13414:1298:::1;;;13669:9;:45;;13665:1047;;;9946:8;13739:4;:11;;13731:106;;;;-1:-1:-1::0;;;13731:106:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13852:30;:37:::0;;;13665:1047:::1;;;13920:9;:45;;13916:796;;;9946:8;13990:4;:11;;13982:107;;;;-1:-1:-1::0;;;13982:107:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14104:30;:37:::0;;;13916:796:::1;;;14172:9;:45;;14168:544;;;9946:8;14242:4;:11;;14234:107;;;;-1:-1:-1::0;;;14234:107:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14356:30;:37:::0;;;14168:544:::1;;;14424:9;:43;;14420:292;;;14484:28;:35:::0;;;14420:292:::1;;;14550:9;-1:-1:-1::0;;;14550:25:0::1;14546:166;;;14592:10;:17:::0;;;14546:166:::1;14728:33;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;;::::1;12358:2411:::0;;:::o;19821:388::-;19908:18;19939:29;19971:56;19981:15;19998:28;;19971:9;:56::i;:::-;19939:88;;20051:58;20061:15;20078:30;;20051:9;:58::i;:::-;20038:71;;20148:21;20134:10;:35;;20133:68;;20186:15;20133:68;;9169:180;9265:5;;;9260:16;;;;;;;;;9252:89;;;;-1:-1:-1;;;9252:89:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17610:360;17670:7;17771:8;;;:4;:8;;;;;17832:26;17776:2;17832:22;:26::i;:::-;17790:30;;;:68;;;17911:3;17869:39;;;;:45;;;;17790:68;17610:360;-1:-1:-1;;17610:360:0:o;16311:1071::-;16591:7;16721:33;16768:196;16811:27;16853:30;16898:24;16937:14;16768:28;:196::i;:::-;16721:243;;17029:24;17056:47;17064:11;17077:25;17056:7;:47::i;:::-;17273:8;;;;:4;:8;;;;;:21;17029:74;;-1:-1:-1;17254:40:0;;17253:85;;17322:16;17253:85;;;17298:8;;;;:4;:8;;;;;:21;17253:85;17234:104;16311:1071;-1:-1:-1;;;;;;;;;16311:1071:0:o;11942:105::-;12031:8;;12024:16::o;9728:189::-;9791:9;9821:6;;;:30;;-1:-1:-1;;9836:5:0;;;9850:1;9845;9836:5;9845:1;9831:15;;;;;:20;9821:30;9813:96;;;;-1:-1:-1;;;9813:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9355:185;9455:5;;;9450:16;;;;9442:90;;;;-1:-1:-1;;;9442:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9546:176;9644:5;;;9639:16;;;;9631:83;;;;-1:-1:-1;;;9631:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12053:104;12140:9;;12133:17::o;9961:118::-;10025:9;9946:8;10051:14;10060:1;10063;10051:8;:14::i;:::-;:20;;;;;;;9961:118;-1:-1:-1;;;9961:118:0:o;10123:198::-;10185:9;10219:1;10215;:5;10207:71;;;;-1:-1:-1;;;10207:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10312:1;10293:16;10302:1;-1:-1:-1;;;10293:8:0;:16::i;10996:908::-;11068:9;11115:1;11117:50;;;;11205:9;;;11215:17;;;;11248:1;11243:6;;11198:53;;11215:17;11229:1;11224:6;;11198:53;;11282:1;11279;11275:9;11332:1;11329;11325:9;11320:14;;11314:563;11337:1;11314:563;;;11389:1;11386;11382:9;11430:1;11426;11422:2;11418:10;11415:17;11405:2;;11445:1;11443;11436:11;11405:2;11486:4;11482:2;11478:13;11520:2;11511:7;11508:15;11505:2;;;11535:1;11533;11526:11;11505:2;11558:15;;;;-1:-1:-1;;11590:8:0;;;11587:2;;;11633:1;11630;11626:9;11699:1;11695;11691:2;11687:10;11684:17;11677:25;11672:1;11665:9;11658:17;11654:49;11651:2;;;11715:1;11713;11706:11;11651:2;11758:4;11754:2;11750:13;11794:2;11785:7;11782:15;11779:2;;;11809:1;11807;11800:11;11779:2;11834:15;;;;-1:-1:-1;;11587:2:0;11352:1;11350;11346:8;11341:13;;11314:563;;;11318:18;11108:780;;11117:50;11132:1;11134:15;;;;11164:1;11159:6;;11125:41;;11134:15;11147:1;11142:6;;11125:41;;11108:780;;11097:800;;;;;:::o;10327:223::-;10417:5;;;10441:6;;;:20;;;10460:1;10455;10451;:5;;;;;;:10;10441:20;10433:87;;;;-1:-1:-1;;;10433:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;10535:1:0;:7;;10878:112;10940:9;10972:1;10967;:6;;10966:16;;10981:1;10966:16;;;-1:-1:-1;10977:1:0;;10962:20;-1:-1:-1;10878:112:0:o;10760:::-;10822:9;10854:1;10849;:6;;10848:16;;10863:1;10848:16;;10556:198;10618:9;10652:1;10648;:5;10640:71;;;;-1:-1:-1;;;10640:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10745:1;10726:16;10735:1;9946:8;10726;:16::i

Swarm Source

ipfs://22066dba05c697ae11a7f5a343ce8b3c19f3e9b76d50c7f0bd8541f42cc8fe41

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  ]
[ 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.