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);
if(ort.tradeType != TradeType.MARKET) _checkDelay(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);
if(_stop != CloseType.LQI) _checkDelay(ot.lastUpdateTime);
uint256 price = _getPrice(ot.base.pairIndex, updateData, 0, 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, 0, 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, 0, 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 _checkDelay(uint256 time) private view {
require(time + minAcceptanceDelay <= block.timestamp, "wait");
}
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 time,
PriceType _type
) internal returns (uint256) {
uint256 oraclePrice;
if (_type != PriceType.LIMIT) {
oraclePrice = oracle.getTokenPrice(
pairInfo.pairFeedId(pairIndex),
pairInfo.priceRollover(pairIndex),
updateData,
_type == PriceType.REQUEST
);
} else {
oraclePrice = oracle.getTokenPrice(
pairInfo.pairFeedId(pairIndex),
pairInfo.priceRollover(pairIndex),
updateData,
time
);
}
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 getTokenPrice(
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
60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b615fbb80620000f36000396000f3fe60806040526004361061023b5760003560e01c80637dc0d1d01161012e578063cc83bfd2116100ab578063f485ccf01161006f578063f485ccf01461064b578063f750704f14610662578063fbfa77cf14610675578063fc2a5b1d14610695578063fd77f87f146106b557600080fd5b8063cc83bfd2146105b6578063e30c3978146105d6578063efbc5fc0146105f4578063efcf0bd01461060b578063f2fde38b1461062b57600080fd5b8063a53fcde8116100f2578063a53fcde81461052c578063a5c34ba71461054c578063bb1c7c2a14610562578063c04398ee14610583578063c0c53b8b1461059657600080fd5b80637dc0d1d01461049b5780637ece45e8146104bb578063806762a0146104db5780638bc846c9146104fb5780638da5cb5b1461050e57600080fd5b80634c7d7d3f116101bc5780636bc81aa2116101805780636bc81aa21461041a578063715018a614610431578063725348901461044657806378250b631461046657806379ba50971461048657600080fd5b80634c7d7d3f1461039157806358d7bf80146103b25780635bd3e1c8146103c95780635c975abb146103e0578063615728f81461040357600080fd5b80631c4695f4116102035780631c4695f4146103055780631c7f6f4c1461031a57806324f746971461033a5780632bf6e0a514610351578063338b01331461037157600080fd5b806304c7ec71146102405780630845d69d1461026257806316b820911461028257806316fff074146102ac57806318897bb7146102e5575b600080fd5b34801561024c57600080fd5b5061026061025b36600461516c565b6106d5565b005b34801561026e57600080fd5b5061026061027d3660046151cc565b6108d4565b34801561028e57600080fd5b5061029961010b5481565b6040519081526020015b60405180910390f35b3480156102b857600080fd5b50610101546102cd906001600160a01b031681565b6040516001600160a01b0390911681526020016102a3565b3480156102f157600080fd5b5060fd546102cd906001600160a01b031681565b34801561031157600080fd5b50610260610943565b34801561032657600080fd5b506102606103353660046151fe565b610b66565b34801561034657600080fd5b506102996101085481565b34801561035d57600080fd5b5061026061036c36600461525e565b610cd5565b34801561037d57600080fd5b5061026061038c366004615297565b610da5565b34801561039d57600080fd5b50610102546102cd906001600160a01b031681565b3480156103be57600080fd5b506102996101095481565b3480156103d557600080fd5b506102996101065481565b3480156103ec57600080fd5b5060655460ff1660405190151581526020016102a3565b34801561040f57600080fd5b506102996101045481565b34801561042657600080fd5b506102996101075481565b34801561043d57600080fd5b50610260611040565b34801561045257600080fd5b506102996104613660046152e9565b611054565b34801561047257600080fd5b5061026061048136600461530b565b6113d4565b34801561049257600080fd5b50610260611454565b3480156104a757600080fd5b5060fc546102cd906001600160a01b031681565b3480156104c757600080fd5b506102606104d63660046151cc565b6114ce565b3480156104e757600080fd5b506102606104f6366004615337565b61154d565b610299610509366004615368565b611720565b34801561051a57600080fd5b506097546001600160a01b03166102cd565b34801561053857600080fd5b506102996105473660046153c2565b611793565b34801561055857600080fd5b5061029960ff5481565b34801561056e57600080fd5b5061010a546102cd906001600160a01b031681565b6102996105913660046153f8565b6117c0565b3480156105a257600080fd5b506102606105b1366004615431565b611a8d565b3480156105c257600080fd5b506102606105d1366004615471565b611c7e565b3480156105e257600080fd5b5060c9546001600160a01b03166102cd565b34801561060057600080fd5b506102996101055481565b34801561061757600080fd5b506102606106263660046154b8565b6120dc565b34801561063757600080fd5b5061026061064636600461551d565b6122a2565b34801561065757600080fd5b506102996101005481565b610299610670366004615547565b612313565b34801561068157600080fd5b5060fe546102cd906001600160a01b031681565b3480156106a157600080fd5b5060fb546102cd906001600160a01b031681565b3480156106c157600080fd5b506102606106d03660046155ce565b612365565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610721573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074591906156c1565b80515190915061075490612a7f565b600061076c8260000151602001518585600080612ac4565b905085156107c0578151606001516107865780861061078a565b8086115b6107c05760405162461bcd60e51b8152602060048201526002602482015261074760f41b60448201526064015b60405180910390fd5b841561080d578151606001516107d8578085116107dc565b8085105b61080d5760405162461bcd60e51b81526020600482015260026024820152611cdb60f21b60448201526064016107b7565b610101546040516311ceca8960e11b815260048101899052600060248201819052604482018990526064820188905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b15801561087057600080fd5b505af1158015610884573d6000803e3d6000fd5b5050604080518a8152602081018a90529081018890527f3fea1f17d88eda811ab87655f92885a6ec5fc9fd390aca775b9327f43ad00d77925060600190505b60405180910390a150505050505050565b6108dc612d9d565b61010b8490556101068390556101078290556101088190556040805185815260208101859052908101839052606081018290527faac5f778cabbb5dc9b9bd42735e5edd375300dc814bb0a323d1fc879d247a1f7906080015b60405180910390a150505050565b61010160009054906101000a90046001600160a01b03166001600160a01b031663fc2a5b1d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb919061572f565b60fb80546001600160a01b0319166001600160a01b0392831617905561010154604080516307dc0d1d60e41b815290519190921691637dc0d1d09160048083019260209291908290030181865afa158015610a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3e919061572f565b60fc80546001600160a01b0319166001600160a01b0392831617905561010154604080516318897bb760e01b8152905191909216916318897bb79160048083019260209291908290030181865afa158015610a9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac1919061572f565b60fd80546001600160a01b0319166001600160a01b03928316179055610101546040805163fbfa77cf60e01b81529051919092169163fbfa77cf9160048083019260209291908290030181865afa158015610b20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b44919061572f565b60fe80546001600160a01b0319166001600160a01b0392909216919091179055565b610b6e612df7565b600260ff548111610b915760405162461bcd60e51b81526004016107b79061574c565b6101015460405163471b4d7560e01b8152600481018690526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015610bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c01919061576f565b9050610c108160a00151612e50565b600081516002811115610c2557610c25615810565b14610c3757610c378160a00151612e8c565b60008082516002811115610c4d57610c4d615810565b14610c59576001610c5c565b60025b90506000610c7983602001516020015187878660a0015186612ac4565b90506000610cb188856020015160fb60009054906101000a90046001600160a01b031687606001518860800151878a60000151612ed3565b9050610cc2846040015189836133c5565b5050505050610cd060018055565b505050565b610cdd612d9d565b6001600160a01b03821615801590610cfd57506001600160a01b03811615155b610d355760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107b7565b61010180546001600160a01b038481166001600160a01b0319928316811790935561010280549185169190921681179091556040805192835260208301919091527f41fe2135e07f51f107aa1df22b2d51b5b6328f3a324fbfc555699785941adb59910160405180910390a15050565b610dad612df7565b600260ff548111610dd05760405162461bcd60e51b81526004016107b79061574c565b6101015460405163315896b560e11b815260048101879052602481018690526000916001600160a01b0316906362b12d6a90604401608060405180830381865afa158015610e22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e469190615826565b9050610e558160400151612e50565b806060015115610e965760405162461bcd60e51b815260206004820152600c60248201526b616c7265616479206578656360a01b60448201526064016107b7565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610ee2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0691906156c1565b90506000610f24826000015160200151878786604001516002612ac4565b90506000610f488360200151838560000151608001518660000151606001516134b0565b610101546040516368a5479360e11b8152600481018c9052602481018b9052600160448201529192506001600160a01b03169063d14a8f2690606401600060405180830381600087803b158015610f9e57600080fd5b505af1158015610fb2573d6000803e3d6000fd5b505060fb548651610fd993506001600160a01b0390911691508b908590879060008761358b565b604080518a8152602081018a905260018183015290517f28cf3bfcf594f6c4e9da1e79297930dbd971dcae2e08a19857abc14e759e94019181900360600190a161102c84602001518a8a60016000613d19565b505050505061103a60018055565b50505050565b611048612d9d565b6110526000613e31565b565b61010154604051633a02776f60e11b81526004810184905260009182916001600160a01b0390911690637404eede9060240161012060405180830381865afa1580156110a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c891906156c1565b905080602001516000036110e05760009150506113ce565b60006111028260200151858460000151608001518560000151606001516134b0565b82516080810151604090910151919250600091670de0b6b3a764000091611128916158bc565b61113291906158f1565b60fb5484516020810151606090910151604051637325d71160e01b8152600481018b90526024810192909252604482018490521515606482015291925060009182916001600160a01b031690637325d711906084016040805180830381865afa1580156111a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c79190615905565b91509150600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8a88600001516020015189602001518a60000151604001518b60000151608001518c60000151606001516040518763ffffffff1660e01b8152600401611261969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a29190615929565b865160c00151909150600090600190156112d9578751606001516112cd57875160c0015183106112d6565b875160c0015183115b90505b8080156112f657506112f6838b60018b6000015160600151613e4a565b1561132357610104548851604001516103e891611312916158bc565b61131c91906158f1565b91506113b0565b60fb548851602001516040516341b51a0d60e11b815260048101919091526103e8916001600160a01b03169063836a341a90602401602060405180830381865afa158015611375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113999190615929565b6113a390886158bc565b6113ad91906158f1565b91505b8751604001516113c39088868886613ee6565b985050505050505050505b92915050565b6113dc612d9d565b6103e881610104546113ee9190615942565b106113f857600080fd5b61010a80546001600160a01b0319166001600160a01b0384169081179091556101098290556040518281527f9241e21d4fa6dd55661c8694538bfc11a7d44d81d5766840312d2513f55fa67d9060200160405180910390a25050565b60c95433906001600160a01b031681146114c25760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016107b7565b6114cb81613e31565b50565b6114d6612d9d565b6103e8841080156114e857506103e883105b6114f157600080fd5b61010484905560ff8190556101058390556101008290556040805185815260208101859052908101839052606081018290527fe33eb1ee60efac814379b14a1d72ec5d666301d3264613e9d3f4ad9ef38b094690608001610935565b611555612df7565b600260ff5481116115785760405162461bcd60e51b81526004016107b79061574c565b6101015460405163471b4d7560e01b8152600481018490526000916001600160a01b03169063471b4d759060240161018060405180830381865afa1580156115c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e8919061576f565b90506115fb816020015160000151612a7f565b8051611608906000613f46565b61010154610102546020830151805160409182015191516352f950a960e11b81526001600160a01b039485169463a5f2a1529461164b949116929160040161595a565b600060405180830381600087803b15801561166557600080fd5b505af1158015611679573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018790526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b1580156116c457600080fd5b505af11580156116d8573d6000803e3d6000fd5b505050507f1dbfda3a6640539c3fac591e271a7b4ccd445cf9bc2b951e58abde22dfe73f538360405161170d91815260200190565b60405180910390a150506114cb60018055565b600061172a612df7565b6103e8831061173857600080fd5b60006103e861174785876158bc565b61175191906158f1565b9050600061175f8287615942565b9050600061176d838861597e565b905061177d600089848489613fa7565b935050505061178b60018055565b949350505050565b60fb54610105546000916117b7916001600160a01b0390911690879087878761413e565b95945050505050565b60006117ca612df7565b600260ff5481116117ed5760405162461bcd60e51b81526004016107b79061574c565b610101546040516346cb95c960e11b8152600481018790526000916001600160a01b031690638d972b9290602401602060405180830381865afa158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185c9190615929565b61010154604051633a02776f60e11b8152600481018990529192506000916001600160a01b0390911690637404eede9060240161012060405180830381865afa1580156118ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d191906156c1565b90506118dc8661424b565b8051516118e890612a7f565b6118f56101065486614285565b6118ff8683615942565b8151604001519092508211156119415760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107b7565b80516040015182146119825760fb5481516020810151604090910151611982926001600160a01b0316919061197790869061597e565b8451608001516142de565b61010154604080516080810182528881526001600160a01b0388811660208301908152600083850181815260608501828152955162c9f2ed60e81b8152600481018f905294516024860152915183166044850152905160648401529251151560848301529192919091169063c9f2ed009060a4016020604051808303816000875af1158015611a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a399190615929565b6040805189815242602082015291925082918a917f7695d3ca62416d30d27e9fac1080c5322b164e257e8151db3b139aec5d81605e910160405180910390a39350505050611a8660018055565b9392505050565b600054610100900460ff1615808015611aad5750600054600160ff909116105b80611ac75750303b158015611ac7575060005460ff166001145b611b2a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016107b7565b6000805460ff191660011790558015611b4d576000805461ff0019166101001790555b611b55614392565b611b5d6143c1565b611b6684613e31565b6001600160a01b03831615801590611b8657506001600160a01b03821615155b8015611b9a57506001600160a01b03841615155b611bd25760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107b7565b61010180546001600160a01b038086166001600160a01b0319928316179092556101028054928516929091169190911790556032610104556103cf610105556601c6bf5263400061010655600061010b5562030d4061010855655af3107a400061010755601461010055801561103a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610935565b611c86612df7565b600260ff548111611ca95760405162461bcd60e51b81526004016107b79061574c565b6000846003811115611cbd57611cbd615810565b03611cf65760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107b7565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015611d42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6691906156c1565b9050611d758160400151612e50565b6001856003811115611d8957611d89615810565b14611d9b57611d9b8160400151612e8c565b6000611db4826000015160200151868660006001612ac4565b905060006001876003811115611dcc57611dcc615810565b03611eec5760fb548351602080820151908601516040808401516080850151606090950151915163369e333760e11b8152600481018f9052602481019490945260448401929092526064830191909152608482019290925290151560a48201526001600160a01b0390911690636d3c666e9060c401602060405180830381865afa158015611e5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e829190615929565b835160c0015190915015611ee757825160600151611ea757825160c001518110611eb0565b825160c0015181115b611ee75760405162461bcd60e51b81526020600482015260086024820152671cdb08199a5c9cdd60c21b60448201526064016107b7565b611f93565b6002876003811115611f0057611f00615810565b03611f5157611f2483602001518460000151608001518560000151606001516143f0565b835160a0015190915015611ee757825160a0810151606090910151611f4a918391614452565b9050611f93565b825160c00151611f8b5760405162461bcd60e51b81526020600482015260056024820152641b9bc81cdb60da1b60448201526064016107b7565b50815160c001515b611fa7818389866000015160600151613e4a565b611fdf5760405162461bcd60e51b81526020600482015260096024820152680dcdee840a4cac2c6d60bb1b60448201526064016107b7565b60fb54835160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916120179160040190815260200190565b602060405180830381865afa158015612034573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120589190615995565b80156120765750600187600381111561207357612073615810565b14155b1561207f578091505b60006120a18460200151848660000151608001518760000151606001516134b0565b60fb548551604001519192506120ca916001600160a01b03909116908b90869088908d8761358b565b83515161102c908a600060018c613d19565b6101015460405163471b4d7560e01b8152600481018890526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015612128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214c919061576f565b905061215f816020015160000151612a7f565b805161216c906000613f46565b8315612196576121878160200151878787856000015161447d565b60608101849052608081018490525b82156121a857602081015160a0018390525b81156121ba57602081015160c0018290525b60fb546020820151606083015160808401516121e1936001600160a01b0316929190614503565b61010154604051631e34099d60e01b815260048101899052602481018690526044810186905260648101859052608481018490526001600160a01b0390911690631e34099d9060a401600060405180830381600087803b15801561224457600080fd5b505af1158015612258573d6000803e3d6000fd5b5050604080518a815260208101889052908101869052606081018590527fed9036017ec7fc31a1ca97298d80b8219039778a809afd38dc6480cea3964a4b925060800190506108c3565b6122aa612d9d565b60c980546001600160a01b0383166001600160a01b031990911681179091556122db6097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600061231d612df7565b612328876000613f46565b61234361233a368890038801886159b2565b8686868b61447d565b6123508787858686613fa7565b905061235b60018055565b9695505050505050565b61236d612df7565b600260ff5481116123905760405162461bcd60e51b81526004016107b79061574c565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa1580156123dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240091906156c1565b80515190915061240f90612a7f565b6124188661424b565b80516080810151604090910151600091612431916158bc565b610101546040516346cb95c960e11b8152600481018b90529192506001600160a01b031690638d972b9290602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190615929565b156124da5760405162461bcd60e51b815260206004820152600a6024820152697761697420636c6f736560b01b60448201526064016107b7565b60006124f28360000151602001518787600080612ac4565b9050600080881561267657600061251f8660200151858860000151608001518960000151606001516134b0565b90506125316402540be4006009615a57565b81126125695760405162461bcd60e51b81526020600482015260076024820152661b585e08141b9b60ca1b60448201526064016107b7565b85516040015161257a908c90615942565b925061258683866158f1565b60fb548751602081015160609091015160405163369dd0b160e01b81526004810192909252602482018f9052151560448201529193506001600160a01b03169063369dd0b190606401602060405180830381865afa1580156125ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126109190615995565b1561264f5760405162461bcd60e51b815260206004820152600f60248201526e10dbdb1b185d195c985b131a5b5a5d608a1b60448201526064016107b7565b6101025461010154612670916001600160a01b03908116913391168e6145d6565b50612914565b8451604001518a1061269a5760405162461bcd60e51b81526004016107b790615adc565b8451604001516126ab908b9061597e565b855160c0015190925015801590612736575060fb54855160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916126f59160040190815260200190565b602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127369190615995565b1561277557612758856000015160c00151846003886000015160600151613e4a565b156127755760405162461bcd60e51b81526004016107b790615adc565b61277f82856158f1565b9050600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8d886000015160200151896020015187878c60000151606001516040518763ffffffff1660e01b8152600401612807969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa158015612824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128489190615929565b905061285f81856001896000015160600151613e4a565b1561287c5760405162461bcd60e51b81526004016107b790615adc565b61010160009054906101000a90046001600160a01b03166001600160a01b031663a5f2a15261010260009054906101000a90046001600160a01b03168860000151600001518e6040518463ffffffff1660e01b81526004016128e09392919061595a565b600060405180830381600087803b1580156128fa57600080fd5b505af115801561290e573d6000803e3d6000fd5b50505050505b60fb54855160200151612932916001600160a01b03169084846142de565b610101546040516311ceca8960e11b8152600481018d9052602481018490526000604482018190526064820181905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b505050506000670de0b6b3a764000082846129c491906158bc565b6129ce91906158f1565b6129e0670de0b6b3a7640000876158f1565b6129ea919061597e565b60fb5487516020810151606090910151929350612a19926001600160a01b03909216918e9085908f600061462e565b604080518d8152602081018d90528b151581830152606081018590526080810184905290517fb58ece2937681ab71ee2a4257af71abb8d43386650f2fd177ee49164f8a0a4ca9181900360a00190a150505050505050612a7860018055565b5050505050565b6001600160a01b03811633146114cb5760405162461bcd60e51b815260206004820152600a6024820152693737ba103a3930b232b960b11b60448201526064016107b7565b6000806002836002811115612adb57612adb615810565b14612c445760fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b039283169263d46720d092169062e9f38b90602401602060405180830381865afa158015612b32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b569190615929565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc39190615995565b89896000896002811115612bd957612bd9615810565b146040518663ffffffff1660e01b8152600401612bfa959493929190615bb8565b6020604051808303816000875af1158015612c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3d9190615929565b9050612d90565b60fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b0392831692635c3c66dd92169062e9f38b90602401602060405180830381865afa158015612c96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cba9190615929565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612d03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d279190615995565b8989896040518663ffffffff1660e01b8152600401612d4a959493929190615bee565b6020604051808303816000875af1158015612d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8d9190615929565b90505b6000811161235b57600080fd5b6097546001600160a01b031633146110525760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107b7565b600260015403612e495760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107b7565b6002600155565b806000036114cb5760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195e1a5cdd60ba1b60448201526064016107b7565b426101005482612e9c9190615942565b11156114cb5760405162461bcd60e51b81526004016107b7906020808252600490820152631dd85a5d60e21b604082015260600190565b600080670de0b6b3a764000088608001518960400151612ef391906158bc565b612efd91906158f1565b9050612f188785610105548b60200151858d6060015161413e565b9350600080612f2c898b8a8a8a888b614721565b90925090506000856002811115612f4557612f45615810565b148015612f50575081155b1561306b5761010154610102548b516040808e015190516352f950a960e11b81526001600160a01b039485169463a5f2a15294612f9494911692909160040161595a565b600060405180830381600087803b158015612fae57600080fd5b505af1158015612fc2573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018f90526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b15801561300d57600080fd5b505af1158015613021573d6000803e3d6000fd5b5050604080518e8152600060208201527f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def648935001905060405180910390a1600093505050506133ba565b808261308a5760405162461bcd60e51b81526004016107b79190615c4e565b506000620186a08a6001600160a01b0316638251135b8d602001516040518263ffffffff1660e01b81526004016130c391815260200190565b602060405180830381865afa1580156130e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131049190615929565b61310e90866158bc565b61311891906158f1565b9050808b60400181815161312c919061597e565b90525060808b015160408c0151670de0b6b3a76400009161314c916158bc565b61315691906158f1565b935061316981858d6000015160016149bd565b6131858a8c602001518d60400151878f6060015160018061462e565b60408051606081019091528b81526000906020810160018960028111156131ae576131ae615810565b036131b9578b6131bb565b895b81526020016000815250905061010160009054906101000a90046001600160a01b03166001600160a01b0316638611e17e8e836040518363ffffffff1660e01b815260040161320b929190615cef565b600060405180830381600087803b15801561322557600080fd5b505af1158015613239573d6000803e3d6000fd5b505050508a6001600160a01b0316636ada93dd8e8e602001518f606001516040518463ffffffff1660e01b81526004016132889392919092835260208301919091521515604082015260600190565b600060405180830381600087803b1580156132a257600080fd5b505af11580156132b6573d6000803e3d6000fd5b5050505061010160009054906101000a90046001600160a01b03166001600160a01b031663d07abd598e6040518263ffffffff1660e01b81526004016132fe91815260200190565b600060405180830381600087803b15801561331857600080fd5b505af115801561332c573d6000803e3d6000fd5b505050507f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def6488d600160405161336d9291909182521515602082015260400190565b60405180910390a17f09c087e430ee6913868eafe26e6d9da87f95984c61bde74e50e28ecd09da890a8d82846040516133a893929190615d04565b60405180910390a16001955050505050505b979650505050505050565b61010b546001600160a01b0384163b1561349b57610107546133e79082615942565b6101085460405163b2a11f8560e01b81526004810186905284151560248201529192506000916001600160a01b0387169163b2a11f8591604401600060405180830381600088803b15801561343b57600080fd5b5087f19350505050801561344d575060015b15613456575060015b604080516001600160a01b038716815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a1505b801561103a5761103a81614b25565b60018055565b6000806134c36402540be4006009615a57565b905060008315613513576134d687614bad565b6402540be4006134e589614bad565b6134ee89614bad565b6134f89190615d28565b6135029190615a57565b61350c9190615d67565b9050613555565b61351c87614bad565b6402540be40061352b88614bad565b6135348a614bad565b61353e9190615d28565b6135489190615a57565b6135529190615d67565b90505b670de0b6b3a76400006135688683615a57565b6135729190615d67565b905081811361358157806133ba565b5095945050505050565b6135bd6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8451608001516000906135d090866158bc565b905060006135e6670de0b6b3a7640000836158f1565b90508560018660038111156135fd576135fd615810565b0361363d576103e8610104548861361491906158bc565b61361e91906158f1565b608085015261362c87614bf5565b613636908261597e565b90506136e0565b8751602001516040516341b51a0d60e11b81526004810191909152670de0b6b3a764000090620186a0906001600160a01b038e169063836a341a90602401602060405180830381865afa158015613698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136bc9190615929565b6136c690866158bc565b6136d091906158f1565b6136da91906158f1565b60808501525b87516020810151606090910151604051637325d71160e01b8152600481018d9052602481019290925260448201849052151560648201526001600160a01b038c1690637325d711906084016040805180830381865afa158015613747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061376b9190615905565b6040860181905260208601829052608086015161378e928a928992909190613ee6565b606085015260808401518851516137a99190849060006149bd565b60808401516137b8908261597e565b905083606001518111156139435760608401511561384357610101546101025489515160608701516040516352f950a960e11b81526001600160a01b039485169463a5f2a1529461381094911692909160040161595a565b600060405180830381600087803b15801561382a57600080fd5b505af115801561383e573d6000803e3d6000fd5b505050505b6000846060015182613855919061597e565b610101546101025460fe546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a15293613895938116921690869060040161595a565b600060405180830381600087803b1580156138af57600080fd5b505af11580156138c3573d6000803e3d6000fd5b505060fe548b515160405163ceb5caa560e01b81526001600160a01b0391821660048201526024810186905260006044820181905260648201529116925063ceb5caa59150608401600060405180830381600087803b15801561392557600080fd5b505af1158015613939573d6000803e3d6000fd5b5050505050613a3c565b6000818560600151613955919061597e565b905080156139c65760fe5489515160405163496d1af960e11b81526001600160a01b039182166004820152602481018490529116906392da35f290604401600060405180830381600087803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b505050505b8115613a3a5761010154610102548a51516040516352f950a960e11b81526001600160a01b039384169363a5f2a15293613a0793911691879060040161595a565b600060405180830381600087803b158015613a2157600080fd5b505af1158015613a35573d6000803e3d6000fd5b505050505b505b875160400151600090613a5090899061597e565b9050826000829003613bc0576101015460405163348c68ad60e11b8152600481018e90526001600160a01b0390911690636918d15a90602401600060405180830381600087803b158015613aa357600080fd5b505af1158015613ab7573d6000803e3d6000fd5b505050508c6001600160a01b031663b8d040e48d6040518263ffffffff1660e01b8152600401613ae991815260200190565b600060405180830381600087803b158015613b0357600080fd5b505af1158015613b17573d6000803e3d6000fd5b505061010154604051631eb17e1b60e21b81526001600160a01b039091169250637ac5f86c9150613b50908f9060040190815260200190565b600060405180830381600087803b158015613b6a57600080fd5b505af1158015613b7e573d6000803e3d6000fd5b505050507fbe2b332e8e34afe0840746913f0e88f88fbbda69b3c05c49a197de3f559412778c604051613bb391815260200190565b60405180910390a1613c95565b895160800151670de0b6b3a764000090613bda90846158bc565b613be491906158f1565b8a516080810151604090910151670de0b6b3a764000091613c04916158bc565b613c0e91906158f1565b613c18919061597e565b610101546040516311ceca8960e11b8152600481018f9052602481018590526000604482018190526064820152600160848201529192506001600160a01b03169063239d95129060a401600060405180830381600087803b158015613c7c57600080fd5b505af1158015613c90573d6000803e3d6000fd5b505050505b613cb58d8b60000151602001518b848e600001516060015160008061462e565b7f24b27bc2a65d006b06d5ee8450abfa71760f2aac880fcf5555af1e692cfaf5398c8c8b89602001518a604001518b608001518c606001518f604051613d02989796959493929190615da9565b60405180910390a150505050505050505050505050565b60006001600160a01b0386163b15613df5576101075461010654613d3d9190615942565b90506000866001600160a01b031663657409e261010854888888886040518663ffffffff1660e01b8152600401613d779493929190615de6565b600060405180830381600088803b158015613d9157600080fd5b5087f193505050508015613da3575060015b15613dac575060015b604080516001600160a01b038916815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a150613dfb565b50610106545b6000826003811115613e0f57613e0f615810565b148015613e1b57508015155b15613e2957613e2981614b25565b505050505050565b60c980546001600160a01b03191690556114cb81614cb1565b60008115613e9c576002836003811115613e6657613e66615810565b1480613e8357506000836003811115613e8157613e81615810565b145b15613e9257508383101561178b565b508383111561178b565b6002836003811115613eb057613eb0615810565b1480613ecd57506000836003811115613ecb57613ecb615810565b145b15613edc57508383111561178b565b508383101561178b565b60008083856402540be400613efb898b615a57565b613f059190615d67565b613f0f908a615e09565b613f199190615d28565b613f239190615d28565b9050613f2f8382615d28565b90506000811361235b576000979650505050505050565b806002811115613f5857613f58615810565b826002811115613f6a57613f6a615810565b03613fa35760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107b7565b5050565b6000613fbe613fb9602087018761551d565b612a7f565b613fcb61010b5483614285565b60fb54613ff1906001600160a01b0316613fea368890038801886159b2565b8686614503565b6101025461010154614016916001600160a01b039081169133911660408901356145d6565b60006040518060c0016040528088600281111561403557614035615810565b8152602001614049368990038901896159b2565b8152602001846001600160a01b031681526020018681526020018581526020014281525090506000614095600088602001356101036000815461408b90615e4a565b9182905550614d03565b6101015460405163030dfab360e61b81529192506001600160a01b03169063c37eacc0906140c99084908690600401615ec8565b600060405180830381600087803b1580156140e357600080fd5b505af11580156140f7573d6000803e3d6000fd5b50505050807fc815d98967a87feaaa8e57736b69b57611867c43e87d7c0cd7ba5edf3f13c5288360405161412b9190615edd565b60405180910390a2979650505050505050565b60405163a1d54e9b60e01b81526004810184905260009081906001600160a01b0389169063a1d54e9b90602401602060405180830381865afa158015614188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ac9190615929565b905060006141bc88888487614d46565b604051633f54af9960e11b815260048101829052602481018890528515156044820152606481018790529091506001600160a01b038a1690637ea95f3290608401602060405180830381865afa15801561421a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061423e9190615929565b9998505050505050505050565b806000036114cb5760405162461bcd60e51b8152602060048201526007602482015266076616c75655f360cc1b60448201526064016107b7565b6001600160a01b038116156142a557610107546142a29083615942565b91505b813414613fa35760405162461bcd60e51b8152602060048201526007602482015266666565206d697360c81b60448201526064016107b7565b60405163a833064560e01b81526004810184905260248101839052604481018290526000906001600160a01b0386169063a833064590606401602060405180830381865afa158015614334573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143589190615995565b905080612a785760405162461bcd60e51b81526020600482015260086024820152676f75742073697a6560c01b60448201526064016107b7565b600054610100900460ff166143b95760405162461bcd60e51b81526004016107b790615eec565b611052614da6565b600054610100900460ff166143e85760405162461bcd60e51b81526004016107b790615eec565b611052614dd9565b60008083670de0b6b3a76400006144086009886158bc565b61441291906158bc565b61441c91906158f1565b905082156144365761442e8186615942565b915050611a86565b80851015614448576000915050611a86565b61442e818661597e565b60008115614470578284106144675782614469565b835b9050611a86565b8284116144675782614469565b600061449186602001518686600080612ac4565b905060006144bb60fb60009054906101000a90046001600160a01b03168884876101055488614e00565b9050806144fa5760405162461bcd60e51b815260206004820152600d60248201526c1a5b1b1959d85b081b1a5b5a5d609a1b60448201526064016107b7565b50505050505050565b61451b848460200151856040015186608001516142de565b60008360a00151600014806145485750836060015161454057818460a0015110614548565b828460a00151115b905060008460c00151600014806145775750846060015161456f57838560c0015111614577565b828560c00151105b9050600083851015801561458b5750600084115b80156145945750825b801561459d5750815b9050806144fa5760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107b7565b61103a846323b872dd60e01b8585856040516024016145f79392919061595a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614ea8565b6040516310787e2f60e11b81526004810187905260248101869052831515604482015282151560648201526001600160a01b038816906320f0fc5e90608401600060405180830381600087803b15801561468757600080fd5b505af115801561469b573d6000803e3d6000fd5b50505050836000146144fa57604051631ae6a88f60e31b81526004810187905260248101859052831515604482015281151560648201526001600160a01b0388169063d735447890608401600060405180830381600087803b15801561470057600080fd5b505af1158015614714573d6000803e3d6000fd5b5050505050505050505050565b600060606147368787878b6060015187614f7d565b61476a57505060408051808201909152600f81526e1c1c9a58d9481bdd5d081b1a5b5a5d608a1b60208201526000906149b1565b60208801516040808a015160608b0151915163369dd0b160e01b815260048101939093526024830152151560448201526001600160a01b038a169063369dd0b190606401602060405180830381865afa1580156147cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147ef9190615995565b1561482457505060408051808201909152600f81526e10dbdb1b185d195c985b131a5b5a5d608a1b60208201526000906149b1565b6020880151606089015160405163ec8b6fa160e01b8152600481019290925260248201869052151560448201526001600160a01b038a169063ec8b6fa190606401602060405180830381865afa158015614882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a69190615995565b6148d857505060408051808201909152600d81526c125b9d195c995cdd131a5b5a5d609a1b60208201526000906149b1565b60008360028111156148ec576148ec615810565b1461499c5760208801516060890151604051632ff8ac0760e21b81526001600160a01b038c169263bfe2b01c9261492c9288918d918c9190600401615f37565b602060405180830381865afa158015614949573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061496d9190615995565b61499c57505060408051808201909152600a8152691bdd5d0814dc1c99585960b21b60208201526000906149b1565b50506040805160208101909152600081526001905b97509795505050505050565b610101546101025460fd546040516352f950a960e11b81526001600160a01b039384169363a5f2a152936149fc9390821692911690899060040161595a565b600060405180830381600087803b158015614a1657600080fd5b505af1158015614a2a573d6000803e3d6000fd5b505050508015614aac5760fd5460405163031708bd60e11b81526001600160a01b03848116600483015233602483015260448201879052606482018690529091169063062e117a90608401600060405180830381600087803b158015614a8f57600080fd5b505af1158015614aa3573d6000803e3d6000fd5b5050505061103a565b60fd546040516312f8aacd60e21b81526001600160a01b038481166004830152336024830152604482018790526064820186905290911690634be2ab3490608401600060405180830381600087803b158015614b0757600080fd5b505af1158015614b1b573d6000803e3d6000fd5b5050505050505050565b604051600090339083908381818185875af1925050503d8060008114614b67576040519150601f19603f3d011682016040523d82523d6000602084013e614b6c565b606091505b5050905080613fa35760405162461bcd60e51b815260206004820152600d60248201526c1d1c985b9cd9995c8819985a5b609a1b60448201526064016107b7565b60006001600160ff1b03821115614bf15760405162461bcd60e51b81526020600482015260086024820152676f766572666c6f7760c01b60448201526064016107b7565b5090565b61010a5460009081906001600160a01b031615801590614c1757506101095415155b156113ce576103e86101095484614c2e91906158bc565b614c3891906158f1565b610101546101025461010a546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a15293614c79938116921690869060040161595a565b600060405180830381600087803b158015614c9357600080fd5b505af1158015614ca7573d6000803e3d6000fd5b5050505092915050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600062ffffff83108015614d1d57506001600160e01b0382105b614d395760405162461bcd60e51b81526004016107b790615adc565b5060e09190911b17919050565b600080614d55856103e861597e565b905060006103e88281614d68888b6158bc565b614d7291906158f1565b614d7c91906158bc565b614d8691906158f1565b905083614d9c57614d97818861597e565b6133ba565b6133ba8188615942565b600054610100900460ff16614dcd5760405162461bcd60e51b81526004016107b790615eec565b6065805460ff19169055565b600054610100900460ff166134aa5760405162461bcd60e51b81526004016107b790615eec565b600080670de0b6b3a764000087608001518860400151614e2091906158bc565b614e2a91906158f1565b9050614e428887868a60200151858c6060015161413e565b9550866060015115614e7b576001836002811115614e6257614e62615810565b03614e7157505083831061235b565b505083831161235b565b6001836002811115614e8f57614e8f615810565b03614e9e57505083831161235b565b505083831061235b565b6000614efd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661500e9092919063ffffffff16565b9050805160001480614f1e575080806020019051810190614f1e9190615995565b610cd05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107b7565b600080826002811115614f9257614f92615810565b03614fae57848410158015614fa75750858411155b90506117b7565b8215614fe1576001826002811115614fc857614fc8615810565b03614fd75750838311156117b7565b50848310156117b7565b6001826002811115614ff557614ff5615810565b036150045750848310156117b7565b50838311156117b7565b606061178b848460008585600080866001600160a01b031685876040516150359190615f69565b60006040518083038185875af1925050503d8060008114615072576040519150601f19603f3d011682016040523d82523d6000602084013e615077565b606091505b50915091506133ba87838387606083156150f25782516000036150eb576001600160a01b0385163b6150eb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b7565b508161178b565b61178b83838151156151075781518083602001fd5b8060405162461bcd60e51b81526004016107b79190615c4e565b60008083601f84011261513357600080fd5b5081356001600160401b0381111561514a57600080fd5b6020830191508360208260051b850101111561516557600080fd5b9250929050565b60008060008060006080868803121561518457600080fd5b85359450602086013593506040860135925060608601356001600160401b038111156151af57600080fd5b6151bb88828901615121565b969995985093965092949392505050565b600080600080608085870312156151e257600080fd5b5050823594602084013594506040840135936060013592509050565b60008060006040848603121561521357600080fd5b8335925060208401356001600160401b0381111561523057600080fd5b61523c86828701615121565b9497909650939450505050565b6001600160a01b03811681146114cb57600080fd5b6000806040838503121561527157600080fd5b823561527c81615249565b9150602083013561528c81615249565b809150509250929050565b600080600080606085870312156152ad57600080fd5b843593506020850135925060408501356001600160401b038111156152d157600080fd5b6152dd87828801615121565b95989497509550505050565b600080604083850312156152fc57600080fd5b50508035926020909101359150565b6000806040838503121561531e57600080fd5b823561532981615249565b946020939093013593505050565b60006020828403121561534957600080fd5b5035919050565b600060e0828403121561536257600080fd5b50919050565b600080600080610140858703121561537f57600080fd5b6153898686615350565b935060e0850135925061010085013591506101208501356153a981615249565b939692955090935050565b80151581146114cb57600080fd5b600080600080608085870312156153d857600080fd5b84359350602085013592506040850135915060608501356153a9816153b4565b60008060006060848603121561540d57600080fd5b8335925060208401359150604084013561542681615249565b809150509250925092565b60008060006060848603121561544657600080fd5b833561545181615249565b9250602084013561546181615249565b9150604084013561542681615249565b6000806000806060858703121561548757600080fd5b8435935060208501356004811061549d57600080fd5b925060408501356001600160401b038111156152d157600080fd5b60008060008060008060a087890312156154d157600080fd5b8635955060208701356001600160401b038111156154ee57600080fd5b6154fa89828a01615121565b979a90995096976040810135976060820135975060809091013595509350505050565b60006020828403121561552f57600080fd5b8135611a8681615249565b600381106114cb57600080fd5b600080600080600080610160878903121561556157600080fd5b863561556c8161553a565b955061557b8860208901615350565b94506101008701356001600160401b0381111561559757600080fd5b6155a389828a01615121565b90955093505061012087013591506101408701356155c081615249565b809150509295509295509295565b6000806000806000608086880312156155e657600080fd5b853594506020860135935060408601356155ff816153b4565b925060608601356001600160401b038111156151af57600080fd5b600060e0828403121561562c57600080fd5b60405160e081018181106001600160401b038211171561565c57634e487b7160e01b600052604160045260246000fd5b8060405250809150825161566f81615249565b8082525060208301516020820152604083015160408201526060830151615695816153b4565b806060830152506080830151608082015260a083015160a082015260c083015160c08201525092915050565b600061012082840312156156d457600080fd5b604051606081018181106001600160401b038211171561570457634e487b7160e01b600052604160045260246000fd5b604052615711848461561a565b815260e0830151602082015261010090920151604083015250919050565b60006020828403121561574157600080fd5b8151611a8681615249565b60208082526009908201526839bbb4b1b41037b33360b91b604082015260600190565b6000610180828403121561578257600080fd5b60405160c081018181106001600160401b03821117156157b257634e487b7160e01b600052604160045260246000fd5b60405282516157c08161553a565b81526157cf846020850161561a565b60208201526101008301516157e381615249565b6040820152610120830151606082015261014083015160808201526101609092015160a083015250919050565b634e487b7160e01b600052602160045260246000fd5b60006080828403121561583857600080fd5b604051608081018181106001600160401b038211171561586857634e487b7160e01b600052604160045260246000fd5b60405282518152602083015161587d81615249565b602082015260408381015190820152606083015161589a816153b4565b60608201529392505050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156158d6576158d66158a6565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615900576159006158db565b500490565b6000806040838503121561591857600080fd5b505080516020909101519092909150565b60006020828403121561593b57600080fd5b5051919050565b60008219821115615955576159556158a6565b500190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600082821015615990576159906158a6565b500390565b6000602082840312156159a757600080fd5b8151611a86816153b4565b600060e082840312156159c457600080fd5b60405160e081018181106001600160401b03821117156159f457634e487b7160e01b600052604160045260246000fd5b6040528235615a0281615249565b8082525060208301356020820152604083013560408201526060830135615a28816153b4565b806060830152506080830135608082015260a083013560a082015260c083013560c08201528091505092915050565b60006001600160ff1b0381841382841380821686840486111615615a7d57615a7d6158a6565b600160ff1b6000871282811687830589121615615a9c57615a9c6158a6565b60008712925087820587128484161615615ab857615ab86158a6565b87850587128184161615615ace57615ace6158a6565b505050929093029392505050565b6020808252600890820152671bdd5d08189bdb9960c21b604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006020808501808196508560051b810191508460005b87811015615bab5782840389528135601e19883603018112615b6257600080fd5b870185810190356001600160401b03811115615b7d57600080fd5b803603821315615b8c57600080fd5b615b97868284615afe565b9a87019a9550505090840190600101615b41565b5091979650505050505050565b8581528415156020820152608060408201526000615bda608083018587615b27565b905082151560608301529695505050505050565b8581528415156020820152608060408201526000615c10608083018587615b27565b90508260608301529695505050505050565b60005b83811015615c3d578181015183820152602001615c25565b8381111561103a5750506000910152565b6020815260008251806020840152615c6d816040850160208701615c22565b601f01601f19169190910160400192915050565b80516001600160a01b0316825260208082015190830152604080820151908301526060808201511515908301526080808201519083015260a0818101519083015260c090810151910152565b615cd8828251615c81565b602081015160e08301526040015161010090910152565b8281526101408101611a866020830184615ccd565b8381526101608101615d196020830185615ccd565b82610140830152949350505050565b60008083128015600160ff1b850184121615615d4657615d466158a6565b6001600160ff1b0384018313811615615d6157615d616158a6565b50500390565b600082615d7657615d766158db565b600160ff1b821460001984141615615d9057615d906158a6565b500590565b60048110615da557615da5615810565b9052565b6000610100820190508982528860208301528760408301528660608301528560808301528460a08301528360c083015261423e60e0830184615d95565b848152602081018490528215156040820152608081016117b76060830184615d95565b600080821280156001600160ff1b0384900385131615615e2b57615e2b6158a6565b600160ff1b8390038412811615615e4457615e446158a6565b50500190565b600060018201615e5c57615e5c6158a6565b5060010190565b60038110615da557615da5615810565b615e7e828251615e63565b6020810151615e906020840182615c81565b5060408101516001600160a01b03166101008301526060810151610120830152608081015161014083015260a0015161016090910152565b8281526101a08101611a866020830184615e73565b61018081016113ce8284615e73565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101615f4b6020830187615e63565b84604083015283606083015282151560808301529695505050505050565b60008251615f7b818460208701615c22565b919091019291505056fea26469706673582212204e3078ef521543cf93b50e1ec045a6b14fa2a28cd791c7fe5397460968eba5f764736f6c634300080f0033
Deployed Bytecode
0x60806040526004361061023b5760003560e01c80637dc0d1d01161012e578063cc83bfd2116100ab578063f485ccf01161006f578063f485ccf01461064b578063f750704f14610662578063fbfa77cf14610675578063fc2a5b1d14610695578063fd77f87f146106b557600080fd5b8063cc83bfd2146105b6578063e30c3978146105d6578063efbc5fc0146105f4578063efcf0bd01461060b578063f2fde38b1461062b57600080fd5b8063a53fcde8116100f2578063a53fcde81461052c578063a5c34ba71461054c578063bb1c7c2a14610562578063c04398ee14610583578063c0c53b8b1461059657600080fd5b80637dc0d1d01461049b5780637ece45e8146104bb578063806762a0146104db5780638bc846c9146104fb5780638da5cb5b1461050e57600080fd5b80634c7d7d3f116101bc5780636bc81aa2116101805780636bc81aa21461041a578063715018a614610431578063725348901461044657806378250b631461046657806379ba50971461048657600080fd5b80634c7d7d3f1461039157806358d7bf80146103b25780635bd3e1c8146103c95780635c975abb146103e0578063615728f81461040357600080fd5b80631c4695f4116102035780631c4695f4146103055780631c7f6f4c1461031a57806324f746971461033a5780632bf6e0a514610351578063338b01331461037157600080fd5b806304c7ec71146102405780630845d69d1461026257806316b820911461028257806316fff074146102ac57806318897bb7146102e5575b600080fd5b34801561024c57600080fd5b5061026061025b36600461516c565b6106d5565b005b34801561026e57600080fd5b5061026061027d3660046151cc565b6108d4565b34801561028e57600080fd5b5061029961010b5481565b6040519081526020015b60405180910390f35b3480156102b857600080fd5b50610101546102cd906001600160a01b031681565b6040516001600160a01b0390911681526020016102a3565b3480156102f157600080fd5b5060fd546102cd906001600160a01b031681565b34801561031157600080fd5b50610260610943565b34801561032657600080fd5b506102606103353660046151fe565b610b66565b34801561034657600080fd5b506102996101085481565b34801561035d57600080fd5b5061026061036c36600461525e565b610cd5565b34801561037d57600080fd5b5061026061038c366004615297565b610da5565b34801561039d57600080fd5b50610102546102cd906001600160a01b031681565b3480156103be57600080fd5b506102996101095481565b3480156103d557600080fd5b506102996101065481565b3480156103ec57600080fd5b5060655460ff1660405190151581526020016102a3565b34801561040f57600080fd5b506102996101045481565b34801561042657600080fd5b506102996101075481565b34801561043d57600080fd5b50610260611040565b34801561045257600080fd5b506102996104613660046152e9565b611054565b34801561047257600080fd5b5061026061048136600461530b565b6113d4565b34801561049257600080fd5b50610260611454565b3480156104a757600080fd5b5060fc546102cd906001600160a01b031681565b3480156104c757600080fd5b506102606104d63660046151cc565b6114ce565b3480156104e757600080fd5b506102606104f6366004615337565b61154d565b610299610509366004615368565b611720565b34801561051a57600080fd5b506097546001600160a01b03166102cd565b34801561053857600080fd5b506102996105473660046153c2565b611793565b34801561055857600080fd5b5061029960ff5481565b34801561056e57600080fd5b5061010a546102cd906001600160a01b031681565b6102996105913660046153f8565b6117c0565b3480156105a257600080fd5b506102606105b1366004615431565b611a8d565b3480156105c257600080fd5b506102606105d1366004615471565b611c7e565b3480156105e257600080fd5b5060c9546001600160a01b03166102cd565b34801561060057600080fd5b506102996101055481565b34801561061757600080fd5b506102606106263660046154b8565b6120dc565b34801561063757600080fd5b5061026061064636600461551d565b6122a2565b34801561065757600080fd5b506102996101005481565b610299610670366004615547565b612313565b34801561068157600080fd5b5060fe546102cd906001600160a01b031681565b3480156106a157600080fd5b5060fb546102cd906001600160a01b031681565b3480156106c157600080fd5b506102606106d03660046155ce565b612365565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610721573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074591906156c1565b80515190915061075490612a7f565b600061076c8260000151602001518585600080612ac4565b905085156107c0578151606001516107865780861061078a565b8086115b6107c05760405162461bcd60e51b8152602060048201526002602482015261074760f41b60448201526064015b60405180910390fd5b841561080d578151606001516107d8578085116107dc565b8085105b61080d5760405162461bcd60e51b81526020600482015260026024820152611cdb60f21b60448201526064016107b7565b610101546040516311ceca8960e11b815260048101899052600060248201819052604482018990526064820188905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b15801561087057600080fd5b505af1158015610884573d6000803e3d6000fd5b5050604080518a8152602081018a90529081018890527f3fea1f17d88eda811ab87655f92885a6ec5fc9fd390aca775b9327f43ad00d77925060600190505b60405180910390a150505050505050565b6108dc612d9d565b61010b8490556101068390556101078290556101088190556040805185815260208101859052908101839052606081018290527faac5f778cabbb5dc9b9bd42735e5edd375300dc814bb0a323d1fc879d247a1f7906080015b60405180910390a150505050565b61010160009054906101000a90046001600160a01b03166001600160a01b031663fc2a5b1d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb919061572f565b60fb80546001600160a01b0319166001600160a01b0392831617905561010154604080516307dc0d1d60e41b815290519190921691637dc0d1d09160048083019260209291908290030181865afa158015610a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3e919061572f565b60fc80546001600160a01b0319166001600160a01b0392831617905561010154604080516318897bb760e01b8152905191909216916318897bb79160048083019260209291908290030181865afa158015610a9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac1919061572f565b60fd80546001600160a01b0319166001600160a01b03928316179055610101546040805163fbfa77cf60e01b81529051919092169163fbfa77cf9160048083019260209291908290030181865afa158015610b20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b44919061572f565b60fe80546001600160a01b0319166001600160a01b0392909216919091179055565b610b6e612df7565b600260ff548111610b915760405162461bcd60e51b81526004016107b79061574c565b6101015460405163471b4d7560e01b8152600481018690526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015610bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c01919061576f565b9050610c108160a00151612e50565b600081516002811115610c2557610c25615810565b14610c3757610c378160a00151612e8c565b60008082516002811115610c4d57610c4d615810565b14610c59576001610c5c565b60025b90506000610c7983602001516020015187878660a0015186612ac4565b90506000610cb188856020015160fb60009054906101000a90046001600160a01b031687606001518860800151878a60000151612ed3565b9050610cc2846040015189836133c5565b5050505050610cd060018055565b505050565b610cdd612d9d565b6001600160a01b03821615801590610cfd57506001600160a01b03811615155b610d355760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107b7565b61010180546001600160a01b038481166001600160a01b0319928316811790935561010280549185169190921681179091556040805192835260208301919091527f41fe2135e07f51f107aa1df22b2d51b5b6328f3a324fbfc555699785941adb59910160405180910390a15050565b610dad612df7565b600260ff548111610dd05760405162461bcd60e51b81526004016107b79061574c565b6101015460405163315896b560e11b815260048101879052602481018690526000916001600160a01b0316906362b12d6a90604401608060405180830381865afa158015610e22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e469190615826565b9050610e558160400151612e50565b806060015115610e965760405162461bcd60e51b815260206004820152600c60248201526b616c7265616479206578656360a01b60448201526064016107b7565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015610ee2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0691906156c1565b90506000610f24826000015160200151878786604001516002612ac4565b90506000610f488360200151838560000151608001518660000151606001516134b0565b610101546040516368a5479360e11b8152600481018c9052602481018b9052600160448201529192506001600160a01b03169063d14a8f2690606401600060405180830381600087803b158015610f9e57600080fd5b505af1158015610fb2573d6000803e3d6000fd5b505060fb548651610fd993506001600160a01b0390911691508b908590879060008761358b565b604080518a8152602081018a905260018183015290517f28cf3bfcf594f6c4e9da1e79297930dbd971dcae2e08a19857abc14e759e94019181900360600190a161102c84602001518a8a60016000613d19565b505050505061103a60018055565b50505050565b611048612d9d565b6110526000613e31565b565b61010154604051633a02776f60e11b81526004810184905260009182916001600160a01b0390911690637404eede9060240161012060405180830381865afa1580156110a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c891906156c1565b905080602001516000036110e05760009150506113ce565b60006111028260200151858460000151608001518560000151606001516134b0565b82516080810151604090910151919250600091670de0b6b3a764000091611128916158bc565b61113291906158f1565b60fb5484516020810151606090910151604051637325d71160e01b8152600481018b90526024810192909252604482018490521515606482015291925060009182916001600160a01b031690637325d711906084016040805180830381865afa1580156111a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c79190615905565b91509150600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8a88600001516020015189602001518a60000151604001518b60000151608001518c60000151606001516040518763ffffffff1660e01b8152600401611261969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a29190615929565b865160c00151909150600090600190156112d9578751606001516112cd57875160c0015183106112d6565b875160c0015183115b90505b8080156112f657506112f6838b60018b6000015160600151613e4a565b1561132357610104548851604001516103e891611312916158bc565b61131c91906158f1565b91506113b0565b60fb548851602001516040516341b51a0d60e11b815260048101919091526103e8916001600160a01b03169063836a341a90602401602060405180830381865afa158015611375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113999190615929565b6113a390886158bc565b6113ad91906158f1565b91505b8751604001516113c39088868886613ee6565b985050505050505050505b92915050565b6113dc612d9d565b6103e881610104546113ee9190615942565b106113f857600080fd5b61010a80546001600160a01b0319166001600160a01b0384169081179091556101098290556040518281527f9241e21d4fa6dd55661c8694538bfc11a7d44d81d5766840312d2513f55fa67d9060200160405180910390a25050565b60c95433906001600160a01b031681146114c25760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016107b7565b6114cb81613e31565b50565b6114d6612d9d565b6103e8841080156114e857506103e883105b6114f157600080fd5b61010484905560ff8190556101058390556101008290556040805185815260208101859052908101839052606081018290527fe33eb1ee60efac814379b14a1d72ec5d666301d3264613e9d3f4ad9ef38b094690608001610935565b611555612df7565b600260ff5481116115785760405162461bcd60e51b81526004016107b79061574c565b6101015460405163471b4d7560e01b8152600481018490526000916001600160a01b03169063471b4d759060240161018060405180830381865afa1580156115c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e8919061576f565b90506115fb816020015160000151612a7f565b8051611608906000613f46565b61010154610102546020830151805160409182015191516352f950a960e11b81526001600160a01b039485169463a5f2a1529461164b949116929160040161595a565b600060405180830381600087803b15801561166557600080fd5b505af1158015611679573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018790526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b1580156116c457600080fd5b505af11580156116d8573d6000803e3d6000fd5b505050507f1dbfda3a6640539c3fac591e271a7b4ccd445cf9bc2b951e58abde22dfe73f538360405161170d91815260200190565b60405180910390a150506114cb60018055565b600061172a612df7565b6103e8831061173857600080fd5b60006103e861174785876158bc565b61175191906158f1565b9050600061175f8287615942565b9050600061176d838861597e565b905061177d600089848489613fa7565b935050505061178b60018055565b949350505050565b60fb54610105546000916117b7916001600160a01b0390911690879087878761413e565b95945050505050565b60006117ca612df7565b600260ff5481116117ed5760405162461bcd60e51b81526004016107b79061574c565b610101546040516346cb95c960e11b8152600481018790526000916001600160a01b031690638d972b9290602401602060405180830381865afa158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185c9190615929565b61010154604051633a02776f60e11b8152600481018990529192506000916001600160a01b0390911690637404eede9060240161012060405180830381865afa1580156118ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d191906156c1565b90506118dc8661424b565b8051516118e890612a7f565b6118f56101065486614285565b6118ff8683615942565b8151604001519092508211156119415760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107b7565b80516040015182146119825760fb5481516020810151604090910151611982926001600160a01b0316919061197790869061597e565b8451608001516142de565b61010154604080516080810182528881526001600160a01b0388811660208301908152600083850181815260608501828152955162c9f2ed60e81b8152600481018f905294516024860152915183166044850152905160648401529251151560848301529192919091169063c9f2ed009060a4016020604051808303816000875af1158015611a15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a399190615929565b6040805189815242602082015291925082918a917f7695d3ca62416d30d27e9fac1080c5322b164e257e8151db3b139aec5d81605e910160405180910390a39350505050611a8660018055565b9392505050565b600054610100900460ff1615808015611aad5750600054600160ff909116105b80611ac75750303b158015611ac7575060005460ff166001145b611b2a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016107b7565b6000805460ff191660011790558015611b4d576000805461ff0019166101001790555b611b55614392565b611b5d6143c1565b611b6684613e31565b6001600160a01b03831615801590611b8657506001600160a01b03821615155b8015611b9a57506001600160a01b03841615155b611bd25760405162461bcd60e51b81526020600482015260096024820152680616464726573735f360bc1b60448201526064016107b7565b61010180546001600160a01b038086166001600160a01b0319928316179092556101028054928516929091169190911790556032610104556103cf610105556601c6bf5263400061010655600061010b5562030d4061010855655af3107a400061010755601461010055801561103a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610935565b611c86612df7565b600260ff548111611ca95760405162461bcd60e51b81526004016107b79061574c565b6000846003811115611cbd57611cbd615810565b03611cf65760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107b7565b61010154604051633a02776f60e11b8152600481018790526000916001600160a01b031690637404eede9060240161012060405180830381865afa158015611d42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6691906156c1565b9050611d758160400151612e50565b6001856003811115611d8957611d89615810565b14611d9b57611d9b8160400151612e8c565b6000611db4826000015160200151868660006001612ac4565b905060006001876003811115611dcc57611dcc615810565b03611eec5760fb548351602080820151908601516040808401516080850151606090950151915163369e333760e11b8152600481018f9052602481019490945260448401929092526064830191909152608482019290925290151560a48201526001600160a01b0390911690636d3c666e9060c401602060405180830381865afa158015611e5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e829190615929565b835160c0015190915015611ee757825160600151611ea757825160c001518110611eb0565b825160c0015181115b611ee75760405162461bcd60e51b81526020600482015260086024820152671cdb08199a5c9cdd60c21b60448201526064016107b7565b611f93565b6002876003811115611f0057611f00615810565b03611f5157611f2483602001518460000151608001518560000151606001516143f0565b835160a0015190915015611ee757825160a0810151606090910151611f4a918391614452565b9050611f93565b825160c00151611f8b5760405162461bcd60e51b81526020600482015260056024820152641b9bc81cdb60da1b60448201526064016107b7565b50815160c001515b611fa7818389866000015160600151613e4a565b611fdf5760405162461bcd60e51b81526020600482015260096024820152680dcdee840a4cac2c6d60bb1b60448201526064016107b7565b60fb54835160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916120179160040190815260200190565b602060405180830381865afa158015612034573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120589190615995565b80156120765750600187600381111561207357612073615810565b14155b1561207f578091505b60006120a18460200151848660000151608001518760000151606001516134b0565b60fb548551604001519192506120ca916001600160a01b03909116908b90869088908d8761358b565b83515161102c908a600060018c613d19565b6101015460405163471b4d7560e01b8152600481018890526000916001600160a01b03169063471b4d759060240161018060405180830381865afa158015612128573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214c919061576f565b905061215f816020015160000151612a7f565b805161216c906000613f46565b8315612196576121878160200151878787856000015161447d565b60608101849052608081018490525b82156121a857602081015160a0018390525b81156121ba57602081015160c0018290525b60fb546020820151606083015160808401516121e1936001600160a01b0316929190614503565b61010154604051631e34099d60e01b815260048101899052602481018690526044810186905260648101859052608481018490526001600160a01b0390911690631e34099d9060a401600060405180830381600087803b15801561224457600080fd5b505af1158015612258573d6000803e3d6000fd5b5050604080518a815260208101889052908101869052606081018590527fed9036017ec7fc31a1ca97298d80b8219039778a809afd38dc6480cea3964a4b925060800190506108c3565b6122aa612d9d565b60c980546001600160a01b0383166001600160a01b031990911681179091556122db6097546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600061231d612df7565b612328876000613f46565b61234361233a368890038801886159b2565b8686868b61447d565b6123508787858686613fa7565b905061235b60018055565b9695505050505050565b61236d612df7565b600260ff5481116123905760405162461bcd60e51b81526004016107b79061574c565b61010154604051633a02776f60e11b8152600481018890526000916001600160a01b031690637404eede9060240161012060405180830381865afa1580156123dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240091906156c1565b80515190915061240f90612a7f565b6124188661424b565b80516080810151604090910151600091612431916158bc565b610101546040516346cb95c960e11b8152600481018b90529192506001600160a01b031690638d972b9290602401602060405180830381865afa15801561247c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a09190615929565b156124da5760405162461bcd60e51b815260206004820152600a6024820152697761697420636c6f736560b01b60448201526064016107b7565b60006124f28360000151602001518787600080612ac4565b9050600080881561267657600061251f8660200151858860000151608001518960000151606001516134b0565b90506125316402540be4006009615a57565b81126125695760405162461bcd60e51b81526020600482015260076024820152661b585e08141b9b60ca1b60448201526064016107b7565b85516040015161257a908c90615942565b925061258683866158f1565b60fb548751602081015160609091015160405163369dd0b160e01b81526004810192909252602482018f9052151560448201529193506001600160a01b03169063369dd0b190606401602060405180830381865afa1580156125ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126109190615995565b1561264f5760405162461bcd60e51b815260206004820152600f60248201526e10dbdb1b185d195c985b131a5b5a5d608a1b60448201526064016107b7565b6101025461010154612670916001600160a01b03908116913391168e6145d6565b50612914565b8451604001518a1061269a5760405162461bcd60e51b81526004016107b790615adc565b8451604001516126ab908b9061597e565b855160c0015190925015801590612736575060fb54855160200151604051636d9bbfa160e11b81526001600160a01b039092169163db377f42916126f59160040190815260200190565b602060405180830381865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127369190615995565b1561277557612758856000015160c00151846003886000015160600151613e4a565b156127755760405162461bcd60e51b81526004016107b790615adc565b61277f82856158f1565b9050600060fb60009054906101000a90046001600160a01b03166001600160a01b0316636d3c666e8d886000015160200151896020015187878c60000151606001516040518763ffffffff1660e01b8152600401612807969594939291909586526020860194909452604085019290925260608401526080830152151560a082015260c00190565b602060405180830381865afa158015612824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128489190615929565b905061285f81856001896000015160600151613e4a565b1561287c5760405162461bcd60e51b81526004016107b790615adc565b61010160009054906101000a90046001600160a01b03166001600160a01b031663a5f2a15261010260009054906101000a90046001600160a01b03168860000151600001518e6040518463ffffffff1660e01b81526004016128e09392919061595a565b600060405180830381600087803b1580156128fa57600080fd5b505af115801561290e573d6000803e3d6000fd5b50505050505b60fb54855160200151612932916001600160a01b03169084846142de565b610101546040516311ceca8960e11b8152600481018d9052602481018490526000604482018190526064820181905260848201526001600160a01b039091169063239d95129060a401600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b505050506000670de0b6b3a764000082846129c491906158bc565b6129ce91906158f1565b6129e0670de0b6b3a7640000876158f1565b6129ea919061597e565b60fb5487516020810151606090910151929350612a19926001600160a01b03909216918e9085908f600061462e565b604080518d8152602081018d90528b151581830152606081018590526080810184905290517fb58ece2937681ab71ee2a4257af71abb8d43386650f2fd177ee49164f8a0a4ca9181900360a00190a150505050505050612a7860018055565b5050505050565b6001600160a01b03811633146114cb5760405162461bcd60e51b815260206004820152600a6024820152693737ba103a3930b232b960b11b60448201526064016107b7565b6000806002836002811115612adb57612adb615810565b14612c445760fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b039283169263d46720d092169062e9f38b90602401602060405180830381865afa158015612b32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b569190615929565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc39190615995565b89896000896002811115612bd957612bd9615810565b146040518663ffffffff1660e01b8152600401612bfa959493929190615bb8565b6020604051808303816000875af1158015612c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3d9190615929565b9050612d90565b60fc5460fb5460405162e9f38b60e01b8152600481018a90526001600160a01b0392831692635c3c66dd92169062e9f38b90602401602060405180830381865afa158015612c96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cba9190615929565b60fb54604051638359077160e01b8152600481018c90526001600160a01b0390911690638359077190602401602060405180830381865afa158015612d03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d279190615995565b8989896040518663ffffffff1660e01b8152600401612d4a959493929190615bee565b6020604051808303816000875af1158015612d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d8d9190615929565b90505b6000811161235b57600080fd5b6097546001600160a01b031633146110525760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107b7565b600260015403612e495760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107b7565b6002600155565b806000036114cb5760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195e1a5cdd60ba1b60448201526064016107b7565b426101005482612e9c9190615942565b11156114cb5760405162461bcd60e51b81526004016107b7906020808252600490820152631dd85a5d60e21b604082015260600190565b600080670de0b6b3a764000088608001518960400151612ef391906158bc565b612efd91906158f1565b9050612f188785610105548b60200151858d6060015161413e565b9350600080612f2c898b8a8a8a888b614721565b90925090506000856002811115612f4557612f45615810565b148015612f50575081155b1561306b5761010154610102548b516040808e015190516352f950a960e11b81526001600160a01b039485169463a5f2a15294612f9494911692909160040161595a565b600060405180830381600087803b158015612fae57600080fd5b505af1158015612fc2573d6000803e3d6000fd5b50506101015460405163d07abd5960e01b8152600481018f90526001600160a01b03909116925063d07abd599150602401600060405180830381600087803b15801561300d57600080fd5b505af1158015613021573d6000803e3d6000fd5b5050604080518e8152600060208201527f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def648935001905060405180910390a1600093505050506133ba565b808261308a5760405162461bcd60e51b81526004016107b79190615c4e565b506000620186a08a6001600160a01b0316638251135b8d602001516040518263ffffffff1660e01b81526004016130c391815260200190565b602060405180830381865afa1580156130e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131049190615929565b61310e90866158bc565b61311891906158f1565b9050808b60400181815161312c919061597e565b90525060808b015160408c0151670de0b6b3a76400009161314c916158bc565b61315691906158f1565b935061316981858d6000015160016149bd565b6131858a8c602001518d60400151878f6060015160018061462e565b60408051606081019091528b81526000906020810160018960028111156131ae576131ae615810565b036131b9578b6131bb565b895b81526020016000815250905061010160009054906101000a90046001600160a01b03166001600160a01b0316638611e17e8e836040518363ffffffff1660e01b815260040161320b929190615cef565b600060405180830381600087803b15801561322557600080fd5b505af1158015613239573d6000803e3d6000fd5b505050508a6001600160a01b0316636ada93dd8e8e602001518f606001516040518463ffffffff1660e01b81526004016132889392919092835260208301919091521515604082015260600190565b600060405180830381600087803b1580156132a257600080fd5b505af11580156132b6573d6000803e3d6000fd5b5050505061010160009054906101000a90046001600160a01b03166001600160a01b031663d07abd598e6040518263ffffffff1660e01b81526004016132fe91815260200190565b600060405180830381600087803b15801561331857600080fd5b505af115801561332c573d6000803e3d6000fd5b505050507f6fc494543173949b35b8ae1933d2c0f5208180b4f2aef262bb87523bb1def6488d600160405161336d9291909182521515602082015260400190565b60405180910390a17f09c087e430ee6913868eafe26e6d9da87f95984c61bde74e50e28ecd09da890a8d82846040516133a893929190615d04565b60405180910390a16001955050505050505b979650505050505050565b61010b546001600160a01b0384163b1561349b57610107546133e79082615942565b6101085460405163b2a11f8560e01b81526004810186905284151560248201529192506000916001600160a01b0387169163b2a11f8591604401600060405180830381600088803b15801561343b57600080fd5b5087f19350505050801561344d575060015b15613456575060015b604080516001600160a01b038716815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a1505b801561103a5761103a81614b25565b60018055565b6000806134c36402540be4006009615a57565b905060008315613513576134d687614bad565b6402540be4006134e589614bad565b6134ee89614bad565b6134f89190615d28565b6135029190615a57565b61350c9190615d67565b9050613555565b61351c87614bad565b6402540be40061352b88614bad565b6135348a614bad565b61353e9190615d28565b6135489190615a57565b6135529190615d67565b90505b670de0b6b3a76400006135688683615a57565b6135729190615d67565b905081811361358157806133ba565b5095945050505050565b6135bd6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b8451608001516000906135d090866158bc565b905060006135e6670de0b6b3a7640000836158f1565b90508560018660038111156135fd576135fd615810565b0361363d576103e8610104548861361491906158bc565b61361e91906158f1565b608085015261362c87614bf5565b613636908261597e565b90506136e0565b8751602001516040516341b51a0d60e11b81526004810191909152670de0b6b3a764000090620186a0906001600160a01b038e169063836a341a90602401602060405180830381865afa158015613698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136bc9190615929565b6136c690866158bc565b6136d091906158f1565b6136da91906158f1565b60808501525b87516020810151606090910151604051637325d71160e01b8152600481018d9052602481019290925260448201849052151560648201526001600160a01b038c1690637325d711906084016040805180830381865afa158015613747573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061376b9190615905565b6040860181905260208601829052608086015161378e928a928992909190613ee6565b606085015260808401518851516137a99190849060006149bd565b60808401516137b8908261597e565b905083606001518111156139435760608401511561384357610101546101025489515160608701516040516352f950a960e11b81526001600160a01b039485169463a5f2a1529461381094911692909160040161595a565b600060405180830381600087803b15801561382a57600080fd5b505af115801561383e573d6000803e3d6000fd5b505050505b6000846060015182613855919061597e565b610101546101025460fe546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a15293613895938116921690869060040161595a565b600060405180830381600087803b1580156138af57600080fd5b505af11580156138c3573d6000803e3d6000fd5b505060fe548b515160405163ceb5caa560e01b81526001600160a01b0391821660048201526024810186905260006044820181905260648201529116925063ceb5caa59150608401600060405180830381600087803b15801561392557600080fd5b505af1158015613939573d6000803e3d6000fd5b5050505050613a3c565b6000818560600151613955919061597e565b905080156139c65760fe5489515160405163496d1af960e11b81526001600160a01b039182166004820152602481018490529116906392da35f290604401600060405180830381600087803b1580156139ad57600080fd5b505af11580156139c1573d6000803e3d6000fd5b505050505b8115613a3a5761010154610102548a51516040516352f950a960e11b81526001600160a01b039384169363a5f2a15293613a0793911691879060040161595a565b600060405180830381600087803b158015613a2157600080fd5b505af1158015613a35573d6000803e3d6000fd5b505050505b505b875160400151600090613a5090899061597e565b9050826000829003613bc0576101015460405163348c68ad60e11b8152600481018e90526001600160a01b0390911690636918d15a90602401600060405180830381600087803b158015613aa357600080fd5b505af1158015613ab7573d6000803e3d6000fd5b505050508c6001600160a01b031663b8d040e48d6040518263ffffffff1660e01b8152600401613ae991815260200190565b600060405180830381600087803b158015613b0357600080fd5b505af1158015613b17573d6000803e3d6000fd5b505061010154604051631eb17e1b60e21b81526001600160a01b039091169250637ac5f86c9150613b50908f9060040190815260200190565b600060405180830381600087803b158015613b6a57600080fd5b505af1158015613b7e573d6000803e3d6000fd5b505050507fbe2b332e8e34afe0840746913f0e88f88fbbda69b3c05c49a197de3f559412778c604051613bb391815260200190565b60405180910390a1613c95565b895160800151670de0b6b3a764000090613bda90846158bc565b613be491906158f1565b8a516080810151604090910151670de0b6b3a764000091613c04916158bc565b613c0e91906158f1565b613c18919061597e565b610101546040516311ceca8960e11b8152600481018f9052602481018590526000604482018190526064820152600160848201529192506001600160a01b03169063239d95129060a401600060405180830381600087803b158015613c7c57600080fd5b505af1158015613c90573d6000803e3d6000fd5b505050505b613cb58d8b60000151602001518b848e600001516060015160008061462e565b7f24b27bc2a65d006b06d5ee8450abfa71760f2aac880fcf5555af1e692cfaf5398c8c8b89602001518a604001518b608001518c606001518f604051613d02989796959493929190615da9565b60405180910390a150505050505050505050505050565b60006001600160a01b0386163b15613df5576101075461010654613d3d9190615942565b90506000866001600160a01b031663657409e261010854888888886040518663ffffffff1660e01b8152600401613d779493929190615de6565b600060405180830381600088803b158015613d9157600080fd5b5087f193505050508015613da3575060015b15613dac575060015b604080516001600160a01b038916815282151560208201527f46ddbd62fc1a7626fe9c43026cb0694aec0b031fe81ac66fb4cfe9381dc6fe72910160405180910390a150613dfb565b50610106545b6000826003811115613e0f57613e0f615810565b148015613e1b57508015155b15613e2957613e2981614b25565b505050505050565b60c980546001600160a01b03191690556114cb81614cb1565b60008115613e9c576002836003811115613e6657613e66615810565b1480613e8357506000836003811115613e8157613e81615810565b145b15613e9257508383101561178b565b508383111561178b565b6002836003811115613eb057613eb0615810565b1480613ecd57506000836003811115613ecb57613ecb615810565b145b15613edc57508383111561178b565b508383101561178b565b60008083856402540be400613efb898b615a57565b613f059190615d67565b613f0f908a615e09565b613f199190615d28565b613f239190615d28565b9050613f2f8382615d28565b90506000811361235b576000979650505050505050565b806002811115613f5857613f58615810565b826002811115613f6a57613f6a615810565b03613fa35760405162461bcd60e51b81526020600482015260096024820152681d5b9cdd5c1c1bdc9d60ba1b60448201526064016107b7565b5050565b6000613fbe613fb9602087018761551d565b612a7f565b613fcb61010b5483614285565b60fb54613ff1906001600160a01b0316613fea368890038801886159b2565b8686614503565b6101025461010154614016916001600160a01b039081169133911660408901356145d6565b60006040518060c0016040528088600281111561403557614035615810565b8152602001614049368990038901896159b2565b8152602001846001600160a01b031681526020018681526020018581526020014281525090506000614095600088602001356101036000815461408b90615e4a565b9182905550614d03565b6101015460405163030dfab360e61b81529192506001600160a01b03169063c37eacc0906140c99084908690600401615ec8565b600060405180830381600087803b1580156140e357600080fd5b505af11580156140f7573d6000803e3d6000fd5b50505050807fc815d98967a87feaaa8e57736b69b57611867c43e87d7c0cd7ba5edf3f13c5288360405161412b9190615edd565b60405180910390a2979650505050505050565b60405163a1d54e9b60e01b81526004810184905260009081906001600160a01b0389169063a1d54e9b90602401602060405180830381865afa158015614188573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ac9190615929565b905060006141bc88888487614d46565b604051633f54af9960e11b815260048101829052602481018890528515156044820152606481018790529091506001600160a01b038a1690637ea95f3290608401602060405180830381865afa15801561421a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061423e9190615929565b9998505050505050505050565b806000036114cb5760405162461bcd60e51b8152602060048201526007602482015266076616c75655f360cc1b60448201526064016107b7565b6001600160a01b038116156142a557610107546142a29083615942565b91505b813414613fa35760405162461bcd60e51b8152602060048201526007602482015266666565206d697360c81b60448201526064016107b7565b60405163a833064560e01b81526004810184905260248101839052604481018290526000906001600160a01b0386169063a833064590606401602060405180830381865afa158015614334573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143589190615995565b905080612a785760405162461bcd60e51b81526020600482015260086024820152676f75742073697a6560c01b60448201526064016107b7565b600054610100900460ff166143b95760405162461bcd60e51b81526004016107b790615eec565b611052614da6565b600054610100900460ff166143e85760405162461bcd60e51b81526004016107b790615eec565b611052614dd9565b60008083670de0b6b3a76400006144086009886158bc565b61441291906158bc565b61441c91906158f1565b905082156144365761442e8186615942565b915050611a86565b80851015614448576000915050611a86565b61442e818661597e565b60008115614470578284106144675782614469565b835b9050611a86565b8284116144675782614469565b600061449186602001518686600080612ac4565b905060006144bb60fb60009054906101000a90046001600160a01b03168884876101055488614e00565b9050806144fa5760405162461bcd60e51b815260206004820152600d60248201526c1a5b1b1959d85b081b1a5b5a5d609a1b60448201526064016107b7565b50505050505050565b61451b848460200151856040015186608001516142de565b60008360a00151600014806145485750836060015161454057818460a0015110614548565b828460a00151115b905060008460c00151600014806145775750846060015161456f57838560c0015111614577565b828560c00151105b9050600083851015801561458b5750600084115b80156145945750825b801561459d5750815b9050806144fa5760405162461bcd60e51b81526020600482015260076024820152661a5b1b1959d85b60ca1b60448201526064016107b7565b61103a846323b872dd60e01b8585856040516024016145f79392919061595a565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614ea8565b6040516310787e2f60e11b81526004810187905260248101869052831515604482015282151560648201526001600160a01b038816906320f0fc5e90608401600060405180830381600087803b15801561468757600080fd5b505af115801561469b573d6000803e3d6000fd5b50505050836000146144fa57604051631ae6a88f60e31b81526004810187905260248101859052831515604482015281151560648201526001600160a01b0388169063d735447890608401600060405180830381600087803b15801561470057600080fd5b505af1158015614714573d6000803e3d6000fd5b5050505050505050505050565b600060606147368787878b6060015187614f7d565b61476a57505060408051808201909152600f81526e1c1c9a58d9481bdd5d081b1a5b5a5d608a1b60208201526000906149b1565b60208801516040808a015160608b0151915163369dd0b160e01b815260048101939093526024830152151560448201526001600160a01b038a169063369dd0b190606401602060405180830381865afa1580156147cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147ef9190615995565b1561482457505060408051808201909152600f81526e10dbdb1b185d195c985b131a5b5a5d608a1b60208201526000906149b1565b6020880151606089015160405163ec8b6fa160e01b8152600481019290925260248201869052151560448201526001600160a01b038a169063ec8b6fa190606401602060405180830381865afa158015614882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a69190615995565b6148d857505060408051808201909152600d81526c125b9d195c995cdd131a5b5a5d609a1b60208201526000906149b1565b60008360028111156148ec576148ec615810565b1461499c5760208801516060890151604051632ff8ac0760e21b81526001600160a01b038c169263bfe2b01c9261492c9288918d918c9190600401615f37565b602060405180830381865afa158015614949573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061496d9190615995565b61499c57505060408051808201909152600a8152691bdd5d0814dc1c99585960b21b60208201526000906149b1565b50506040805160208101909152600081526001905b97509795505050505050565b610101546101025460fd546040516352f950a960e11b81526001600160a01b039384169363a5f2a152936149fc9390821692911690899060040161595a565b600060405180830381600087803b158015614a1657600080fd5b505af1158015614a2a573d6000803e3d6000fd5b505050508015614aac5760fd5460405163031708bd60e11b81526001600160a01b03848116600483015233602483015260448201879052606482018690529091169063062e117a90608401600060405180830381600087803b158015614a8f57600080fd5b505af1158015614aa3573d6000803e3d6000fd5b5050505061103a565b60fd546040516312f8aacd60e21b81526001600160a01b038481166004830152336024830152604482018790526064820186905290911690634be2ab3490608401600060405180830381600087803b158015614b0757600080fd5b505af1158015614b1b573d6000803e3d6000fd5b5050505050505050565b604051600090339083908381818185875af1925050503d8060008114614b67576040519150601f19603f3d011682016040523d82523d6000602084013e614b6c565b606091505b5050905080613fa35760405162461bcd60e51b815260206004820152600d60248201526c1d1c985b9cd9995c8819985a5b609a1b60448201526064016107b7565b60006001600160ff1b03821115614bf15760405162461bcd60e51b81526020600482015260086024820152676f766572666c6f7760c01b60448201526064016107b7565b5090565b61010a5460009081906001600160a01b031615801590614c1757506101095415155b156113ce576103e86101095484614c2e91906158bc565b614c3891906158f1565b610101546101025461010a546040516352f950a960e11b81529394506001600160a01b039283169363a5f2a15293614c79938116921690869060040161595a565b600060405180830381600087803b158015614c9357600080fd5b505af1158015614ca7573d6000803e3d6000fd5b5050505092915050565b609780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600062ffffff83108015614d1d57506001600160e01b0382105b614d395760405162461bcd60e51b81526004016107b790615adc565b5060e09190911b17919050565b600080614d55856103e861597e565b905060006103e88281614d68888b6158bc565b614d7291906158f1565b614d7c91906158bc565b614d8691906158f1565b905083614d9c57614d97818861597e565b6133ba565b6133ba8188615942565b600054610100900460ff16614dcd5760405162461bcd60e51b81526004016107b790615eec565b6065805460ff19169055565b600054610100900460ff166134aa5760405162461bcd60e51b81526004016107b790615eec565b600080670de0b6b3a764000087608001518860400151614e2091906158bc565b614e2a91906158f1565b9050614e428887868a60200151858c6060015161413e565b9550866060015115614e7b576001836002811115614e6257614e62615810565b03614e7157505083831061235b565b505083831161235b565b6001836002811115614e8f57614e8f615810565b03614e9e57505083831161235b565b505083831061235b565b6000614efd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661500e9092919063ffffffff16565b9050805160001480614f1e575080806020019051810190614f1e9190615995565b610cd05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107b7565b600080826002811115614f9257614f92615810565b03614fae57848410158015614fa75750858411155b90506117b7565b8215614fe1576001826002811115614fc857614fc8615810565b03614fd75750838311156117b7565b50848310156117b7565b6001826002811115614ff557614ff5615810565b036150045750848310156117b7565b50838311156117b7565b606061178b848460008585600080866001600160a01b031685876040516150359190615f69565b60006040518083038185875af1925050503d8060008114615072576040519150601f19603f3d011682016040523d82523d6000602084013e615077565b606091505b50915091506133ba87838387606083156150f25782516000036150eb576001600160a01b0385163b6150eb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b7565b508161178b565b61178b83838151156151075781518083602001fd5b8060405162461bcd60e51b81526004016107b79190615c4e565b60008083601f84011261513357600080fd5b5081356001600160401b0381111561514a57600080fd5b6020830191508360208260051b850101111561516557600080fd5b9250929050565b60008060008060006080868803121561518457600080fd5b85359450602086013593506040860135925060608601356001600160401b038111156151af57600080fd5b6151bb88828901615121565b969995985093965092949392505050565b600080600080608085870312156151e257600080fd5b5050823594602084013594506040840135936060013592509050565b60008060006040848603121561521357600080fd5b8335925060208401356001600160401b0381111561523057600080fd5b61523c86828701615121565b9497909650939450505050565b6001600160a01b03811681146114cb57600080fd5b6000806040838503121561527157600080fd5b823561527c81615249565b9150602083013561528c81615249565b809150509250929050565b600080600080606085870312156152ad57600080fd5b843593506020850135925060408501356001600160401b038111156152d157600080fd5b6152dd87828801615121565b95989497509550505050565b600080604083850312156152fc57600080fd5b50508035926020909101359150565b6000806040838503121561531e57600080fd5b823561532981615249565b946020939093013593505050565b60006020828403121561534957600080fd5b5035919050565b600060e0828403121561536257600080fd5b50919050565b600080600080610140858703121561537f57600080fd5b6153898686615350565b935060e0850135925061010085013591506101208501356153a981615249565b939692955090935050565b80151581146114cb57600080fd5b600080600080608085870312156153d857600080fd5b84359350602085013592506040850135915060608501356153a9816153b4565b60008060006060848603121561540d57600080fd5b8335925060208401359150604084013561542681615249565b809150509250925092565b60008060006060848603121561544657600080fd5b833561545181615249565b9250602084013561546181615249565b9150604084013561542681615249565b6000806000806060858703121561548757600080fd5b8435935060208501356004811061549d57600080fd5b925060408501356001600160401b038111156152d157600080fd5b60008060008060008060a087890312156154d157600080fd5b8635955060208701356001600160401b038111156154ee57600080fd5b6154fa89828a01615121565b979a90995096976040810135976060820135975060809091013595509350505050565b60006020828403121561552f57600080fd5b8135611a8681615249565b600381106114cb57600080fd5b600080600080600080610160878903121561556157600080fd5b863561556c8161553a565b955061557b8860208901615350565b94506101008701356001600160401b0381111561559757600080fd5b6155a389828a01615121565b90955093505061012087013591506101408701356155c081615249565b809150509295509295509295565b6000806000806000608086880312156155e657600080fd5b853594506020860135935060408601356155ff816153b4565b925060608601356001600160401b038111156151af57600080fd5b600060e0828403121561562c57600080fd5b60405160e081018181106001600160401b038211171561565c57634e487b7160e01b600052604160045260246000fd5b8060405250809150825161566f81615249565b8082525060208301516020820152604083015160408201526060830151615695816153b4565b806060830152506080830151608082015260a083015160a082015260c083015160c08201525092915050565b600061012082840312156156d457600080fd5b604051606081018181106001600160401b038211171561570457634e487b7160e01b600052604160045260246000fd5b604052615711848461561a565b815260e0830151602082015261010090920151604083015250919050565b60006020828403121561574157600080fd5b8151611a8681615249565b60208082526009908201526839bbb4b1b41037b33360b91b604082015260600190565b6000610180828403121561578257600080fd5b60405160c081018181106001600160401b03821117156157b257634e487b7160e01b600052604160045260246000fd5b60405282516157c08161553a565b81526157cf846020850161561a565b60208201526101008301516157e381615249565b6040820152610120830151606082015261014083015160808201526101609092015160a083015250919050565b634e487b7160e01b600052602160045260246000fd5b60006080828403121561583857600080fd5b604051608081018181106001600160401b038211171561586857634e487b7160e01b600052604160045260246000fd5b60405282518152602083015161587d81615249565b602082015260408381015190820152606083015161589a816153b4565b60608201529392505050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156158d6576158d66158a6565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615900576159006158db565b500490565b6000806040838503121561591857600080fd5b505080516020909101519092909150565b60006020828403121561593b57600080fd5b5051919050565b60008219821115615955576159556158a6565b500190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600082821015615990576159906158a6565b500390565b6000602082840312156159a757600080fd5b8151611a86816153b4565b600060e082840312156159c457600080fd5b60405160e081018181106001600160401b03821117156159f457634e487b7160e01b600052604160045260246000fd5b6040528235615a0281615249565b8082525060208301356020820152604083013560408201526060830135615a28816153b4565b806060830152506080830135608082015260a083013560a082015260c083013560c08201528091505092915050565b60006001600160ff1b0381841382841380821686840486111615615a7d57615a7d6158a6565b600160ff1b6000871282811687830589121615615a9c57615a9c6158a6565b60008712925087820587128484161615615ab857615ab86158a6565b87850587128184161615615ace57615ace6158a6565b505050929093029392505050565b6020808252600890820152671bdd5d08189bdb9960c21b604082015260600190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b81835260006020808501808196508560051b810191508460005b87811015615bab5782840389528135601e19883603018112615b6257600080fd5b870185810190356001600160401b03811115615b7d57600080fd5b803603821315615b8c57600080fd5b615b97868284615afe565b9a87019a9550505090840190600101615b41565b5091979650505050505050565b8581528415156020820152608060408201526000615bda608083018587615b27565b905082151560608301529695505050505050565b8581528415156020820152608060408201526000615c10608083018587615b27565b90508260608301529695505050505050565b60005b83811015615c3d578181015183820152602001615c25565b8381111561103a5750506000910152565b6020815260008251806020840152615c6d816040850160208701615c22565b601f01601f19169190910160400192915050565b80516001600160a01b0316825260208082015190830152604080820151908301526060808201511515908301526080808201519083015260a0818101519083015260c090810151910152565b615cd8828251615c81565b602081015160e08301526040015161010090910152565b8281526101408101611a866020830184615ccd565b8381526101608101615d196020830185615ccd565b82610140830152949350505050565b60008083128015600160ff1b850184121615615d4657615d466158a6565b6001600160ff1b0384018313811615615d6157615d616158a6565b50500390565b600082615d7657615d766158db565b600160ff1b821460001984141615615d9057615d906158a6565b500590565b60048110615da557615da5615810565b9052565b6000610100820190508982528860208301528760408301528660608301528560808301528460a08301528360c083015261423e60e0830184615d95565b848152602081018490528215156040820152608081016117b76060830184615d95565b600080821280156001600160ff1b0384900385131615615e2b57615e2b6158a6565b600160ff1b8390038412811615615e4457615e446158a6565b50500190565b600060018201615e5c57615e5c6158a6565b5060010190565b60038110615da557615da5615810565b615e7e828251615e63565b6020810151615e906020840182615c81565b5060408101516001600160a01b03166101008301526060810151610120830152608081015161014083015260a0015161016090910152565b8281526101a08101611a866020830184615e73565b61018081016113ce8284615e73565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101615f4b6020830187615e63565b84604083015283606083015282151560808301529695505050505050565b60008251615f7b818460208701615c22565b919091019291505056fea26469706673582212204e3078ef521543cf93b50e1ec045a6b14fa2a28cd791c7fe5397460968eba5f764736f6c634300080f0033
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.