Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Orders
Compiler Version
v0.7.5+commit.eb77ed08
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; pragma experimental ABIEncoderV2; import 'SafeMath.sol'; import 'Math.sol'; import 'IIntegralFactory.sol'; import 'IIntegralPair.sol'; import 'TokenShares.sol'; library Orders { using SafeMath for uint256; using TokenShares for TokenShares.Data; using TransferHelper for address; enum OrderType { Empty, Deposit, Withdraw, Sell, Buy } enum OrderStatus { NonExistent, EnqueuedWaiting, EnqueuedReady, ExecutedSucceeded, ExecutedFailed, Canceled } event MaxGasLimitSet(uint256 maxGasLimit); event GasPriceInertiaSet(uint256 gasPriceInertia); event MaxGasPriceImpactSet(uint256 maxGasPriceImpact); event TransferGasCostSet(address token, uint256 gasCost); event DepositEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); event WithdrawEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); event SellEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); event BuyEnqueued(uint256 indexed orderId, uint128 validAfterTimestamp, uint256 gasPrice); uint8 private constant DEPOSIT_TYPE = 1; uint8 private constant WITHDRAW_TYPE = 2; uint8 private constant BUY_TYPE = 3; uint8 private constant BUY_INVERTED_TYPE = 4; uint8 private constant SELL_TYPE = 5; uint8 private constant SELL_INVERTED_TYPE = 6; uint8 private constant UNWRAP_NOT_FAILED = 0; uint8 private constant KEEP_NOT_FAILED = 1; uint8 private constant UNWRAP_FAILED = 2; uint8 private constant KEEP_FAILED = 3; uint256 private constant ETHER_TRANSFER_COST = 2300; uint256 private constant BUFFER_COST = 10000; uint256 private constant EXECUTE_PREPARATION_COST = 55000; // dequeue + getPair in execute uint256 public constant ETHER_TRANSFER_CALL_COST = 10000; uint256 public constant PAIR_TRANSFER_COST = 55000; uint256 public constant REFUND_END_COST = 2 * ETHER_TRANSFER_COST + BUFFER_COST; uint256 public constant ORDER_BASE_COST = EXECUTE_PREPARATION_COST + REFUND_END_COST; uint256 private constant TIMESTAMP_OFFSET = 1609455600; // 2021 Jan 1 struct PairInfo { address pair; address token0; address token1; } struct Data { uint256 delay; uint256 newestOrderId; uint256 lastProcessedOrderId; mapping(uint256 => StoredOrder) orderQueue; address factory; uint256 maxGasLimit; uint256 gasPrice; uint256 gasPriceInertia; uint256 maxGasPriceImpact; mapping(uint32 => PairInfo) pairs; mapping(address => uint256) transferGasCosts; mapping(uint256 => bool) canceled; mapping(address => bool) depositDisabled; mapping(address => bool) withdrawDisabled; mapping(address => bool) buyDisabled; mapping(address => bool) sellDisabled; } struct StoredOrder { // slot 1 uint8 orderType; uint32 validAfterTimestamp; uint8 unwrapAndFailure; uint32 deadline; uint32 gasLimit; uint32 gasPrice; uint112 liquidityOrRatio; // slot 1 uint112 value0; uint112 value1; uint32 pairId; // slot2 address to; uint32 minRatioChangeToSwap; uint32 minSwapPrice; uint32 maxSwapPrice; } struct DepositOrder { uint32 pairId; uint256 share0; uint256 share1; uint256 initialRatio; uint256 minRatioChangeToSwap; uint256 minSwapPrice; uint256 maxSwapPrice; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } struct WithdrawOrder { uint32 pairId; uint256 liquidity; uint256 amount0Min; uint256 amount1Min; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } struct SellOrder { uint32 pairId; bool inverse; uint256 shareIn; uint256 amountOutMin; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } struct BuyOrder { uint32 pairId; bool inverse; uint256 shareInMax; uint256 amountOut; bool unwrap; address to; uint256 gasPrice; uint256 gasLimit; uint256 deadline; } function decodeType(uint256 internalType) internal pure returns (OrderType orderType) { if (internalType == DEPOSIT_TYPE) { orderType = OrderType.Deposit; } else if (internalType == WITHDRAW_TYPE) { orderType = OrderType.Withdraw; } else if (internalType == BUY_TYPE) { orderType = OrderType.Buy; } else if (internalType == BUY_INVERTED_TYPE) { orderType = OrderType.Buy; } else if (internalType == SELL_TYPE) { orderType = OrderType.Sell; } else if (internalType == SELL_INVERTED_TYPE) { orderType = OrderType.Sell; } else { orderType = OrderType.Empty; } } function getOrder(Data storage data, uint256 orderId) public view returns (OrderType orderType, uint256 validAfterTimestamp) { StoredOrder storage order = data.orderQueue[orderId]; uint8 internalType = order.orderType; validAfterTimestamp = uint32ToTimestamp(order.validAfterTimestamp); orderType = decodeType(internalType); } function getOrderStatus(Data storage data, uint256 orderId) external view returns (OrderStatus orderStatus) { if (orderId > data.newestOrderId) { return OrderStatus.NonExistent; } if (data.canceled[orderId]) { return OrderStatus.Canceled; } if (isRefundFailed(data, orderId)) { return OrderStatus.ExecutedFailed; } (OrderType orderType, uint256 validAfterTimestamp) = getOrder(data, orderId); if (orderType == OrderType.Empty) { return OrderStatus.ExecutedSucceeded; } if (validAfterTimestamp >= block.timestamp) { return OrderStatus.EnqueuedWaiting; } return OrderStatus.EnqueuedReady; } function getPair( Data storage data, address tokenA, address tokenB ) internal returns ( address pair, uint32 pairId, bool inverted ) { inverted = tokenA > tokenB; (address token0, address token1) = inverted ? (tokenB, tokenA) : (tokenA, tokenB); pair = IIntegralFactory(data.factory).getPair(token0, token1); pairId = uint32(bytes4(keccak256(abi.encodePacked((pair))))); require(pair != address(0), 'OS_PAIR_NONEXISTENT'); if (data.pairs[pairId].pair == address(0)) { data.pairs[pairId] = PairInfo(pair, token0, token1); } } function getPairInfo(Data storage data, uint32 pairId) external view returns ( address pair, address token0, address token1 ) { PairInfo storage info = data.pairs[pairId]; pair = info.pair; token0 = info.token0; token1 = info.token1; } function getDepositOrder(Data storage data, uint256 index) public view returns (DepositOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == DEPOSIT_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.share0 = stored.value0; order.share1 = stored.value1; order.initialRatio = stored.liquidityOrRatio; order.minRatioChangeToSwap = stored.minRatioChangeToSwap; order.minSwapPrice = float32ToUint(stored.minSwapPrice); order.maxSwapPrice = float32ToUint(stored.maxSwapPrice); order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getWithdrawOrder(Data storage data, uint256 index) public view returns (WithdrawOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == WITHDRAW_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.liquidity = stored.liquidityOrRatio; order.amount0Min = stored.value0; order.amount1Min = stored.value1; order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getSellOrder(Data storage data, uint256 index) public view returns (SellOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == SELL_TYPE || stored.orderType == SELL_INVERTED_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.inverse = stored.orderType == SELL_INVERTED_TYPE; order.shareIn = stored.value0; order.amountOutMin = stored.value1; order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getBuyOrder(Data storage data, uint256 index) public view returns (BuyOrder memory order) { StoredOrder memory stored = data.orderQueue[index]; require(stored.orderType == BUY_TYPE || stored.orderType == BUY_INVERTED_TYPE, 'OS_INVALID_ORDER_TYPE'); order.pairId = stored.pairId; order.inverse = stored.orderType == BUY_INVERTED_TYPE; order.shareInMax = stored.value0; order.amountOut = stored.value1; order.unwrap = getUnwrap(stored.unwrapAndFailure); order.to = stored.to; order.gasPrice = uint32ToGasPrice(stored.gasPrice); order.gasLimit = stored.gasLimit; order.deadline = uint32ToTimestamp(stored.deadline); } function getFailedOrderType(Data storage data, uint256 orderId) external view returns (OrderType orderType, uint256 validAfterTimestamp) { require(isRefundFailed(data, orderId), 'OS_NO_POSSIBLE_REFUND'); (orderType, validAfterTimestamp) = getOrder(data, orderId); } function getUnwrap(uint8 unwrapAndFailure) private pure returns (bool) { return unwrapAndFailure == UNWRAP_FAILED || unwrapAndFailure == UNWRAP_NOT_FAILED; } function getUnwrapAndFailure(bool unwrap) private pure returns (uint8) { return unwrap ? UNWRAP_NOT_FAILED : KEEP_NOT_FAILED; } function timestampToUint32(uint256 timestamp) private pure returns (uint32 timestamp32) { if (timestamp == uint256(-1)) { return uint32(-1); } timestamp32 = uintToUint32(timestamp.sub(TIMESTAMP_OFFSET)); } function uint32ToTimestamp(uint32 timestamp32) private pure returns (uint256 timestamp) { if (timestamp32 == uint32(-1)) { return uint256(-1); } if (timestamp32 == 0) { return 0; } timestamp = uint256(timestamp32) + TIMESTAMP_OFFSET; } function gasPriceToUint32(uint256 gasPrice) private pure returns (uint32 gasPrice32) { require((gasPrice / 1e6) * 1e6 == gasPrice, 'OS_GAS_PRICE_PRECISION'); gasPrice32 = uintToUint32(gasPrice / 1e6); } function uint32ToGasPrice(uint32 gasPrice32) public pure returns (uint256 gasPrice) { gasPrice = uint256(gasPrice32) * 1e6; } function uintToUint32(uint256 number) private pure returns (uint32 number32) { number32 = uint32(number); require(uint256(number32) == number, 'OS_OVERFLOW_32'); } function uintToUint112(uint256 number) private pure returns (uint112 number112) { number112 = uint112(number); require(uint256(number112) == number, 'OS_OVERFLOW_112'); } function uintToFloat32(uint256 number) internal pure returns (uint32 float32) { // Number is encoded on 4 bytes. 3 bytes for mantissa and 1 for exponent. // If the number fits in the mantissa we set the exponent to zero and return. if (number < 2 << 24) { return uint32(number << 8); } // We find the exponent by counting the number of trailing zeroes. // Simultaneously we remove those zeroes from the number. uint32 exponent; for (exponent = 0; exponent < 256 - 24; exponent++) { // Last bit is one. if (number & 1 == 1) { break; } number = number >> 1; } // The number must fit in the mantissa. require(number < 2 << 24, 'OS_OVERFLOW_FLOAT_ENCODE'); // Set the first three bytes to the number and the fourth to the exponent. float32 = uint32(number << 8) | exponent; } function float32ToUint(uint32 float32) internal pure returns (uint256 number) { // Number is encoded on 4 bytes. 3 bytes for mantissa and 1 for exponent. // We get the exponent by extracting the last byte. uint256 exponent = float32 & 0xFF; // Sanity check. Only triggered for values not encoded with uintToFloat32. require(exponent <= 256 - 24, 'OS_OVERFLOW_FLOAT_DECODE'); // We get the mantissa by extracting the first three bytes and removing the fourth. uint256 mantissa = (float32 & 0xFFFFFF00) >> 8; // We add exponent number zeroes after the mantissa. number = mantissa << exponent; } function enqueueDepositOrder(Data storage data, DepositOrder memory depositOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit DepositEnqueued(data.newestOrderId, validAfterTimestamp, depositOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( DEPOSIT_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(depositOrder.unwrap), timestampToUint32(depositOrder.deadline), uintToUint32(depositOrder.gasLimit), gasPriceToUint32(depositOrder.gasPrice), uintToUint112(depositOrder.initialRatio), uintToUint112(depositOrder.share0), uintToUint112(depositOrder.share1), depositOrder.pairId, depositOrder.to, uint32(depositOrder.minRatioChangeToSwap), uintToFloat32(depositOrder.minSwapPrice), uintToFloat32(depositOrder.maxSwapPrice) ); } function enqueueWithdrawOrder(Data storage data, WithdrawOrder memory withdrawOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit WithdrawEnqueued(data.newestOrderId, validAfterTimestamp, withdrawOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( WITHDRAW_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(withdrawOrder.unwrap), timestampToUint32(withdrawOrder.deadline), uintToUint32(withdrawOrder.gasLimit), gasPriceToUint32(withdrawOrder.gasPrice), uintToUint112(withdrawOrder.liquidity), uintToUint112(withdrawOrder.amount0Min), uintToUint112(withdrawOrder.amount1Min), withdrawOrder.pairId, withdrawOrder.to, 0, // maxRatioChange 0, // minSwapPrice 0 // maxSwapPrice ); } function enqueueSellOrder(Data storage data, SellOrder memory sellOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit SellEnqueued(data.newestOrderId, validAfterTimestamp, sellOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( sellOrder.inverse ? SELL_INVERTED_TYPE : SELL_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(sellOrder.unwrap), timestampToUint32(sellOrder.deadline), uintToUint32(sellOrder.gasLimit), gasPriceToUint32(sellOrder.gasPrice), 0, // liquidityOrRatio uintToUint112(sellOrder.shareIn), uintToUint112(sellOrder.amountOutMin), sellOrder.pairId, sellOrder.to, 0, // maxRatioChange 0, // minSwapPrice 0 // maxSwapPrice ); } function enqueueBuyOrder(Data storage data, BuyOrder memory buyOrder) internal { data.newestOrderId++; uint128 validAfterTimestamp = uint128(block.timestamp + data.delay); emit BuyEnqueued(data.newestOrderId, validAfterTimestamp, buyOrder.gasPrice); data.orderQueue[data.newestOrderId] = StoredOrder( buyOrder.inverse ? BUY_INVERTED_TYPE : BUY_TYPE, timestampToUint32(validAfterTimestamp), getUnwrapAndFailure(buyOrder.unwrap), timestampToUint32(buyOrder.deadline), uintToUint32(buyOrder.gasLimit), gasPriceToUint32(buyOrder.gasPrice), 0, // liquidityOrRatio uintToUint112(buyOrder.shareInMax), uintToUint112(buyOrder.amountOut), buyOrder.pairId, buyOrder.to, 0, // maxRatioChange 0, // minSwapPrice 0 // maxSwapPrice ); } function isRefundFailed(Data storage data, uint256 index) internal view returns (bool) { uint8 unwrapAndFailure = data.orderQueue[index].unwrapAndFailure; return unwrapAndFailure == UNWRAP_FAILED || unwrapAndFailure == KEEP_FAILED; } function markRefundFailed(Data storage data) internal { StoredOrder storage stored = data.orderQueue[data.lastProcessedOrderId]; stored.unwrapAndFailure = stored.unwrapAndFailure == UNWRAP_NOT_FAILED ? UNWRAP_FAILED : KEEP_FAILED; } function getNextOrder(Data storage data) internal view returns (OrderType orderType, uint256 validAfterTimestamp) { return getOrder(data, data.lastProcessedOrderId + 1); } function dequeueCanceledOrder(Data storage data) external { data.lastProcessedOrderId++; } function dequeueDepositOrder(Data storage data) external returns (DepositOrder memory order) { data.lastProcessedOrderId++; order = getDepositOrder(data, data.lastProcessedOrderId); } function dequeueWithdrawOrder(Data storage data) external returns (WithdrawOrder memory order) { data.lastProcessedOrderId++; order = getWithdrawOrder(data, data.lastProcessedOrderId); } function dequeueSellOrder(Data storage data) external returns (SellOrder memory order) { data.lastProcessedOrderId++; order = getSellOrder(data, data.lastProcessedOrderId); } function dequeueBuyOrder(Data storage data) external returns (BuyOrder memory order) { data.lastProcessedOrderId++; order = getBuyOrder(data, data.lastProcessedOrderId); } function forgetOrder(Data storage data, uint256 orderId) internal { delete data.orderQueue[orderId]; } function forgetLastProcessedOrder(Data storage data) internal { delete data.orderQueue[data.lastProcessedOrderId]; } struct DepositParams { address token0; address token1; uint256 amount0; uint256 amount1; uint256 initialRatio; uint256 minRatioChangeToSwap; uint256 minSwapPrice; uint256 maxSwapPrice; bool wrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function deposit( Data storage data, DepositParams calldata depositParams, TokenShares.Data storage tokenShares ) external { require( data.transferGasCosts[depositParams.token0] != 0 && data.transferGasCosts[depositParams.token1] != 0, 'OS_TOKEN_TRANSFER_GAS_COST_UNSET' ); checkOrderParams( data, depositParams.to, depositParams.gasLimit, depositParams.submitDeadline, depositParams.executionDeadline, ORDER_BASE_COST.add(data.transferGasCosts[depositParams.token0]).add( data.transferGasCosts[depositParams.token1] ) ); require(depositParams.amount0 != 0 || depositParams.amount1 != 0, 'OS_NO_AMOUNT'); (address pair, uint32 pairId, bool inverted) = getPair(data, depositParams.token0, depositParams.token1); require(!data.depositDisabled[pair], 'OS_DEPOSIT_DISABLED'); uint256 value = msg.value; // allocate gas refund if (depositParams.token0 == tokenShares.weth && depositParams.wrap) { value = value.sub(depositParams.amount0, 'OS_NOT_ENOUGH_FUNDS'); } else if (depositParams.token1 == tokenShares.weth && depositParams.wrap) { value = value.sub(depositParams.amount1, 'OS_NOT_ENOUGH_FUNDS'); } allocateGasRefund(data, value, depositParams.gasLimit); uint256 shares0 = tokenShares.amountToShares(depositParams.token0, depositParams.amount0, depositParams.wrap); uint256 shares1 = tokenShares.amountToShares(depositParams.token1, depositParams.amount1, depositParams.wrap); IIntegralPair(pair).syncWithOracle(); enqueueDepositOrder( data, DepositOrder( pairId, inverted ? shares1 : shares0, inverted ? shares0 : shares1, depositParams.initialRatio, depositParams.minRatioChangeToSwap, depositParams.minSwapPrice, depositParams.maxSwapPrice, depositParams.wrap, depositParams.to, data.gasPrice, depositParams.gasLimit, depositParams.executionDeadline ) ); } struct WithdrawParams { address token0; address token1; uint256 liquidity; uint256 amount0Min; uint256 amount1Min; bool unwrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function withdraw(Data storage data, WithdrawParams calldata withdrawParams) external { (address pair, uint32 pairId, bool inverted) = getPair(data, withdrawParams.token0, withdrawParams.token1); require(!data.withdrawDisabled[pair], 'OS_WITHDRAW_DISABLED'); checkOrderParams( data, withdrawParams.to, withdrawParams.gasLimit, withdrawParams.submitDeadline, withdrawParams.executionDeadline, ORDER_BASE_COST.add(PAIR_TRANSFER_COST) ); require(withdrawParams.liquidity != 0, 'OS_NO_LIQUIDITY'); allocateGasRefund(data, msg.value, withdrawParams.gasLimit); pair.safeTransferFrom(msg.sender, address(this), withdrawParams.liquidity); IIntegralPair(pair).syncWithOracle(); enqueueWithdrawOrder( data, WithdrawOrder( pairId, withdrawParams.liquidity, inverted ? withdrawParams.amount1Min : withdrawParams.amount0Min, inverted ? withdrawParams.amount0Min : withdrawParams.amount1Min, withdrawParams.unwrap, withdrawParams.to, data.gasPrice, withdrawParams.gasLimit, withdrawParams.executionDeadline ) ); } struct SellParams { address tokenIn; address tokenOut; uint256 amountIn; uint256 amountOutMin; bool wrapUnwrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function sell( Data storage data, SellParams calldata sellParams, TokenShares.Data storage tokenShares ) external { require(data.transferGasCosts[sellParams.tokenIn] != 0, 'OS_TOKEN_TRANSFER_GAS_COST_UNSET'); checkOrderParams( data, sellParams.to, sellParams.gasLimit, sellParams.submitDeadline, sellParams.executionDeadline, ORDER_BASE_COST.add(data.transferGasCosts[sellParams.tokenIn]) ); require(sellParams.amountIn != 0, 'OS_NO_AMOUNT_IN'); (address pair, uint32 pairId, bool inverted) = getPair(data, sellParams.tokenIn, sellParams.tokenOut); require(!data.sellDisabled[pair], 'OS_SELL_DISABLED'); uint256 value = msg.value; // allocate gas refund if (sellParams.tokenIn == tokenShares.weth && sellParams.wrapUnwrap) { value = value.sub(sellParams.amountIn, 'OS_NOT_ENOUGH_FUNDS'); } allocateGasRefund(data, value, sellParams.gasLimit); uint256 shares = tokenShares.amountToShares(sellParams.tokenIn, sellParams.amountIn, sellParams.wrapUnwrap); IIntegralPair(pair).syncWithOracle(); enqueueSellOrder( data, SellOrder( pairId, inverted, shares, sellParams.amountOutMin, sellParams.wrapUnwrap, sellParams.to, data.gasPrice, sellParams.gasLimit, sellParams.executionDeadline ) ); } struct BuyParams { address tokenIn; address tokenOut; uint256 amountInMax; uint256 amountOut; bool wrapUnwrap; address to; uint256 gasLimit; uint256 submitDeadline; uint256 executionDeadline; } function buy( Data storage data, BuyParams calldata buyParams, TokenShares.Data storage tokenShares ) external { require(data.transferGasCosts[buyParams.tokenIn] != 0, 'OS_TOKEN_TRANSFER_GAS_COST_UNSET'); checkOrderParams( data, buyParams.to, buyParams.gasLimit, buyParams.submitDeadline, buyParams.executionDeadline, ORDER_BASE_COST.add(data.transferGasCosts[buyParams.tokenIn]) ); require(buyParams.amountOut != 0, 'OS_NO_AMOUNT_OUT'); (address pair, uint32 pairId, bool inverted) = getPair(data, buyParams.tokenIn, buyParams.tokenOut); require(!data.buyDisabled[pair], 'OS_BUY_DISABLED'); uint256 value = msg.value; // allocate gas refund if (buyParams.tokenIn == tokenShares.weth && buyParams.wrapUnwrap) { value = value.sub(buyParams.amountInMax, 'OS_NOT_ENOUGH_FUNDS'); } allocateGasRefund(data, value, buyParams.gasLimit); uint256 shares = tokenShares.amountToShares(buyParams.tokenIn, buyParams.amountInMax, buyParams.wrapUnwrap); IIntegralPair(pair).syncWithOracle(); enqueueBuyOrder( data, BuyOrder( pairId, inverted, shares, buyParams.amountOut, buyParams.wrapUnwrap, buyParams.to, data.gasPrice, buyParams.gasLimit, buyParams.executionDeadline ) ); } function checkOrderParams( Data storage data, address to, uint256 gasLimit, uint256 submitDeadline, uint256 executionDeadline, uint256 minGasLimit ) private view { require(submitDeadline >= block.timestamp, 'OS_EXPIRED'); require(executionDeadline > block.timestamp.add(data.delay), 'OS_INVALID_DEADLINE'); require(gasLimit <= data.maxGasLimit, 'OS_GAS_LIMIT_TOO_HIGH'); require(gasLimit >= minGasLimit, 'OS_GAS_LIMIT_TOO_LOW'); require(to != address(0), 'OS_NO_ADDRESS'); } function allocateGasRefund( Data storage data, uint256 value, uint256 gasLimit ) private returns (uint256 futureFee) { futureFee = data.gasPrice.mul(gasLimit); require(value >= futureFee, 'OS_NOT_ENOUGH_FUNDS'); if (value > futureFee) { msg.sender.transfer(value.sub(futureFee)); } } function updateGasPrice(Data storage data, uint256 gasUsed) external { uint256 scale = Math.min(gasUsed, data.maxGasPriceImpact); uint256 updated = data.gasPrice.mul(data.gasPriceInertia.sub(scale)).add(tx.gasprice.mul(scale)).div( data.gasPriceInertia ); // we lower the precision for gas savings in order queue data.gasPrice = updated - (updated % 1e6); } function setMaxGasLimit(Data storage data, uint256 _maxGasLimit) external { require(_maxGasLimit <= 10000000, 'OS_MAX_GAS_LIMIT_TOO_HIGH'); data.maxGasLimit = _maxGasLimit; emit MaxGasLimitSet(_maxGasLimit); } function setGasPriceInertia(Data storage data, uint256 _gasPriceInertia) external { require(_gasPriceInertia >= 1, 'OS_INVALID_INERTIA'); data.gasPriceInertia = _gasPriceInertia; emit GasPriceInertiaSet(_gasPriceInertia); } function setMaxGasPriceImpact(Data storage data, uint256 _maxGasPriceImpact) external { require(_maxGasPriceImpact <= data.gasPriceInertia, 'OS_INVALID_MAX_GAS_PRICE_IMPACT'); data.maxGasPriceImpact = _maxGasPriceImpact; emit MaxGasPriceImpactSet(_maxGasPriceImpact); } function setTransferGasCost( Data storage data, address token, uint256 gasCost ) external { data.transferGasCosts[token] = gasCost; emit TransferGasCostSet(token, gasCost); } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) library SafeMath { function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x, 'SM_ADD_OVERFLOW'); } function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { z = sub(x, y, 'SM_SUB_UNDERFLOW'); } function sub( uint256 x, uint256 y, string memory message ) internal pure returns (uint256 z) { require((z = x - y) <= x, message); } function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(y == 0 || (z = x * y) / y == x, 'SM_MUL_OVERFLOW'); } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, 'SM_DIV_BY_ZERO'); uint256 c = a / b; return c; } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; // a library for performing various math operations library Math { function min(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x < y ? x : y; } function max(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x > y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; interface IIntegralFactory { event PairCreated(address indexed token0, address indexed token1, address pair, uint256); event OwnerSet(address owner); function owner() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function createPair( address tokenA, address tokenB, address oracle, address trader ) external returns (address pair); function setOwner(address) external; function setMintFee( address tokenA, address tokenB, uint256 fee ) external; function setBurnFee( address tokenA, address tokenB, uint256 fee ) external; function setSwapFee( address tokenA, address tokenB, uint256 fee ) external; function setOracle( address tokenA, address tokenB, address oracle ) external; function setTrader( address tokenA, address tokenB, address trader ) external; function collect( address tokenA, address tokenB, address to ) external; function withdraw( address tokenA, address tokenB, uint256 amount, address to ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'IERC20.sol'; interface IIntegralERC20 is IERC20 { function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; interface IReserves { event Sync(uint112 reserve0, uint112 reserve1); event Fees(uint256 fee0, uint256 fee1); function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 lastTimestamp ); function getReferences() external view returns ( uint112 reference0, uint112 reference1, uint32 epoch ); function getFees() external view returns (uint256 fee0, uint256 fee1); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'IIntegralERC20.sol'; import 'IReserves.sol'; interface IIntegralPair is IIntegralERC20, IReserves { event Mint(address indexed sender, address indexed to); event Burn(address indexed sender, address indexed to); event Swap(address indexed sender, address indexed to); event SetMintFee(uint256 fee); event SetBurnFee(uint256 fee); event SetSwapFee(uint256 fee); event SetOracle(address account); event SetTrader(address trader); event SetToken0AbsoluteLimit(uint256 limit); event SetToken1AbsoluteLimit(uint256 limit); event SetToken0RelativeLimit(uint256 limit); event SetToken1RelativeLimit(uint256 limit); event SetPriceDeviationLimit(uint256 limit); function MINIMUM_LIQUIDITY() external pure returns (uint256); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function oracle() external view returns (address); function trader() external view returns (address); function mintFee() external view returns (uint256); function setMintFee(uint256 fee) external; function mint(address to) external returns (uint256 liquidity); function burnFee() external view returns (uint256); function setBurnFee(uint256 fee) external; function burn(address to) external returns (uint256 amount0, uint256 amount1); function swapFee() external view returns (uint256); function setSwapFee(uint256 fee) external; function setOracle(address account) external; function setTrader(address account) external; function token0AbsoluteLimit() external view returns (uint256); function setToken0AbsoluteLimit(uint256 limit) external; function token1AbsoluteLimit() external view returns (uint256); function setToken1AbsoluteLimit(uint256 limit) external; function token0RelativeLimit() external view returns (uint256); function setToken0RelativeLimit(uint256 limit) external; function token1RelativeLimit() external view returns (uint256); function setToken1RelativeLimit(uint256 limit) external; function priceDeviationLimit() external view returns (uint256); function setPriceDeviationLimit(uint256 limit) external; function collect(address to) external; function swap( uint256 amount0Out, uint256 amount1Out, address to ) external; function sync() external; function initialize( address _token0, address _token1, address _oracle, address _trader ) external; function syncWithOracle() external; function fullSync() external; function getSpotPrice() external view returns (uint256 spotPrice); function getSwapAmount0In(uint256 amount1Out) external view returns (uint256 swapAmount0In); function getSwapAmount1In(uint256 amount0Out) external view returns (uint256 swapAmount1In); function getSwapAmount0Out(uint256 amount1In) external view returns (uint256 swapAmount0Out); function getSwapAmount1Out(uint256 amount0In) external view returns (uint256 swapAmount1Out); function getDepositAmount0In(uint256 amount0) external view returns (uint256 depositAmount0In); function getDepositAmount1In(uint256 amount1) external view returns (uint256 depositAmount1In); }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity =0.7.5; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TH_APPROVE_FAILED'); } function safeTransfer( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TH_TRANSFER_FAILED'); } function safeTransferFrom( address token, address from, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TH_TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{ value: value }(new bytes(0)); require(success, 'TH_ETH_TRANSFER_FAILED'); } }
// SPDX-License-Identifier: GPL-3.0-or-later // Deployed with donations via Gitcoin GR9 pragma solidity 0.7.5; import 'IERC20.sol'; import 'IWETH.sol'; import 'SafeMath.sol'; import 'TransferHelper.sol'; library TokenShares { using SafeMath for uint256; using TransferHelper for address; event UnwrapFailed(address to, uint256 amount); struct Data { mapping(address => uint256) totalShares; address weth; } function setWeth(Data storage data, address _weth) internal { data.weth = _weth; } function sharesToAmount( Data storage data, address token, uint256 share ) external returns (uint256) { if (share == 0) { return 0; } if (token == data.weth) { return share; } require(data.totalShares[token] >= share, 'TS_INSUFFICIENT_BALANCE'); uint256 balance = IERC20(token).balanceOf(address(this)); uint256 value = balance.mul(share).div(data.totalShares[token]); data.totalShares[token] = data.totalShares[token].sub(share); return value; } function amountToShares( Data storage data, address token, uint256 amount, bool wrap ) external returns (uint256) { if (amount == 0) { return 0; } if (token == data.weth) { if (wrap) { require(msg.value >= amount, 'TS_INSUFFICIENT_AMOUNT'); IWETH(token).deposit{ value: amount }(); } else { token.safeTransferFrom(msg.sender, address(this), amount); } return amount; } else { uint256 balanceBefore = IERC20(token).balanceOf(address(this)); require(balanceBefore > 0 || data.totalShares[token] == 0, 'TS_INVALID_SHARES'); if (data.totalShares[token] == 0) { data.totalShares[token] = balanceBefore; } token.safeTransferFrom(msg.sender, address(this), amount); uint256 balanceAfter = IERC20(token).balanceOf(address(this)); require(balanceAfter > balanceBefore, 'TS_INVALID_TRANSFER'); if (balanceBefore > 0) { uint256 lastShares = data.totalShares[token]; data.totalShares[token] = lastShares.mul(balanceAfter).div(balanceBefore); return data.totalShares[token] - lastShares; } else { data.totalShares[token] = balanceAfter; data.totalShares[token] = balanceAfter; return balanceAfter; } } } function onUnwrapFailed( Data storage data, address to, uint256 amount ) external { emit UnwrapFailed(to, amount); IWETH(data.weth).deposit{ value: amount }(); TransferHelper.safeTransfer(data.weth, to, amount); } }
{ "libraries": { "SafeMath.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "Math.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "IIntegralFactory.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "IERC20.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "IIntegralERC20.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "IReserves.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "IIntegralPair.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "IWETH.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "TransferHelper.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "TokenShares.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" }, "Orders.sol": { "TokenShares": "0xc82938b53e0e190459ba4e3502bf26f194760183" } }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"validAfterTimestamp","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"gasPrice","type":"uint256"}],"name":"BuyEnqueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"validAfterTimestamp","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"gasPrice","type":"uint256"}],"name":"DepositEnqueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"gasPriceInertia","type":"uint256"}],"name":"GasPriceInertiaSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxGasLimit","type":"uint256"}],"name":"MaxGasLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxGasPriceImpact","type":"uint256"}],"name":"MaxGasPriceImpactSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"validAfterTimestamp","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"gasPrice","type":"uint256"}],"name":"SellEnqueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasCost","type":"uint256"}],"name":"TransferGasCostSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"validAfterTimestamp","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"gasPrice","type":"uint256"}],"name":"WithdrawEnqueued","type":"event"},{"inputs":[],"name":"ETHER_TRANSFER_CALL_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORDER_BASE_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAIR_TRANSFER_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REFUND_END_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"gasPrice32","type":"uint32"}],"name":"uint32ToGasPrice","outputs":[{"internalType":"uint256","name":"gasPrice","type":"uint256"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
613992610026600b82828239805160001a60731461001957fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106101b35760003560e01c80638794a43311610103578063a9e617e8116100a1578063b2456a071161007b578063b2456a071461045e578063b3e0f2d61461047e578063c5f989bc14610491578063ed7667d9146104a4576101b3565b8063a9e617e814610423578063ac16065c14610443578063ac1ecdb31461044b576101b3565b80639b83ffce116100dd5780639b83ffce146103a35780639db74df1146103c3578063a1ba1395146103e3578063a81df10f14610403576101b3565b80638794a433146103685780638f0e6bef1461037057806399c886d214610390576101b3565b80631ae4f06f116101705780634e1eb8601161014a5780634e1eb860146102e657806365879921146103085780636702eca314610328578063758e99b314610348576101b3565b80631ae4f06f146102855780631fa286fa146102a65780632e9d30e1146102c6576101b3565b806305d4bd11146101b857806306227f88146101da578063117d7ab1146101fa57806311c8197f1461022357806313ed2f6114610243578063158db7c714610270575b600080fd5b8180156101c457600080fd5b506101d86101d3366004613092565b6104ac565b005b8180156101e657600080fd5b506101d86101f53660046130e1565b6104b8565b61020d610208366004613192565b610825565b60405161021a919061380c565b60405180910390f35b610236610231366004613192565b610a2a565b60405161021a91906137d7565b81801561024f57600080fd5b5061026361025e366004613092565b610c09565b60405161021a91906138ac565b610278610c2f565b60405161021a919061393b565b610298610293366004613192565b610c35565b60405161021a929190613324565b8180156102b257600080fd5b506101d86102c1366004613192565b610c73565b8180156102d257600080fd5b506102366102e1366004613092565b610cda565b6102f96102f43660046131b3565b610cfa565b60405161021a939291906132d4565b81801561031457600080fd5b506101d861032336600461315a565b610d33565b81801561033457600080fd5b506101d8610343366004613192565b610f24565b81801561035457600080fd5b506101d86103633660046130e1565b610f7e565b610278611274565b81801561037c57600080fd5b506101d861038b366004613118565b61127a565b61026361039e366004613192565b6117b1565b6103b66103b1366004613192565b611922565b60405161021a9190613310565b8180156103cf57600080fd5b506101d86103de366004613192565b6119be565b8180156103ef57600080fd5b506102366103fe366004613092565b611a2b565b81801561040f57600080fd5b5061020d61041e366004613092565b611a4b565b81801561042f57600080fd5b506101d861043e366004613192565b611a6b565b610278611ac3565b610236610459366004613192565b611ac9565b81801561046a57600080fd5b506101d86104793660046130aa565b611c4e565b61027861048c3660046131f6565b611caa565b61029861049f366004613192565b611cb8565b610278611cff565b60020180546001019055565b600a830160006104cb602085018561303a565b6001600160a01b0316815260208101919091526040016000205461050a5760405162461bcd60e51b815260040161050190613734565b60405180910390fd5b61056d8361051e60c0850160a0860161303a565b60c085013560e0860135610100870135610568600a8a01600061054460208c018c61303a565b6001600160a01b0316815260208101919091526040016000205462010fe090611d06565b611d50565b606082013561058e5760405162461bcd60e51b81526004016105019061363f565b600080806105b8866105a3602088018861303a565b6105b36040890160208a0161303a565b611e0d565b6001600160a01b0383166000908152600e8a016020526040902054929550909350915060ff16156105fb5760405162461bcd60e51b81526004016105019061368d565b600184015434906001600160a01b0316610618602088018861303a565b6001600160a01b0316148015610639575061063960a0870160808801613072565b1561067a5760408051808201825260138152724f535f4e4f545f454e4f5547485f46554e445360681b60208201526106779183919089013590611fbe565b90505b61068987828860c00135612056565b50600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b92876106b460208b018b61303a565b60408b01356106c960a08d0160808e01613072565b6040518563ffffffff1660e01b81526004016106e894939291906137e6565b60206040518083038186803b15801561070057600080fd5b505af4158015610714573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073891906131de565b9050846001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561077557600080fd5b505af1158015610789573d6000803e3d6000fd5b5050505061081b886040518061012001604052808763ffffffff16815260200186151581526020018481526020018a6060013581526020018a60800160208101906107d49190613072565b151581526020016107eb60c08c0160a08d0161303a565b6001600160a01b031681526020018b6006015481526020018a60c0013581526020018a61010001358152506120cf565b5050505050505050565b61082d612e6c565b610835612ede565b50600082815260038401602090815260409182902082516101c081018452815460ff80821680845263ffffffff610100808504821697860197909752600160281b840490921696840196909652600160301b820481166060840152600160501b820481166080840152600160701b808304821660a08501526001600160701b03600160901b909304831660c085015260018086015480851660e087015291820490931695840195909552600160e01b9485900481166101208401526002909301546001600160a01b038116610140840152600160a01b81048416610160840152600160c01b81048416610180840152939093049091166101a0820152911461094f5760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff908116835260e08201516001600160701b0390811660208501526101008301518116604085015260c08301511660608401526101608201511660808301526101808101516109a790612405565b60a08301526101a08101516109bb90612405565b60c083015260408101516109ce9061243f565b151560e08301526101408101516001600160a01b031661010083015260a08101516109f890611caa565b610120830152608081015163ffffffff166101408301526060810151610a1d9061245a565b6101608301525092915050565b610a32612f52565b610a3a612ede565b5060008281526003848101602090815260409283902083516101c081018552815460ff80821680845261010080840463ffffffff90811697860197909752600160281b840490921697840197909752600160301b820485166060840152600160501b820485166080840152600160701b808304861660a0850152600160901b9092046001600160701b0390811660c0850152600185015480821660e08601529283041690830152600160e01b9081900484166101208301526002909201546001600160a01b038116610140830152600160a01b81048416610160830152600160c01b81048416610180830152919091049091166101a0820152911480610b445750805160ff166004145b610b605760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff168252805160ff16600414602083015260e08101516001600160701b039081166040808501919091526101008301519091166060840152810151610bae9061243f565b151560808301526101408101516001600160a01b031660a080840191909152810151610bd990611caa565b60c0830152608081015163ffffffff1660e08301526060810151610bfc9061245a565b6101008301525092915050565b610c11612fb1565b60028201805460010190819055610c299083906117b1565b92915050565b61390881565b600080610c428484612499565b610c5e5760405162461bcd60e51b8152600401610501906134aa565b610c688484611cb8565b909590945092505050565b8160070154811115610c975760405162461bcd60e51b815260040161050190613608565b600882018190556040517f536bed877ca8a6a35942227bd9830bfa713b5822f6c5172a85fb51033975391c90610cce90839061393b565b60405180910390a15050565b610ce2612f52565b60028201805460010190819055610c29908390611ac9565b63ffffffff166000908152600990910160205260409020805460018201546002909201546001600160a01b039182169392821692911690565b60008080610d5885610d48602087018761303a565b6105b3604088016020890161303a565b6001600160a01b0383166000908152600d89016020526040902054929550909350915060ff1615610d9b5760405162461bcd60e51b815260040161050190613398565b610dcf85610daf60e0870160c0880161303a565b60e087013561010088013561012089013561056862010fe061d6d8611d06565b6040840135610df05760405162461bcd60e51b81526004016105019061370b565b610dff85348660e00135612056565b50610e196001600160a01b038416333060408801356124ce565b826001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e5457600080fd5b505af1158015610e68573d6000803e3d6000fd5b50505050610f1d856040518061012001604052808563ffffffff1681526020018760400135815260200184610ea1578760600135610ea7565b87608001355b815260200184610ebb578760800135610ec1565b87606001355b8152602001610ed660c0890160a08a01613072565b15158152602001610eed60e0890160c08a0161303a565b6001600160a01b03168152602001886006015481526020018760e001358152602001876101200135815250612639565b5050505050565b62989680811115610f475760405162461bcd60e51b8152600401610501906137a0565b600582018190556040517f664d00954017f8b1153ec0813e86deff4b0eabd0548b1de8a6993f4549e0d42c90610cce90839061393b565b600a83016000610f91602085018561303a565b6001600160a01b03168152602081019190915260400160002054610fc75760405162461bcd60e51b815260040161050190613734565b610fdb8361051e60c0850160a0860161303a565b6040820135610ffc5760405162461bcd60e51b815260040161050190613481565b60008080611011866105a3602088018861303a565b6001600160a01b0383166000908152600f8a016020526040902054929550909350915060ff16156110545760405162461bcd60e51b8152600401610501906135de565b600184015434906001600160a01b0316611071602088018861303a565b6001600160a01b0316148015611092575061109260a0870160808801613072565b156110d35760408051808201825260138152724f535f4e4f545f454e4f5547485f46554e445360681b60208201526110d09183919089013590611fbe565b90505b6110e287828860c00135612056565b50600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b928761110d60208b018b61303a565b60408b013561112260a08d0160808e01613072565b6040518563ffffffff1660e01b815260040161114194939291906137e6565b60206040518083038186803b15801561115957600080fd5b505af415801561116d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119191906131de565b9050846001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156111ce57600080fd5b505af11580156111e2573d6000803e3d6000fd5b5050505061081b886040518061012001604052808763ffffffff16815260200186151581526020018481526020018a6060013581526020018a608001602081019061122d9190613072565b1515815260200161124460c08c0160a08d0161303a565b6001600160a01b031681526020018b6006015481526020018a60c0013581526020018a6101000135815250612746565b61271081565b600a8301600061128d602085018561303a565b6001600160a01b03168152602081019190915260400160002054158015906112e35750600a830160006112c6604085016020860161303a565b6001600160a01b0316815260208101919091526040016000205415155b6112ff5760405162461bcd60e51b815260040161050190613734565b611383836113156101408501610120860161303a565b610140850135610160860135610180870135610568600a8a01600061134060408c0160208d0161303a565b6001600160a01b03166001600160a01b031681526020019081526020016000205461137d8b600a0160008c6000016020810190610544919061303a565b90611d06565b60408201351515806113985750606082013515155b6113b45760405162461bcd60e51b81526004016105019061358b565b600080806113c9866105a3602088018861303a565b6001600160a01b0383166000908152600c8a016020526040902054929550909350915060ff161561140c5760405162461bcd60e51b8152600401610501906135b1565b600184015434906001600160a01b0316611429602088018861303a565b6001600160a01b031614801561144c575061144c61012087016101008801613072565b156114915760408051808201825260138152724f535f4e4f545f454e4f5547485f46554e445360681b602082015261148a9183919089013590611fbe565b9050611515565b60018501546001600160a01b03166114af604088016020890161303a565b6001600160a01b03161480156114d257506114d261012087016101008801613072565b15611515576040805180820190915260138152724f535f4e4f545f454e4f5547485f46554e445360681b6020820152611512908290606089013590611fbe565b90505b6115258782886101400135612056565b50600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b928761155060208b018b61303a565b60408b01356115676101208d016101008e01613072565b6040518563ffffffff1660e01b815260040161158694939291906137e6565b60206040518083038186803b15801561159e57600080fd5b505af41580156115b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d691906131de565b9050600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b928861160560408c0160208d0161303a565b60608c013561161c6101208e016101008f01613072565b6040518563ffffffff1660e01b815260040161163b94939291906137e6565b60206040518083038186803b15801561165357600080fd5b505af4158015611667573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168b91906131de565b9050856001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156116c857600080fd5b505af11580156116dc573d6000803e3d6000fd5b505050506117a6896040518061018001604052808863ffffffff168152602001876117075785611709565b845b815260200187611719578461171b565b855b81526020018b6080013581526020018b60a0013581526020018b60c0013581526020018b60e0013581526020018b61010001602081019061175c9190613072565b151581526020016117756101408d016101208e0161303a565b6001600160a01b031681526020018c6006015481526020018b610140013581526020018b61018001358152506127cf565b505050505050505050565b6117b9612fb1565b6117c1612ede565b50600082815260038401602090815260409182902082516101c081018452815460ff80821680845261010080840463ffffffff90811697860197909752600160281b840490921696840196909652600160301b820485166060840152600160501b820485166080840152600160701b808304861660a0850152600160901b9092046001600160701b0390811660c0850152600185015480821660e08601529283041690830152600160e01b9081900484166101208301526002928301546001600160a01b038116610140840152600160a01b81048516610160840152600160c01b81048516610180840152049092166101a08301529091146118d55760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff16825260c08101516001600160701b03908116602084015260e082015181166040808501919091526101008301519091166060840152810151610bae9061243f565b6000826001015482111561193857506000610c29565b6000828152600b8401602052604090205460ff161561195957506005610c29565b6119638383612499565b1561197057506004610c29565b60008061197d8585611cb8565b9092509050600082600481111561199057fe5b14156119a157600392505050610c29565b4281106119b357600192505050610c29565b506002949350505050565b60006119ce828460080154612bbf565b90506000611a148460070154611a0e6119f0853a612bd590919063ffffffff16565b600788015461137d90611a039088612c33565b60068a015490612bd5565b90612c68565b9050620f4240810690036006909301929092555050565b611a33612f52565b60028201805460010190819055610c29908390610a2a565b611a53612e6c565b60028201805460010190819055610c29908390610825565b6001811015611a8c5760405162461bcd60e51b81526004016105019061333c565b600782018190556040517fc93fa9fe410a29e605394838b98dd2b3b4b790b4f45b67dd8c0ddcdd149c4a7490610cce90839061393b565b61d6d881565b611ad1612f52565b611ad9612ede565b50600082815260038401602090815260409182902082516101c081018452815460ff80821680845261010080840463ffffffff90811697860197909752600160281b840490921696840196909652600160301b820485166060840152600160501b820485166080840152600160701b808304861660a0850152600160901b9092046001600160701b0390811660c0850152600185015480821660e08601529283041690830152600160e01b9081900484166101208301526002909201546001600160a01b038116610140830152600160a01b81048416610160830152600160c01b81048416610180830152919091049091166101a08201529060051480611be45750805160ff166006145b611c005760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff168252805160ff16600614602083015260e08101516001600160701b039081166040808501919091526101008301519091166060840152810151610bae9061243f565b6001600160a01b0382166000908152600a8401602052604090819020829055517f8563e1de6a8955dcbdc3719833791025efb62c4cb350b8a64bc6823168115f0290611c9d90849084906132f7565b60405180910390a1505050565b63ffffffff16620f42400290565b60008181526003830160205260408120805482919060ff811690611ce690610100900463ffffffff1661245a565b9250611cf48160ff16612cc3565b935050509250929050565b62010fe081565b80820182811015610c29576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b42831015611d705760405162461bcd60e51b815260040161050190613669565b8554611d7d904290611d06565b8211611d9b5760405162461bcd60e51b8152600401610501906136de565b8560050154841115611dbf5760405162461bcd60e51b8152600401610501906134d9565b80841015611ddf5760405162461bcd60e51b8152600401610501906133ed565b6001600160a01b038516611e055760405162461bcd60e51b8152600401610501906133c6565b505050505050565b6000806001600160a01b0380841690851611818082611e2d578686611e30565b85875b6004808b015460405163e6a4390560e01b81529395509193506001600160a01b039091169163e6a4390591611e699186918691016132ba565b60206040518083038186803b158015611e8157600080fd5b505afa158015611e95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb99190613056565b945084604051602001611ecc919061329d565b60408051601f19818403018152919052805160209091012060e01c93506001600160a01b038516611f0f5760405162461bcd60e51b815260040161050190613508565b63ffffffff841660009081526009890160205260409020546001600160a01b0316611fb357604080516060810182526001600160a01b038781168252848116602080840191825285831684860190815263ffffffff8a16600090815260098f01909252949020925183546001600160a01b03199081169184169190911784559051600184018054831691841691909117905592516002909201805490931691161790555b505093509350939050565b818303818482111561204e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612013578181015183820152602001611ffb565b50505050905090810190601f1680156120405780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b60068301546000906120689083612bd5565b90508083101561208a5760405162461bcd60e51b81526004016105019061355e565b808311156120c857336108fc6120a08584612c33565b6040518115909202916000818181858888f1935050505015801561204e573d6000803e3d6000fd5b9392505050565b6001808301805490910190819055825460c08301516040514290920192917f8e1149b1ae4941f00e4f06729893afa4b802faea79df7aba3c17208f3547201a9161211b91859190613922565b60405180910390a2604051806101c00160405280836020015161213f576003612142565b60045b60ff16815260200161215c836001600160801b0316612d33565b63ffffffff1681526020016121748460800151612d5e565b60ff16815260200161218a846101000151612d33565b63ffffffff1681526020016121a28460e00151612d6c565b63ffffffff1681526020016121ba8460c00151612d92565b63ffffffff16815260200160006001600160701b031681526020016121e28460400151612dcb565b6001600160701b031681526020016121fd8460600151612dcb565b6001600160701b039081168252845163ffffffff90811660208085019190915260a0968701516001600160a01b03908116604080870191909152600060608088018290526080808901839052978b0182905260018c81015483526003909c0185529082902088518154958a0151938a0151928a0151988a01519b8a015160c08b015160ff1990971660ff9283161764ffffffff00191661010095891686021765ff00000000001916600160281b92909416919091029290921769ffffffff0000000000001916600160301b988716989098029790971763ffffffff60501b1916600160501b9a86169a909a029990991763ffffffff60701b1916600160701b9985168a021771ffffffffffffffffffffffffffffffffffff16600160901b9386169390930292909217855560e08601519885018054928701516101208801516dffffffffffffffffffffffffffff199094169a86169a909a176dffffffffffffffffffffffffffff60701b191699909416909702979097176001600160e01b03908116600160e01b988316890217909255610140840151600290930180546101608601516101808701516101a0909701516001600160a01b0319909216959098169490941763ffffffff60a01b1916600160a01b978316979097029690961763ffffffff60c01b1916600160c01b948216949094029390931716911690930292909217905550565b600060ff821660e881111561242c5760405162461bcd60e51b815260040161050190613769565b60089290921c62ffffff1690911b919050565b600060ff821660021480610c2957505060ff8116155b919050565b600063ffffffff82811614156124735750600019612455565b63ffffffff821661248657506000612455565b5063ffffffff8116635fee57f001919050565b6000818152600383016020526040812054600160281b900460ff1660028114806124c6575060ff81166003145b949350505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b602083106125535780518252601f199092019160209182019101612534565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146125b5576040519150601f19603f3d011682016040523d82523d6000602084013e6125ba565b606091505b50915091508180156125e85750805115806125e857508080602001905160208110156125e557600080fd5b50515b611e05576040805162461bcd60e51b815260206004820152601760248201527f54485f5452414e534645525f46524f4d5f4641494c4544000000000000000000604482015290519081900360640190fd5b6001808301805490910190819055825460c08301516040514290920192917f035ab43d9a5fed70815a96282a434191776a82af7346684e06946bfaf4bf69189161268591859190613922565b60405180910390a2604051806101c00160405280600260ff1681526020016126b5836001600160801b0316612d33565b63ffffffff1681526020016126cd8460800151612d5e565b60ff1681526020016126e3846101000151612d33565b63ffffffff1681526020016126fb8460e00151612d6c565b63ffffffff1681526020016127138460c00151612d92565b63ffffffff16815260200161272b8460200151612dcb565b6001600160701b031681526020016121e28460400151612dcb565b6001808301805490910190819055825460c08301516040514290920192917fdb60298d9ace7090c4c203a97d8c532a17de2a6d9f19ede5e2b52dadc6cd9c059161279291859190613922565b60405180910390a2604051806101c0016040528083602001516127b6576005612142565b6006815260200161215c6001600160801b038416612d33565b600180830180549091019081905582546101208301516040514290920192917f6615ed5af05d4e62d9351a6827f4947db8cda3f821102b956d096952dcba831e9161281c91859190613922565b60405180910390a2604051806101c00160405280600160ff16815260200161284c836001600160801b0316612d33565b63ffffffff1681526020016128648460e00151612d5e565b60ff16815260200161287a846101600151612d33565b63ffffffff168152602001612893846101400151612d6c565b63ffffffff1681526020016128ac846101200151612d92565b63ffffffff1681526020016128c48460600151612dcb565b6001600160701b031681526020016128df8460200151612dcb565b6001600160701b031681526020016128fa8460400151612dcb565b6001600160701b03168152602001836000015163ffffffff1681526020018361010001516001600160a01b03168152602001836080015163ffffffff1681526020016129498460a00151612df4565b63ffffffff1681526020016129618460c00151612df4565b63ffffffff168152508360030160008560010154815260200190815260200160002060008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548160ff021916908360ff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600e6101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160000160126101000a8154816001600160701b0302191690836001600160701b0316021790555060e08201518160010160006101000a8154816001600160701b0302191690836001600160701b0316021790555061010082015181600101600e6101000a8154816001600160701b0302191690836001600160701b0316021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101608201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160186101000a81548163ffffffff021916908363ffffffff1602179055506101a082015181600201601c6101000a81548163ffffffff021916908363ffffffff160217905550905050505050565b6000818310612bce57816120c8565b5090919050565b6000811580612bf057505080820282828281612bed57fe5b04145b610c29576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4d554c5f4f564552464c4f5760881b604482015290519081900360640190fd5b60006120c883836040518060400160405280601081526020016f534d5f5355425f554e444552464c4f5760801b815250611fbe565b6000808211612caf576040805162461bcd60e51b815260206004820152600e60248201526d534d5f4449565f42595f5a45524f60901b604482015290519081900360640190fd5b6000828481612cba57fe5b04949350505050565b60006001821415612cd657506001612455565b6002821415612ce757506002612455565b6003821415612cf857506004612455565b6004821415612d0957506004612455565b6005821415612d1a57506003612455565b6006821415612d2b57506003612455565b506000919050565b6000600019821415612d485750600019612455565b610c29612d5983635fee57f0612c33565b612d6c565b600081612d2b576001610c29565b8063ffffffff811681146124555760405162461bcd60e51b8152600401610501906136b6565b600081620f42408104620f42400214612dbd5760405162461bcd60e51b815260040161050190613368565b610c29620f42408304612d6c565b806001600160701b03811681146124555760405162461bcd60e51b815260040161050190613535565b60006302000000821015612e0d5750600881901b612455565b60005b60e88163ffffffff161015612e3c578260011660011415612e3057612e3c565b600192831c9201612e10565b63020000008310612e5f5760405162461bcd60e51b81526004016105019061341b565b600883901b179050919050565b604051806101800160405280600063ffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915290565b604051806101200160405280600063ffffffff168152602001600015158152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604051806101200160405280600063ffffffff16815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b60006101208284031215613020578081fd5b50919050565b803563ffffffff8116811461245557600080fd5b60006020828403121561304b578081fd5b81356120c881613944565b600060208284031215613067578081fd5b81516120c881613944565b600060208284031215613083578081fd5b813580151581146120c8578182fd5b6000602082840312156130a3578081fd5b5035919050565b6000806000606084860312156130be578182fd5b8335925060208401356130d081613944565b929592945050506040919091013590565b600080600061016084860312156130f6578283fd5b83359250613107856020860161300e565b915061014084013590509250925092565b60008060008385036101e081121561312e578384fd5b843593506101a0601f1982011215613144578283fd5b506020840191506101c084013590509250925092565b60008082840361016081121561316e578283fd5b83359250610140601f1982011215613184578182fd5b506020830190509250929050565b600080604083850312156131a4578182fd5b50508035926020909101359150565b600080604083850312156131c5578182fd5b823591506131d560208401613026565b90509250929050565b6000602082840312156131ef578081fd5b5051919050565b600060208284031215613207578081fd5b6120c882613026565b6001600160a01b03169052565b15159052565b63ffffffff81511682526020810151151560208301526040810151604083015260608101516060830152608081015161325f608084018261321d565b5060a081015161327260a0840182613210565b5060c0818101519083015260e0808201519083015261010090810151910152565b63ffffffff169052565b60609190911b6bffffffffffffffffffffffff1916815260140190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b6001600160a01b03929092168252602082015260400190565b602081016006831061331e57fe5b91905290565b604081016005841061333257fe5b9281526020015290565b6020808252601290820152714f535f494e56414c49445f494e455254494160701b604082015260600190565b60208082526016908201527527a9afa3a0a9afa82924a1a2afa82922a1a4a9a4a7a760511b604082015260600190565b60208082526014908201527313d4d7d5d2551211149055d7d11254d05093115160621b604082015260600190565b6020808252600d908201526c4f535f4e4f5f4144445245535360981b604082015260600190565b6020808252601490820152734f535f4741535f4c494d49545f544f4f5f4c4f5760601b604082015260600190565b60208082526018908201527f4f535f4f564552464c4f575f464c4f41545f454e434f44450000000000000000604082015260600190565b6020808252601590820152744f535f494e56414c49445f4f524445525f5459504560581b604082015260600190565b6020808252600f908201526e27a9afa727afa0a6a7aaa72a2fa4a760891b604082015260600190565b60208082526015908201527413d4d7d393d7d413d4d4d250931157d49151955391605a1b604082015260600190565b60208082526015908201527409ea6be8e82a6be98929a92a8bea89e9ebe90928e9605b1b604082015260600190565b60208082526013908201527213d4d7d410525497d393d391561254d5115395606a1b604082015260600190565b6020808252600f908201526e27a9afa7ab22a9232627abaf98989960891b604082015260600190565b6020808252601390820152724f535f4e4f545f454e4f5547485f46554e445360681b604082015260600190565b6020808252600c908201526b13d4d7d393d7d05353d5539560a21b604082015260600190565b60208082526013908201527213d4d7d1115413d4d25517d11254d050931151606a1b604082015260600190565b60208082526010908201526f13d4d7d4d1531317d11254d05093115160821b604082015260600190565b6020808252601f908201527f4f535f494e56414c49445f4d41585f4741535f50524943455f494d5041435400604082015260600190565b60208082526010908201526f13d4d7d393d7d05353d5539517d3d55560821b604082015260600190565b6020808252600a908201526913d4d7d156141254915160b21b604082015260600190565b6020808252600f908201526e13d4d7d0955657d11254d050931151608a1b604082015260600190565b6020808252600e908201526d27a9afa7ab22a9232627abaf999960911b604082015260600190565b6020808252601390820152724f535f494e56414c49445f444541444c494e4560681b604082015260600190565b6020808252600f908201526e4f535f4e4f5f4c495155494449545960881b604082015260600190565b6020808252818101527f4f535f544f4b454e5f5452414e534645525f4741535f434f53545f554e534554604082015260600190565b60208082526018908201527f4f535f4f564552464c4f575f464c4f41545f4445434f44450000000000000000604082015260600190565b60208082526019908201527f4f535f4d41585f4741535f4c494d49545f544f4f5f4849474800000000000000604082015260600190565b6101208101610c298284613223565b9384526001600160a01b0392909216602084015260408301521515606082015260800190565b600061018082019050613820828451613293565b6020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015161386e60e084018261321d565b506101008084015161388282850182613210565b50506101208381015190830152610140808401519083015261016092830151929091019190915290565b60006101208201905063ffffffff835116825260208301516020830152604083015160408301526060830151606083015260808301511515608083015260a08301516138fb60a0840182613210565b5060c083015160c083015260e083015160e083015261010080840151818401525092915050565b6001600160801b03929092168252602082015260400190565b90815260200190565b6001600160a01b038116811461395957600080fd5b5056fea264697066735822122020e766a06457358cb2e094653228f18c458c557551d6d572a0390f961ebc825364736f6c63430007050033
Deployed Bytecode
0x737218d567b671e36c4e6b3257b8919196cf68ff5e30146080604052600436106101b35760003560e01c80638794a43311610103578063a9e617e8116100a1578063b2456a071161007b578063b2456a071461045e578063b3e0f2d61461047e578063c5f989bc14610491578063ed7667d9146104a4576101b3565b8063a9e617e814610423578063ac16065c14610443578063ac1ecdb31461044b576101b3565b80639b83ffce116100dd5780639b83ffce146103a35780639db74df1146103c3578063a1ba1395146103e3578063a81df10f14610403576101b3565b80638794a433146103685780638f0e6bef1461037057806399c886d214610390576101b3565b80631ae4f06f116101705780634e1eb8601161014a5780634e1eb860146102e657806365879921146103085780636702eca314610328578063758e99b314610348576101b3565b80631ae4f06f146102855780631fa286fa146102a65780632e9d30e1146102c6576101b3565b806305d4bd11146101b857806306227f88146101da578063117d7ab1146101fa57806311c8197f1461022357806313ed2f6114610243578063158db7c714610270575b600080fd5b8180156101c457600080fd5b506101d86101d3366004613092565b6104ac565b005b8180156101e657600080fd5b506101d86101f53660046130e1565b6104b8565b61020d610208366004613192565b610825565b60405161021a919061380c565b60405180910390f35b610236610231366004613192565b610a2a565b60405161021a91906137d7565b81801561024f57600080fd5b5061026361025e366004613092565b610c09565b60405161021a91906138ac565b610278610c2f565b60405161021a919061393b565b610298610293366004613192565b610c35565b60405161021a929190613324565b8180156102b257600080fd5b506101d86102c1366004613192565b610c73565b8180156102d257600080fd5b506102366102e1366004613092565b610cda565b6102f96102f43660046131b3565b610cfa565b60405161021a939291906132d4565b81801561031457600080fd5b506101d861032336600461315a565b610d33565b81801561033457600080fd5b506101d8610343366004613192565b610f24565b81801561035457600080fd5b506101d86103633660046130e1565b610f7e565b610278611274565b81801561037c57600080fd5b506101d861038b366004613118565b61127a565b61026361039e366004613192565b6117b1565b6103b66103b1366004613192565b611922565b60405161021a9190613310565b8180156103cf57600080fd5b506101d86103de366004613192565b6119be565b8180156103ef57600080fd5b506102366103fe366004613092565b611a2b565b81801561040f57600080fd5b5061020d61041e366004613092565b611a4b565b81801561042f57600080fd5b506101d861043e366004613192565b611a6b565b610278611ac3565b610236610459366004613192565b611ac9565b81801561046a57600080fd5b506101d86104793660046130aa565b611c4e565b61027861048c3660046131f6565b611caa565b61029861049f366004613192565b611cb8565b610278611cff565b60020180546001019055565b600a830160006104cb602085018561303a565b6001600160a01b0316815260208101919091526040016000205461050a5760405162461bcd60e51b815260040161050190613734565b60405180910390fd5b61056d8361051e60c0850160a0860161303a565b60c085013560e0860135610100870135610568600a8a01600061054460208c018c61303a565b6001600160a01b0316815260208101919091526040016000205462010fe090611d06565b611d50565b606082013561058e5760405162461bcd60e51b81526004016105019061363f565b600080806105b8866105a3602088018861303a565b6105b36040890160208a0161303a565b611e0d565b6001600160a01b0383166000908152600e8a016020526040902054929550909350915060ff16156105fb5760405162461bcd60e51b81526004016105019061368d565b600184015434906001600160a01b0316610618602088018861303a565b6001600160a01b0316148015610639575061063960a0870160808801613072565b1561067a5760408051808201825260138152724f535f4e4f545f454e4f5547485f46554e445360681b60208201526106779183919089013590611fbe565b90505b61068987828860c00135612056565b50600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b92876106b460208b018b61303a565b60408b01356106c960a08d0160808e01613072565b6040518563ffffffff1660e01b81526004016106e894939291906137e6565b60206040518083038186803b15801561070057600080fd5b505af4158015610714573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073891906131de565b9050846001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561077557600080fd5b505af1158015610789573d6000803e3d6000fd5b5050505061081b886040518061012001604052808763ffffffff16815260200186151581526020018481526020018a6060013581526020018a60800160208101906107d49190613072565b151581526020016107eb60c08c0160a08d0161303a565b6001600160a01b031681526020018b6006015481526020018a60c0013581526020018a61010001358152506120cf565b5050505050505050565b61082d612e6c565b610835612ede565b50600082815260038401602090815260409182902082516101c081018452815460ff80821680845263ffffffff610100808504821697860197909752600160281b840490921696840196909652600160301b820481166060840152600160501b820481166080840152600160701b808304821660a08501526001600160701b03600160901b909304831660c085015260018086015480851660e087015291820490931695840195909552600160e01b9485900481166101208401526002909301546001600160a01b038116610140840152600160a01b81048416610160840152600160c01b81048416610180840152939093049091166101a0820152911461094f5760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff908116835260e08201516001600160701b0390811660208501526101008301518116604085015260c08301511660608401526101608201511660808301526101808101516109a790612405565b60a08301526101a08101516109bb90612405565b60c083015260408101516109ce9061243f565b151560e08301526101408101516001600160a01b031661010083015260a08101516109f890611caa565b610120830152608081015163ffffffff166101408301526060810151610a1d9061245a565b6101608301525092915050565b610a32612f52565b610a3a612ede565b5060008281526003848101602090815260409283902083516101c081018552815460ff80821680845261010080840463ffffffff90811697860197909752600160281b840490921697840197909752600160301b820485166060840152600160501b820485166080840152600160701b808304861660a0850152600160901b9092046001600160701b0390811660c0850152600185015480821660e08601529283041690830152600160e01b9081900484166101208301526002909201546001600160a01b038116610140830152600160a01b81048416610160830152600160c01b81048416610180830152919091049091166101a0820152911480610b445750805160ff166004145b610b605760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff168252805160ff16600414602083015260e08101516001600160701b039081166040808501919091526101008301519091166060840152810151610bae9061243f565b151560808301526101408101516001600160a01b031660a080840191909152810151610bd990611caa565b60c0830152608081015163ffffffff1660e08301526060810151610bfc9061245a565b6101008301525092915050565b610c11612fb1565b60028201805460010190819055610c299083906117b1565b92915050565b61390881565b600080610c428484612499565b610c5e5760405162461bcd60e51b8152600401610501906134aa565b610c688484611cb8565b909590945092505050565b8160070154811115610c975760405162461bcd60e51b815260040161050190613608565b600882018190556040517f536bed877ca8a6a35942227bd9830bfa713b5822f6c5172a85fb51033975391c90610cce90839061393b565b60405180910390a15050565b610ce2612f52565b60028201805460010190819055610c29908390611ac9565b63ffffffff166000908152600990910160205260409020805460018201546002909201546001600160a01b039182169392821692911690565b60008080610d5885610d48602087018761303a565b6105b3604088016020890161303a565b6001600160a01b0383166000908152600d89016020526040902054929550909350915060ff1615610d9b5760405162461bcd60e51b815260040161050190613398565b610dcf85610daf60e0870160c0880161303a565b60e087013561010088013561012089013561056862010fe061d6d8611d06565b6040840135610df05760405162461bcd60e51b81526004016105019061370b565b610dff85348660e00135612056565b50610e196001600160a01b038416333060408801356124ce565b826001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610e5457600080fd5b505af1158015610e68573d6000803e3d6000fd5b50505050610f1d856040518061012001604052808563ffffffff1681526020018760400135815260200184610ea1578760600135610ea7565b87608001355b815260200184610ebb578760800135610ec1565b87606001355b8152602001610ed660c0890160a08a01613072565b15158152602001610eed60e0890160c08a0161303a565b6001600160a01b03168152602001886006015481526020018760e001358152602001876101200135815250612639565b5050505050565b62989680811115610f475760405162461bcd60e51b8152600401610501906137a0565b600582018190556040517f664d00954017f8b1153ec0813e86deff4b0eabd0548b1de8a6993f4549e0d42c90610cce90839061393b565b600a83016000610f91602085018561303a565b6001600160a01b03168152602081019190915260400160002054610fc75760405162461bcd60e51b815260040161050190613734565b610fdb8361051e60c0850160a0860161303a565b6040820135610ffc5760405162461bcd60e51b815260040161050190613481565b60008080611011866105a3602088018861303a565b6001600160a01b0383166000908152600f8a016020526040902054929550909350915060ff16156110545760405162461bcd60e51b8152600401610501906135de565b600184015434906001600160a01b0316611071602088018861303a565b6001600160a01b0316148015611092575061109260a0870160808801613072565b156110d35760408051808201825260138152724f535f4e4f545f454e4f5547485f46554e445360681b60208201526110d09183919089013590611fbe565b90505b6110e287828860c00135612056565b50600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b928761110d60208b018b61303a565b60408b013561112260a08d0160808e01613072565b6040518563ffffffff1660e01b815260040161114194939291906137e6565b60206040518083038186803b15801561115957600080fd5b505af415801561116d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119191906131de565b9050846001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156111ce57600080fd5b505af11580156111e2573d6000803e3d6000fd5b5050505061081b886040518061012001604052808763ffffffff16815260200186151581526020018481526020018a6060013581526020018a608001602081019061122d9190613072565b1515815260200161124460c08c0160a08d0161303a565b6001600160a01b031681526020018b6006015481526020018a60c0013581526020018a6101000135815250612746565b61271081565b600a8301600061128d602085018561303a565b6001600160a01b03168152602081019190915260400160002054158015906112e35750600a830160006112c6604085016020860161303a565b6001600160a01b0316815260208101919091526040016000205415155b6112ff5760405162461bcd60e51b815260040161050190613734565b611383836113156101408501610120860161303a565b610140850135610160860135610180870135610568600a8a01600061134060408c0160208d0161303a565b6001600160a01b03166001600160a01b031681526020019081526020016000205461137d8b600a0160008c6000016020810190610544919061303a565b90611d06565b60408201351515806113985750606082013515155b6113b45760405162461bcd60e51b81526004016105019061358b565b600080806113c9866105a3602088018861303a565b6001600160a01b0383166000908152600c8a016020526040902054929550909350915060ff161561140c5760405162461bcd60e51b8152600401610501906135b1565b600184015434906001600160a01b0316611429602088018861303a565b6001600160a01b031614801561144c575061144c61012087016101008801613072565b156114915760408051808201825260138152724f535f4e4f545f454e4f5547485f46554e445360681b602082015261148a9183919089013590611fbe565b9050611515565b60018501546001600160a01b03166114af604088016020890161303a565b6001600160a01b03161480156114d257506114d261012087016101008801613072565b15611515576040805180820190915260138152724f535f4e4f545f454e4f5547485f46554e445360681b6020820152611512908290606089013590611fbe565b90505b6115258782886101400135612056565b50600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b928761155060208b018b61303a565b60408b01356115676101208d016101008e01613072565b6040518563ffffffff1660e01b815260040161158694939291906137e6565b60206040518083038186803b15801561159e57600080fd5b505af41580156115b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d691906131de565b9050600073c82938b53e0e190459ba4e3502bf26f1947601836345f92b928861160560408c0160208d0161303a565b60608c013561161c6101208e016101008f01613072565b6040518563ffffffff1660e01b815260040161163b94939291906137e6565b60206040518083038186803b15801561165357600080fd5b505af4158015611667573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168b91906131de565b9050856001600160a01b03166399ce42bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156116c857600080fd5b505af11580156116dc573d6000803e3d6000fd5b505050506117a6896040518061018001604052808863ffffffff168152602001876117075785611709565b845b815260200187611719578461171b565b855b81526020018b6080013581526020018b60a0013581526020018b60c0013581526020018b60e0013581526020018b61010001602081019061175c9190613072565b151581526020016117756101408d016101208e0161303a565b6001600160a01b031681526020018c6006015481526020018b610140013581526020018b61018001358152506127cf565b505050505050505050565b6117b9612fb1565b6117c1612ede565b50600082815260038401602090815260409182902082516101c081018452815460ff80821680845261010080840463ffffffff90811697860197909752600160281b840490921696840196909652600160301b820485166060840152600160501b820485166080840152600160701b808304861660a0850152600160901b9092046001600160701b0390811660c0850152600185015480821660e08601529283041690830152600160e01b9081900484166101208301526002928301546001600160a01b038116610140840152600160a01b81048516610160840152600160c01b81048516610180840152049092166101a08301529091146118d55760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff16825260c08101516001600160701b03908116602084015260e082015181166040808501919091526101008301519091166060840152810151610bae9061243f565b6000826001015482111561193857506000610c29565b6000828152600b8401602052604090205460ff161561195957506005610c29565b6119638383612499565b1561197057506004610c29565b60008061197d8585611cb8565b9092509050600082600481111561199057fe5b14156119a157600392505050610c29565b4281106119b357600192505050610c29565b506002949350505050565b60006119ce828460080154612bbf565b90506000611a148460070154611a0e6119f0853a612bd590919063ffffffff16565b600788015461137d90611a039088612c33565b60068a015490612bd5565b90612c68565b9050620f4240810690036006909301929092555050565b611a33612f52565b60028201805460010190819055610c29908390610a2a565b611a53612e6c565b60028201805460010190819055610c29908390610825565b6001811015611a8c5760405162461bcd60e51b81526004016105019061333c565b600782018190556040517fc93fa9fe410a29e605394838b98dd2b3b4b790b4f45b67dd8c0ddcdd149c4a7490610cce90839061393b565b61d6d881565b611ad1612f52565b611ad9612ede565b50600082815260038401602090815260409182902082516101c081018452815460ff80821680845261010080840463ffffffff90811697860197909752600160281b840490921696840196909652600160301b820485166060840152600160501b820485166080840152600160701b808304861660a0850152600160901b9092046001600160701b0390811660c0850152600185015480821660e08601529283041690830152600160e01b9081900484166101208301526002909201546001600160a01b038116610140830152600160a01b81048416610160830152600160c01b81048416610180830152919091049091166101a08201529060051480611be45750805160ff166006145b611c005760405162461bcd60e51b815260040161050190613452565b61012081015163ffffffff168252805160ff16600614602083015260e08101516001600160701b039081166040808501919091526101008301519091166060840152810151610bae9061243f565b6001600160a01b0382166000908152600a8401602052604090819020829055517f8563e1de6a8955dcbdc3719833791025efb62c4cb350b8a64bc6823168115f0290611c9d90849084906132f7565b60405180910390a1505050565b63ffffffff16620f42400290565b60008181526003830160205260408120805482919060ff811690611ce690610100900463ffffffff1661245a565b9250611cf48160ff16612cc3565b935050509250929050565b62010fe081565b80820182811015610c29576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b42831015611d705760405162461bcd60e51b815260040161050190613669565b8554611d7d904290611d06565b8211611d9b5760405162461bcd60e51b8152600401610501906136de565b8560050154841115611dbf5760405162461bcd60e51b8152600401610501906134d9565b80841015611ddf5760405162461bcd60e51b8152600401610501906133ed565b6001600160a01b038516611e055760405162461bcd60e51b8152600401610501906133c6565b505050505050565b6000806001600160a01b0380841690851611818082611e2d578686611e30565b85875b6004808b015460405163e6a4390560e01b81529395509193506001600160a01b039091169163e6a4390591611e699186918691016132ba565b60206040518083038186803b158015611e8157600080fd5b505afa158015611e95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb99190613056565b945084604051602001611ecc919061329d565b60408051601f19818403018152919052805160209091012060e01c93506001600160a01b038516611f0f5760405162461bcd60e51b815260040161050190613508565b63ffffffff841660009081526009890160205260409020546001600160a01b0316611fb357604080516060810182526001600160a01b038781168252848116602080840191825285831684860190815263ffffffff8a16600090815260098f01909252949020925183546001600160a01b03199081169184169190911784559051600184018054831691841691909117905592516002909201805490931691161790555b505093509350939050565b818303818482111561204e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612013578181015183820152602001611ffb565b50505050905090810190601f1680156120405780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b60068301546000906120689083612bd5565b90508083101561208a5760405162461bcd60e51b81526004016105019061355e565b808311156120c857336108fc6120a08584612c33565b6040518115909202916000818181858888f1935050505015801561204e573d6000803e3d6000fd5b9392505050565b6001808301805490910190819055825460c08301516040514290920192917f8e1149b1ae4941f00e4f06729893afa4b802faea79df7aba3c17208f3547201a9161211b91859190613922565b60405180910390a2604051806101c00160405280836020015161213f576003612142565b60045b60ff16815260200161215c836001600160801b0316612d33565b63ffffffff1681526020016121748460800151612d5e565b60ff16815260200161218a846101000151612d33565b63ffffffff1681526020016121a28460e00151612d6c565b63ffffffff1681526020016121ba8460c00151612d92565b63ffffffff16815260200160006001600160701b031681526020016121e28460400151612dcb565b6001600160701b031681526020016121fd8460600151612dcb565b6001600160701b039081168252845163ffffffff90811660208085019190915260a0968701516001600160a01b03908116604080870191909152600060608088018290526080808901839052978b0182905260018c81015483526003909c0185529082902088518154958a0151938a0151928a0151988a01519b8a015160c08b015160ff1990971660ff9283161764ffffffff00191661010095891686021765ff00000000001916600160281b92909416919091029290921769ffffffff0000000000001916600160301b988716989098029790971763ffffffff60501b1916600160501b9a86169a909a029990991763ffffffff60701b1916600160701b9985168a021771ffffffffffffffffffffffffffffffffffff16600160901b9386169390930292909217855560e08601519885018054928701516101208801516dffffffffffffffffffffffffffff199094169a86169a909a176dffffffffffffffffffffffffffff60701b191699909416909702979097176001600160e01b03908116600160e01b988316890217909255610140840151600290930180546101608601516101808701516101a0909701516001600160a01b0319909216959098169490941763ffffffff60a01b1916600160a01b978316979097029690961763ffffffff60c01b1916600160c01b948216949094029390931716911690930292909217905550565b600060ff821660e881111561242c5760405162461bcd60e51b815260040161050190613769565b60089290921c62ffffff1690911b919050565b600060ff821660021480610c2957505060ff8116155b919050565b600063ffffffff82811614156124735750600019612455565b63ffffffff821661248657506000612455565b5063ffffffff8116635fee57f001919050565b6000818152600383016020526040812054600160281b900460ff1660028114806124c6575060ff81166003145b949350505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b602083106125535780518252601f199092019160209182019101612534565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146125b5576040519150601f19603f3d011682016040523d82523d6000602084013e6125ba565b606091505b50915091508180156125e85750805115806125e857508080602001905160208110156125e557600080fd5b50515b611e05576040805162461bcd60e51b815260206004820152601760248201527f54485f5452414e534645525f46524f4d5f4641494c4544000000000000000000604482015290519081900360640190fd5b6001808301805490910190819055825460c08301516040514290920192917f035ab43d9a5fed70815a96282a434191776a82af7346684e06946bfaf4bf69189161268591859190613922565b60405180910390a2604051806101c00160405280600260ff1681526020016126b5836001600160801b0316612d33565b63ffffffff1681526020016126cd8460800151612d5e565b60ff1681526020016126e3846101000151612d33565b63ffffffff1681526020016126fb8460e00151612d6c565b63ffffffff1681526020016127138460c00151612d92565b63ffffffff16815260200161272b8460200151612dcb565b6001600160701b031681526020016121e28460400151612dcb565b6001808301805490910190819055825460c08301516040514290920192917fdb60298d9ace7090c4c203a97d8c532a17de2a6d9f19ede5e2b52dadc6cd9c059161279291859190613922565b60405180910390a2604051806101c0016040528083602001516127b6576005612142565b6006815260200161215c6001600160801b038416612d33565b600180830180549091019081905582546101208301516040514290920192917f6615ed5af05d4e62d9351a6827f4947db8cda3f821102b956d096952dcba831e9161281c91859190613922565b60405180910390a2604051806101c00160405280600160ff16815260200161284c836001600160801b0316612d33565b63ffffffff1681526020016128648460e00151612d5e565b60ff16815260200161287a846101600151612d33565b63ffffffff168152602001612893846101400151612d6c565b63ffffffff1681526020016128ac846101200151612d92565b63ffffffff1681526020016128c48460600151612dcb565b6001600160701b031681526020016128df8460200151612dcb565b6001600160701b031681526020016128fa8460400151612dcb565b6001600160701b03168152602001836000015163ffffffff1681526020018361010001516001600160a01b03168152602001836080015163ffffffff1681526020016129498460a00151612df4565b63ffffffff1681526020016129618460c00151612df4565b63ffffffff168152508360030160008560010154815260200190815260200160002060008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548160ff021916908360ff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600e6101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160000160126101000a8154816001600160701b0302191690836001600160701b0316021790555060e08201518160010160006101000a8154816001600160701b0302191690836001600160701b0316021790555061010082015181600101600e6101000a8154816001600160701b0302191690836001600160701b0316021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101608201518160020160146101000a81548163ffffffff021916908363ffffffff1602179055506101808201518160020160186101000a81548163ffffffff021916908363ffffffff1602179055506101a082015181600201601c6101000a81548163ffffffff021916908363ffffffff160217905550905050505050565b6000818310612bce57816120c8565b5090919050565b6000811580612bf057505080820282828281612bed57fe5b04145b610c29576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4d554c5f4f564552464c4f5760881b604482015290519081900360640190fd5b60006120c883836040518060400160405280601081526020016f534d5f5355425f554e444552464c4f5760801b815250611fbe565b6000808211612caf576040805162461bcd60e51b815260206004820152600e60248201526d534d5f4449565f42595f5a45524f60901b604482015290519081900360640190fd5b6000828481612cba57fe5b04949350505050565b60006001821415612cd657506001612455565b6002821415612ce757506002612455565b6003821415612cf857506004612455565b6004821415612d0957506004612455565b6005821415612d1a57506003612455565b6006821415612d2b57506003612455565b506000919050565b6000600019821415612d485750600019612455565b610c29612d5983635fee57f0612c33565b612d6c565b600081612d2b576001610c29565b8063ffffffff811681146124555760405162461bcd60e51b8152600401610501906136b6565b600081620f42408104620f42400214612dbd5760405162461bcd60e51b815260040161050190613368565b610c29620f42408304612d6c565b806001600160701b03811681146124555760405162461bcd60e51b815260040161050190613535565b60006302000000821015612e0d5750600881901b612455565b60005b60e88163ffffffff161015612e3c578260011660011415612e3057612e3c565b600192831c9201612e10565b63020000008310612e5f5760405162461bcd60e51b81526004016105019061341b565b600883901b179050919050565b604051806101800160405280600063ffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915290565b604051806101200160405280600063ffffffff168152602001600015158152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b604051806101200160405280600063ffffffff16815260200160008152602001600081526020016000815260200160001515815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b60006101208284031215613020578081fd5b50919050565b803563ffffffff8116811461245557600080fd5b60006020828403121561304b578081fd5b81356120c881613944565b600060208284031215613067578081fd5b81516120c881613944565b600060208284031215613083578081fd5b813580151581146120c8578182fd5b6000602082840312156130a3578081fd5b5035919050565b6000806000606084860312156130be578182fd5b8335925060208401356130d081613944565b929592945050506040919091013590565b600080600061016084860312156130f6578283fd5b83359250613107856020860161300e565b915061014084013590509250925092565b60008060008385036101e081121561312e578384fd5b843593506101a0601f1982011215613144578283fd5b506020840191506101c084013590509250925092565b60008082840361016081121561316e578283fd5b83359250610140601f1982011215613184578182fd5b506020830190509250929050565b600080604083850312156131a4578182fd5b50508035926020909101359150565b600080604083850312156131c5578182fd5b823591506131d560208401613026565b90509250929050565b6000602082840312156131ef578081fd5b5051919050565b600060208284031215613207578081fd5b6120c882613026565b6001600160a01b03169052565b15159052565b63ffffffff81511682526020810151151560208301526040810151604083015260608101516060830152608081015161325f608084018261321d565b5060a081015161327260a0840182613210565b5060c0818101519083015260e0808201519083015261010090810151910152565b63ffffffff169052565b60609190911b6bffffffffffffffffffffffff1916815260140190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b6001600160a01b03929092168252602082015260400190565b602081016006831061331e57fe5b91905290565b604081016005841061333257fe5b9281526020015290565b6020808252601290820152714f535f494e56414c49445f494e455254494160701b604082015260600190565b60208082526016908201527527a9afa3a0a9afa82924a1a2afa82922a1a4a9a4a7a760511b604082015260600190565b60208082526014908201527313d4d7d5d2551211149055d7d11254d05093115160621b604082015260600190565b6020808252600d908201526c4f535f4e4f5f4144445245535360981b604082015260600190565b6020808252601490820152734f535f4741535f4c494d49545f544f4f5f4c4f5760601b604082015260600190565b60208082526018908201527f4f535f4f564552464c4f575f464c4f41545f454e434f44450000000000000000604082015260600190565b6020808252601590820152744f535f494e56414c49445f4f524445525f5459504560581b604082015260600190565b6020808252600f908201526e27a9afa727afa0a6a7aaa72a2fa4a760891b604082015260600190565b60208082526015908201527413d4d7d393d7d413d4d4d250931157d49151955391605a1b604082015260600190565b60208082526015908201527409ea6be8e82a6be98929a92a8bea89e9ebe90928e9605b1b604082015260600190565b60208082526013908201527213d4d7d410525497d393d391561254d5115395606a1b604082015260600190565b6020808252600f908201526e27a9afa7ab22a9232627abaf98989960891b604082015260600190565b6020808252601390820152724f535f4e4f545f454e4f5547485f46554e445360681b604082015260600190565b6020808252600c908201526b13d4d7d393d7d05353d5539560a21b604082015260600190565b60208082526013908201527213d4d7d1115413d4d25517d11254d050931151606a1b604082015260600190565b60208082526010908201526f13d4d7d4d1531317d11254d05093115160821b604082015260600190565b6020808252601f908201527f4f535f494e56414c49445f4d41585f4741535f50524943455f494d5041435400604082015260600190565b60208082526010908201526f13d4d7d393d7d05353d5539517d3d55560821b604082015260600190565b6020808252600a908201526913d4d7d156141254915160b21b604082015260600190565b6020808252600f908201526e13d4d7d0955657d11254d050931151608a1b604082015260600190565b6020808252600e908201526d27a9afa7ab22a9232627abaf999960911b604082015260600190565b6020808252601390820152724f535f494e56414c49445f444541444c494e4560681b604082015260600190565b6020808252600f908201526e4f535f4e4f5f4c495155494449545960881b604082015260600190565b6020808252818101527f4f535f544f4b454e5f5452414e534645525f4741535f434f53545f554e534554604082015260600190565b60208082526018908201527f4f535f4f564552464c4f575f464c4f41545f4445434f44450000000000000000604082015260600190565b60208082526019908201527f4f535f4d41585f4741535f4c494d49545f544f4f5f4849474800000000000000604082015260600190565b6101208101610c298284613223565b9384526001600160a01b0392909216602084015260408301521515606082015260800190565b600061018082019050613820828451613293565b6020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015161386e60e084018261321d565b506101008084015161388282850182613210565b50506101208381015190830152610140808401519083015261016092830151929091019190915290565b60006101208201905063ffffffff835116825260208301516020830152604083015160408301526060830151606083015260808301511515608083015260a08301516138fb60a0840182613210565b5060c083015160c083015260e083015160e083015261010080840151818401525092915050565b6001600160801b03929092168252602082015260400190565b90815260200190565b6001600160a01b038116811461395957600080fd5b5056fea264697066735822122020e766a06457358cb2e094653228f18c458c557551d6d572a0390f961ebc825364736f6c63430007050033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.