Source Code
Overview
ETH Balance
ETH Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Trading
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import "./interfaces/IVault.sol";
import "./interfaces/IOracle.sol";
import "./libs/TradingHelper.sol";
import "./interfaces/IFeeHelper.sol";
import "./interfaces/IPairInfos.sol";
import "./interfaces/ITradingStorage.sol";
import "./interfaces/ITradingReceiverCallback.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {TradeBase, OpenTrade, OpenRequest, CloseRequest, TradeType, CloseType} from "./libs/Types.sol";
import {LIQ_THRESHOLD_P, LEV_DENOMINATOR, DENOMINATOR, MILLAGE_DENOMINATOR, MAX_GAIN, FEE_DENOMINATOR} from "./libs/VarConstant.sol";
contract Trading is Initializable, ReentrancyGuardUpgradeable, PausableUpgradeable, Ownable2StepUpgradeable {
struct CloseData {
uint256 closePrice;
int256 fundingFee;
uint256 rolloverFee;
uint256 valueToSend;
uint256 closingFee;
}
enum PriceType {
REQUEST,
EXEC,
LIMIT
}
IPairInfos public pairInfo;
IOracle public oracle;
IFeeHelper public feeHelper;
IVault public vault;
uint256 public tradeSwitch;
uint256 public minAcceptanceDelay;
ITradingStorage public storageT;
address public standardToken;
uint256 internal nonces;
uint256 public liquidationP; // x1000 %
uint256 public spreadReductionP; // x1000 %
uint256 public nativeForClose;
uint256 public nativeForCallback;
uint256 public callbackGasLimit;
uint256 public reserveRate;
address public reserveReceiver;
uint256 public nativeForOpen;
event SetReserve(address indexed _receiver, uint256 _rate);
event SetParams(
uint256 _liquidationP,
uint256 _spreadReductionP,
uint256 _minAcceptanceDelay,
uint256 _tradeSwitch
);
event SetContract(address _tradingStorage, address _standardToken);
event SetNativeFeeForKeeper(uint256 _forOpen, uint256 _forClose, uint256 _forCallback, uint256 _gasLimit);
event RequestOpen(uint256 indexed orderId, OpenRequest _request);
event ExecRequestOpen(uint256 orderId, bool status);
event RequestClose(uint256 indexed orderId, uint256 indexed index, uint256 _closeMargin, uint256 requstTime);
event ExecRequestClose(uint256 orderId, uint256 index, bool status);
event Open(uint256 orderId, OpenTrade t, uint256 fee);
event Close(
uint256 orderId,
uint256 closePrice,
uint256 _closeMargin,
int256 fundingFee,
uint256 rolloverFee,
uint256 closeFee,
uint256 afterFee,
CloseType s
);
event TradeClosed(uint256 orderId);
event UpdateTPAndSL(uint256 orderId, uint256 tp, uint256 sl);
event UpdateOpenRequest(uint256 orderId, uint256 limitPrice, uint256 tp, uint256 sl);
event CancelOpen(uint256 orderId);
event UpdateMargin(uint256 orderId, uint256 amount, bool isAdd, uint256 margin, uint256 leverage);
event Callback(address target, bool resut);
modifier checkSwitch(uint _check) {
require(_check > tradeSwitch, "swich off");
_;
}
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize(address owner, ITradingStorage _storageT, address _standardToken) public initializer {
__Pausable_init();
__ReentrancyGuard_init();
_transferOwnership(owner);
require(address(_storageT) != address(0) && _standardToken != address(0) && owner != address(0), "address_0");
storageT = _storageT;
standardToken = _standardToken;
liquidationP = 50;
spreadReductionP = 975;
nativeForClose = 0.0005 ether;
nativeForOpen = 0;
callbackGasLimit = 200000;
nativeForCallback = 0.0001 ether;
minAcceptanceDelay = 20;
}
function link() external {
pairInfo = IPairInfos(storageT.pairInfo());
oracle = IOracle(storageT.oracle());
feeHelper = IFeeHelper(storageT.feeHelper());
vault = IVault(storageT.vault());
}
function setParams(
uint256 _liquidationP,
uint256 _spreadReductionP,
uint256 _minAcceptanceDelay,
uint256 _tradeSwitch
) external onlyOwner {
require(_liquidationP < MILLAGE_DENOMINATOR && _spreadReductionP < MILLAGE_DENOMINATOR);
liquidationP = _liquidationP;
tradeSwitch = _tradeSwitch;
spreadReductionP = _spreadReductionP;
minAcceptanceDelay = _minAcceptanceDelay;
emit SetParams(_liquidationP, _spreadReductionP, _minAcceptanceDelay, _tradeSwitch);
}
function setReserve(address _receiver, uint256 _rate) external onlyOwner {
require(liquidationP + _rate < MILLAGE_DENOMINATOR);
reserveReceiver = _receiver;
reserveRate = _rate;
emit SetReserve(_receiver, _rate);
}
function setNativeFeeForKeeper(
uint256 _forOpen,
uint256 _forClose,
uint256 _forCallback,
uint256 _gasLimit
) external onlyOwner {
nativeForOpen = _forOpen;
nativeForClose = _forClose;
nativeForCallback = _forCallback;
callbackGasLimit = _gasLimit;
emit SetNativeFeeForKeeper(_forOpen, _forClose, _forCallback, _gasLimit);
}
function setContract(address _tradingStorage, address _standardToken) external onlyOwner {
require(_tradingStorage != address(0) && _standardToken != address(0), "address_0");
storageT = ITradingStorage(_tradingStorage);
standardToken = _standardToken;
emit SetContract(_tradingStorage, _standardToken);
}
function requestOpenMarket(
TradeBase calldata _base,
uint256 marketPrice,
uint256 slippage,
address callTarget
) external payable nonReentrant returns (uint256) {
require(slippage < MILLAGE_DENOMINATOR);
uint256 deviation = (marketPrice * slippage) / MILLAGE_DENOMINATOR;
uint256 max = marketPrice + deviation;
uint256 min = marketPrice - deviation;
return _requestOpen(TradeType.MARKET, _base, max, min, callTarget);
}
function requestOpenLimit(
TradeType _t,
TradeBase calldata _base,
bytes[] calldata updateData,
uint256 limit,
address callTarget
) external payable nonReentrant returns (uint256) {
_assertTradeTypeInequality(_t, TradeType.MARKET);
_checkLimit(_base, updateData, limit, _t);
return _requestOpen(_t, _base, limit, limit, callTarget);
}
function requestClose(
uint256 _orderId,
uint256 _closeMargin,
address callTarget
) external payable nonReentrant checkSwitch(2) returns (uint256) {
uint256 requestAmount = storageT.getCloseRequstAmount(_orderId);
OpenTrade memory ot = storageT.getOpenTrade(_orderId);
_checkAmount(_closeMargin);
_checkTrader(ot.base.trader);
_checkNativeFee(nativeForClose, callTarget);
requestAmount += _closeMargin;
require(requestAmount <= ot.base.margin, "illegal");
if (requestAmount != ot.base.margin) {
_checkPositionSizeAndLeverage(
pairInfo,
ot.base.pairIndex,
(ot.base.margin - requestAmount),
ot.base.leverage
);
}
uint256 index = storageT.storeCloseRequst(_orderId, CloseRequest(_closeMargin, callTarget, 0, false));
emit RequestClose(_orderId, index, _closeMargin, block.timestamp);
return index;
}
function openTrade(uint256 _orderId, bytes[] calldata updateData) external nonReentrant checkSwitch(2) {
OpenRequest memory ort = storageT.getOpenRequest(_orderId);
_checkExist(ort.time);
PriceType _type = ort.tradeType == TradeType.MARKET ? PriceType.LIMIT : PriceType.EXEC;
uint256 price = _getPrice(ort.base.pairIndex, updateData, ort.time, _type);
bool result = _openTrade(_orderId, ort.base, pairInfo, ort.maxPrice, ort.minPrice, price, ort.tradeType);
_openCallBack(ort.callTarget, _orderId, result);
}
function closeTrade(
uint256 _orderId,
uint256 index,
bytes[] calldata updateData
) external nonReentrant checkSwitch(2) {
CloseRequest memory crt = storageT.getCloseRequest(_orderId, index);
_checkExist(crt.time);
require(!crt.isDone,"already exec");
OpenTrade memory ot = storageT.getOpenTrade(_orderId);
uint256 price = _getPrice(ot.base.pairIndex, updateData, crt.time, PriceType.LIMIT);
int profit = TradingHelper.getPercentProfit(ot.openPrice, price, ot.base.leverage, ot.base.long);
storageT.doneCloseRequst(_orderId, index, true);
_closeTrade(pairInfo, _orderId, price, ot, crt.closeMargin, CloseType.INITIATIVE, profit);
emit ExecRequestClose(_orderId, index, true);
_closeCallBack(crt.callTarget, _orderId, index, true, CloseType.INITIATIVE);
}
function stopTrade(
uint256 _orderId,
CloseType _stop,
bytes[] calldata updateData
) external nonReentrant checkSwitch(2) {
require(_stop != CloseType.INITIATIVE, "unsupport");
OpenTrade memory ot = storageT.getOpenTrade(_orderId);
_checkExist(ot.lastUpdateTime);
uint256 minAccept = ot.lastUpdateTime;
if(_stop == CloseType.LQI) minAccept = 0;
uint256 price = _getPrice(ot.base.pairIndex, updateData, minAccept, PriceType.EXEC);
uint256 limitPrice;
if (_stop == CloseType.LQI) {
limitPrice = pairInfo.getTradeLiquidationPrice(
_orderId,
ot.base.pairIndex,
ot.openPrice,
ot.base.margin,
ot.base.leverage,
ot.base.long
);
if (ot.base.sl > 0) {
require(ot.base.long ? limitPrice > ot.base.sl : limitPrice < ot.base.sl, "sl first");
}
} else if (_stop == CloseType.TP) {
limitPrice = TradingHelper.getMaxProfitPrice(ot.openPrice, ot.base.leverage, ot.base.long);
if (ot.base.tp > 0) {
limitPrice = _compare(limitPrice, ot.base.tp, ot.base.long);
}
} else {
require(ot.base.sl > 0, "no sl");
limitPrice = ot.base.sl;
}
require(TradingHelper.isClosePriceReach(limitPrice, price, _stop, ot.base.long), "not Reach");
if (pairInfo.guaranteedSlAndTPEnable(ot.base.pairIndex) && _stop != CloseType.LQI) {
price = limitPrice;
}
int profit = TradingHelper.getPercentProfit(ot.openPrice, price, ot.base.leverage, ot.base.long);
_closeTrade(pairInfo, _orderId, price, ot, ot.base.margin, _stop, profit);
_closeCallBack(ot.base.trader, _orderId, 0, true, _stop);
}
function updateMargin(
uint256 _orderId,
uint256 _amount,
bool _isAdd,
bytes[] calldata updateData
) external nonReentrant checkSwitch(2) {
OpenTrade memory ot = storageT.getOpenTrade(_orderId);
_checkTrader(ot.base.trader);
_checkAmount(_amount);
uint256 position = ot.base.margin * ot.base.leverage;
require(storageT.getCloseRequstAmount(_orderId) == 0, "wait close");
uint256 price = _getPrice(ot.base.pairIndex, updateData, ot.lastUpdateTime, PriceType.REQUEST);
uint256 newMargin;
uint256 leverage;
if (_isAdd) {
int profit = TradingHelper.getPercentProfit(ot.openPrice, price, ot.base.leverage, ot.base.long);
require(profit < int(MAX_GAIN) * int(DENOMINATOR), "max Pnl");
newMargin = ot.base.margin + _amount;
leverage = position / newMargin;
require(
!pairInfo.isExceedGroupsCollateralLimit(ot.base.pairIndex, _amount, ot.base.long),
"CollateralLimit"
);
SafeERC20.safeTransferFrom(IERC20(standardToken), msg.sender, address(storageT), _amount);
} else {
require(ot.base.margin > _amount, "out bond");
newMargin = ot.base.margin - _amount;
if (ot.base.sl > 0 && pairInfo.guaranteedSlAndTPEnable(ot.base.pairIndex)) {
require(!TradingHelper.isClosePriceReach(ot.base.sl, price, CloseType.SL, ot.base.long), "out bond");
}
leverage = position / newMargin;
uint256 liqPrice = pairInfo.getTradeLiquidationPrice(
_orderId,
ot.base.pairIndex,
ot.openPrice,
newMargin,
leverage,
ot.base.long
);
require(!TradingHelper.isClosePriceReach(liqPrice, price, CloseType.LQI, ot.base.long), "out bond");
storageT.transferTo(standardToken, ot.base.trader, _amount);
}
_checkPositionSizeAndLeverage(pairInfo, ot.base.pairIndex, newMargin, leverage);
storageT.updateOpentrade(_orderId, newMargin, 0, 0, false);
uint positionChange = position / LEV_DENOMINATOR - (newMargin * leverage) / LEV_DENOMINATOR;
_updateCollateralAndOpenInterest(
pairInfo,
ot.base.pairIndex,
_amount,
positionChange,
ot.base.long,
_isAdd,
false
);
emit UpdateMargin(_orderId, _amount, _isAdd, newMargin, leverage);
}
function cancelOpen(uint256 _orderId) external nonReentrant checkSwitch(2) {
OpenRequest memory ort = storageT.getOpenRequest(_orderId);
_checkTrader(ort.base.trader);
_assertTradeTypeInequality(ort.tradeType, TradeType.MARKET);
storageT.transferTo(standardToken, ort.base.trader, ort.base.margin);
storageT.delOpenRequst(_orderId);
emit CancelOpen(_orderId);
}
function updateOpenRequest(
uint256 orderId,
bytes[] calldata updateData,
uint256 limit,
uint256 tp,
uint256 sl
) external {
OpenRequest memory ort = storageT.getOpenRequest(orderId);
_checkTrader(ort.base.trader);
_assertTradeTypeInequality(ort.tradeType, TradeType.MARKET);
if (limit > 0) {
_checkLimit(ort.base, updateData, limit, ort.tradeType);
ort.maxPrice = limit;
ort.minPrice = limit;
}
if (tp > 0) {
ort.base.tp = tp;
}
if (sl > 0) {
ort.base.sl = sl;
}
_checkOpen(pairInfo, ort.base, ort.maxPrice, ort.minPrice);
storageT.updateOpenRequst(orderId, limit, limit, tp, sl);
emit UpdateOpenRequest(orderId, limit, tp, sl);
}
function updateTPAndSL(uint256 orderId, uint256 tp, uint256 sl, bytes[] calldata updateData) external {
OpenTrade memory ot = storageT.getOpenTrade(orderId);
_checkTrader(ot.base.trader);
uint256 price = _getPrice(ot.base.pairIndex, updateData, ot.lastUpdateTime, PriceType.REQUEST);
if (tp > 0) {
require(ot.base.long ? tp > price : tp < price, "tp");
}
if (sl > 0) {
require(ot.base.long ? sl < price : sl > price, "sl");
}
storageT.updateOpentrade(orderId, 0, tp, sl, false);
emit UpdateTPAndSL(orderId, tp, sl);
}
function getTradeValue(uint256 orderId, uint256 price) external view returns (uint256) {
OpenTrade memory ot = storageT.getOpenTrade(orderId);
if (ot.openPrice == 0) {
return 0;
}
int profit = TradingHelper.getPercentProfit(ot.openPrice, price, ot.base.leverage, ot.base.long);
uint256 position = (ot.base.margin * ot.base.leverage) / LEV_DENOMINATOR;
(int fundingFee, uint rolloverFee) = pairInfo.getFundingAndRolloverFee(
orderId,
ot.base.pairIndex,
position,
ot.base.long
);
uint256 liqPrice = pairInfo.getTradeLiquidationPrice(
orderId,
ot.base.pairIndex,
ot.openPrice,
ot.base.margin,
ot.base.leverage,
ot.base.long
);
uint closingFee;
bool noSLFirst = true;
if (ot.base.sl > 0) {
noSLFirst = ot.base.long ? liqPrice > ot.base.sl : liqPrice < ot.base.sl;
}
if (noSLFirst && TradingHelper.isClosePriceReach(liqPrice, price, CloseType.LQI, ot.base.long)) {
closingFee = (ot.base.margin * liquidationP) / MILLAGE_DENOMINATOR;
} else {
closingFee = (position * pairInfo.pairCloseFeeP(ot.base.pairIndex)) / MILLAGE_DENOMINATOR;
}
return TradingHelper.getTradeValue(ot.base.margin, profit, rolloverFee, fundingFee, closingFee);
}
function getPriceAfterImpact(
uint256 price,
uint256 pairIndex,
uint256 position,
bool isLong
) external view returns (uint256) {
return TradingHelper.getPriceAfterImpact(pairInfo, price, spreadReductionP, pairIndex, position, isLong);
}
function _requestOpen(
TradeType _t,
TradeBase calldata _base,
uint256 max,
uint256 min,
address callTarget
) internal returns (uint256) {
_checkTrader(_base.trader);
_checkNativeFee(nativeForOpen, callTarget);
_checkOpen(pairInfo, _base, max, min);
SafeERC20.safeTransferFrom(IERC20(standardToken), msg.sender, address(storageT), _base.margin);
OpenRequest memory ort = OpenRequest(_t, _base, callTarget, max, min, block.timestamp);
uint256 orderId = TradingHelper.getOrderId(0, _base.pairIndex, ++nonces);
storageT.storeOpenRequst(orderId, ort);
emit RequestOpen(orderId, ort);
return orderId;
}
function _openTrade(
uint256 orderId,
TradeBase memory base,
IPairInfos _pairInfo,
uint256 max,
uint256 min,
uint256 oraclePrice,
TradeType tradeType
) internal returns (bool) {
uint256 position = (base.margin * base.leverage) / LEV_DENOMINATOR;
oraclePrice = TradingHelper.getPriceAfterImpact(
_pairInfo,
oraclePrice,
spreadReductionP,
base.pairIndex,
position,
base.long
);
(bool result, string memory message) = TradingHelper.withinLimit(
_pairInfo,
base,
max,
min,
oraclePrice,
position,
tradeType
);
if (tradeType == TradeType.MARKET && !result) {
storageT.transferTo(standardToken, base.trader, base.margin);
storageT.delOpenRequst(orderId);
emit ExecRequestOpen(orderId, false);
return false;
} else {
require(result, message);
}
uint256 totalFee = (position * _pairInfo.pairOpenFeeP(base.pairIndex)) / FEE_DENOMINATOR;
base.margin -= totalFee;
position = (base.margin * base.leverage) / LEV_DENOMINATOR;
_dealFee(totalFee, position, base.trader, true);
_updateCollateralAndOpenInterest(_pairInfo, base.pairIndex, base.margin, position, base.long, true, true);
OpenTrade memory ot = OpenTrade(base, tradeType != TradeType.LIMIT ? oraclePrice : max, 0);
storageT.storeOpenTrade(orderId, ot);
_pairInfo.storeTradeInitialAccFees(orderId, base.pairIndex, base.long);
storageT.delOpenRequst(orderId);
emit ExecRequestOpen(orderId, true);
emit Open(orderId, ot, totalFee);
return true;
}
function _closeTrade(
IPairInfos _pairInfo,
uint256 orderId,
uint256 closePrice,
OpenTrade memory _ot,
uint256 _closeMargin,
CloseType s,
int profit
) internal {
CloseData memory closeData;
uint256 positionNotDiv = _closeMargin * _ot.base.leverage;
uint256 closePosition = (positionNotDiv) / LEV_DENOMINATOR;
uint256 left = _closeMargin;
if (s == CloseType.LQI) {
closeData.closingFee = (_closeMargin * liquidationP) / MILLAGE_DENOMINATOR;
left -= _reserve(_closeMargin);
} else {
closeData.closingFee =
(positionNotDiv * _pairInfo.pairCloseFeeP(_ot.base.pairIndex)) /
FEE_DENOMINATOR /
LEV_DENOMINATOR;
}
(closeData.fundingFee, closeData.rolloverFee) = _pairInfo.getFundingAndRolloverFee(
orderId,
_ot.base.pairIndex,
closePosition,
_ot.base.long
);
closeData.valueToSend = TradingHelper.getTradeValue(
_closeMargin,
profit,
closeData.rolloverFee,
closeData.fundingFee,
closeData.closingFee
);
_dealFee(closeData.closingFee, closePosition, _ot.base.trader, false);
left -= closeData.closingFee;
if (left > closeData.valueToSend) {
if (closeData.valueToSend != 0) {
storageT.transferTo(standardToken, _ot.base.trader, closeData.valueToSend);
}
uint256 toVault = left - closeData.valueToSend;
storageT.transferTo(standardToken, address(vault), toVault);
vault.receiveFromTrader(_ot.base.trader, toVault, 0, false);
} else {
uint256 fromVault = closeData.valueToSend - left;
if (fromVault > 0) {
vault.sendToTrader(_ot.base.trader, fromVault);
}
if (left > 0) {
storageT.transferTo(standardToken, _ot.base.trader, left);
}
}
uint256 leftMargin = _ot.base.margin - _closeMargin;
uint256 subPosition = closePosition;
if (leftMargin == 0) {
storageT.delOpenTrade(orderId);
_pairInfo.delTradeInitialAccFees(orderId);
storageT.delClose(orderId);
emit TradeClosed(orderId);
} else {
subPosition =
(_ot.base.margin * _ot.base.leverage) /
LEV_DENOMINATOR -
(leftMargin * _ot.base.leverage) /
LEV_DENOMINATOR;
storageT.updateOpentrade(orderId, leftMargin, 0, 0, true);
}
_updateCollateralAndOpenInterest(
_pairInfo,
_ot.base.pairIndex,
_closeMargin,
subPosition,
_ot.base.long,
false,
false
);
emit Close(
orderId,
closePrice,
_closeMargin,
closeData.fundingFee,
closeData.rolloverFee,
closeData.closingFee,
closeData.valueToSend,
s
);
}
function _checkLimit(TradeBase memory base, bytes[] calldata updateData, uint256 limit, TradeType t) private {
uint256 price = _getPrice(base.pairIndex, updateData, 0, PriceType.REQUEST);
bool checkLimitPrice = TradingHelper.checkLimitPrice(pairInfo, base, price, limit, spreadReductionP, t);
require(checkLimitPrice, "illegal limit");
}
function _updateCollateralAndOpenInterest(
IPairInfos _pairInfo,
uint256 pairIndex,
uint256 collateral,
uint256 position,
bool long,
bool collateralIncrease,
bool positionIncrease
) private {
_pairInfo.updateGroupCollateral(pairIndex, collateral, long, collateralIncrease);
if (position != 0) {
_pairInfo.updateOpenInterest(pairIndex, position, long, positionIncrease);
}
}
function _checkNativeFee(uint256 nativeFee, address callTarget) private {
if (callTarget != address(0)) {
nativeFee += nativeForCallback;
}
require(msg.value == nativeFee, "fee mis");
}
function _checkTrader(address trader) private view {
require(trader == msg.sender, "not trader");
}
function _assertTradeTypeInequality(TradeType c, TradeType a) private pure {
require(c != a, "unsupport");
}
function _checkExist(uint256 time) private pure {
require(time != 0,"not exist");
}
function _checkOpen(IPairInfos _pairInfo, TradeBase memory _base, uint256 _max, uint256 _min) private view {
_checkPositionSizeAndLeverage(_pairInfo, _base.pairIndex, _base.margin, _base.leverage);
bool tp = _base.tp == 0 || (_base.long ? _base.tp > _max : _base.tp < _min);
bool sl = _base.sl == 0 || (_base.long ? _base.sl < _min : _base.sl > _max);
bool result = _max >= _min && _min > 0 && tp && sl;
require(result, "illegal");
}
function _checkPositionSizeAndLeverage(
IPairInfos _pairInfo,
uint256 pairIndex,
uint256 margin,
uint256 leverage
) private view {
bool size = _pairInfo.legalPositionSizeAndLeverage(pairIndex, margin, leverage);
require(size, "out size");
}
function _checkAmount(uint256 amount) private pure {
require(amount != 0, "value_0");
}
function _reserve(uint256 _amount) private returns (uint256) {
uint256 toReserve;
if (reserveReceiver != address(0) && reserveRate != 0) {
toReserve = (_amount * reserveRate) / MILLAGE_DENOMINATOR;
storageT.transferTo(standardToken, reserveReceiver, toReserve);
}
return toReserve;
}
function _dealFee(uint256 fee, uint256 position, address trader, bool isOpen) private {
storageT.transferTo(standardToken, address(feeHelper), fee);
if (isOpen) {
feeHelper.dealOpenFee(trader, msg.sender, fee, position);
} else {
feeHelper.dealCloseFee(trader, msg.sender, fee, position);
}
}
function _compare(uint256 a, uint256 b, bool min) private pure returns (uint256) {
if (min) {
return a < b ? a : b;
} else {
return a > b ? a : b;
}
}
function _openCallBack(address target, uint256 orderId, bool exec) internal {
uint256 nativeAmount = nativeForOpen;
if (target.code.length > 0) {
nativeAmount += nativeForCallback;
bool success;
try ITradingReceiverCallback(target).onTradeOpen{gas: callbackGasLimit}(orderId, exec) {
success = true;
} catch {}
emit Callback(target, success);
}
if (nativeAmount != 0) transferNativeFee(nativeAmount);
}
function _getPrice(
uint256 pairIndex,
bytes[] calldata updateData,
uint256 minAccept,
PriceType _type
) internal returns (uint256) {
uint256 oraclePrice;
if (_type != PriceType.LIMIT) {
oraclePrice = oracle.getTokenPriceWithMinAccept(
pairInfo.pairFeedId(pairIndex),
pairInfo.priceRollover(pairIndex),
updateData,
minAccept,
_type == PriceType.REQUEST
);
} else {
oraclePrice = oracle.getTokenPriceBenchmark(
pairInfo.pairFeedId(pairIndex),
pairInfo.priceRollover(pairIndex),
updateData,
minAccept
);
}
require(oraclePrice > 0);
return oraclePrice;
}
function _closeCallBack(address target, uint256 orderId, uint256 index, bool exec, CloseType t) internal {
uint256 nativeAmount;
if (target.code.length > 0) {
nativeAmount = nativeForClose + nativeForCallback;
bool success;
try ITradingReceiverCallback(target).onTradeClose{gas: callbackGasLimit}(orderId, index, exec, t) {
success = true;
} catch {}
emit Callback(target, success);
} else {
nativeAmount = nativeForClose;
}
if (t == CloseType.INITIATIVE && nativeAmount != 0) {
transferNativeFee(nativeAmount);
}
}
function transferNativeFee(uint256 amount) private {
(bool result, ) = (msg.sender).call{value: amount}("");
require(result, "transfer fail");
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.0;
import "./OwnableUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
function __Ownable2Step_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable2Step_init_unchained() internal onlyInitializing {
}
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
_transferOwnership(sender);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
function __Pausable_init_unchained() internal onlyInitializing {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
interface IFeeHelper {
function dealOpenFee(address trader, address keeper, uint256 totalFee, uint256 position) external;
function dealCloseFee(address trader, address keeper, uint256 totalFee, uint256 position) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
interface IOracle {
function getTokenPrice(
bytes32 feedId,
bool priceRollover,
bytes[] calldata updateData,
bool isRequest
) external returns (uint256);
function getTokenPriceWithMinAccept(
bytes32 feedId,
bool priceRollover,
bytes[] calldata updateData,
uint256 minAccept,
bool isRequest
) external returns (uint256);
function getTokenPriceBenchmark(
bytes32 feedId,
bool priceRollover,
bytes[] calldata updateData,
uint256 time
) external returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {TradeType} from "../libs/Types.sol";
interface IPairInfos {
function pairFeedId(uint _pairIndex) external view returns (bytes32);
function withinMaxSpread(
uint256 pairIndex,
TradeType tradeType,
uint256 limit,
uint256 current,
bool isLong
) external view returns (bool result);
function isExceedGroupsCollateralLimit(uint256 pairIndex, uint256 position, bool long) external view returns (bool);
function isInPairInterestLimit(uint pairIndex, uint256 position, bool isLong) external view returns (bool);
function legalPositionSizeAndLeverage(
uint256 pairIndex,
uint256 margin,
uint256 leverage
) external view returns (bool);
function pairSpreadP(uint _pairIndex) external view returns (uint);
function pairOpenFeeP(uint _pairIndex) external view returns (uint);
function pairCloseFeeP(uint _pairIndex) external view returns (uint);
function priceRollover(uint _pairIndex) external view returns (bool);
function guaranteedSlAndTPEnable(uint _pairIndex) external view returns (bool);
function occupiedCollateral() external view returns (uint256);
function getTradePriceImpact(
uint openPrice,
uint pairIndex,
bool long,
uint tradeOpenInterest
) external view returns (uint priceAfterImpact);
function updateGroupCollateral(uint _pairIndex, uint _amount, bool _long, bool _increase) external;
function updateOpenInterest(uint _pairIndex, uint _amount, bool _long, bool _increase) external;
function storeTradeInitialAccFees(uint256 orderId, uint256 pairIndex, bool long) external;
function delTradeInitialAccFees(uint256 orderId) external;
function getFundingAndRolloverFee(
uint256 orderId,
uint256 pairIndex,
uint256 position,
bool long
) external view returns (int256 fundingFee, uint256 rolloverFee);
function getTradeLiquidationPrice(
uint256 orderId,
uint pairIndex,
uint openPrice,
uint collateral,
uint leverage,
bool long
) external view returns (uint);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {CloseType} from "../libs/Types.sol";
interface ITradingReceiverCallback {
function onTradeOpen(uint256 orderId, bool _wasExecuted) external;
function onTradeClose(uint256 orderId, uint256 index, bool _wasExecuted, CloseType c) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {TradeBase, OpenTrade, OpenRequest, CloseRequest} from "../libs/Types.sol";
interface ITradingStorage {
function storeOpenTrade(uint256 orderId, OpenTrade memory _openTrade) external;
function delOpenTrade(uint256 orderId) external;
function updateOpentrade(uint256 orderId, uint256 margin, uint256 tp, uint256 sl, bool isClose) external;
function storeOpenRequst(uint256 _orderId, OpenRequest memory _request) external;
function delOpenRequst(uint256 _orderId) external;
function updateOpenRequst(uint256 orderId, uint256 _max, uint256 _min, uint256 _tp, uint256 _sl) external;
function storeCloseRequst(uint256 _orderId, CloseRequest memory _request) external returns (uint256 index);
function doneCloseRequst(uint256 _orderId, uint256 index, bool exec) external;
function delClose(uint256 orderId) external;
function getOpenTrade(uint256 orderId) external view returns (OpenTrade memory);
function getOpenRequest(uint256 orderId) external view returns (OpenRequest memory);
function getCloseRequest(uint256 orderId, uint256 index) external view returns (CloseRequest memory);
function getCloseRequstAmount(uint256 orderId) external view returns (uint256);
function transferTo(address token, address to, uint256 amount) external;
function trading() external view returns (address);
function pool() external view returns (address);
function vault() external view returns (address);
function pairInfo() external view returns (address);
function oracle() external view returns (address);
function feeHelper() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
interface IVault {
function distributeReward(uint _amount, bool _send) external;
function currentBalance() external view returns (uint);
function sendToTrader(address _trader, uint _amount) external;
function receiveFromTrader(address _trader, uint _amount, uint _vaultFee, bool _send) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import "../interfaces/IPairInfos.sol";
import {TradeBase, OpenTrade, OpenRequest, CloseRequest, TradeType, CloseType} from "./Types.sol";
import {LIQ_THRESHOLD_P, LEV_DENOMINATOR, DENOMINATOR, MILLAGE_DENOMINATOR, MAX_GAIN} from "./VarConstant.sol";
library TradingHelper {
function getPercentProfit(
uint256 _openPrice,
uint256 _currentPrice,
uint256 leverage,
bool isLong
) internal pure returns (int256) {
int maxPnlP = int(MAX_GAIN) * int(DENOMINATOR);
int p;
if (isLong) {
p = ((toInt(_currentPrice) - toInt(_openPrice)) * int(DENOMINATOR)) / toInt(_openPrice);
} else {
p = ((toInt(_openPrice) - toInt(_currentPrice)) * int(DENOMINATOR)) / toInt(_openPrice);
}
p = (p * int(leverage)) / int(LEV_DENOMINATOR);
p = p > maxPnlP ? maxPnlP : p;
return p;
}
function getMaxProfitPrice(uint256 openPrice, uint256 leverage, bool isLong) internal pure returns (uint256) {
uint256 distance = (openPrice * MAX_GAIN * LEV_DENOMINATOR) / leverage;
if (isLong) {
return openPrice + distance;
} else {
if (openPrice < distance) {
return 0;
} else {
return openPrice - distance;
}
}
}
function getTradeValue(
uint margin,
int percentProfit,
uint rolloverFee,
int fundingFee,
uint closingFee
) internal pure returns (uint256) {
int value = int(margin) + (int(margin) * percentProfit) / int(DENOMINATOR) - int(rolloverFee) - fundingFee;
value -= int(closingFee);
return value > 0 ? uint(value) : 0;
}
function getPriceAfterImpact(
IPairInfos _pairInfo,
uint256 price,
uint spreadReductionP,
uint256 pairIndex,
uint256 position,
bool isLong
) internal view returns (uint256) {
uint spreadP = _pairInfo.pairSpreadP(pairIndex);
uint256 marketExecutionPrice = getMarketExecutionPrice(price, spreadReductionP, spreadP, isLong);
return _pairInfo.getTradePriceImpact(marketExecutionPrice, pairIndex, isLong, position);
}
function getMarketExecutionPrice(
uint price,
uint spreadReductionP,
uint spreadP,
bool long
) internal pure returns (uint) {
//uint priceDiff = (price * (spreadP * MILLAGE_DENOMINATOR - (spreadP * spreadReductionP))) / MILLAGE_DENOMINATOR / MILLAGE_DENOMINATOR ;
uint256 actualPriceSpreadPercentage = MILLAGE_DENOMINATOR - spreadReductionP;
uint priceDiff = (((price * spreadP) / MILLAGE_DENOMINATOR) * actualPriceSpreadPercentage) /
MILLAGE_DENOMINATOR;
return long ? price + priceDiff : price - priceDiff;
}
function isClosePriceReach(
uint256 limitPrice,
uint256 currentPrice,
CloseType _s,
bool isLong
) internal pure returns (bool) {
if (isLong) {
if (_s == CloseType.TP || _s == CloseType.INITIATIVE) {
return currentPrice >= limitPrice;
} else {
return currentPrice <= limitPrice;
}
} else {
if (_s == CloseType.TP || _s == CloseType.INITIATIVE) {
return currentPrice <= limitPrice;
} else {
return currentPrice >= limitPrice;
}
}
}
function isOpenPriceReach(
uint256 max,
uint256 min,
uint256 currentPrice,
bool isLong,
TradeType tradeType
) internal pure returns (bool) {
if (tradeType == TradeType.MARKET) {
return currentPrice >= min && currentPrice <= max;
}
if (isLong) {
if (tradeType == TradeType.LIMIT) {
return currentPrice <= min;
} else {
return currentPrice >= max;
}
} else {
if (tradeType == TradeType.LIMIT) {
return currentPrice >= max;
} else {
return currentPrice <= min;
}
}
}
function withinLimit(
IPairInfos _pairInfo,
TradeBase memory base,
uint256 max,
uint256 min,
uint256 priceAfterImpact,
uint256 position,
TradeType tradeType
) internal view returns (bool, string memory) {
if (!isOpenPriceReach(max, min, priceAfterImpact, base.long, tradeType)) {
return (false, "price out limit");
}
if (_pairInfo.isExceedGroupsCollateralLimit(base.pairIndex, base.margin, base.long)) {
return (false, "CollateralLimit");
}
if (!_pairInfo.isInPairInterestLimit(base.pairIndex, position, base.long)) {
return (false, "InterestLimit");
}
if (tradeType != TradeType.MARKET) {
if (!_pairInfo.withinMaxSpread(base.pairIndex, tradeType, max, priceAfterImpact, base.long)) {
return (false, "out Spread");
}
}
return (true, "");
}
function getOrderId(uint8 version, uint256 pairIndex, uint256 nonce) internal pure returns (uint256) {
require(pairIndex < type(uint24).max && nonce < type(uint224).max, "out bond");
return (version << 248) | (pairIndex << 224) | nonce;
}
function checkLimitPrice(
IPairInfos _pairInfo,
TradeBase memory _base,
uint256 price,
uint256 limit,
uint256 spreadReductionP,
TradeType tradeType
) internal view returns (bool) {
uint256 position = (_base.margin * _base.leverage) / LEV_DENOMINATOR;
price = getPriceAfterImpact(_pairInfo, price, spreadReductionP, _base.pairIndex, position, _base.long);
if (_base.long) {
if (tradeType == TradeType.LIMIT) {
return limit < price;
} else {
return limit > price;
}
} else {
if (tradeType == TradeType.LIMIT) {
return limit > price;
} else {
return limit < price;
}
}
}
function toInt(uint256 v) internal pure returns (int) {
require(v <= uint256(type(int256).max), "overflow");
return int(v);
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
enum CloseType {
INITIATIVE,
LQI,
TP,
SL
}
enum TradeType {
MARKET,
LIMIT,
STOP
}
struct TradeBase {
address trader;
uint256 pairIndex;
uint256 margin;
bool long;
uint leverage; // x10?
uint tp;
uint sl;
}
struct OpenTrade {
TradeBase base;
uint256 openPrice; // x10**18
uint256 lastUpdateTime;
}
struct OpenRequest {
TradeType tradeType;
TradeBase base;
address callTarget;
uint256 maxPrice; // x10**18
uint256 minPrice; // x10**18
uint256 time;
}
struct CloseRequest {
uint256 closeMargin;
address callTarget;
uint256 time;
bool isDone;
}
struct Close {
uint256 requestAmount;
CloseRequest[] requests;
}// SPDX-License-Identifier: MIT pragma solidity 0.8.15; uint256 constant DENOMINATOR = 10 ** 10; uint256 constant LEV_DENOMINATOR = 10 ** 18; // leverage 10**18 -> 1 uint256 constant MILLAGE_DENOMINATOR = 1000; uint256 constant FEE_DENOMINATOR = 100000; uint256 constant LIQ_THRESHOLD_P = 900; // 90% uint256 constant MIN_LEVERAGE = 1 * 10 ** 17; uint256 constant MAX_LEVERAGE = 100 * 10 ** 18; uint256 constant MAX_GAIN = 9; //900%
{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"resut","type":"bool"}],"name":"Callback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"CancelOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_closeMargin","type":"uint256"},{"indexed":false,"internalType":"int256","name":"fundingFee","type":"int256"},{"indexed":false,"internalType":"uint256","name":"rolloverFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"afterFee","type":"uint256"},{"indexed":false,"internalType":"enum CloseType","name":"s","type":"uint8"}],"name":"Close","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"ExecRequestClose","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"ExecRequestOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"components":[{"components":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"bool","name":"long","type":"bool"},{"internalType":"uint256","name":"leverage","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"}],"internalType":"struct TradeBase","name":"base","type":"tuple"},{"internalType":"uint256","name":"openPrice","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"}],"indexed":false,"internalType":"struct OpenTrade","name":"t","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Open","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_closeMargin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requstTime","type":"uint256"}],"name":"RequestClose","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"orderId","type":"uint256"},{"components":[{"internalType":"enum TradeType","name":"tradeType","type":"uint8"},{"components":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"bool","name":"long","type":"bool"},{"internalType":"uint256","name":"leverage","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"}],"internalType":"struct TradeBase","name":"base","type":"tuple"},{"internalType":"address","name":"callTarget","type":"address"},{"internalType":"uint256","name":"maxPrice","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"time","type":"uint256"}],"indexed":false,"internalType":"struct OpenRequest","name":"_request","type":"tuple"}],"name":"RequestOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_tradingStorage","type":"address"},{"indexed":false,"internalType":"address","name":"_standardToken","type":"address"}],"name":"SetContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_forOpen","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_forClose","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_forCallback","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"SetNativeFeeForKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_liquidationP","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_spreadReductionP","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_minAcceptanceDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tradeSwitch","type":"uint256"}],"name":"SetParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"SetReserve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"}],"name":"TradeClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isAdd","type":"bool"},{"indexed":false,"internalType":"uint256","name":"margin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leverage","type":"uint256"}],"name":"UpdateMargin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"limitPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sl","type":"uint256"}],"name":"UpdateOpenRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"orderId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sl","type":"uint256"}],"name":"UpdateTPAndSL","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"callbackGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"}],"name":"cancelOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes[]","name":"updateData","type":"bytes[]"}],"name":"closeTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeHelper","outputs":[{"internalType":"contract IFeeHelper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"position","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"}],"name":"getPriceAfterImpact","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"getTradeValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"contract ITradingStorage","name":"_storageT","type":"address"},{"internalType":"address","name":"_standardToken","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"link","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquidationP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAcceptanceDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeForCallback","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeForClose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeForOpen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"},{"internalType":"bytes[]","name":"updateData","type":"bytes[]"}],"name":"openTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairInfo","outputs":[{"internalType":"contract IPairInfos","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"},{"internalType":"uint256","name":"_closeMargin","type":"uint256"},{"internalType":"address","name":"callTarget","type":"address"}],"name":"requestClose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum TradeType","name":"_t","type":"uint8"},{"components":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"bool","name":"long","type":"bool"},{"internalType":"uint256","name":"leverage","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"}],"internalType":"struct TradeBase","name":"_base","type":"tuple"},{"internalType":"bytes[]","name":"updateData","type":"bytes[]"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"address","name":"callTarget","type":"address"}],"name":"requestOpenLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"bool","name":"long","type":"bool"},{"internalType":"uint256","name":"leverage","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"}],"internalType":"struct TradeBase","name":"_base","type":"tuple"},{"internalType":"uint256","name":"marketPrice","type":"uint256"},{"internalType":"uint256","name":"slippage","type":"uint256"},{"internalType":"address","name":"callTarget","type":"address"}],"name":"requestOpenMarket","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"reserveRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserveReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tradingStorage","type":"address"},{"internalType":"address","name":"_standardToken","type":"address"}],"name":"setContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_forOpen","type":"uint256"},{"internalType":"uint256","name":"_forClose","type":"uint256"},{"internalType":"uint256","name":"_forCallback","type":"uint256"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"setNativeFeeForKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_liquidationP","type":"uint256"},{"internalType":"uint256","name":"_spreadReductionP","type":"uint256"},{"internalType":"uint256","name":"_minAcceptanceDelay","type":"uint256"},{"internalType":"uint256","name":"_tradeSwitch","type":"uint256"}],"name":"setParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spreadReductionP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"standardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"},{"internalType":"enum CloseType","name":"_stop","type":"uint8"},{"internalType":"bytes[]","name":"updateData","type":"bytes[]"}],"name":"stopTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"storageT","outputs":[{"internalType":"contract ITradingStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeSwitch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_isAdd","type":"bool"},{"internalType":"bytes[]","name":"updateData","type":"bytes[]"}],"name":"updateMargin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"bytes[]","name":"updateData","type":"bytes[]"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"}],"name":"updateOpenRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"orderId","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"},{"internalType":"bytes[]","name":"updateData","type":"bytes[]"}],"name":"updateTPAndSL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b615f8b80620000f36000396000f3fe60806040526004361061023b5760003560e01c80637dc0d1d01161012e578063cc83bfd2116100ab578063f485ccf01161006f578063f485ccf01461064b578063f750704f14610662578063fbfa77cf14610675578063fc2a5b1d14610695578063fd77f87f146106b557600080fd5b8063cc83bfd2146105b6578063e30c3978146105d6578063efbc5fc0146105f4578063efcf0bd01461060b578063f2fde38b1461062b57600080fd5b8063a53fcde8116100f2578063a53fcde81461052c578063a5c34ba71461054c578063bb1c7c2a14610562578063c04398ee14610583578063c0c53b8b1461059657600080fd5b80637dc0d1d01461049b5780637ece45e8146104bb578063806762a0146104db5780638bc846c9146104fb5780638da5cb5b1461050e57600080fd5b80634c7d7d3f116101bc5780636bc81aa2116101805780636bc81aa21461041a578063715018a614610431578063725348901461044657806378250b631461046657806379ba50971461048657600080fd5b80634c7d7d3f1461039157806358d7bf80146103b25780635bd3e1c8146103c95780635c975abb146103e0578063615728f81461040357600080fd5b80631c4695f4116102035780631c4695f4146103055780631c7f6f4c1461031a57806324f746971461033a5780632bf6e0a514610351578063338b01331461037157600080fd5b806304c7ec71146102405780630845d69d1461026257806316b820911461028257806316fff074146102ac57806318897bb7146102e5575b600080fd5b34801561024c57600080fd5b5061026061025b366004615136565b6106d5565b005b34801561026e57600080fd5b5061026061027d366004615196565b6108d8565b34801561028e57600080fd5b5061029961010b5481565b6040519081526020015b60405180910390f35b3480156102b857600080fd5b50610101546102cd906001600160a01b031681565b6040516001600160a01b0390911681526020016102a3565b3480156102f157600080fd5b5060fd546102cd906001600160a01b031681565b34801561031157600080fd5b50610260610947565b34801561032657600080fd5b506102606103353660046151c8565b610b6a565b34801561034657600080fd5b506102996101085481565b34801561035d57600080fd5b5061026061036c366004615228565b610cb2565b34801561037d57600080fd5b5061026061038c366004615261565b610d82565b34801561039d57600080fd5b50610102546102cd906001600160a01b031681565b3480156103be57600080fd5b506102996101095481565b3480156103d557600080fd5b506102996101065481565b3480156103ec57600080fd5b5060655460ff1660405190151581526020016102a3565b34801561040f57600080fd5b506102996101045481565b34801561042657600080fd5b506102996101075481565b34801561043d57600080fd5b5061026061101d565b34801561045257600080fd5b506102996104613660046152b3565b611031565b34801561047257600080fd5b506102606104813660046152d5565b6113b1565b34801561049257600080fd5b50610260611431565b3480156104a757600080fd5b5060fc546102cd906001600160a01b031681565b3480156104c757600080fd5b506102606104d6366004615196565b6114ab565b3480156104e757600080fd5b506102606104f6366004615301565b61152a565b610299610509366004615332565b6116fd565b34801561051a57600080fd5b506097546001600160a01b03166102cd565b34801561053857600080fd5b5061029961054736600461538c565b611770565b34801561055857600080fd5b5061029960ff5481565b34801561056e57600080fd5b5061010a546102cd906001600160a01b031681565b6102996105913660046153c2565b61179d565b3480156105a257600080fd5b506102606105b13660046153fb565b611a6a565b3480156105c257600080fd5b506102606105d136600461543b565b611c5b565b3480156105e257600080fd5b5060c9546001600160a01b03166102cd565b34801561060057600080fd5b506102996101055481565b34801561061757600080fd5b50610260610626366004615482565b6120e7565b34801561063757600080fd5b506102606106463660046154e7565b6122ad565b34801561065757600080fd5b506102996101005481565b610299610670366004615511565b61231e565b34801561068157600080fd5b5060fe546102cd906001600160a01b031681565b3480156106a157600080fd5b5060fb546102cd906001600160a01b031681565b3480156106c157600080fd5b506102606106d0366004615598565b612370565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610721573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610745919061568b565b80515190915061075490612a8e565b6000610770826000015160200151858585604001516000612ad3565b905085156107c45781516060015161078a5780861061078e565b8086115b6107c45760405162461bcd60e51b8152602060048201526002602482015261074760f41b60448201526064015b60405180910390fd5b8415610811578151606001516107dc578085116107e0565b8085105b6108115760405162461bcd60e51b81526020600482015260026024820152611cdb60f21b60448201526064016107bb565b610101546040516311ceca8960e11b815260048101899052600060248201819052604482018990526064820188905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b15801561087457600080fd5b505af1158015610888573d6000803e3d6000fd5b5050604080518a8152602081018a90529081018890527f3fea1f17d88eda811ab87655f92885a6ec5fc9fd390aca775b9327f43ad00d77925060600190505b60405180910390a150505050505050565b6108e0612dae565b61010b8490556101068390556101078290556101088190556040805185815260208101859052908101839052606081018290527faac5f778cabbb5dc9b9bd42735e5edd375300dc814bb0a323d1fc879d247a1f7906080015b60405180910390a150505050565b61010160009054906101000a90046001600160a01b03166001600160a01b031663fc2a5b1d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bf91906156f9565b60fb80546001600160a01b0319166001600160a01b0392831617905561010154604080516307dc0d1d60e41b815290519190921691637dc0d1d09160048083019260209291908290030181865afa158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4291906156f9565b60fc80546001600160a01b0319166001600160a01b0392831617905561010154604080516318897bb760e01b8152905191909216916318897bb79160048083019260209291908290030181865afa158015610aa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac591906156f9565b60fd80546001600160a01b0319166001600160a01b03928316179055610101546040805163fbfa77cf60e01b81529051919092169163fbfa77cf9160048083019260209291908290030181865afa158015610b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4891906156f9565b60fe80546001600160a01b0319166001600160a01b0392909216919091179055565b610b72612e08565b600260ff548111610b955760405162461bcd60e51b81526004016107bb90615716565b6101015460405163471b4d7560e01b8152600481018690526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015610be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c059190615739565b9050610c148160a00151612e61565b60008082516002811115610c2a57610c2a6157da565b14610c36576001610c39565b60025b90506000610c5683602001516020015187878660a0015186612ad3565b90506000610c8e88856020015160fb60009054906101000a90046001600160a01b031687606001518860800151878a60000151612e9d565b9050610c9f8460400151898361338f565b5050505050610cad60018055565b505050565b610cba612dae565b6001600160a01b03821615801590610cda57506001600160a01b03811615155b610d125760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107bb565b61010180546001600160a01b038481166001600160a01b0319928316811790935561010280549185169190921681179091556040805192835260208301919091527f41fe2135e07f51f107aa1df22b2d51b5b6328f3a324fbfc555699785941adb59910160405180910390a15050565b610d8a612e08565b600260ff548111610dad5760405162461bcd60e51b81526004016107bb90615716565b6101015460405163315896b560e11b815260048101879052602481018690526000916001600160a01b0316906362b12d6a90604401608060405180830381865afa158015610dff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2391906157f0565b9050610e328160400151612e61565b806060015115610e735760405162461bcd60e51b815260206004820152600c60248201526b616c7265616479206578656360a01b60448201526064016107bb565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee3919061568b565b90506000610f01826000015160200151878786604001516002612ad3565b90506000610f2583602001518385600001516080015186600001516060015161347a565b610101546040516368a5479360e11b8152600481018c9052602481018b9052600160448201529192506001600160a01b03169063d14a8f2690606401600060405180830381600087803b158015610f7b57600080fd5b505af1158015610f8f573d6000803e3d6000fd5b505060fb548651610fb693506001600160a01b0390911691508b9085908790600087613555565b604080518a8152602081018a905260018183015290517f28cf3bfcf594f6c4e9da1e79297930dbd971dcae2e08a19857abc14e759e94019181900360600190a161100984602001518a8a60016000613ce3565b505050505061101760018055565b50505050565b611025612dae565b61102f6000613dfb565b565b61010154604051633a02776f60e11b81526004810184905260009182916001600160a01b0390911690637404eede9060240161012060405180830381865afa158015611081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a5919061568b565b905080602001516000036110bd5760009150506113ab565b60006110df82602001518584600001516080015185600001516060015161347a565b82516080810151604090910151919250600091670de0b6b3a76400009161110591615886565b61110f91906158bb565b60fb5484516020810151606090910151604051637325d71160e01b8152600481018b90526024810192909252604482018490521515606482015291925060009182916001600160a01b031690637325d711906084016040805180830381865afa158015611180573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a491906158cf565b91509150600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8a88600001516020015189602001518a60000151604001518b60000151608001518c60000151606001516040518763ffffffff1660e01b815260040161123e969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f91906158f3565b865160c00151909150600090600190156112b6578751606001516112aa57875160c0015183106112b3565b875160c0015183115b90505b8080156112d357506112d3838b60018b6000015160600151613e14565b1561130057610104548851604001516103e8916112ef91615886565b6112f991906158bb565b915061138d565b60fb548851602001516040516341b51a0d60e11b815260048101919091526103e8916001600160a01b03169063836a341a90602401602060405180830381865afa158015611352573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137691906158f3565b6113809088615886565b61138a91906158bb565b91505b8751604001516113a09088868886613eb0565b985050505050505050505b92915050565b6113b9612dae565b6103e881610104546113cb919061590c565b106113d557600080fd5b61010a80546001600160a01b0319166001600160a01b0384169081179091556101098290556040518281527f9241e21d4fa6dd55661c8694538bfc11a7d44d81d5766840312d2513f55fa67d9060200160405180910390a25050565b60c95433906001600160a01b0316811461149f5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016107bb565b6114a881613dfb565b50565b6114b3612dae565b6103e8841080156114c557506103e883105b6114ce57600080fd5b61010484905560ff8190556101058390556101008290556040805185815260208101859052908101839052606081018290527fe33eb1ee60efac814379b14a1d72ec5d666301d3264613e9d3f4ad9ef38b094690608001610939565b611532612e08565b600260ff5481116115555760405162461bcd60e51b81526004016107bb90615716565b6101015460405163471b4d7560e01b8152600481018490526000916001600160a01b03169063471b4d759060240161018060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c59190615739565b90506115d8816020015160000151612a8e565b80516115e5906000613f10565b61010154610102546020830151805160409182015191516352f950a960e11b81526001600160a01b039485169463a5f2a152946116289491169291600401615924565b600060405180830381600087803b15801561164257600080fd5b505af1158015611656573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018790526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b1580156116a157600080fd5b505af11580156116b5573d6000803e3d6000fd5b505050507f1dbfda3a6640539c3fac591e271a7b4ccd445cf9bc2b951e58abde22dfe73f53836040516116ea91815260200190565b60405180910390a150506114a860018055565b6000611707612e08565b6103e8831061171557600080fd5b60006103e86117248587615886565b61172e91906158bb565b9050600061173c828761590c565b9050600061174a8388615948565b905061175a600089848489613f71565b935050505061176860018055565b949350505050565b60fb5461010554600091611794916001600160a01b03909116908790878787614108565b95945050505050565b60006117a7612e08565b600260ff5481116117ca5760405162461bcd60e51b81526004016107bb90615716565b610101546040516346cb95c960e11b8152600481018790526000916001600160a01b031690638d972b9290602401602060405180830381865afa158015611815573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183991906158f3565b61010154604051633a02776f60e11b8152600481018990529192506000916001600160a01b0390911690637404eede9060240161012060405180830381865afa15801561188a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ae919061568b565b90506118b986614215565b8051516118c590612a8e565b6118d2610106548661424f565b6118dc868361590c565b81516040015190925082111561191e5760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107bb565b805160400151821461195f5760fb548151602081015160409091015161195f926001600160a01b03169190611954908690615948565b8451608001516142a8565b61010154604080516080810182528881526001600160a01b0388811660208301908152600083850181815260608501828152955162c9f2ed60e81b8152600481018f905294516024860152915183166044850152905160648401529251151560848301529192919091169063c9f2ed009060a4016020604051808303816000875af11580156119f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1691906158f3565b6040805189815242602082015291925082918a917f7695d3ca62416d30d27e9fac1080c5322b164e257e8151db3b139aec5d81605e910160405180910390a39350505050611a6360018055565b9392505050565b600054610100900460ff1615808015611a8a5750600054600160ff909116105b80611aa45750303b158015611aa4575060005460ff166001145b611b075760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016107bb565b6000805460ff191660011790558015611b2a576000805461ff0019166101001790555b611b3261435c565b611b3a61438b565b611b4384613dfb565b6001600160a01b03831615801590611b6357506001600160a01b03821615155b8015611b7757506001600160a01b03841615155b611baf5760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107bb565b61010180546001600160a01b038086166001600160a01b0319928316179092556101028054928516929091169190911790556032610104556103cf610105556601c6bf5263400061010655600061010b5562030d4061010855655af3107a4000610107556014610100558015611017576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610939565b611c63612e08565b600260ff548111611c865760405162461bcd60e51b81526004016107bb90615716565b6000846003811115611c9a57611c9a6157da565b03611cd35760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107bb565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015611d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d43919061568b565b9050611d528160400151612e61565b60408101516001866003811115611d6b57611d6b6157da565b03611d74575060005b6000611d8c8360000151602001518787856001612ad3565b905060006001886003811115611da457611da46157da565b03611ee85760fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8a86600001516020015187602001518860000151604001518960000151608001518a60000151606001516040518763ffffffff1660e01b8152600401611e3d969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa158015611e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7e91906158f3565b845160c0015190915015611ee357835160600151611ea357835160c001518110611eac565b835160c0015181115b611ee35760405162461bcd60e51b81526020600482015260086024820152671cdb08199a5c9cdd60c21b60448201526064016107bb565b611f8f565b6002886003811115611efc57611efc6157da565b03611f4d57611f2084602001518560000151608001518660000151606001516143ba565b845160a0015190915015611ee357835160a0810151606090910151611f4691839161441c565b9050611f8f565b835160c00151611f875760405162461bcd60e51b81526020600482015260056024820152641b9bc81cdb60da1b60448201526064016107bb565b50825160c001515b611fa381838a876000015160600151613e14565b611fdb5760405162461bcd60e51b81526020600482015260096024820152680dcdee840a4cac2c6d60bb1b60448201526064016107bb565b60fb54845160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916120139160040190815260200190565b602060405180830381865afa158015612030573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612054919061595f565b80156120725750600188600381111561206f5761206f6157da565b14155b1561207b578091505b600061209d85602001518487600001516080015188600001516060015161347a565b60fb548651604001519192506120c6916001600160a01b03909116908c90869089908e87613555565b8451516120d8908b600060018d613ce3565b50505050505061101760018055565b6101015460405163471b4d7560e01b8152600481018890526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015612133573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121579190615739565b905061216a816020015160000151612a8e565b8051612177906000613f10565b83156121a15761219281602001518787878560000151614447565b60608101849052608081018490525b82156121b357602081015160a0018390525b81156121c557602081015160c0018290525b60fb546020820151606083015160808401516121ec936001600160a01b03169291906144cd565b61010154604051631e34099d60e01b815260048101899052602481018690526044810186905260648101859052608481018490526001600160a01b0390911690631e34099d9060a401600060405180830381600087803b15801561224f57600080fd5b505af1158015612263573d6000803e3d6000fd5b5050604080518a815260208101889052908101869052606081018590527fed9036017ec7fc31a1ca97298d80b8219039778a809afd38dc6480cea3964a4b925060800190506108c7565b6122b5612dae565b60c980546001600160a01b0383166001600160a01b031990911681179091556122e66097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000612328612e08565b612333876000613f10565b61234e6123453688900388018861597c565b8686868b614447565b61235b8787858686613f71565b905061236660018055565b9695505050505050565b612378612e08565b600260ff54811161239b5760405162461bcd60e51b81526004016107bb90615716565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa1580156123e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240b919061568b565b80515190915061241a90612a8e565b61242386614215565b8051608081015160409091015160009161243c91615886565b610101546040516346cb95c960e11b8152600481018b90529192506001600160a01b031690638d972b9290602401602060405180830381865afa158015612487573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ab91906158f3565b156124e55760405162461bcd60e51b815260206004820152600a6024820152697761697420636c6f736560b01b60448201526064016107bb565b6000612501836000015160200151878786604001516000612ad3565b9050600080881561268557600061252e86602001518588600001516080015189600001516060015161347a565b90506125406402540be4006009615a21565b81126125785760405162461bcd60e51b81526020600482015260076024820152661b585e08141b9b60ca1b60448201526064016107bb565b855160400151612589908c9061590c565b925061259583866158bb565b60fb548751602081015160609091015160405163369dd0b160e01b81526004810192909252602482018f9052151560448201529193506001600160a01b03169063369dd0b190606401602060405180830381865afa1580156125fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261f919061595f565b1561265e5760405162461bcd60e51b815260206004820152600f60248201526e10dbdb1b185d195c985b131a5b5a5d608a1b60448201526064016107bb565b610102546101015461267f916001600160a01b03908116913391168e6145a0565b50612923565b8451604001518a106126a95760405162461bcd60e51b81526004016107bb90615aa6565b8451604001516126ba908b90615948565b855160c0015190925015801590612745575060fb54855160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916127049160040190815260200190565b602060405180830381865afa158015612721573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612745919061595f565b1561278457612767856000015160c00151846003886000015160600151613e14565b156127845760405162461bcd60e51b81526004016107bb90615aa6565b61278e82856158bb565b9050600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8d886000015160200151896020015187878c60000151606001516040518763ffffffff1660e01b8152600401612816969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa158015612833573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285791906158f3565b905061286e81856001896000015160600151613e14565b1561288b5760405162461bcd60e51b81526004016107bb90615aa6565b61010160009054906101000a90046001600160a01b03166001600160a01b031663a5f2a15261010260009054906101000a90046001600160a01b03168860000151600001518e6040518463ffffffff1660e01b81526004016128ef93929190615924565b600060405180830381600087803b15801561290957600080fd5b505af115801561291d573d6000803e3d6000fd5b50505050505b60fb54855160200151612941916001600160a01b03169084846142a8565b610101546040516311ceca8960e11b8152600481018d9052602481018490526000604482018190526064820181905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b1580156129a457600080fd5b505af11580156129b8573d6000803e3d6000fd5b505050506000670de0b6b3a764000082846129d39190615886565b6129dd91906158bb565b6129ef670de0b6b3a7640000876158bb565b6129f99190615948565b60fb5487516020810151606090910151929350612a28926001600160a01b03909216918e9085908f60006145f8565b604080518d8152602081018d90528b151581830152606081018590526080810184905290517fb58ece2937681ab71ee2a4257af71abb8d43386650f2fd177ee49164f8a0a4ca9181900360a00190a150505050505050612a8760018055565b5050505050565b6001600160a01b03811633146114a85760405162461bcd60e51b815260206004820152600a6024820152693737ba103a3930b232b960b11b60448201526064016107bb565b6000806002836002811115612aea57612aea6157da565b14612c555760fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b0392831692638cfd7c8792169062e9f38b90602401602060405180830381865afa158015612b41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6591906158f3565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612bae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd2919061595f565b89898960008a6002811115612be957612be96157da565b146040518763ffffffff1660e01b8152600401612c0b96959493929190615b82565b6020604051808303816000875af1158015612c2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4e91906158f3565b9050612da1565b60fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b039283169263815f4aed92169062e9f38b90602401602060405180830381865afa158015612ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccb91906158f3565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612d14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d38919061595f565b8989896040518663ffffffff1660e01b8152600401612d5b959493929190615bbe565b6020604051808303816000875af1158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e91906158f3565b90505b6000811161236657600080fd5b6097546001600160a01b0316331461102f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bb565b600260015403612e5a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107bb565b6002600155565b806000036114a85760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195e1a5cdd60ba1b60448201526064016107bb565b600080670de0b6b3a764000088608001518960400151612ebd9190615886565b612ec791906158bb565b9050612ee28785610105548b60200151858d60600151614108565b9350600080612ef6898b8a8a8a888b6146eb565b90925090506000856002811115612f0f57612f0f6157da565b148015612f1a575081155b156130355761010154610102548b516040808e015190516352f950a960e11b81526001600160a01b039485169463a5f2a15294612f5e949116929091600401615924565b600060405180830381600087803b158015612f7857600080fd5b505af1158015612f8c573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018f90526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b158015612fd757600080fd5b505af1158015612feb573d6000803e3d6000fd5b5050604080518e8152600060208201527f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def648935001905060405180910390a160009350505050613384565b80826130545760405162461bcd60e51b81526004016107bb9190615c1e565b506000620186a08a6001600160a01b0316638251135b8d602001516040518263ffffffff1660e01b815260040161308d91815260200190565b602060405180830381865afa1580156130aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ce91906158f3565b6130d89086615886565b6130e291906158bb565b9050808b6040018181516130f69190615948565b90525060808b015160408c0151670de0b6b3a76400009161311691615886565b61312091906158bb565b935061313381858d600001516001614987565b61314f8a8c602001518d60400151878f606001516001806145f8565b60408051606081019091528b8152600090602081016001896002811115613178576131786157da565b03613183578b613185565b895b81526020016000815250905061010160009054906101000a90046001600160a01b03166001600160a01b0316638611e17e8e836040518363ffffffff1660e01b81526004016131d5929190615cbf565b600060405180830381600087803b1580156131ef57600080fd5b505af1158015613203573d6000803e3d6000fd5b505050508a6001600160a01b0316636ada93dd8e8e602001518f606001516040518463ffffffff1660e01b81526004016132529392919092835260208301919091521515604082015260600190565b600060405180830381600087803b15801561326c57600080fd5b505af1158015613280573d6000803e3d6000fd5b5050505061010160009054906101000a90046001600160a01b03166001600160a01b031663d07abd598e6040518263ffffffff1660e01b81526004016132c891815260200190565b600060405180830381600087803b1580156132e257600080fd5b505af11580156132f6573d6000803e3d6000fd5b505050507f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def6488d60016040516133379291909182521515602082015260400190565b60405180910390a17f09c087e430ee6913868eafe26e6d9da87f95984c61bde74e50e28ecd09da890a8d828460405161337293929190615cd4565b60405180910390a16001955050505050505b979650505050505050565b61010b546001600160a01b0384163b1561346557610107546133b1908261590c565b6101085460405163b2a11f8560e01b81526004810186905284151560248201529192506000916001600160a01b0387169163b2a11f8591604401600060405180830381600088803b15801561340557600080fd5b5087f193505050508015613417575060015b15613420575060015b604080516001600160a01b038716815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a1505b80156110175761101781614aef565b60018055565b60008061348d6402540be4006009615a21565b9050600083156134dd576134a087614b77565b6402540be4006134af89614b77565b6134b889614b77565b6134c29190615cf8565b6134cc9190615a21565b6134d69190615d37565b905061351f565b6134e687614b77565b6402540be4006134f588614b77565b6134fe8a614b77565b6135089190615cf8565b6135129190615a21565b61351c9190615d37565b90505b670de0b6b3a76400006135328683615a21565b61353c9190615d37565b905081811361354b5780613384565b5095945050505050565b6135876040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b84516080015160009061359a9086615886565b905060006135b0670de0b6b3a7640000836158bb565b90508560018660038111156135c7576135c76157da565b03613607576103e861010454886135de9190615886565b6135e891906158bb565b60808501526135f687614bbf565b6136009082615948565b90506136aa565b8751602001516040516341b51a0d60e11b81526004810191909152670de0b6b3a764000090620186a0906001600160a01b038e169063836a341a90602401602060405180830381865afa158015613662573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368691906158f3565b6136909086615886565b61369a91906158bb565b6136a491906158bb565b60808501525b87516020810151606090910151604051637325d71160e01b8152600481018d9052602481019290925260448201849052151560648201526001600160a01b038c1690637325d711906084016040805180830381865afa158015613711573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373591906158cf565b60408601819052602086018290526080860151613758928a928992909190613eb0565b60608501526080840151885151613773919084906000614987565b60808401516137829082615948565b9050836060015181111561390d5760608401511561380d57610101546101025489515160608701516040516352f950a960e11b81526001600160a01b039485169463a5f2a152946137da949116929091600401615924565b600060405180830381600087803b1580156137f457600080fd5b505af1158015613808573d6000803e3d6000fd5b505050505b600084606001518261381f9190615948565b610101546101025460fe546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a1529361385f9381169216908690600401615924565b600060405180830381600087803b15801561387957600080fd5b505af115801561388d573d6000803e3d6000fd5b505060fe548b515160405163ceb5caa560e01b81526001600160a01b0391821660048201526024810186905260006044820181905260648201529116925063ceb5caa59150608401600060405180830381600087803b1580156138ef57600080fd5b505af1158015613903573d6000803e3d6000fd5b5050505050613a06565b600081856060015161391f9190615948565b905080156139905760fe5489515160405163496d1af960e11b81526001600160a01b039182166004820152602481018490529116906392da35f290604401600060405180830381600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b505050505b8115613a045761010154610102548a51516040516352f950a960e11b81526001600160a01b039384169363a5f2a152936139d1939116918790600401615924565b600060405180830381600087803b1580156139eb57600080fd5b505af11580156139ff573d6000803e3d6000fd5b505050505b505b875160400151600090613a1a908990615948565b9050826000829003613b8a576101015460405163348c68ad60e11b8152600481018e90526001600160a01b0390911690636918d15a90602401600060405180830381600087803b158015613a6d57600080fd5b505af1158015613a81573d6000803e3d6000fd5b505050508c6001600160a01b031663b8d040e48d6040518263ffffffff1660e01b8152600401613ab391815260200190565b600060405180830381600087803b158015613acd57600080fd5b505af1158015613ae1573d6000803e3d6000fd5b505061010154604051631eb17e1b60e21b81526001600160a01b039091169250637ac5f86c9150613b1a908f9060040190815260200190565b600060405180830381600087803b158015613b3457600080fd5b505af1158015613b48573d6000803e3d6000fd5b505050507fbe2b332e8e34afe0840746913f0e88f88fbbda69b3c05c49a197de3f559412778c604051613b7d91815260200190565b60405180910390a1613c5f565b895160800151670de0b6b3a764000090613ba49084615886565b613bae91906158bb565b8a516080810151604090910151670de0b6b3a764000091613bce91615886565b613bd891906158bb565b613be29190615948565b610101546040516311ceca8960e11b8152600481018f9052602481018590526000604482018190526064820152600160848201529192506001600160a01b03169063239d95129060a401600060405180830381600087803b158015613c4657600080fd5b505af1158015613c5a573d6000803e3d6000fd5b505050505b613c7f8d8b60000151602001518b848e60000151606001516000806145f8565b7f24b27bc2a65d006b06d5ee8450abfa71760f2aac880fcf5555af1e692cfaf5398c8c8b89602001518a604001518b608001518c606001518f604051613ccc989796959493929190615d79565b60405180910390a150505050505050505050505050565b60006001600160a01b0386163b15613dbf576101075461010654613d07919061590c565b90506000866001600160a01b031663657409e261010854888888886040518663ffffffff1660e01b8152600401613d419493929190615db6565b600060405180830381600088803b158015613d5b57600080fd5b5087f193505050508015613d6d575060015b15613d76575060015b604080516001600160a01b038916815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a150613dc5565b50610106545b6000826003811115613dd957613dd96157da565b148015613de557508015155b15613df357613df381614aef565b505050505050565b60c980546001600160a01b03191690556114a881614c7b565b60008115613e66576002836003811115613e3057613e306157da565b1480613e4d57506000836003811115613e4b57613e4b6157da565b145b15613e5c575083831015611768565b5083831115611768565b6002836003811115613e7a57613e7a6157da565b1480613e9757506000836003811115613e9557613e956157da565b145b15613ea6575083831115611768565b5083831015611768565b60008083856402540be400613ec5898b615a21565b613ecf9190615d37565b613ed9908a615dd9565b613ee39190615cf8565b613eed9190615cf8565b9050613ef98382615cf8565b905060008113612366576000979650505050505050565b806002811115613f2257613f226157da565b826002811115613f3457613f346157da565b03613f6d5760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107bb565b5050565b6000613f88613f8360208701876154e7565b612a8e565b613f9561010b548361424f565b60fb54613fbb906001600160a01b0316613fb43688900388018861597c565b86866144cd565b6101025461010154613fe0916001600160a01b039081169133911660408901356145a0565b60006040518060c00160405280886002811115613fff57613fff6157da565b81526020016140133689900389018961597c565b8152602001846001600160a01b03168152602001868152602001858152602001428152509050600061405f600088602001356101036000815461405590615e1a565b9182905550614ccd565b6101015460405163030dfab360e61b81529192506001600160a01b03169063c37eacc0906140939084908690600401615e98565b600060405180830381600087803b1580156140ad57600080fd5b505af11580156140c1573d6000803e3d6000fd5b50505050807fc815d98967a87feaaa8e57736b69b57611867c43e87d7c0cd7ba5edf3f13c528836040516140f59190615ead565b60405180910390a2979650505050505050565b60405163a1d54e9b60e01b81526004810184905260009081906001600160a01b0389169063a1d54e9b90602401602060405180830381865afa158015614152573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061417691906158f3565b9050600061418688888487614d10565b604051633f54af9960e11b815260048101829052602481018890528515156044820152606481018790529091506001600160a01b038a1690637ea95f3290608401602060405180830381865afa1580156141e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061420891906158f3565b9998505050505050505050565b806000036114a85760405162461bcd60e51b8152602060048201526007602482015266076616c75655f360cc1b60448201526064016107bb565b6001600160a01b0381161561426f576101075461426c908361590c565b91505b813414613f6d5760405162461bcd60e51b8152602060048201526007602482015266666565206d697360c81b60448201526064016107bb565b60405163a833064560e01b81526004810184905260248101839052604481018290526000906001600160a01b0386169063a833064590606401602060405180830381865afa1580156142fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614322919061595f565b905080612a875760405162461bcd60e51b81526020600482015260086024820152676f75742073697a6560c01b60448201526064016107bb565b600054610100900460ff166143835760405162461bcd60e51b81526004016107bb90615ebc565b61102f614d70565b600054610100900460ff166143b25760405162461bcd60e51b81526004016107bb90615ebc565b61102f614da3565b60008083670de0b6b3a76400006143d2600988615886565b6143dc9190615886565b6143e691906158bb565b90508215614400576143f8818661590c565b915050611a63565b80851015614412576000915050611a63565b6143f88186615948565b6000811561443a578284106144315782614433565b835b9050611a63565b8284116144315782614433565b600061445b86602001518686600080612ad3565b9050600061448560fb60009054906101000a90046001600160a01b03168884876101055488614dca565b9050806144c45760405162461bcd60e51b815260206004820152600d60248201526c1a5b1b1959d85b081b1a5b5a5d609a1b60448201526064016107bb565b50505050505050565b6144e5848460200151856040015186608001516142a8565b60008360a00151600014806145125750836060015161450a57818460a0015110614512565b828460a00151115b905060008460c00151600014806145415750846060015161453957838560c0015111614541565b828560c00151105b905060008385101580156145555750600084115b801561455e5750825b80156145675750815b9050806144c45760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107bb565b611017846323b872dd60e01b8585856040516024016145c193929190615924565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614e72565b6040516310787e2f60e11b81526004810187905260248101869052831515604482015282151560648201526001600160a01b038816906320f0fc5e90608401600060405180830381600087803b15801561465157600080fd5b505af1158015614665573d6000803e3d6000fd5b50505050836000146144c457604051631ae6a88f60e31b81526004810187905260248101859052831515604482015281151560648201526001600160a01b0388169063d735447890608401600060405180830381600087803b1580156146ca57600080fd5b505af11580156146de573d6000803e3d6000fd5b5050505050505050505050565b600060606147008787878b6060015187614f47565b61473457505060408051808201909152600f81526e1c1c9a58d9481bdd5d081b1a5b5a5d608a1b602082015260009061497b565b60208801516040808a015160608b0151915163369dd0b160e01b815260048101939093526024830152151560448201526001600160a01b038a169063369dd0b190606401602060405180830381865afa158015614795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147b9919061595f565b156147ee57505060408051808201909152600f81526e10dbdb1b185d195c985b131a5b5a5d608a1b602082015260009061497b565b6020880151606089015160405163ec8b6fa160e01b8152600481019290925260248201869052151560448201526001600160a01b038a169063ec8b6fa190606401602060405180830381865afa15801561484c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614870919061595f565b6148a257505060408051808201909152600d81526c125b9d195c995cdd131a5b5a5d609a1b602082015260009061497b565b60008360028111156148b6576148b66157da565b146149665760208801516060890151604051632ff8ac0760e21b81526001600160a01b038c169263bfe2b01c926148f69288918d918c9190600401615f07565b602060405180830381865afa158015614913573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614937919061595f565b61496657505060408051808201909152600a8152691bdd5d0814dc1c99585960b21b602082015260009061497b565b50506040805160208101909152600081526001905b97509795505050505050565b610101546101025460fd546040516352f950a960e11b81526001600160a01b039384169363a5f2a152936149c693908216929116908990600401615924565b600060405180830381600087803b1580156149e057600080fd5b505af11580156149f4573d6000803e3d6000fd5b505050508015614a765760fd5460405163031708bd60e11b81526001600160a01b03848116600483015233602483015260448201879052606482018690529091169063062e117a90608401600060405180830381600087803b158015614a5957600080fd5b505af1158015614a6d573d6000803e3d6000fd5b50505050611017565b60fd546040516312f8aacd60e21b81526001600160a01b038481166004830152336024830152604482018790526064820186905290911690634be2ab3490608401600060405180830381600087803b158015614ad157600080fd5b505af1158015614ae5573d6000803e3d6000fd5b5050505050505050565b604051600090339083908381818185875af1925050503d8060008114614b31576040519150601f19603f3d011682016040523d82523d6000602084013e614b36565b606091505b5050905080613f6d5760405162461bcd60e51b815260206004820152600d60248201526c1d1c985b9cd9995c8819985a5b609a1b60448201526064016107bb565b60006001600160ff1b03821115614bbb5760405162461bcd60e51b81526020600482015260086024820152676f766572666c6f7760c01b60448201526064016107bb565b5090565b61010a5460009081906001600160a01b031615801590614be157506101095415155b156113ab576103e86101095484614bf89190615886565b614c0291906158bb565b610101546101025461010a546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a15293614c439381169216908690600401615924565b600060405180830381600087803b158015614c5d57600080fd5b505af1158015614c71573d6000803e3d6000fd5b5050505092915050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600062ffffff83108015614ce757506001600160e01b0382105b614d035760405162461bcd60e51b81526004016107bb90615aa6565b5060e09190911b17919050565b600080614d1f856103e8615948565b905060006103e88281614d32888b615886565b614d3c91906158bb565b614d469190615886565b614d5091906158bb565b905083614d6657614d618188615948565b613384565b613384818861590c565b600054610100900460ff16614d975760405162461bcd60e51b81526004016107bb90615ebc565b6065805460ff19169055565b600054610100900460ff166134745760405162461bcd60e51b81526004016107bb90615ebc565b600080670de0b6b3a764000087608001518860400151614dea9190615886565b614df491906158bb565b9050614e0c8887868a60200151858c60600151614108565b9550866060015115614e45576001836002811115614e2c57614e2c6157da565b03614e3b575050838310612366565b5050838311612366565b6001836002811115614e5957614e596157da565b03614e68575050838311612366565b5050838310612366565b6000614ec7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614fd89092919063ffffffff16565b9050805160001480614ee8575080806020019051810190614ee8919061595f565b610cad5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107bb565b600080826002811115614f5c57614f5c6157da565b03614f7857848410158015614f715750858411155b9050611794565b8215614fab576001826002811115614f9257614f926157da565b03614fa1575083831115611794565b5084831015611794565b6001826002811115614fbf57614fbf6157da565b03614fce575084831015611794565b5083831115611794565b6060611768848460008585600080866001600160a01b03168587604051614fff9190615f39565b60006040518083038185875af1925050503d806000811461503c576040519150601f19603f3d011682016040523d82523d6000602084013e615041565b606091505b509150915061338487838387606083156150bc5782516000036150b5576001600160a01b0385163b6150b55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107bb565b5081611768565b61176883838151156150d15781518083602001fd5b8060405162461bcd60e51b81526004016107bb9190615c1e565b60008083601f8401126150fd57600080fd5b5081356001600160401b0381111561511457600080fd5b6020830191508360208260051b850101111561512f57600080fd5b9250929050565b60008060008060006080868803121561514e57600080fd5b85359450602086013593506040860135925060608601356001600160401b0381111561517957600080fd5b615185888289016150eb565b969995985093965092949392505050565b600080600080608085870312156151ac57600080fd5b5050823594602084013594506040840135936060013592509050565b6000806000604084860312156151dd57600080fd5b8335925060208401356001600160401b038111156151fa57600080fd5b615206868287016150eb565b9497909650939450505050565b6001600160a01b03811681146114a857600080fd5b6000806040838503121561523b57600080fd5b823561524681615213565b9150602083013561525681615213565b809150509250929050565b6000806000806060858703121561527757600080fd5b843593506020850135925060408501356001600160401b0381111561529b57600080fd5b6152a7878288016150eb565b95989497509550505050565b600080604083850312156152c657600080fd5b50508035926020909101359150565b600080604083850312156152e857600080fd5b82356152f381615213565b946020939093013593505050565b60006020828403121561531357600080fd5b5035919050565b600060e0828403121561532c57600080fd5b50919050565b600080600080610140858703121561534957600080fd5b615353868661531a565b935060e08501359250610100850135915061012085013561537381615213565b939692955090935050565b80151581146114a857600080fd5b600080600080608085870312156153a257600080fd5b84359350602085013592506040850135915060608501356153738161537e565b6000806000606084860312156153d757600080fd5b833592506020840135915060408401356153f081615213565b809150509250925092565b60008060006060848603121561541057600080fd5b833561541b81615213565b9250602084013561542b81615213565b915060408401356153f081615213565b6000806000806060858703121561545157600080fd5b8435935060208501356004811061546757600080fd5b925060408501356001600160401b0381111561529b57600080fd5b60008060008060008060a0878903121561549b57600080fd5b8635955060208701356001600160401b038111156154b857600080fd5b6154c489828a016150eb565b979a90995096976040810135976060820135975060809091013595509350505050565b6000602082840312156154f957600080fd5b8135611a6381615213565b600381106114a857600080fd5b600080600080600080610160878903121561552b57600080fd5b863561553681615504565b9550615545886020890161531a565b94506101008701356001600160401b0381111561556157600080fd5b61556d89828a016150eb565b909550935050610120870135915061014087013561558a81615213565b809150509295509295509295565b6000806000806000608086880312156155b057600080fd5b853594506020860135935060408601356155c98161537e565b925060608601356001600160401b0381111561517957600080fd5b600060e082840312156155f657600080fd5b60405160e081018181106001600160401b038211171561562657634e487b7160e01b600052604160045260246000fd5b8060405250809150825161563981615213565b808252506020830151602082015260408301516040820152606083015161565f8161537e565b806060830152506080830151608082015260a083015160a082015260c083015160c08201525092915050565b6000610120828403121561569e57600080fd5b604051606081018181106001600160401b03821117156156ce57634e487b7160e01b600052604160045260246000fd5b6040526156db84846155e4565b815260e0830151602082015261010090920151604083015250919050565b60006020828403121561570b57600080fd5b8151611a6381615213565b60208082526009908201526839bbb4b1b41037b33360b91b604082015260600190565b6000610180828403121561574c57600080fd5b60405160c081018181106001600160401b038211171561577c57634e487b7160e01b600052604160045260246000fd5b604052825161578a81615504565b815261579984602085016155e4565b60208201526101008301516157ad81615213565b6040820152610120830151606082015261014083015160808201526101609092015160a083015250919050565b634e487b7160e01b600052602160045260246000fd5b60006080828403121561580257600080fd5b604051608081018181106001600160401b038211171561583257634e487b7160e01b600052604160045260246000fd5b60405282518152602083015161584781615213565b60208201526040838101519082015260608301516158648161537e565b60608201529392505050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156158a0576158a0615870565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826158ca576158ca6158a5565b500490565b600080604083850312156158e257600080fd5b505080516020909101519092909150565b60006020828403121561590557600080fd5b5051919050565b6000821982111561591f5761591f615870565b500190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60008282101561595a5761595a615870565b500390565b60006020828403121561597157600080fd5b8151611a638161537e565b600060e0828403121561598e57600080fd5b60405160e081018181106001600160401b03821117156159be57634e487b7160e01b600052604160045260246000fd5b60405282356159cc81615213565b80825250602083013560208201526040830135604082015260608301356159f28161537e565b806060830152506080830135608082015260a083013560a082015260c083013560c08201528091505092915050565b60006001600160ff1b0381841382841380821686840486111615615a4757615a47615870565b600160ff1b6000871282811687830589121615615a6657615a66615870565b60008712925087820587128484161615615a8257615a82615870565b87850587128184161615615a9857615a98615870565b505050929093029392505050565b6020808252600890820152671bdd5d08189bdb9960c21b604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006020808501808196508560051b810191508460005b87811015615b755782840389528135601e19883603018112615b2c57600080fd5b870185810190356001600160401b03811115615b4757600080fd5b803603821315615b5657600080fd5b615b61868284615ac8565b9a87019a9550505090840190600101615b0b565b5091979650505050505050565b868152851515602082015260a060408201526000615ba460a083018688615af1565b606083019490945250901515608090910152949350505050565b8581528415156020820152608060408201526000615be0608083018587615af1565b90508260608301529695505050505050565b60005b83811015615c0d578181015183820152602001615bf5565b838111156110175750506000910152565b6020815260008251806020840152615c3d816040850160208701615bf2565b601f01601f19169190910160400192915050565b80516001600160a01b0316825260208082015190830152604080820151908301526060808201511515908301526080808201519083015260a0818101519083015260c090810151910152565b615ca8828251615c51565b602081015160e08301526040015161010090910152565b8281526101408101611a636020830184615c9d565b8381526101608101615ce96020830185615c9d565b82610140830152949350505050565b60008083128015600160ff1b850184121615615d1657615d16615870565b6001600160ff1b0384018313811615615d3157615d31615870565b50500390565b600082615d4657615d466158a5565b600160ff1b821460001984141615615d6057615d60615870565b500590565b60048110615d7557615d756157da565b9052565b6000610100820190508982528860208301528760408301528660608301528560808301528460a08301528360c083015261420860e0830184615d65565b848152602081018490528215156040820152608081016117946060830184615d65565b600080821280156001600160ff1b0384900385131615615dfb57615dfb615870565b600160ff1b8390038412811615615e1457615e14615870565b50500190565b600060018201615e2c57615e2c615870565b5060010190565b60038110615d7557615d756157da565b615e4e828251615e33565b6020810151615e606020840182615c51565b5060408101516001600160a01b03166101008301526060810151610120830152608081015161014083015260a0015161016090910152565b8281526101a08101611a636020830184615e43565b61018081016113ab8284615e43565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101615f1b6020830187615e33565b84604083015283606083015282151560808301529695505050505050565b60008251615f4b818460208701615bf2565b919091019291505056fea26469706673582212207f1af6183e9090ee4f6b6f56f1d185f437f2721a64e30602e8eab33c4508eb6264736f6c634300080f0033
Deployed Bytecode
0x60806040526004361061023b5760003560e01c80637dc0d1d01161012e578063cc83bfd2116100ab578063f485ccf01161006f578063f485ccf01461064b578063f750704f14610662578063fbfa77cf14610675578063fc2a5b1d14610695578063fd77f87f146106b557600080fd5b8063cc83bfd2146105b6578063e30c3978146105d6578063efbc5fc0146105f4578063efcf0bd01461060b578063f2fde38b1461062b57600080fd5b8063a53fcde8116100f2578063a53fcde81461052c578063a5c34ba71461054c578063bb1c7c2a14610562578063c04398ee14610583578063c0c53b8b1461059657600080fd5b80637dc0d1d01461049b5780637ece45e8146104bb578063806762a0146104db5780638bc846c9146104fb5780638da5cb5b1461050e57600080fd5b80634c7d7d3f116101bc5780636bc81aa2116101805780636bc81aa21461041a578063715018a614610431578063725348901461044657806378250b631461046657806379ba50971461048657600080fd5b80634c7d7d3f1461039157806358d7bf80146103b25780635bd3e1c8146103c95780635c975abb146103e0578063615728f81461040357600080fd5b80631c4695f4116102035780631c4695f4146103055780631c7f6f4c1461031a57806324f746971461033a5780632bf6e0a514610351578063338b01331461037157600080fd5b806304c7ec71146102405780630845d69d1461026257806316b820911461028257806316fff074146102ac57806318897bb7146102e5575b600080fd5b34801561024c57600080fd5b5061026061025b366004615136565b6106d5565b005b34801561026e57600080fd5b5061026061027d366004615196565b6108d8565b34801561028e57600080fd5b5061029961010b5481565b6040519081526020015b60405180910390f35b3480156102b857600080fd5b50610101546102cd906001600160a01b031681565b6040516001600160a01b0390911681526020016102a3565b3480156102f157600080fd5b5060fd546102cd906001600160a01b031681565b34801561031157600080fd5b50610260610947565b34801561032657600080fd5b506102606103353660046151c8565b610b6a565b34801561034657600080fd5b506102996101085481565b34801561035d57600080fd5b5061026061036c366004615228565b610cb2565b34801561037d57600080fd5b5061026061038c366004615261565b610d82565b34801561039d57600080fd5b50610102546102cd906001600160a01b031681565b3480156103be57600080fd5b506102996101095481565b3480156103d557600080fd5b506102996101065481565b3480156103ec57600080fd5b5060655460ff1660405190151581526020016102a3565b34801561040f57600080fd5b506102996101045481565b34801561042657600080fd5b506102996101075481565b34801561043d57600080fd5b5061026061101d565b34801561045257600080fd5b506102996104613660046152b3565b611031565b34801561047257600080fd5b506102606104813660046152d5565b6113b1565b34801561049257600080fd5b50610260611431565b3480156104a757600080fd5b5060fc546102cd906001600160a01b031681565b3480156104c757600080fd5b506102606104d6366004615196565b6114ab565b3480156104e757600080fd5b506102606104f6366004615301565b61152a565b610299610509366004615332565b6116fd565b34801561051a57600080fd5b506097546001600160a01b03166102cd565b34801561053857600080fd5b5061029961054736600461538c565b611770565b34801561055857600080fd5b5061029960ff5481565b34801561056e57600080fd5b5061010a546102cd906001600160a01b031681565b6102996105913660046153c2565b61179d565b3480156105a257600080fd5b506102606105b13660046153fb565b611a6a565b3480156105c257600080fd5b506102606105d136600461543b565b611c5b565b3480156105e257600080fd5b5060c9546001600160a01b03166102cd565b34801561060057600080fd5b506102996101055481565b34801561061757600080fd5b50610260610626366004615482565b6120e7565b34801561063757600080fd5b506102606106463660046154e7565b6122ad565b34801561065757600080fd5b506102996101005481565b610299610670366004615511565b61231e565b34801561068157600080fd5b5060fe546102cd906001600160a01b031681565b3480156106a157600080fd5b5060fb546102cd906001600160a01b031681565b3480156106c157600080fd5b506102606106d0366004615598565b612370565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610721573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610745919061568b565b80515190915061075490612a8e565b6000610770826000015160200151858585604001516000612ad3565b905085156107c45781516060015161078a5780861061078e565b8086115b6107c45760405162461bcd60e51b8152602060048201526002602482015261074760f41b60448201526064015b60405180910390fd5b8415610811578151606001516107dc578085116107e0565b8085105b6108115760405162461bcd60e51b81526020600482015260026024820152611cdb60f21b60448201526064016107bb565b610101546040516311ceca8960e11b815260048101899052600060248201819052604482018990526064820188905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b15801561087457600080fd5b505af1158015610888573d6000803e3d6000fd5b5050604080518a8152602081018a90529081018890527f3fea1f17d88eda811ab87655f92885a6ec5fc9fd390aca775b9327f43ad00d77925060600190505b60405180910390a150505050505050565b6108e0612dae565b61010b8490556101068390556101078290556101088190556040805185815260208101859052908101839052606081018290527faac5f778cabbb5dc9b9bd42735e5edd375300dc814bb0a323d1fc879d247a1f7906080015b60405180910390a150505050565b61010160009054906101000a90046001600160a01b03166001600160a01b031663fc2a5b1d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bf91906156f9565b60fb80546001600160a01b0319166001600160a01b0392831617905561010154604080516307dc0d1d60e41b815290519190921691637dc0d1d09160048083019260209291908290030181865afa158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4291906156f9565b60fc80546001600160a01b0319166001600160a01b0392831617905561010154604080516318897bb760e01b8152905191909216916318897bb79160048083019260209291908290030181865afa158015610aa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac591906156f9565b60fd80546001600160a01b0319166001600160a01b03928316179055610101546040805163fbfa77cf60e01b81529051919092169163fbfa77cf9160048083019260209291908290030181865afa158015610b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4891906156f9565b60fe80546001600160a01b0319166001600160a01b0392909216919091179055565b610b72612e08565b600260ff548111610b955760405162461bcd60e51b81526004016107bb90615716565b6101015460405163471b4d7560e01b8152600481018690526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015610be1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c059190615739565b9050610c148160a00151612e61565b60008082516002811115610c2a57610c2a6157da565b14610c36576001610c39565b60025b90506000610c5683602001516020015187878660a0015186612ad3565b90506000610c8e88856020015160fb60009054906101000a90046001600160a01b031687606001518860800151878a60000151612e9d565b9050610c9f8460400151898361338f565b5050505050610cad60018055565b505050565b610cba612dae565b6001600160a01b03821615801590610cda57506001600160a01b03811615155b610d125760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107bb565b61010180546001600160a01b038481166001600160a01b0319928316811790935561010280549185169190921681179091556040805192835260208301919091527f41fe2135e07f51f107aa1df22b2d51b5b6328f3a324fbfc555699785941adb59910160405180910390a15050565b610d8a612e08565b600260ff548111610dad5760405162461bcd60e51b81526004016107bb90615716565b6101015460405163315896b560e11b815260048101879052602481018690526000916001600160a01b0316906362b12d6a90604401608060405180830381865afa158015610dff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2391906157f0565b9050610e328160400151612e61565b806060015115610e735760405162461bcd60e51b815260206004820152600c60248201526b616c7265616479206578656360a01b60448201526064016107bb565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee3919061568b565b90506000610f01826000015160200151878786604001516002612ad3565b90506000610f2583602001518385600001516080015186600001516060015161347a565b610101546040516368a5479360e11b8152600481018c9052602481018b9052600160448201529192506001600160a01b03169063d14a8f2690606401600060405180830381600087803b158015610f7b57600080fd5b505af1158015610f8f573d6000803e3d6000fd5b505060fb548651610fb693506001600160a01b0390911691508b9085908790600087613555565b604080518a8152602081018a905260018183015290517f28cf3bfcf594f6c4e9da1e79297930dbd971dcae2e08a19857abc14e759e94019181900360600190a161100984602001518a8a60016000613ce3565b505050505061101760018055565b50505050565b611025612dae565b61102f6000613dfb565b565b61010154604051633a02776f60e11b81526004810184905260009182916001600160a01b0390911690637404eede9060240161012060405180830381865afa158015611081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a5919061568b565b905080602001516000036110bd5760009150506113ab565b60006110df82602001518584600001516080015185600001516060015161347a565b82516080810151604090910151919250600091670de0b6b3a76400009161110591615886565b61110f91906158bb565b60fb5484516020810151606090910151604051637325d71160e01b8152600481018b90526024810192909252604482018490521515606482015291925060009182916001600160a01b031690637325d711906084016040805180830381865afa158015611180573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a491906158cf565b91509150600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8a88600001516020015189602001518a60000151604001518b60000151608001518c60000151606001516040518763ffffffff1660e01b815260040161123e969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa15801561125b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127f91906158f3565b865160c00151909150600090600190156112b6578751606001516112aa57875160c0015183106112b3565b875160c0015183115b90505b8080156112d357506112d3838b60018b6000015160600151613e14565b1561130057610104548851604001516103e8916112ef91615886565b6112f991906158bb565b915061138d565b60fb548851602001516040516341b51a0d60e11b815260048101919091526103e8916001600160a01b03169063836a341a90602401602060405180830381865afa158015611352573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137691906158f3565b6113809088615886565b61138a91906158bb565b91505b8751604001516113a09088868886613eb0565b985050505050505050505b92915050565b6113b9612dae565b6103e881610104546113cb919061590c565b106113d557600080fd5b61010a80546001600160a01b0319166001600160a01b0384169081179091556101098290556040518281527f9241e21d4fa6dd55661c8694538bfc11a7d44d81d5766840312d2513f55fa67d9060200160405180910390a25050565b60c95433906001600160a01b0316811461149f5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016107bb565b6114a881613dfb565b50565b6114b3612dae565b6103e8841080156114c557506103e883105b6114ce57600080fd5b61010484905560ff8190556101058390556101008290556040805185815260208101859052908101839052606081018290527fe33eb1ee60efac814379b14a1d72ec5d666301d3264613e9d3f4ad9ef38b094690608001610939565b611532612e08565b600260ff5481116115555760405162461bcd60e51b81526004016107bb90615716565b6101015460405163471b4d7560e01b8152600481018490526000916001600160a01b03169063471b4d759060240161018060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c59190615739565b90506115d8816020015160000151612a8e565b80516115e5906000613f10565b61010154610102546020830151805160409182015191516352f950a960e11b81526001600160a01b039485169463a5f2a152946116289491169291600401615924565b600060405180830381600087803b15801561164257600080fd5b505af1158015611656573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018790526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b1580156116a157600080fd5b505af11580156116b5573d6000803e3d6000fd5b505050507f1dbfda3a6640539c3fac591e271a7b4ccd445cf9bc2b951e58abde22dfe73f53836040516116ea91815260200190565b60405180910390a150506114a860018055565b6000611707612e08565b6103e8831061171557600080fd5b60006103e86117248587615886565b61172e91906158bb565b9050600061173c828761590c565b9050600061174a8388615948565b905061175a600089848489613f71565b935050505061176860018055565b949350505050565b60fb5461010554600091611794916001600160a01b03909116908790878787614108565b95945050505050565b60006117a7612e08565b600260ff5481116117ca5760405162461bcd60e51b81526004016107bb90615716565b610101546040516346cb95c960e11b8152600481018790526000916001600160a01b031690638d972b9290602401602060405180830381865afa158015611815573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183991906158f3565b61010154604051633a02776f60e11b8152600481018990529192506000916001600160a01b0390911690637404eede9060240161012060405180830381865afa15801561188a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ae919061568b565b90506118b986614215565b8051516118c590612a8e565b6118d2610106548661424f565b6118dc868361590c565b81516040015190925082111561191e5760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107bb565b805160400151821461195f5760fb548151602081015160409091015161195f926001600160a01b03169190611954908690615948565b8451608001516142a8565b61010154604080516080810182528881526001600160a01b0388811660208301908152600083850181815260608501828152955162c9f2ed60e81b8152600481018f905294516024860152915183166044850152905160648401529251151560848301529192919091169063c9f2ed009060a4016020604051808303816000875af11580156119f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a1691906158f3565b6040805189815242602082015291925082918a917f7695d3ca62416d30d27e9fac1080c5322b164e257e8151db3b139aec5d81605e910160405180910390a39350505050611a6360018055565b9392505050565b600054610100900460ff1615808015611a8a5750600054600160ff909116105b80611aa45750303b158015611aa4575060005460ff166001145b611b075760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016107bb565b6000805460ff191660011790558015611b2a576000805461ff0019166101001790555b611b3261435c565b611b3a61438b565b611b4384613dfb565b6001600160a01b03831615801590611b6357506001600160a01b03821615155b8015611b7757506001600160a01b03841615155b611baf5760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107bb565b61010180546001600160a01b038086166001600160a01b0319928316179092556101028054928516929091169190911790556032610104556103cf610105556601c6bf5263400061010655600061010b5562030d4061010855655af3107a4000610107556014610100558015611017576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610939565b611c63612e08565b600260ff548111611c865760405162461bcd60e51b81526004016107bb90615716565b6000846003811115611c9a57611c9a6157da565b03611cd35760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107bb565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015611d1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d43919061568b565b9050611d528160400151612e61565b60408101516001866003811115611d6b57611d6b6157da565b03611d74575060005b6000611d8c8360000151602001518787856001612ad3565b905060006001886003811115611da457611da46157da565b03611ee85760fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8a86600001516020015187602001518860000151604001518960000151608001518a60000151606001516040518763ffffffff1660e01b8152600401611e3d969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa158015611e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7e91906158f3565b845160c0015190915015611ee357835160600151611ea357835160c001518110611eac565b835160c0015181115b611ee35760405162461bcd60e51b81526020600482015260086024820152671cdb08199a5c9cdd60c21b60448201526064016107bb565b611f8f565b6002886003811115611efc57611efc6157da565b03611f4d57611f2084602001518560000151608001518660000151606001516143ba565b845160a0015190915015611ee357835160a0810151606090910151611f4691839161441c565b9050611f8f565b835160c00151611f875760405162461bcd60e51b81526020600482015260056024820152641b9bc81cdb60da1b60448201526064016107bb565b50825160c001515b611fa381838a876000015160600151613e14565b611fdb5760405162461bcd60e51b81526020600482015260096024820152680dcdee840a4cac2c6d60bb1b60448201526064016107bb565b60fb54845160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916120139160040190815260200190565b602060405180830381865afa158015612030573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612054919061595f565b80156120725750600188600381111561206f5761206f6157da565b14155b1561207b578091505b600061209d85602001518487600001516080015188600001516060015161347a565b60fb548651604001519192506120c6916001600160a01b03909116908c90869089908e87613555565b8451516120d8908b600060018d613ce3565b50505050505061101760018055565b6101015460405163471b4d7560e01b8152600481018890526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015612133573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121579190615739565b905061216a816020015160000151612a8e565b8051612177906000613f10565b83156121a15761219281602001518787878560000151614447565b60608101849052608081018490525b82156121b357602081015160a0018390525b81156121c557602081015160c0018290525b60fb546020820151606083015160808401516121ec936001600160a01b03169291906144cd565b61010154604051631e34099d60e01b815260048101899052602481018690526044810186905260648101859052608481018490526001600160a01b0390911690631e34099d9060a401600060405180830381600087803b15801561224f57600080fd5b505af1158015612263573d6000803e3d6000fd5b5050604080518a815260208101889052908101869052606081018590527fed9036017ec7fc31a1ca97298d80b8219039778a809afd38dc6480cea3964a4b925060800190506108c7565b6122b5612dae565b60c980546001600160a01b0383166001600160a01b031990911681179091556122e66097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000612328612e08565b612333876000613f10565b61234e6123453688900388018861597c565b8686868b614447565b61235b8787858686613f71565b905061236660018055565b9695505050505050565b612378612e08565b600260ff54811161239b5760405162461bcd60e51b81526004016107bb90615716565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa1580156123e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240b919061568b565b80515190915061241a90612a8e565b61242386614215565b8051608081015160409091015160009161243c91615886565b610101546040516346cb95c960e11b8152600481018b90529192506001600160a01b031690638d972b9290602401602060405180830381865afa158015612487573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ab91906158f3565b156124e55760405162461bcd60e51b815260206004820152600a6024820152697761697420636c6f736560b01b60448201526064016107bb565b6000612501836000015160200151878786604001516000612ad3565b9050600080881561268557600061252e86602001518588600001516080015189600001516060015161347a565b90506125406402540be4006009615a21565b81126125785760405162461bcd60e51b81526020600482015260076024820152661b585e08141b9b60ca1b60448201526064016107bb565b855160400151612589908c9061590c565b925061259583866158bb565b60fb548751602081015160609091015160405163369dd0b160e01b81526004810192909252602482018f9052151560448201529193506001600160a01b03169063369dd0b190606401602060405180830381865afa1580156125fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261f919061595f565b1561265e5760405162461bcd60e51b815260206004820152600f60248201526e10dbdb1b185d195c985b131a5b5a5d608a1b60448201526064016107bb565b610102546101015461267f916001600160a01b03908116913391168e6145a0565b50612923565b8451604001518a106126a95760405162461bcd60e51b81526004016107bb90615aa6565b8451604001516126ba908b90615948565b855160c0015190925015801590612745575060fb54855160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916127049160040190815260200190565b602060405180830381865afa158015612721573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612745919061595f565b1561278457612767856000015160c00151846003886000015160600151613e14565b156127845760405162461bcd60e51b81526004016107bb90615aa6565b61278e82856158bb565b9050600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8d886000015160200151896020015187878c60000151606001516040518763ffffffff1660e01b8152600401612816969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa158015612833573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285791906158f3565b905061286e81856001896000015160600151613e14565b1561288b5760405162461bcd60e51b81526004016107bb90615aa6565b61010160009054906101000a90046001600160a01b03166001600160a01b031663a5f2a15261010260009054906101000a90046001600160a01b03168860000151600001518e6040518463ffffffff1660e01b81526004016128ef93929190615924565b600060405180830381600087803b15801561290957600080fd5b505af115801561291d573d6000803e3d6000fd5b50505050505b60fb54855160200151612941916001600160a01b03169084846142a8565b610101546040516311ceca8960e11b8152600481018d9052602481018490526000604482018190526064820181905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b1580156129a457600080fd5b505af11580156129b8573d6000803e3d6000fd5b505050506000670de0b6b3a764000082846129d39190615886565b6129dd91906158bb565b6129ef670de0b6b3a7640000876158bb565b6129f99190615948565b60fb5487516020810151606090910151929350612a28926001600160a01b03909216918e9085908f60006145f8565b604080518d8152602081018d90528b151581830152606081018590526080810184905290517fb58ece2937681ab71ee2a4257af71abb8d43386650f2fd177ee49164f8a0a4ca9181900360a00190a150505050505050612a8760018055565b5050505050565b6001600160a01b03811633146114a85760405162461bcd60e51b815260206004820152600a6024820152693737ba103a3930b232b960b11b60448201526064016107bb565b6000806002836002811115612aea57612aea6157da565b14612c555760fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b0392831692638cfd7c8792169062e9f38b90602401602060405180830381865afa158015612b41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6591906158f3565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612bae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bd2919061595f565b89898960008a6002811115612be957612be96157da565b146040518763ffffffff1660e01b8152600401612c0b96959493929190615b82565b6020604051808303816000875af1158015612c2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4e91906158f3565b9050612da1565b60fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b039283169263815f4aed92169062e9f38b90602401602060405180830381865afa158015612ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ccb91906158f3565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612d14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d38919061595f565b8989896040518663ffffffff1660e01b8152600401612d5b959493929190615bbe565b6020604051808303816000875af1158015612d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d9e91906158f3565b90505b6000811161236657600080fd5b6097546001600160a01b0316331461102f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107bb565b600260015403612e5a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107bb565b6002600155565b806000036114a85760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195e1a5cdd60ba1b60448201526064016107bb565b600080670de0b6b3a764000088608001518960400151612ebd9190615886565b612ec791906158bb565b9050612ee28785610105548b60200151858d60600151614108565b9350600080612ef6898b8a8a8a888b6146eb565b90925090506000856002811115612f0f57612f0f6157da565b148015612f1a575081155b156130355761010154610102548b516040808e015190516352f950a960e11b81526001600160a01b039485169463a5f2a15294612f5e949116929091600401615924565b600060405180830381600087803b158015612f7857600080fd5b505af1158015612f8c573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018f90526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b158015612fd757600080fd5b505af1158015612feb573d6000803e3d6000fd5b5050604080518e8152600060208201527f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def648935001905060405180910390a160009350505050613384565b80826130545760405162461bcd60e51b81526004016107bb9190615c1e565b506000620186a08a6001600160a01b0316638251135b8d602001516040518263ffffffff1660e01b815260040161308d91815260200190565b602060405180830381865afa1580156130aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ce91906158f3565b6130d89086615886565b6130e291906158bb565b9050808b6040018181516130f69190615948565b90525060808b015160408c0151670de0b6b3a76400009161311691615886565b61312091906158bb565b935061313381858d600001516001614987565b61314f8a8c602001518d60400151878f606001516001806145f8565b60408051606081019091528b8152600090602081016001896002811115613178576131786157da565b03613183578b613185565b895b81526020016000815250905061010160009054906101000a90046001600160a01b03166001600160a01b0316638611e17e8e836040518363ffffffff1660e01b81526004016131d5929190615cbf565b600060405180830381600087803b1580156131ef57600080fd5b505af1158015613203573d6000803e3d6000fd5b505050508a6001600160a01b0316636ada93dd8e8e602001518f606001516040518463ffffffff1660e01b81526004016132529392919092835260208301919091521515604082015260600190565b600060405180830381600087803b15801561326c57600080fd5b505af1158015613280573d6000803e3d6000fd5b5050505061010160009054906101000a90046001600160a01b03166001600160a01b031663d07abd598e6040518263ffffffff1660e01b81526004016132c891815260200190565b600060405180830381600087803b1580156132e257600080fd5b505af11580156132f6573d6000803e3d6000fd5b505050507f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def6488d60016040516133379291909182521515602082015260400190565b60405180910390a17f09c087e430ee6913868eafe26e6d9da87f95984c61bde74e50e28ecd09da890a8d828460405161337293929190615cd4565b60405180910390a16001955050505050505b979650505050505050565b61010b546001600160a01b0384163b1561346557610107546133b1908261590c565b6101085460405163b2a11f8560e01b81526004810186905284151560248201529192506000916001600160a01b0387169163b2a11f8591604401600060405180830381600088803b15801561340557600080fd5b5087f193505050508015613417575060015b15613420575060015b604080516001600160a01b038716815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a1505b80156110175761101781614aef565b60018055565b60008061348d6402540be4006009615a21565b9050600083156134dd576134a087614b77565b6402540be4006134af89614b77565b6134b889614b77565b6134c29190615cf8565b6134cc9190615a21565b6134d69190615d37565b905061351f565b6134e687614b77565b6402540be4006134f588614b77565b6134fe8a614b77565b6135089190615cf8565b6135129190615a21565b61351c9190615d37565b90505b670de0b6b3a76400006135328683615a21565b61353c9190615d37565b905081811361354b5780613384565b5095945050505050565b6135876040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b84516080015160009061359a9086615886565b905060006135b0670de0b6b3a7640000836158bb565b90508560018660038111156135c7576135c76157da565b03613607576103e861010454886135de9190615886565b6135e891906158bb565b60808501526135f687614bbf565b6136009082615948565b90506136aa565b8751602001516040516341b51a0d60e11b81526004810191909152670de0b6b3a764000090620186a0906001600160a01b038e169063836a341a90602401602060405180830381865afa158015613662573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368691906158f3565b6136909086615886565b61369a91906158bb565b6136a491906158bb565b60808501525b87516020810151606090910151604051637325d71160e01b8152600481018d9052602481019290925260448201849052151560648201526001600160a01b038c1690637325d711906084016040805180830381865afa158015613711573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061373591906158cf565b60408601819052602086018290526080860151613758928a928992909190613eb0565b60608501526080840151885151613773919084906000614987565b60808401516137829082615948565b9050836060015181111561390d5760608401511561380d57610101546101025489515160608701516040516352f950a960e11b81526001600160a01b039485169463a5f2a152946137da949116929091600401615924565b600060405180830381600087803b1580156137f457600080fd5b505af1158015613808573d6000803e3d6000fd5b505050505b600084606001518261381f9190615948565b610101546101025460fe546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a1529361385f9381169216908690600401615924565b600060405180830381600087803b15801561387957600080fd5b505af115801561388d573d6000803e3d6000fd5b505060fe548b515160405163ceb5caa560e01b81526001600160a01b0391821660048201526024810186905260006044820181905260648201529116925063ceb5caa59150608401600060405180830381600087803b1580156138ef57600080fd5b505af1158015613903573d6000803e3d6000fd5b5050505050613a06565b600081856060015161391f9190615948565b905080156139905760fe5489515160405163496d1af960e11b81526001600160a01b039182166004820152602481018490529116906392da35f290604401600060405180830381600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b505050505b8115613a045761010154610102548a51516040516352f950a960e11b81526001600160a01b039384169363a5f2a152936139d1939116918790600401615924565b600060405180830381600087803b1580156139eb57600080fd5b505af11580156139ff573d6000803e3d6000fd5b505050505b505b875160400151600090613a1a908990615948565b9050826000829003613b8a576101015460405163348c68ad60e11b8152600481018e90526001600160a01b0390911690636918d15a90602401600060405180830381600087803b158015613a6d57600080fd5b505af1158015613a81573d6000803e3d6000fd5b505050508c6001600160a01b031663b8d040e48d6040518263ffffffff1660e01b8152600401613ab391815260200190565b600060405180830381600087803b158015613acd57600080fd5b505af1158015613ae1573d6000803e3d6000fd5b505061010154604051631eb17e1b60e21b81526001600160a01b039091169250637ac5f86c9150613b1a908f9060040190815260200190565b600060405180830381600087803b158015613b3457600080fd5b505af1158015613b48573d6000803e3d6000fd5b505050507fbe2b332e8e34afe0840746913f0e88f88fbbda69b3c05c49a197de3f559412778c604051613b7d91815260200190565b60405180910390a1613c5f565b895160800151670de0b6b3a764000090613ba49084615886565b613bae91906158bb565b8a516080810151604090910151670de0b6b3a764000091613bce91615886565b613bd891906158bb565b613be29190615948565b610101546040516311ceca8960e11b8152600481018f9052602481018590526000604482018190526064820152600160848201529192506001600160a01b03169063239d95129060a401600060405180830381600087803b158015613c4657600080fd5b505af1158015613c5a573d6000803e3d6000fd5b505050505b613c7f8d8b60000151602001518b848e60000151606001516000806145f8565b7f24b27bc2a65d006b06d5ee8450abfa71760f2aac880fcf5555af1e692cfaf5398c8c8b89602001518a604001518b608001518c606001518f604051613ccc989796959493929190615d79565b60405180910390a150505050505050505050505050565b60006001600160a01b0386163b15613dbf576101075461010654613d07919061590c565b90506000866001600160a01b031663657409e261010854888888886040518663ffffffff1660e01b8152600401613d419493929190615db6565b600060405180830381600088803b158015613d5b57600080fd5b5087f193505050508015613d6d575060015b15613d76575060015b604080516001600160a01b038916815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a150613dc5565b50610106545b6000826003811115613dd957613dd96157da565b148015613de557508015155b15613df357613df381614aef565b505050505050565b60c980546001600160a01b03191690556114a881614c7b565b60008115613e66576002836003811115613e3057613e306157da565b1480613e4d57506000836003811115613e4b57613e4b6157da565b145b15613e5c575083831015611768565b5083831115611768565b6002836003811115613e7a57613e7a6157da565b1480613e9757506000836003811115613e9557613e956157da565b145b15613ea6575083831115611768565b5083831015611768565b60008083856402540be400613ec5898b615a21565b613ecf9190615d37565b613ed9908a615dd9565b613ee39190615cf8565b613eed9190615cf8565b9050613ef98382615cf8565b905060008113612366576000979650505050505050565b806002811115613f2257613f226157da565b826002811115613f3457613f346157da565b03613f6d5760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107bb565b5050565b6000613f88613f8360208701876154e7565b612a8e565b613f9561010b548361424f565b60fb54613fbb906001600160a01b0316613fb43688900388018861597c565b86866144cd565b6101025461010154613fe0916001600160a01b039081169133911660408901356145a0565b60006040518060c00160405280886002811115613fff57613fff6157da565b81526020016140133689900389018961597c565b8152602001846001600160a01b03168152602001868152602001858152602001428152509050600061405f600088602001356101036000815461405590615e1a565b9182905550614ccd565b6101015460405163030dfab360e61b81529192506001600160a01b03169063c37eacc0906140939084908690600401615e98565b600060405180830381600087803b1580156140ad57600080fd5b505af11580156140c1573d6000803e3d6000fd5b50505050807fc815d98967a87feaaa8e57736b69b57611867c43e87d7c0cd7ba5edf3f13c528836040516140f59190615ead565b60405180910390a2979650505050505050565b60405163a1d54e9b60e01b81526004810184905260009081906001600160a01b0389169063a1d54e9b90602401602060405180830381865afa158015614152573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061417691906158f3565b9050600061418688888487614d10565b604051633f54af9960e11b815260048101829052602481018890528515156044820152606481018790529091506001600160a01b038a1690637ea95f3290608401602060405180830381865afa1580156141e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061420891906158f3565b9998505050505050505050565b806000036114a85760405162461bcd60e51b8152602060048201526007602482015266076616c75655f360cc1b60448201526064016107bb565b6001600160a01b0381161561426f576101075461426c908361590c565b91505b813414613f6d5760405162461bcd60e51b8152602060048201526007602482015266666565206d697360c81b60448201526064016107bb565b60405163a833064560e01b81526004810184905260248101839052604481018290526000906001600160a01b0386169063a833064590606401602060405180830381865afa1580156142fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614322919061595f565b905080612a875760405162461bcd60e51b81526020600482015260086024820152676f75742073697a6560c01b60448201526064016107bb565b600054610100900460ff166143835760405162461bcd60e51b81526004016107bb90615ebc565b61102f614d70565b600054610100900460ff166143b25760405162461bcd60e51b81526004016107bb90615ebc565b61102f614da3565b60008083670de0b6b3a76400006143d2600988615886565b6143dc9190615886565b6143e691906158bb565b90508215614400576143f8818661590c565b915050611a63565b80851015614412576000915050611a63565b6143f88186615948565b6000811561443a578284106144315782614433565b835b9050611a63565b8284116144315782614433565b600061445b86602001518686600080612ad3565b9050600061448560fb60009054906101000a90046001600160a01b03168884876101055488614dca565b9050806144c45760405162461bcd60e51b815260206004820152600d60248201526c1a5b1b1959d85b081b1a5b5a5d609a1b60448201526064016107bb565b50505050505050565b6144e5848460200151856040015186608001516142a8565b60008360a00151600014806145125750836060015161450a57818460a0015110614512565b828460a00151115b905060008460c00151600014806145415750846060015161453957838560c0015111614541565b828560c00151105b905060008385101580156145555750600084115b801561455e5750825b80156145675750815b9050806144c45760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107bb565b611017846323b872dd60e01b8585856040516024016145c193929190615924565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614e72565b6040516310787e2f60e11b81526004810187905260248101869052831515604482015282151560648201526001600160a01b038816906320f0fc5e90608401600060405180830381600087803b15801561465157600080fd5b505af1158015614665573d6000803e3d6000fd5b50505050836000146144c457604051631ae6a88f60e31b81526004810187905260248101859052831515604482015281151560648201526001600160a01b0388169063d735447890608401600060405180830381600087803b1580156146ca57600080fd5b505af11580156146de573d6000803e3d6000fd5b5050505050505050505050565b600060606147008787878b6060015187614f47565b61473457505060408051808201909152600f81526e1c1c9a58d9481bdd5d081b1a5b5a5d608a1b602082015260009061497b565b60208801516040808a015160608b0151915163369dd0b160e01b815260048101939093526024830152151560448201526001600160a01b038a169063369dd0b190606401602060405180830381865afa158015614795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147b9919061595f565b156147ee57505060408051808201909152600f81526e10dbdb1b185d195c985b131a5b5a5d608a1b602082015260009061497b565b6020880151606089015160405163ec8b6fa160e01b8152600481019290925260248201869052151560448201526001600160a01b038a169063ec8b6fa190606401602060405180830381865afa15801561484c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614870919061595f565b6148a257505060408051808201909152600d81526c125b9d195c995cdd131a5b5a5d609a1b602082015260009061497b565b60008360028111156148b6576148b66157da565b146149665760208801516060890151604051632ff8ac0760e21b81526001600160a01b038c169263bfe2b01c926148f69288918d918c9190600401615f07565b602060405180830381865afa158015614913573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614937919061595f565b61496657505060408051808201909152600a8152691bdd5d0814dc1c99585960b21b602082015260009061497b565b50506040805160208101909152600081526001905b97509795505050505050565b610101546101025460fd546040516352f950a960e11b81526001600160a01b039384169363a5f2a152936149c693908216929116908990600401615924565b600060405180830381600087803b1580156149e057600080fd5b505af11580156149f4573d6000803e3d6000fd5b505050508015614a765760fd5460405163031708bd60e11b81526001600160a01b03848116600483015233602483015260448201879052606482018690529091169063062e117a90608401600060405180830381600087803b158015614a5957600080fd5b505af1158015614a6d573d6000803e3d6000fd5b50505050611017565b60fd546040516312f8aacd60e21b81526001600160a01b038481166004830152336024830152604482018790526064820186905290911690634be2ab3490608401600060405180830381600087803b158015614ad157600080fd5b505af1158015614ae5573d6000803e3d6000fd5b5050505050505050565b604051600090339083908381818185875af1925050503d8060008114614b31576040519150601f19603f3d011682016040523d82523d6000602084013e614b36565b606091505b5050905080613f6d5760405162461bcd60e51b815260206004820152600d60248201526c1d1c985b9cd9995c8819985a5b609a1b60448201526064016107bb565b60006001600160ff1b03821115614bbb5760405162461bcd60e51b81526020600482015260086024820152676f766572666c6f7760c01b60448201526064016107bb565b5090565b61010a5460009081906001600160a01b031615801590614be157506101095415155b156113ab576103e86101095484614bf89190615886565b614c0291906158bb565b610101546101025461010a546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a15293614c439381169216908690600401615924565b600060405180830381600087803b158015614c5d57600080fd5b505af1158015614c71573d6000803e3d6000fd5b5050505092915050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600062ffffff83108015614ce757506001600160e01b0382105b614d035760405162461bcd60e51b81526004016107bb90615aa6565b5060e09190911b17919050565b600080614d1f856103e8615948565b905060006103e88281614d32888b615886565b614d3c91906158bb565b614d469190615886565b614d5091906158bb565b905083614d6657614d618188615948565b613384565b613384818861590c565b600054610100900460ff16614d975760405162461bcd60e51b81526004016107bb90615ebc565b6065805460ff19169055565b600054610100900460ff166134745760405162461bcd60e51b81526004016107bb90615ebc565b600080670de0b6b3a764000087608001518860400151614dea9190615886565b614df491906158bb565b9050614e0c8887868a60200151858c60600151614108565b9550866060015115614e45576001836002811115614e2c57614e2c6157da565b03614e3b575050838310612366565b5050838311612366565b6001836002811115614e5957614e596157da565b03614e68575050838311612366565b5050838310612366565b6000614ec7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614fd89092919063ffffffff16565b9050805160001480614ee8575080806020019051810190614ee8919061595f565b610cad5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107bb565b600080826002811115614f5c57614f5c6157da565b03614f7857848410158015614f715750858411155b9050611794565b8215614fab576001826002811115614f9257614f926157da565b03614fa1575083831115611794565b5084831015611794565b6001826002811115614fbf57614fbf6157da565b03614fce575084831015611794565b5083831115611794565b6060611768848460008585600080866001600160a01b03168587604051614fff9190615f39565b60006040518083038185875af1925050503d806000811461503c576040519150601f19603f3d011682016040523d82523d6000602084013e615041565b606091505b509150915061338487838387606083156150bc5782516000036150b5576001600160a01b0385163b6150b55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107bb565b5081611768565b61176883838151156150d15781518083602001fd5b8060405162461bcd60e51b81526004016107bb9190615c1e565b60008083601f8401126150fd57600080fd5b5081356001600160401b0381111561511457600080fd5b6020830191508360208260051b850101111561512f57600080fd5b9250929050565b60008060008060006080868803121561514e57600080fd5b85359450602086013593506040860135925060608601356001600160401b0381111561517957600080fd5b615185888289016150eb565b969995985093965092949392505050565b600080600080608085870312156151ac57600080fd5b5050823594602084013594506040840135936060013592509050565b6000806000604084860312156151dd57600080fd5b8335925060208401356001600160401b038111156151fa57600080fd5b615206868287016150eb565b9497909650939450505050565b6001600160a01b03811681146114a857600080fd5b6000806040838503121561523b57600080fd5b823561524681615213565b9150602083013561525681615213565b809150509250929050565b6000806000806060858703121561527757600080fd5b843593506020850135925060408501356001600160401b0381111561529b57600080fd5b6152a7878288016150eb565b95989497509550505050565b600080604083850312156152c657600080fd5b50508035926020909101359150565b600080604083850312156152e857600080fd5b82356152f381615213565b946020939093013593505050565b60006020828403121561531357600080fd5b5035919050565b600060e0828403121561532c57600080fd5b50919050565b600080600080610140858703121561534957600080fd5b615353868661531a565b935060e08501359250610100850135915061012085013561537381615213565b939692955090935050565b80151581146114a857600080fd5b600080600080608085870312156153a257600080fd5b84359350602085013592506040850135915060608501356153738161537e565b6000806000606084860312156153d757600080fd5b833592506020840135915060408401356153f081615213565b809150509250925092565b60008060006060848603121561541057600080fd5b833561541b81615213565b9250602084013561542b81615213565b915060408401356153f081615213565b6000806000806060858703121561545157600080fd5b8435935060208501356004811061546757600080fd5b925060408501356001600160401b0381111561529b57600080fd5b60008060008060008060a0878903121561549b57600080fd5b8635955060208701356001600160401b038111156154b857600080fd5b6154c489828a016150eb565b979a90995096976040810135976060820135975060809091013595509350505050565b6000602082840312156154f957600080fd5b8135611a6381615213565b600381106114a857600080fd5b600080600080600080610160878903121561552b57600080fd5b863561553681615504565b9550615545886020890161531a565b94506101008701356001600160401b0381111561556157600080fd5b61556d89828a016150eb565b909550935050610120870135915061014087013561558a81615213565b809150509295509295509295565b6000806000806000608086880312156155b057600080fd5b853594506020860135935060408601356155c98161537e565b925060608601356001600160401b0381111561517957600080fd5b600060e082840312156155f657600080fd5b60405160e081018181106001600160401b038211171561562657634e487b7160e01b600052604160045260246000fd5b8060405250809150825161563981615213565b808252506020830151602082015260408301516040820152606083015161565f8161537e565b806060830152506080830151608082015260a083015160a082015260c083015160c08201525092915050565b6000610120828403121561569e57600080fd5b604051606081018181106001600160401b03821117156156ce57634e487b7160e01b600052604160045260246000fd5b6040526156db84846155e4565b815260e0830151602082015261010090920151604083015250919050565b60006020828403121561570b57600080fd5b8151611a6381615213565b60208082526009908201526839bbb4b1b41037b33360b91b604082015260600190565b6000610180828403121561574c57600080fd5b60405160c081018181106001600160401b038211171561577c57634e487b7160e01b600052604160045260246000fd5b604052825161578a81615504565b815261579984602085016155e4565b60208201526101008301516157ad81615213565b6040820152610120830151606082015261014083015160808201526101609092015160a083015250919050565b634e487b7160e01b600052602160045260246000fd5b60006080828403121561580257600080fd5b604051608081018181106001600160401b038211171561583257634e487b7160e01b600052604160045260246000fd5b60405282518152602083015161584781615213565b60208201526040838101519082015260608301516158648161537e565b60608201529392505050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156158a0576158a0615870565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826158ca576158ca6158a5565b500490565b600080604083850312156158e257600080fd5b505080516020909101519092909150565b60006020828403121561590557600080fd5b5051919050565b6000821982111561591f5761591f615870565b500190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60008282101561595a5761595a615870565b500390565b60006020828403121561597157600080fd5b8151611a638161537e565b600060e0828403121561598e57600080fd5b60405160e081018181106001600160401b03821117156159be57634e487b7160e01b600052604160045260246000fd5b60405282356159cc81615213565b80825250602083013560208201526040830135604082015260608301356159f28161537e565b806060830152506080830135608082015260a083013560a082015260c083013560c08201528091505092915050565b60006001600160ff1b0381841382841380821686840486111615615a4757615a47615870565b600160ff1b6000871282811687830589121615615a6657615a66615870565b60008712925087820587128484161615615a8257615a82615870565b87850587128184161615615a9857615a98615870565b505050929093029392505050565b6020808252600890820152671bdd5d08189bdb9960c21b604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006020808501808196508560051b810191508460005b87811015615b755782840389528135601e19883603018112615b2c57600080fd5b870185810190356001600160401b03811115615b4757600080fd5b803603821315615b5657600080fd5b615b61868284615ac8565b9a87019a9550505090840190600101615b0b565b5091979650505050505050565b868152851515602082015260a060408201526000615ba460a083018688615af1565b606083019490945250901515608090910152949350505050565b8581528415156020820152608060408201526000615be0608083018587615af1565b90508260608301529695505050505050565b60005b83811015615c0d578181015183820152602001615bf5565b838111156110175750506000910152565b6020815260008251806020840152615c3d816040850160208701615bf2565b601f01601f19169190910160400192915050565b80516001600160a01b0316825260208082015190830152604080820151908301526060808201511515908301526080808201519083015260a0818101519083015260c090810151910152565b615ca8828251615c51565b602081015160e08301526040015161010090910152565b8281526101408101611a636020830184615c9d565b8381526101608101615ce96020830185615c9d565b82610140830152949350505050565b60008083128015600160ff1b850184121615615d1657615d16615870565b6001600160ff1b0384018313811615615d3157615d31615870565b50500390565b600082615d4657615d466158a5565b600160ff1b821460001984141615615d6057615d60615870565b500590565b60048110615d7557615d756157da565b9052565b6000610100820190508982528860208301528760408301528660608301528560808301528460a08301528360c083015261420860e0830184615d65565b848152602081018490528215156040820152608081016117946060830184615d65565b600080821280156001600160ff1b0384900385131615615dfb57615dfb615870565b600160ff1b8390038412811615615e1457615e14615870565b50500190565b600060018201615e2c57615e2c615870565b5060010190565b60038110615d7557615d756157da565b615e4e828251615e33565b6020810151615e606020840182615c51565b5060408101516001600160a01b03166101008301526060810151610120830152608081015161014083015260a0015161016090910152565b8281526101a08101611a636020830184615e43565b61018081016113ab8284615e43565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101615f1b6020830187615e33565b84604083015283606083015282151560808301529695505050505050565b60008251615f4b818460208701615bf2565b919091019291505056fea26469706673582212207f1af6183e9090ee4f6b6f56f1d185f437f2721a64e30602e8eab33c4508eb6264736f6c634300080f0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 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.