Source Code
Latest 25 from a total of 1,785 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Create Increase ... | 83483206 | 91 days ago | IN | 0.15 MNT | 0.05833175 | ||||
| Create Increase ... | 82301360 | 118 days ago | IN | 20.15 MNT | 0.24261202 | ||||
| Create Increase ... | 82301220 | 118 days ago | IN | 20.15 MNT | 0.24922384 | ||||
| Cancel Multiple | 82185363 | 121 days ago | IN | 0 MNT | 0.04381203 | ||||
| Create Increase ... | 82185154 | 121 days ago | IN | 15.15 MNT | 0.24145764 | ||||
| Create Increase ... | 82185136 | 121 days ago | IN | 15.15 MNT | 0.24959628 | ||||
| Create Increase ... | 82179291 | 121 days ago | IN | 15.15 MNT | 0.24528834 | ||||
| Cancel Increase ... | 82177864 | 121 days ago | IN | 0 MNT | 0.02343656 | ||||
| Create Increase ... | 82177675 | 121 days ago | IN | 15.15 MNT | 0.23251731 | ||||
| Cancel Increase ... | 82177655 | 121 days ago | IN | 0 MNT | 0.02337867 | ||||
| Create Increase ... | 82177164 | 121 days ago | IN | 15.15 MNT | 0.23830802 | ||||
| Cancel Increase ... | 82101743 | 123 days ago | IN | 0 MNT | 0.00950603 | ||||
| Create Increase ... | 82101317 | 123 days ago | IN | 16.15 MNT | 0.09802917 | ||||
| Cancel Increase ... | 80635993 | 157 days ago | IN | 0 MNT | 0.00775619 | ||||
| Cancel Increase ... | 80635988 | 157 days ago | IN | 0 MNT | 0.00908939 | ||||
| Create Decrease ... | 73932746 | 312 days ago | IN | 0.150001 MNT | 0.01528909 | ||||
| Cancel Decrease ... | 73464603 | 323 days ago | IN | 0 MNT | 0.00633661 | ||||
| Cancel Decrease ... | 73464597 | 323 days ago | IN | 0 MNT | 0.00634267 | ||||
| Cancel Increase ... | 73442429 | 323 days ago | IN | 0 MNT | 0.01337489 | ||||
| Create Increase ... | 73442061 | 323 days ago | IN | 0.15 MNT | 0.08817061 | ||||
| Cancel Increase ... | 73442023 | 323 days ago | IN | 0 MNT | 0.01338319 | ||||
| Create Increase ... | 73441536 | 323 days ago | IN | 0.15 MNT | 0.08914611 | ||||
| Cancel Decrease ... | 73441517 | 323 days ago | IN | 0 MNT | 0.00411336 | ||||
| Cancel Increase ... | 73441512 | 323 days ago | IN | 0 MNT | 0.00686126 | ||||
| Create Increase ... | 73441494 | 323 days ago | IN | 0.15 MNT | 0.04955314 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 83483206 | 91 days ago | 0.15 MNT | ||||
| 83483206 | 91 days ago | 2 wei | ||||
| 82301360 | 118 days ago | 20.15 MNT | ||||
| 82301360 | 118 days ago | 8 wei | ||||
| 82301220 | 118 days ago | 20.15 MNT | ||||
| 82301220 | 118 days ago | 8 wei | ||||
| 82185363 | 121 days ago | 15.15 MNT | ||||
| 82185363 | 121 days ago | 15.15 MNT | ||||
| 82185363 | 121 days ago | 15.15 MNT | ||||
| 82185363 | 121 days ago | 15.15 MNT | ||||
| 82185363 | 121 days ago | 15.15 MNT | ||||
| 82185363 | 121 days ago | 15.15 MNT | ||||
| 82185154 | 121 days ago | 15.15 MNT | ||||
| 82185154 | 121 days ago | 8 wei | ||||
| 82185136 | 121 days ago | 15.15 MNT | ||||
| 82185136 | 121 days ago | 8 wei | ||||
| 82179291 | 121 days ago | 15.15 MNT | ||||
| 82179291 | 121 days ago | 8 wei | ||||
| 82177864 | 121 days ago | 15.15 MNT | ||||
| 82177864 | 121 days ago | 15.15 MNT | ||||
| 82177675 | 121 days ago | 15.15 MNT | ||||
| 82177675 | 121 days ago | 8 wei | ||||
| 82177655 | 121 days ago | 15.15 MNT | ||||
| 82177655 | 121 days ago | 15.15 MNT | ||||
| 82177164 | 121 days ago | 15.15 MNT |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OrderBook
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 10 runs
Other Settings:
istanbul EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "../libraries/math/SafeMath.sol";
import "../libraries/token/IERC20.sol";
import "../tokens/interfaces/IWETH.sol";
import "../libraries/token/SafeERC20.sol";
import "../libraries/utils/Address.sol";
import "../libraries/utils/ReentrancyGuard.sol";
import "./interfaces/IRouter.sol";
import "./interfaces/IVault.sol";
import "./interfaces/IOrderBook.sol";
contract OrderBook is ReentrancyGuard, IOrderBook {
using SafeMath for uint256;
using SafeERC20 for IERC20;
using Address for address payable;
uint256 public constant PRICE_PRECISION = 1e30;
uint256 public constant USDG_PRECISION = 1e18;
struct IncreaseOrder {
address account;
address purchaseToken;
uint256 purchaseTokenAmount;
address collateralToken;
address indexToken;
uint256 sizeDelta;
bool isLong;
uint256 triggerPrice;
bool triggerAboveThreshold;
uint256 executionFee;
}
struct DecreaseOrder {
address account;
address collateralToken;
uint256 collateralDelta;
address indexToken;
uint256 sizeDelta;
bool isLong;
uint256 triggerPrice;
bool triggerAboveThreshold;
uint256 executionFee;
}
struct SwapOrder {
address account;
address[] path;
uint256 amountIn;
uint256 minOut;
uint256 triggerRatio;
bool triggerAboveThreshold;
bool shouldUnwrap;
uint256 executionFee;
}
mapping (address => mapping(uint256 => IncreaseOrder)) public increaseOrders;
mapping (address => uint256) public increaseOrdersIndex;
mapping (address => mapping(uint256 => DecreaseOrder)) public decreaseOrders;
mapping (address => uint256) public decreaseOrdersIndex;
mapping (address => mapping(uint256 => SwapOrder)) public swapOrders;
mapping (address => uint256) public swapOrdersIndex;
address public gov;
address public weth;
address public usdg;
address public router;
address public vault;
uint256 public minExecutionFee;
uint256 public minPurchaseTokenAmountUsd;
bool public isInitialized = false;
event CreateIncreaseOrder(
address indexed account,
uint256 orderIndex,
address purchaseToken,
uint256 purchaseTokenAmount,
address collateralToken,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
);
event CancelIncreaseOrder(
address indexed account,
uint256 orderIndex,
address purchaseToken,
uint256 purchaseTokenAmount,
address collateralToken,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
);
event ExecuteIncreaseOrder(
address indexed account,
uint256 orderIndex,
address purchaseToken,
uint256 purchaseTokenAmount,
address collateralToken,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee,
uint256 executionPrice
);
event UpdateIncreaseOrder(
address indexed account,
uint256 orderIndex,
address collateralToken,
address indexToken,
bool isLong,
uint256 sizeDelta,
uint256 triggerPrice,
bool triggerAboveThreshold
);
event CreateDecreaseOrder(
address indexed account,
uint256 orderIndex,
address collateralToken,
uint256 collateralDelta,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
);
event CancelDecreaseOrder(
address indexed account,
uint256 orderIndex,
address collateralToken,
uint256 collateralDelta,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
);
event ExecuteDecreaseOrder(
address indexed account,
uint256 orderIndex,
address collateralToken,
uint256 collateralDelta,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee,
uint256 executionPrice
);
event UpdateDecreaseOrder(
address indexed account,
uint256 orderIndex,
address collateralToken,
uint256 collateralDelta,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold
);
event CreateSwapOrder(
address indexed account,
uint256 orderIndex,
address[] path,
uint256 amountIn,
uint256 minOut,
uint256 triggerRatio,
bool triggerAboveThreshold,
bool shouldUnwrap,
uint256 executionFee
);
event CancelSwapOrder(
address indexed account,
uint256 orderIndex,
address[] path,
uint256 amountIn,
uint256 minOut,
uint256 triggerRatio,
bool triggerAboveThreshold,
bool shouldUnwrap,
uint256 executionFee
);
event UpdateSwapOrder(
address indexed account,
uint256 ordexIndex,
address[] path,
uint256 amountIn,
uint256 minOut,
uint256 triggerRatio,
bool triggerAboveThreshold,
bool shouldUnwrap,
uint256 executionFee
);
event ExecuteSwapOrder(
address indexed account,
uint256 orderIndex,
address[] path,
uint256 amountIn,
uint256 minOut,
uint256 amountOut,
uint256 triggerRatio,
bool triggerAboveThreshold,
bool shouldUnwrap,
uint256 executionFee
);
event Initialize(
address router,
address vault,
address weth,
address usdg,
uint256 minExecutionFee,
uint256 minPurchaseTokenAmountUsd
);
event UpdateMinExecutionFee(uint256 minExecutionFee);
event UpdateMinPurchaseTokenAmountUsd(uint256 minPurchaseTokenAmountUsd);
event UpdateGov(address gov);
modifier onlyGov() {
require(msg.sender == gov, "OrderBook: forbidden");
_;
}
constructor() public {
gov = msg.sender;
}
function initialize(
address _router,
address _vault,
address _weth,
address _usdg,
uint256 _minExecutionFee,
uint256 _minPurchaseTokenAmountUsd
) external onlyGov {
require(!isInitialized, "OrderBook: already initialized");
isInitialized = true;
router = _router;
vault = _vault;
weth = _weth;
usdg = _usdg;
minExecutionFee = _minExecutionFee;
minPurchaseTokenAmountUsd = _minPurchaseTokenAmountUsd;
emit Initialize(_router, _vault, _weth, _usdg, _minExecutionFee, _minPurchaseTokenAmountUsd);
}
receive() external payable {
require(msg.sender == weth, "OrderBook: invalid sender");
}
function setMinExecutionFee(uint256 _minExecutionFee) external onlyGov {
minExecutionFee = _minExecutionFee;
emit UpdateMinExecutionFee(_minExecutionFee);
}
function setMinPurchaseTokenAmountUsd(uint256 _minPurchaseTokenAmountUsd) external onlyGov {
minPurchaseTokenAmountUsd = _minPurchaseTokenAmountUsd;
emit UpdateMinPurchaseTokenAmountUsd(_minPurchaseTokenAmountUsd);
}
function setGov(address _gov) external onlyGov {
gov = _gov;
emit UpdateGov(_gov);
}
function getSwapOrder(address _account, uint256 _orderIndex) override public view returns (
address path0,
address path1,
address path2,
uint256 amountIn,
uint256 minOut,
uint256 triggerRatio,
bool triggerAboveThreshold,
bool shouldUnwrap,
uint256 executionFee
) {
SwapOrder memory order = swapOrders[_account][_orderIndex];
return (
order.path.length > 0 ? order.path[0] : address(0),
order.path.length > 1 ? order.path[1] : address(0),
order.path.length > 2 ? order.path[2] : address(0),
order.amountIn,
order.minOut,
order.triggerRatio,
order.triggerAboveThreshold,
order.shouldUnwrap,
order.executionFee
);
}
function createSwapOrder(
address[] memory _path,
uint256 _amountIn,
uint256 _minOut,
uint256 _triggerRatio, // tokenB / tokenA
bool _triggerAboveThreshold,
uint256 _executionFee,
bool _shouldWrap,
bool _shouldUnwrap
) external payable nonReentrant {
require(_path.length == 2 || _path.length == 3, "OrderBook: invalid _path.length");
require(_path[0] != _path[_path.length - 1], "OrderBook: invalid _path");
require(_amountIn > 0, "OrderBook: invalid _amountIn");
require(_executionFee >= minExecutionFee, "OrderBook: insufficient execution fee");
// always need this call because of mandatory executionFee user has to transfer in ETH
_transferInETH(0);
if (_shouldWrap) {
require(_path[0] == weth, "OrderBook: only weth could be wrapped");
require(msg.value == _executionFee.add(_amountIn), "OrderBook: incorrect value transferred");
} else {
require(msg.value == _executionFee, "OrderBook: incorrect execution fee transferred");
IRouter(router).pluginTransfer(_path[0], msg.sender, address(this), _amountIn);
}
_createSwapOrder(msg.sender, _path, _amountIn, _minOut, _triggerRatio, _triggerAboveThreshold, _shouldUnwrap, _executionFee);
}
function _createSwapOrder(
address _account,
address[] memory _path,
uint256 _amountIn,
uint256 _minOut,
uint256 _triggerRatio,
bool _triggerAboveThreshold,
bool _shouldUnwrap,
uint256 _executionFee
) private {
uint256 _orderIndex = swapOrdersIndex[_account];
SwapOrder memory order = SwapOrder(
_account,
_path,
_amountIn,
_minOut,
_triggerRatio,
_triggerAboveThreshold,
_shouldUnwrap,
_executionFee
);
swapOrdersIndex[_account] = _orderIndex.add(1);
swapOrders[_account][_orderIndex] = order;
emit CreateSwapOrder(
_account,
_orderIndex,
_path,
_amountIn,
_minOut,
_triggerRatio,
_triggerAboveThreshold,
_shouldUnwrap,
_executionFee
);
}
function cancelMultiple(
uint256[] memory _swapOrderIndexes,
uint256[] memory _increaseOrderIndexes,
uint256[] memory _decreaseOrderIndexes
) external {
for (uint256 i = 0; i < _swapOrderIndexes.length; i++) {
cancelSwapOrder(_swapOrderIndexes[i]);
}
for (uint256 i = 0; i < _increaseOrderIndexes.length; i++) {
cancelIncreaseOrder(_increaseOrderIndexes[i]);
}
for (uint256 i = 0; i < _decreaseOrderIndexes.length; i++) {
cancelDecreaseOrder(_decreaseOrderIndexes[i]);
}
}
function cancelSwapOrder(uint256 _orderIndex) public nonReentrant {
SwapOrder memory order = swapOrders[msg.sender][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
delete swapOrders[msg.sender][_orderIndex];
if (order.path[0] == weth) {
_transferOutETH(order.executionFee.add(order.amountIn), msg.sender);
} else {
IERC20(order.path[0]).safeTransfer(msg.sender, order.amountIn);
_transferOutETH(order.executionFee, msg.sender);
}
emit CancelSwapOrder(
msg.sender,
_orderIndex,
order.path,
order.amountIn,
order.minOut,
order.triggerRatio,
order.triggerAboveThreshold,
order.shouldUnwrap,
order.executionFee
);
}
function getUsdgMinPrice(address _otherToken) public view returns (uint256) {
// USDG_PRECISION is the same as 1 USDG
uint256 redemptionAmount = IVault(vault).getRedemptionAmount(_otherToken, USDG_PRECISION);
uint256 otherTokenPrice = IVault(vault).getMinPrice(_otherToken);
uint256 otherTokenDecimals = IVault(vault).tokenDecimals(_otherToken);
return redemptionAmount.mul(otherTokenPrice).div(10 ** otherTokenDecimals);
}
function validateSwapOrderPriceWithTriggerAboveThreshold(
address[] memory _path,
uint256 _triggerRatio
) public view returns (bool) {
require(_path.length == 2 || _path.length == 3, "OrderBook: invalid _path.length");
// limit orders don't need this validation because minOut is enough
// so this validation handles scenarios for stop orders only
// when a user wants to swap when a price of tokenB increases relative to tokenA
address tokenA = _path[0];
address tokenB = _path[_path.length - 1];
uint256 tokenAPrice;
uint256 tokenBPrice;
// 1. USDG doesn't have a price feed so we need to calculate it based on redepmtion amount of a specific token
// That's why USDG price in USD can vary depending on the redepmtion token
// 2. In complex scenarios with path=[USDG, BNB, BTC] we need to know how much BNB we'll get for provided USDG
// to know how much BTC will be received
// That's why in such scenario BNB should be used to determine price of USDG
if (tokenA == usdg) {
// with both _path.length == 2 or 3 we need usdg price against _path[1]
tokenAPrice = getUsdgMinPrice(_path[1]);
} else {
tokenAPrice = IVault(vault).getMinPrice(tokenA);
}
if (tokenB == usdg) {
tokenBPrice = PRICE_PRECISION;
} else {
tokenBPrice = IVault(vault).getMaxPrice(tokenB);
}
uint256 currentRatio = tokenBPrice.mul(PRICE_PRECISION).div(tokenAPrice);
bool isValid = currentRatio > _triggerRatio;
return isValid;
}
function updateSwapOrder(uint256 _orderIndex, uint256 _minOut, uint256 _triggerRatio, bool _triggerAboveThreshold) external nonReentrant {
SwapOrder storage order = swapOrders[msg.sender][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
order.minOut = _minOut;
order.triggerRatio = _triggerRatio;
order.triggerAboveThreshold = _triggerAboveThreshold;
emit UpdateSwapOrder(
msg.sender,
_orderIndex,
order.path,
order.amountIn,
_minOut,
_triggerRatio,
_triggerAboveThreshold,
order.shouldUnwrap,
order.executionFee
);
}
function executeSwapOrder(address _account, uint256 _orderIndex, address payable _feeReceiver) override external nonReentrant {
SwapOrder memory order = swapOrders[_account][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
if (order.triggerAboveThreshold) {
// gas optimisation
// order.minAmount should prevent wrong price execution in case of simple limit order
require(
validateSwapOrderPriceWithTriggerAboveThreshold(order.path, order.triggerRatio),
"OrderBook: invalid price for execution"
);
}
delete swapOrders[_account][_orderIndex];
IERC20(order.path[0]).safeTransfer(vault, order.amountIn);
uint256 _amountOut;
if (order.path[order.path.length - 1] == weth && order.shouldUnwrap) {
_amountOut = _swap(order.path, order.minOut, address(this));
_transferOutETH(_amountOut, payable(order.account));
} else {
_amountOut = _swap(order.path, order.minOut, order.account);
}
// pay executor
_transferOutETH(order.executionFee, _feeReceiver);
emit ExecuteSwapOrder(
_account,
_orderIndex,
order.path,
order.amountIn,
order.minOut,
_amountOut,
order.triggerRatio,
order.triggerAboveThreshold,
order.shouldUnwrap,
order.executionFee
);
}
function validatePositionOrderPrice(
bool _triggerAboveThreshold,
uint256 _triggerPrice,
address _indexToken,
bool _maximizePrice,
bool _raise
) public view returns (uint256, bool) {
uint256 currentPrice = _maximizePrice
? IVault(vault).getMaxPrice(_indexToken) : IVault(vault).getMinPrice(_indexToken);
bool isPriceValid = _triggerAboveThreshold ? currentPrice > _triggerPrice : currentPrice < _triggerPrice;
if (_raise) {
require(isPriceValid, "OrderBook: invalid price for execution");
}
return (currentPrice, isPriceValid);
}
function getDecreaseOrder(address _account, uint256 _orderIndex) override public view returns (
address collateralToken,
uint256 collateralDelta,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
) {
DecreaseOrder memory order = decreaseOrders[_account][_orderIndex];
return (
order.collateralToken,
order.collateralDelta,
order.indexToken,
order.sizeDelta,
order.isLong,
order.triggerPrice,
order.triggerAboveThreshold,
order.executionFee
);
}
function getIncreaseOrder(address _account, uint256 _orderIndex) override public view returns (
address purchaseToken,
uint256 purchaseTokenAmount,
address collateralToken,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
) {
IncreaseOrder memory order = increaseOrders[_account][_orderIndex];
return (
order.purchaseToken,
order.purchaseTokenAmount,
order.collateralToken,
order.indexToken,
order.sizeDelta,
order.isLong,
order.triggerPrice,
order.triggerAboveThreshold,
order.executionFee
);
}
struct CreateIncreaseOrderParams {
address[] path;
uint256 amountIn;
address indexToken;
uint256 minOut;
uint256 sizeDelta;
address collateralToken;
bool isLong;
uint256 triggerPrice;
bool triggerAboveThreshold;
uint256 executionFee;
bool shouldWrap;
}
function createIncreaseOrder(
CreateIncreaseOrderParams calldata params,
bytes[] calldata _pythUpdateData
) external payable nonReentrant {
uint256 pythUpdateFee = _updatePythPrices(_pythUpdateData);
// always need this call because of mandatory executionFee user has to transfer in ETH
_transferInETH(pythUpdateFee);
address[] memory path = params.path;
require(params.executionFee >= minExecutionFee, "OrderBook: insufficient execution fee");
if (params.shouldWrap) {
require(path[0] == weth, "OrderBook: only weth could be wrapped");
require(msg.value.sub(pythUpdateFee) == params.executionFee.add(params.amountIn), "OrderBook: incorrect value transferred");
} else {
require(msg.value.sub(pythUpdateFee) == params.executionFee, "OrderBook: incorrect execution fee transferred");
IRouter(router).pluginTransfer(params.path[0], msg.sender, address(this), params.amountIn);
}
uint256 _purchaseTokenAmount;
if (path.length > 1) {
require(path[0] != path[path.length - 1], "OrderBook: invalid _path"); // path[path.length - 1] = purchaseToken
IERC20(path[0]).safeTransfer(vault, params.amountIn);
_purchaseTokenAmount = _swap(path, params.minOut, address(this));
} else {
_purchaseTokenAmount = params.amountIn;
}
{
uint256 _purchaseTokenAmountUsd = IVault(vault).tokenToUsdMin(path[path.length - 1], _purchaseTokenAmount); // path[path.length - 1] = purchaseToken
require(_purchaseTokenAmountUsd >= minPurchaseTokenAmountUsd, "OrderBook: insufficient collateral");
}
_createIncreaseOrder(
msg.sender,
path[path.length - 1], // purchaseToken
_purchaseTokenAmount,
params.collateralToken,
params.indexToken,
params.sizeDelta,
params.isLong,
params.triggerPrice,
params.triggerAboveThreshold,
params.executionFee
);
}
function _updatePythPrices(bytes[] calldata _pythUpdateData) private returns(uint256 updateFee) {
IPyth pyth = IVault(vault).getPyth();
updateFee = pyth.getUpdateFee(_pythUpdateData);
require(msg.value >= updateFee, "insufficient msg.value to update pyth prices");
pyth.updatePriceFeeds{value: updateFee}(_pythUpdateData);
}
function _createIncreaseOrder(
address _account,
address _purchaseToken,
uint256 _purchaseTokenAmount,
address _collateralToken,
address _indexToken,
uint256 _sizeDelta,
bool _isLong,
uint256 _triggerPrice,
bool _triggerAboveThreshold,
uint256 _executionFee
) private {
uint256 _orderIndex = increaseOrdersIndex[msg.sender];
IncreaseOrder memory order = IncreaseOrder(
_account,
_purchaseToken,
_purchaseTokenAmount,
_collateralToken,
_indexToken,
_sizeDelta,
_isLong,
_triggerPrice,
_triggerAboveThreshold,
_executionFee
);
increaseOrdersIndex[_account] = _orderIndex.add(1);
increaseOrders[_account][_orderIndex] = order;
emit CreateIncreaseOrder(
_account,
_orderIndex,
_purchaseToken,
_purchaseTokenAmount,
_collateralToken,
_indexToken,
_sizeDelta,
_isLong,
_triggerPrice,
_triggerAboveThreshold,
_executionFee
);
}
function updateIncreaseOrder(uint256 _orderIndex, uint256 _sizeDelta, uint256 _triggerPrice, bool _triggerAboveThreshold) external nonReentrant {
IncreaseOrder storage order = increaseOrders[msg.sender][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
order.triggerPrice = _triggerPrice;
order.triggerAboveThreshold = _triggerAboveThreshold;
order.sizeDelta = _sizeDelta;
emit UpdateIncreaseOrder(
msg.sender,
_orderIndex,
order.collateralToken,
order.indexToken,
order.isLong,
_sizeDelta,
_triggerPrice,
_triggerAboveThreshold
);
}
function cancelIncreaseOrder(uint256 _orderIndex) public nonReentrant {
IncreaseOrder memory order = increaseOrders[msg.sender][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
delete increaseOrders[msg.sender][_orderIndex];
if (order.purchaseToken == weth) {
_transferOutETH(order.executionFee.add(order.purchaseTokenAmount), msg.sender);
} else {
IERC20(order.purchaseToken).safeTransfer(msg.sender, order.purchaseTokenAmount);
_transferOutETH(order.executionFee, msg.sender);
}
emit CancelIncreaseOrder(
order.account,
_orderIndex,
order.purchaseToken,
order.purchaseTokenAmount,
order.collateralToken,
order.indexToken,
order.sizeDelta,
order.isLong,
order.triggerPrice,
order.triggerAboveThreshold,
order.executionFee
);
}
function executeIncreaseOrder(address _address, uint256 _orderIndex, address payable _feeReceiver) override external nonReentrant {
IncreaseOrder memory order = increaseOrders[_address][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
// increase long should use max price
// increase short should use min price
(uint256 currentPrice, ) = validatePositionOrderPrice(
order.triggerAboveThreshold,
order.triggerPrice,
order.indexToken,
order.isLong,
true
);
delete increaseOrders[_address][_orderIndex];
IERC20(order.purchaseToken).safeTransfer(vault, order.purchaseTokenAmount);
if (order.purchaseToken != order.collateralToken) {
address[] memory path = new address[](2);
path[0] = order.purchaseToken;
path[1] = order.collateralToken;
uint256 amountOut = _swap(path, 0, address(this));
IERC20(order.collateralToken).safeTransfer(vault, amountOut);
}
IRouter(router).pluginIncreasePosition(order.account, order.collateralToken, order.indexToken, order.sizeDelta, order.isLong);
// pay executor
_transferOutETH(order.executionFee, _feeReceiver);
emit ExecuteIncreaseOrder(
order.account,
_orderIndex,
order.purchaseToken,
order.purchaseTokenAmount,
order.collateralToken,
order.indexToken,
order.sizeDelta,
order.isLong,
order.triggerPrice,
order.triggerAboveThreshold,
order.executionFee,
currentPrice
);
}
function createDecreaseOrder(
address _indexToken,
uint256 _sizeDelta,
address _collateralToken,
uint256 _collateralDelta,
bool _isLong,
uint256 _triggerPrice,
bool _triggerAboveThreshold
) external payable nonReentrant {
_transferInETH(0);
require(msg.value > minExecutionFee, "OrderBook: insufficient execution fee");
_createDecreaseOrder(
msg.sender,
_collateralToken,
_collateralDelta,
_indexToken,
_sizeDelta,
_isLong,
_triggerPrice,
_triggerAboveThreshold
);
}
function _createDecreaseOrder(
address _account,
address _collateralToken,
uint256 _collateralDelta,
address _indexToken,
uint256 _sizeDelta,
bool _isLong,
uint256 _triggerPrice,
bool _triggerAboveThreshold
) private {
uint256 _orderIndex = decreaseOrdersIndex[_account];
DecreaseOrder memory order = DecreaseOrder(
_account,
_collateralToken,
_collateralDelta,
_indexToken,
_sizeDelta,
_isLong,
_triggerPrice,
_triggerAboveThreshold,
msg.value
);
decreaseOrdersIndex[_account] = _orderIndex.add(1);
decreaseOrders[_account][_orderIndex] = order;
emit CreateDecreaseOrder(
_account,
_orderIndex,
_collateralToken,
_collateralDelta,
_indexToken,
_sizeDelta,
_isLong,
_triggerPrice,
_triggerAboveThreshold,
msg.value
);
}
function executeDecreaseOrder(address _address, uint256 _orderIndex, address payable _feeReceiver) override external nonReentrant {
DecreaseOrder memory order = decreaseOrders[_address][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
// decrease long should use min price
// decrease short should use max price
(uint256 currentPrice, ) = validatePositionOrderPrice(
order.triggerAboveThreshold,
order.triggerPrice,
order.indexToken,
!order.isLong,
true
);
delete decreaseOrders[_address][_orderIndex];
uint256 amountOut = IRouter(router).pluginDecreasePosition(
order.account,
order.collateralToken,
order.indexToken,
order.collateralDelta,
order.sizeDelta,
order.isLong,
address(this)
);
// transfer released collateral to user
if (order.collateralToken == weth) {
_transferOutETH(amountOut, payable(order.account));
} else {
IERC20(order.collateralToken).safeTransfer(order.account, amountOut);
}
// pay executor
_transferOutETH(order.executionFee, _feeReceiver);
emit ExecuteDecreaseOrder(
order.account,
_orderIndex,
order.collateralToken,
order.collateralDelta,
order.indexToken,
order.sizeDelta,
order.isLong,
order.triggerPrice,
order.triggerAboveThreshold,
order.executionFee,
currentPrice
);
}
function cancelDecreaseOrder(uint256 _orderIndex) public nonReentrant {
DecreaseOrder memory order = decreaseOrders[msg.sender][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
delete decreaseOrders[msg.sender][_orderIndex];
_transferOutETH(order.executionFee, msg.sender);
emit CancelDecreaseOrder(
order.account,
_orderIndex,
order.collateralToken,
order.collateralDelta,
order.indexToken,
order.sizeDelta,
order.isLong,
order.triggerPrice,
order.triggerAboveThreshold,
order.executionFee
);
}
function updateDecreaseOrder(
uint256 _orderIndex,
uint256 _collateralDelta,
uint256 _sizeDelta,
uint256 _triggerPrice,
bool _triggerAboveThreshold
) external nonReentrant {
DecreaseOrder storage order = decreaseOrders[msg.sender][_orderIndex];
require(order.account != address(0), "OrderBook: non-existent order");
order.triggerPrice = _triggerPrice;
order.triggerAboveThreshold = _triggerAboveThreshold;
order.sizeDelta = _sizeDelta;
order.collateralDelta = _collateralDelta;
emit UpdateDecreaseOrder(
msg.sender,
_orderIndex,
order.collateralToken,
_collateralDelta,
order.indexToken,
_sizeDelta,
order.isLong,
_triggerPrice,
_triggerAboveThreshold
);
}
function _transferInETH(uint256 feeDeduct) private {
if (msg.value != 0) {
IWETH(weth).deposit{value: msg.value.sub(feeDeduct)}();
}
}
function _transferOutETH(uint256 _amountOut, address payable _receiver) private {
IWETH(weth).withdraw(_amountOut);
_receiver.sendValue(_amountOut);
}
function _swap(address[] memory _path, uint256 _minOut, address _receiver) private returns (uint256) {
if (_path.length == 2) {
return _vaultSwap(_path[0], _path[1], _minOut, _receiver);
}
if (_path.length == 3) {
uint256 midOut = _vaultSwap(_path[0], _path[1], 0, address(this));
IERC20(_path[1]).safeTransfer(vault, midOut);
return _vaultSwap(_path[1], _path[2], _minOut, _receiver);
}
revert("OrderBook: invalid _path.length");
}
function _vaultSwap(address _tokenIn, address _tokenOut, uint256 _minOut, address _receiver) private returns (uint256) {
uint256 amountOut;
if (_tokenOut == usdg) { // buyUSDG
amountOut = IVault(vault).buyUSDG(_tokenIn, _receiver);
} else if (_tokenIn == usdg) { // sellUSDG
amountOut = IVault(vault).sellUSDG(_tokenOut, _receiver);
} else { // swap
amountOut = IVault(vault).swap(_tokenIn, _tokenOut, _receiver);
}
require(amountOut >= _minOut, "OrderBook: insufficient amountOut");
return amountOut;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IOrderBook {
function getSwapOrder(address _account, uint256 _orderIndex) external view returns (
address path0,
address path1,
address path2,
uint256 amountIn,
uint256 minOut,
uint256 triggerRatio,
bool triggerAboveThreshold,
bool shouldUnwrap,
uint256 executionFee
);
function getIncreaseOrder(address _account, uint256 _orderIndex) external view returns (
address purchaseToken,
uint256 purchaseTokenAmount,
address collateralToken,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
);
function getDecreaseOrder(address _account, uint256 _orderIndex) external view returns (
address collateralToken,
uint256 collateralDelta,
address indexToken,
uint256 sizeDelta,
bool isLong,
uint256 triggerPrice,
bool triggerAboveThreshold,
uint256 executionFee
);
function executeSwapOrder(address, uint256, address payable) external;
function executeDecreaseOrder(address, uint256, address payable) external;
function executeIncreaseOrder(address, uint256, address payable) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
interface IRouter {
function addPlugin(address _plugin) external;
function pluginTransfer(address _token, address _account, address _receiver, uint256 _amount) external;
function pluginIncreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _sizeDelta, bool _isLong) external;
function pluginDecreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external returns (uint256);
function swap(address[] memory _path, uint256 _amountIn, uint256 _minOut, address _receiver, bytes[] calldata _pythUpdateData) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "../../libraries/pyth/IPyth.sol";
import "./IVaultUtils.sol";
interface IVault {
function isSwapEnabled() external view returns (bool);
function isLeverageEnabled() external view returns (bool);
function setVaultUtils(IVaultUtils _vaultUtils) external;
function setError(uint256 _errorCode, string calldata _error) external;
function router() external view returns (address);
function usdg() external view returns (address);
function gov() external view returns (address);
function whitelistedTokenCount() external view returns (uint256);
function maxLeverage() external view returns (uint256);
function minProfitTime() external view returns (uint256);
function hasDynamicFees() external view returns (bool);
function fundingInterval() external view returns (uint256);
function totalTokenWeights() external view returns (uint256);
function getTargetUsdgAmount(address _token) external view returns (uint256);
function inManagerMode() external view returns (bool);
function inPrivateLiquidationMode() external view returns (bool);
function maxGasPrice() external view returns (uint256);
function approvedRouters(address _account, address _router) external view returns (bool);
function isLiquidator(address _account) external view returns (bool);
function isManager(address _account) external view returns (bool);
function minProfitBasisPoints(address _token) external view returns (uint256);
function tokenBalances(address _token) external view returns (uint256);
function lastFundingTimes(address _token) external view returns (uint256);
function setMaxLeverage(uint256 _maxLeverage) external;
function setInManagerMode(bool _inManagerMode) external;
function setManager(address _manager, bool _isManager) external;
function setIsSwapEnabled(bool _isSwapEnabled) external;
function setIsLeverageEnabled(bool _isLeverageEnabled) external;
function setMaxGasPrice(uint256 _maxGasPrice) external;
function setUsdgAmount(address _token, uint256 _amount) external;
function setBufferAmount(address _token, uint256 _amount) external;
function setMaxGlobalShortSize(address _token, uint256 _amount) external;
function setInPrivateLiquidationMode(bool _inPrivateLiquidationMode) external;
function setLiquidator(address _liquidator, bool _isActive) external;
function setFundingRate(uint256 _fundingInterval, uint256 _fundingRateFactor, uint256 _stableFundingRateFactor) external;
function setFees(
uint256 _taxBasisPoints,
uint256 _stableTaxBasisPoints,
uint256 _mintBurnFeeBasisPoints,
uint256 _swapFeeBasisPoints,
uint256 _stableSwapFeeBasisPoints,
uint256 _marginFeeBasisPoints,
uint256 _liquidationFeeUsd,
uint256 _minProfitTime,
bool _hasDynamicFees
) external;
function setTokenConfig(
address _token,
uint256 _tokenDecimals,
uint256 _redemptionBps,
uint256 _minProfitBps,
uint256 _maxUsdgAmount,
bool _isStable,
bool _isShortable
) external;
function setPriceFeed(address _priceFeed) external;
function withdrawFees(address _token, address _receiver) external returns (uint256);
function directPoolDeposit(address _token) external;
function buyUSDG(address _token, address _receiver) external returns (uint256);
function sellUSDG(address _token, address _receiver) external returns (uint256);
function swap(address _tokenIn, address _tokenOut, address _receiver) external returns (uint256);
function increasePosition(address _account, address _collateralToken, address _indexToken, uint256 _sizeDelta, bool _isLong) external;
function decreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external returns (uint256);
function validateLiquidation(address _account, address _collateralToken, address _indexToken, bool _isLong, bool _raise) external view returns (uint256, uint256);
function liquidatePosition(address _account, address _collateralToken, address _indexToken, bool _isLong, address _feeReceiver) external;
function tokenToUsdMin(address _token, uint256 _tokenAmount) external view returns (uint256);
function priceFeed() external view returns (address);
function fundingRateFactor() external view returns (uint256);
function stableFundingRateFactor() external view returns (uint256);
function cumulativeFundingRates(address _token) external view returns (uint256);
function getNextFundingRate(address _token) external view returns (uint256);
function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256);
function liquidationFeeUsd() external view returns (uint256);
function taxBasisPoints() external view returns (uint256);
function stableTaxBasisPoints() external view returns (uint256);
function mintBurnFeeBasisPoints() external view returns (uint256);
function swapFeeBasisPoints() external view returns (uint256);
function stableSwapFeeBasisPoints() external view returns (uint256);
function marginFeeBasisPoints() external view returns (uint256);
function allWhitelistedTokensLength() external view returns (uint256);
function allWhitelistedTokens(uint256) external view returns (address);
function whitelistedTokens(address _token) external view returns (bool);
function stableTokens(address _token) external view returns (bool);
function shortableTokens(address _token) external view returns (bool);
function feeReserves(address _token) external view returns (uint256);
function globalShortSizes(address _token) external view returns (uint256);
function globalShortAveragePrices(address _token) external view returns (uint256);
function maxGlobalShortSizes(address _token) external view returns (uint256);
function tokenDecimals(address _token) external view returns (uint256);
function tokenWeights(address _token) external view returns (uint256);
function guaranteedUsd(address _token) external view returns (uint256);
function poolAmounts(address _token) external view returns (uint256);
function bufferAmounts(address _token) external view returns (uint256);
function reservedAmounts(address _token) external view returns (uint256);
function usdgAmounts(address _token) external view returns (uint256);
function maxUsdgAmounts(address _token) external view returns (uint256);
function getRedemptionAmount(address _token, uint256 _usdgAmount) external view returns (uint256);
function getPyth() external view returns (IPyth);
function getMaxPrice(address _token) external view returns (uint256);
function getMinPrice(address _token) external view returns (uint256);
function getDelta(address _indexToken, uint256 _size, uint256 _averagePrice, bool _isLong, uint256 _lastIncreasedTime) external view returns (bool, uint256);
function getPosition(address _account, address _collateralToken, address _indexToken, bool _isLong) external view returns (uint256, uint256, uint256, uint256, uint256, uint256, bool, uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IVaultUtils {
function updateCumulativeFundingRate(address _collateralToken, address _indexToken) external returns (bool);
function validateIncreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _sizeDelta, bool _isLong) external view;
function validateDecreasePosition(address _account, address _collateralToken, address _indexToken, uint256 _collateralDelta, uint256 _sizeDelta, bool _isLong, address _receiver) external view;
function validateLiquidation(address _account, address _collateralToken, address _indexToken, bool _isLong, bool _raise) external view returns (uint256, uint256);
function getEntryFundingRate(address _collateralToken, address _indexToken, bool _isLong) external view returns (uint256);
function getPositionFee(address _account, address _collateralToken, address _indexToken, bool _isLong, uint256 _sizeDelta) external view returns (uint256);
function getFundingFee(address _account, address _collateralToken, address _indexToken, bool _isLong, uint256 _size, uint256 _entryFundingRate) external view returns (uint256);
function getBuyUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256);
function getSellUsdgFeeBasisPoints(address _token, uint256 _usdgAmount) external view returns (uint256);
function getSwapFeeBasisPoints(address _tokenIn, address _tokenOut, uint256 _usdgAmount) external view returns (uint256);
function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256);
function getDelta(address _indexToken, uint256 _size, uint256 _averagePrice, bool _isLong, uint256 _lastIncreasedTime) external view returns (bool, uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
import "./PythStructs.sol";
import "./IPythEvents.sol";
/// @title Consume prices from the Pyth Network (https://pyth.network/).
/// @dev Please refer to the guidance at https://docs.pyth.network/consumers/best-practices for how to consume prices safely.
/// @author Pyth Data Association
interface IPyth is IPythEvents {
/// @notice Returns the period (in seconds) that a price feed is considered valid since its publish time
function getValidTimePeriod() external view returns (uint validTimePeriod);
/// @notice Returns the price and confidence interval.
/// @dev Reverts if the price has not been updated within the last `getValidTimePeriod()` seconds.
/// @param id The Pyth Price Feed ID of which to fetch the price and confidence interval.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getPrice(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the exponentially-weighted moving average price and confidence interval.
/// @dev Reverts if the EMA price is not available.
/// @param id The Pyth Price Feed ID of which to fetch the EMA price and confidence interval.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getEmaPrice(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the price of a price feed without any sanity checks.
/// @dev This function returns the most recent price update in this contract without any recency checks.
/// This function is unsafe as the returned price update may be arbitrarily far in the past.
///
/// Users of this function should check the `publishTime` in the price to ensure that the returned price is
/// sufficiently recent for their application. If you are considering using this function, it may be
/// safer / easier to use either `getPrice` or `getPriceNoOlderThan`.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getPriceUnsafe(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the price that is no older than `age` seconds of the current time.
/// @dev This function is a sanity-checked version of `getPriceUnsafe` which is useful in
/// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently
/// recently.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getPriceNoOlderThan(
bytes32 id,
uint age
) external view returns (PythStructs.Price memory price);
/// @notice Returns the exponentially-weighted moving average price of a price feed without any sanity checks.
/// @dev This function returns the same price as `getEmaPrice` in the case where the price is available.
/// However, if the price is not recent this function returns the latest available price.
///
/// The returned price can be from arbitrarily far in the past; this function makes no guarantees that
/// the returned price is recent or useful for any particular application.
///
/// Users of this function should check the `publishTime` in the price to ensure that the returned price is
/// sufficiently recent for their application. If you are considering using this function, it may be
/// safer / easier to use either `getEmaPrice` or `getEmaPriceNoOlderThan`.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getEmaPriceUnsafe(
bytes32 id
) external view returns (PythStructs.Price memory price);
/// @notice Returns the exponentially-weighted moving average price that is no older than `age` seconds
/// of the current time.
/// @dev This function is a sanity-checked version of `getEmaPriceUnsafe` which is useful in
/// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently
/// recently.
/// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.
function getEmaPriceNoOlderThan(
bytes32 id,
uint age
) external view returns (PythStructs.Price memory price);
/// @notice Update price feeds with given update messages.
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
/// `getUpdateFee` with the length of the `updateData` array.
/// Prices will be updated if they are more recent than the current stored prices.
/// The call will succeed even if the update is not the most recent.
/// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid.
/// @param updateData Array of price update data.
function updatePriceFeeds(bytes[] calldata updateData) external payable;
/// @notice Wrapper around updatePriceFeeds that rejects fast if a price update is not necessary. A price update is
/// necessary if the current on-chain publishTime is older than the given publishTime. It relies solely on the
/// given `publishTimes` for the price feeds and does not read the actual price update publish time within `updateData`.
///
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
/// `getUpdateFee` with the length of the `updateData` array.
///
/// `priceIds` and `publishTimes` are two arrays with the same size that correspond to senders known publishTime
/// of each priceId when calling this method. If all of price feeds within `priceIds` have updated and have
/// a newer or equal publish time than the given publish time, it will reject the transaction to save gas.
/// Otherwise, it calls updatePriceFeeds method to update the prices.
///
/// @dev Reverts if update is not needed or the transferred fee is not sufficient or the updateData is invalid.
/// @param updateData Array of price update data.
/// @param priceIds Array of price ids.
/// @param publishTimes Array of publishTimes. `publishTimes[i]` corresponds to known `publishTime` of `priceIds[i]`
function updatePriceFeedsIfNecessary(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64[] calldata publishTimes
) external payable;
/// @notice Returns the required fee to update an array of price updates.
/// @param updateData Array of price update data.
/// @return feeAmount The required fee in Wei.
function getUpdateFee(
bytes[] calldata updateData
) external view returns (uint feeAmount);
/// @notice Parse `updateData` and return price feeds of the given `priceIds` if they are all published
/// within `minPublishTime` and `maxPublishTime`.
///
/// You can use this method if you want to use a Pyth price at a fixed time and not the most recent price;
/// otherwise, please consider using `updatePriceFeeds`. This method does not store the price updates on-chain.
///
/// This method requires the caller to pay a fee in wei; the required fee can be computed by calling
/// `getUpdateFee` with the length of the `updateData` array.
///
///
/// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is
/// no update for any of the given `priceIds` within the given time range.
/// @param updateData Array of price update data.
/// @param priceIds Array of price ids.
/// @param minPublishTime minimum acceptable publishTime for the given `priceIds`.
/// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`.
/// @return feeds Array of the price feeds corresponding to the given `priceIds` (with the same order).
function parsePriceFeedUpdates(
bytes[] calldata updateData,
bytes32[] calldata priceIds,
uint64 minPublishTime,
uint64 maxPublishTime
) external payable returns (PythStructs.PriceFeed[] memory feeds);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.6.12;
/// @title IPythEvents contains the events that Pyth contract emits.
/// @dev This interface can be used for listening to the updates for off-chain and testing purposes.
interface IPythEvents {
/// @dev Emitted when the price feed with `id` has received a fresh update.
/// @param id The Pyth Price Feed ID.
/// @param publishTime Publish time of the given price update.
/// @param price Price of the given price update.
/// @param conf Confidence interval of the given price update.
event PriceFeedUpdate(
bytes32 indexed id,
uint64 publishTime,
int64 price,
uint64 conf
);
/// @dev Emitted when a batch price update is processed successfully.
/// @param chainId ID of the source chain that the batch price update comes from.
/// @param sequenceNumber Sequence number of the batch price update.
event BatchPriceFeedUpdate(uint16 chainId, uint64 sequenceNumber);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.6.12;
contract PythStructs {
// A price with a degree of uncertainty, represented as a price +- a confidence interval.
//
// The confidence interval roughly corresponds to the standard error of a normal distribution.
// Both the price and confidence are stored in a fixed-point numeric representation,
// `x * (10^expo)`, where `expo` is the exponent.
//
// Please refer to the documentation at https://docs.pyth.network/consumers/best-practices for how
// to how this price safely.
struct Price {
// Price
int64 price;
// Confidence interval around the price
uint64 conf;
// Price exponent
int32 expo;
// Unix timestamp describing when the price was published
uint publishTime;
}
// PriceFeed represents a current aggregate price from pyth publisher feeds.
struct PriceFeed {
// The price ID.
bytes32 id;
// Latest available price
Price price;
// Latest available exponentially-weighted moving average price
Price emaPrice;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "./IERC20.sol";
import "../math/SafeMath.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 SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
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'
// solhint-disable-next-line max-line-length
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));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @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");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
/**
* @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
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 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://diligence.consensys.net/posts/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.5.11/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");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(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 functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.3._
*/
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.3._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// 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
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
/**
* @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].
*/
contract ReentrancyGuard {
// 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;
constructor () internal {
_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 make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}//SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}{
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": false
},
"optimizer": {
"enabled": true,
"runs": 10
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": [
"@ensdomains/=node_modules/@ensdomains/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@uniswap/=node_modules/@uniswap/",
"base64-sol/=node_modules/base64-sol/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"hardhat-deploy/=node_modules/hardhat-deploy/",
"hardhat/=node_modules/hardhat/"
]
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralDelta","type":"uint256"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"CancelDecreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"purchaseToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"purchaseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"CancelIncreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"path","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"triggerRatio","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"bool","name":"shouldUnwrap","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"CancelSwapOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralDelta","type":"uint256"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"CreateDecreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"purchaseToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"purchaseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"CreateIncreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"path","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"triggerRatio","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"bool","name":"shouldUnwrap","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"CreateSwapOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralDelta","type":"uint256"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"executionPrice","type":"uint256"}],"name":"ExecuteDecreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"purchaseToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"purchaseTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"executionPrice","type":"uint256"}],"name":"ExecuteIncreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"path","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"triggerRatio","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"bool","name":"shouldUnwrap","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"ExecuteSwapOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"router","type":"address"},{"indexed":false,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"weth","type":"address"},{"indexed":false,"internalType":"address","name":"usdg","type":"address"},{"indexed":false,"internalType":"uint256","name":"minExecutionFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minPurchaseTokenAmountUsd","type":"uint256"}],"name":"Initialize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralDelta","type":"uint256"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"}],"name":"UpdateDecreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"gov","type":"address"}],"name":"UpdateGov","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"orderIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"address","name":"indexToken","type":"address"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"}],"name":"UpdateIncreaseOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minExecutionFee","type":"uint256"}],"name":"UpdateMinExecutionFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minPurchaseTokenAmountUsd","type":"uint256"}],"name":"UpdateMinPurchaseTokenAmountUsd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"ordexIndex","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"path","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"triggerRatio","type":"uint256"},{"indexed":false,"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"indexed":false,"internalType":"bool","name":"shouldUnwrap","type":"bool"},{"indexed":false,"internalType":"uint256","name":"executionFee","type":"uint256"}],"name":"UpdateSwapOrder","type":"event"},{"inputs":[],"name":"PRICE_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDG_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"cancelDecreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"cancelIncreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_swapOrderIndexes","type":"uint256[]"},{"internalType":"uint256[]","name":"_increaseOrderIndexes","type":"uint256[]"},{"internalType":"uint256[]","name":"_decreaseOrderIndexes","type":"uint256[]"}],"name":"cancelMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"cancelSwapOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_indexToken","type":"address"},{"internalType":"uint256","name":"_sizeDelta","type":"uint256"},{"internalType":"address","name":"_collateralToken","type":"address"},{"internalType":"uint256","name":"_collateralDelta","type":"uint256"},{"internalType":"bool","name":"_isLong","type":"bool"},{"internalType":"uint256","name":"_triggerPrice","type":"uint256"},{"internalType":"bool","name":"_triggerAboveThreshold","type":"bool"}],"name":"createDecreaseOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"indexToken","type":"address"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"bool","name":"isLong","type":"bool"},{"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"internalType":"uint256","name":"executionFee","type":"uint256"},{"internalType":"bool","name":"shouldWrap","type":"bool"}],"internalType":"struct OrderBook.CreateIncreaseOrderParams","name":"params","type":"tuple"},{"internalType":"bytes[]","name":"_pythUpdateData","type":"bytes[]"}],"name":"createIncreaseOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_path","type":"address[]"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_minOut","type":"uint256"},{"internalType":"uint256","name":"_triggerRatio","type":"uint256"},{"internalType":"bool","name":"_triggerAboveThreshold","type":"bool"},{"internalType":"uint256","name":"_executionFee","type":"uint256"},{"internalType":"bool","name":"_shouldWrap","type":"bool"},{"internalType":"bool","name":"_shouldUnwrap","type":"bool"}],"name":"createSwapOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"decreaseOrders","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"collateralDelta","type":"uint256"},{"internalType":"address","name":"indexToken","type":"address"},{"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"},{"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"internalType":"uint256","name":"executionFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"decreaseOrdersIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"address payable","name":"_feeReceiver","type":"address"}],"name":"executeDecreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"address payable","name":"_feeReceiver","type":"address"}],"name":"executeIncreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"address payable","name":"_feeReceiver","type":"address"}],"name":"executeSwapOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"getDecreaseOrder","outputs":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"uint256","name":"collateralDelta","type":"uint256"},{"internalType":"address","name":"indexToken","type":"address"},{"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"},{"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"internalType":"uint256","name":"executionFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"getIncreaseOrder","outputs":[{"internalType":"address","name":"purchaseToken","type":"address"},{"internalType":"uint256","name":"purchaseTokenAmount","type":"uint256"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"indexToken","type":"address"},{"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"},{"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"internalType":"uint256","name":"executionFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"getSwapOrder","outputs":[{"internalType":"address","name":"path0","type":"address"},{"internalType":"address","name":"path1","type":"address"},{"internalType":"address","name":"path2","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint256","name":"triggerRatio","type":"uint256"},{"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"internalType":"bool","name":"shouldUnwrap","type":"bool"},{"internalType":"uint256","name":"executionFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_otherToken","type":"address"}],"name":"getUsdgMinPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"increaseOrders","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"purchaseToken","type":"address"},{"internalType":"uint256","name":"purchaseTokenAmount","type":"uint256"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"indexToken","type":"address"},{"internalType":"uint256","name":"sizeDelta","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"},{"internalType":"uint256","name":"triggerPrice","type":"uint256"},{"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"internalType":"uint256","name":"executionFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"increaseOrdersIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_usdg","type":"address"},{"internalType":"uint256","name":"_minExecutionFee","type":"uint256"},{"internalType":"uint256","name":"_minPurchaseTokenAmountUsd","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minExecutionFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minPurchaseTokenAmountUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minExecutionFee","type":"uint256"}],"name":"setMinExecutionFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minPurchaseTokenAmountUsd","type":"uint256"}],"name":"setMinPurchaseTokenAmountUsd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapOrders","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint256","name":"triggerRatio","type":"uint256"},{"internalType":"bool","name":"triggerAboveThreshold","type":"bool"},{"internalType":"bool","name":"shouldUnwrap","type":"bool"},{"internalType":"uint256","name":"executionFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"swapOrdersIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"uint256","name":"_collateralDelta","type":"uint256"},{"internalType":"uint256","name":"_sizeDelta","type":"uint256"},{"internalType":"uint256","name":"_triggerPrice","type":"uint256"},{"internalType":"bool","name":"_triggerAboveThreshold","type":"bool"}],"name":"updateDecreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"uint256","name":"_sizeDelta","type":"uint256"},{"internalType":"uint256","name":"_triggerPrice","type":"uint256"},{"internalType":"bool","name":"_triggerAboveThreshold","type":"bool"}],"name":"updateIncreaseOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"uint256","name":"_minOut","type":"uint256"},{"internalType":"uint256","name":"_triggerRatio","type":"uint256"},{"internalType":"bool","name":"_triggerAboveThreshold","type":"bool"}],"name":"updateSwapOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdg","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_triggerAboveThreshold","type":"bool"},{"internalType":"uint256","name":"_triggerPrice","type":"uint256"},{"internalType":"address","name":"_indexToken","type":"address"},{"internalType":"bool","name":"_maximizePrice","type":"bool"},{"internalType":"bool","name":"_raise","type":"bool"}],"name":"validatePositionOrderPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_path","type":"address[]"},{"internalType":"uint256","name":"_triggerRatio","type":"uint256"}],"name":"validateSwapOrderPriceWithTriggerAboveThreshold","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6080604052600e805460ff1916905534801561001a57600080fd5b506001600055600780546001600160a01b031916331790556151f8806100416000396000f3fe6080604052600436106101c35760003560e01c8062cf066b14610202578063026032ee1461023857806307c7edc31461026c5780630d5cc9381461028c57806311d9444a146102ac57806312d43a51146102cc578063269ae6c2146102ee5780632b7d629014610301578063392e53cd146103375780633fc8cef31461035957806347e0bbd01461036e5780634a686d671461038e5780634c54f0b0146103a357806363ae2103146103d157806379221fa2146103e6578063807c5600146104195780638de10c2e14610439578063939d3b241461044e57806395082d25146104615780639983ee1b146104765780639e23de5c146104965780639e71b0f0146104b6578063a397ea54146104d6578063aec22455146104f6578063c16cde8a14610516578063c4a1821b14610529578063c86b0f7d14610549578063cfad57a214610569578063d0d40cd614610589578063d38ab519146105be578063d3bab1d1146105de578063d566d0ca14610613578063d7c41c7914610633578063f2d2e01b14610653578063f5b91b7b14610688578063f882ac071461069d578063f887ea40146106bd578063fbfa77cf146106d2578063fc2cee62146106e7576101fd565b366101fd576008546001600160a01b031633146101fb5760405162461bcd60e51b81526004016101f290614c9e565b60405180910390fd5b005b600080fd5b34801561020e57600080fd5b5061022261021d366004613e95565b610707565b60405161022f9190614da0565b60405180910390f35b34801561024457600080fd5b50610258610253366004613f1e565b610719565b60405161022f98979695949392919061469f565b34801561027857600080fd5b506101fb610287366004613f49565b6107ec565b34801561029857600080fd5b506101fb6102a73660046142b9565b610b20565b3480156102b857600080fd5b506101fb6102c7366004613f49565b610b8a565b3480156102d857600080fd5b506102e1610e93565b60405161022f9190614406565b6101fb6102fc366004614046565b610ea2565b34801561030d57600080fd5b5061032161031c366004613f1e565b6110da565b60405161022f9a99989796959493929190614580565b34801561034357600080fd5b5061034c61114c565b60405161022f91906147bc565b34801561036557600080fd5b506102e1611155565b34801561037a57600080fd5b506101fb6103893660046142b9565b611164565b34801561039a57600080fd5b506102226113d3565b3480156103af57600080fd5b506103c36103be36600461419c565b6113df565b60405161022f9291906150d1565b3480156103dd57600080fd5b50610222611536565b3480156103f257600080fd5b50610406610401366004613f1e565b61153c565b60405161022f97969594939291906146e8565b34801561042557600080fd5b506101fb6104343660046140e1565b611590565b34801561044557600080fd5b50610222611628565b6101fb61045c36600461421f565b61162e565b34801561046d57600080fd5b50610222611a28565b34801561048257600080fd5b506101fb6104913660046142e9565b611a38565b3480156104a257600080fd5b506102226104b1366004613e95565b611b1b565b3480156104c257600080fd5b506101fb6104d13660046142b9565b611cd9565b3480156104e257600080fd5b506101fb6104f1366004614329565b611eae565b34801561050257600080fd5b50610222610511366004613e95565b611f98565b6101fb610524366004613f8a565b611faa565b34801561053557600080fd5b5061034c610544366004614004565b61201c565b34801561055557600080fd5b506101fb6105643660046142e9565b61221e565b34801561057557600080fd5b506101fb610584366004613e95565b6122f8565b34801561059557600080fd5b506105a96105a4366004613f1e565b61236d565b60405161022f9998979695949392919061452e565b3480156105ca57600080fd5b506101fb6105d9366004613f49565b61252a565b3480156105ea57600080fd5b506105fe6105f9366004613f1e565b6128c2565b60405161022f9998979695949392919061464a565b34801561061f57600080fd5b5061022261062e366004613e95565b6129a8565b34801561063f57600080fd5b506101fb61064e366004613eb1565b6129ba565b34801561065f57600080fd5b5061067361066e366004613f1e565b612ab2565b60405161022f999897969594939291906145dc565b34801561069457600080fd5b506102e1612b1c565b3480156106a957600080fd5b506101fb6106b83660046142b9565b612b2b565b3480156106c957600080fd5b506102e1612da5565b3480156106de57600080fd5b506102e1612db4565b3480156106f357600080fd5b506101fb6107023660046142b9565b612dc3565b60066020526000908152604090205481565b60008060008060008060008061072d613c17565b505050506001600160a01b03968716600090815260036020818152604080842099845298815291889020885161012081018a5281548b16815260018201548b1693810184905260028201549981018a9052918101549099166060820181905260048a01546080830181905260058b015460ff908116151560a0850181905260068d015460c0860181905260078e0154909216151560e086018190526008909d0154610100909501859052949c9a9b929a91995093975092955093509150565b6002600054141561080f5760405162461bcd60e51b81526004016101f290614d69565b600260005561081c613c63565b6001600160a01b038085166000908152600560209081526040808320878452825291829020825161010081018452815490941684526001810180548451818502810185019095528085529193858401939092908301828280156108a857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161088a575b5050509183525050600282015460208201526003820154604082015260048201546060820152600582015460ff8082161515608084015261010090910416151560a082015260069091015460c09091015280519091506001600160a01b03166109235760405162461bcd60e51b81526004016101f290614c31565b8060a001511561095b5761093f8160200151826080015161201c565b61095b5760405162461bcd60e51b81526004016101f290614bb4565b6001600160a01b0384166000908152600560209081526040808320868452909152812080546001600160a01b03191681559061099a6001830182613cb5565b50600060028201819055600382018190556004820181905560058201805461ffff191690556006909101819055600b54604083015160208401518051610a0d946001600160a01b0390941693906109ed57fe5b60200260200101516001600160a01b0316612e229092919063ffffffff16565b600854602082015180516000926001600160a01b031691906000198101908110610a3357fe5b60200260200101516001600160a01b0316148015610a5257508160c001515b15610a7f57610a6a8260200151836060015130612e7d565b9050610a7a818360000151612f89565b610a99565b610a96826020015183606001518460000151612e7d565b90505b610aa78260e0015184612f89565b846001600160a01b03167f7e1fe496989eea92b738a562dbf9c0ae6aa6fcf3f1ef09e95ee4f7603721706b858460200151856040015186606001518688608001518960a001518a60c001518b60e00151604051610b0c99989796959493929190614fdc565b60405180910390a250506001600055505050565b6007546001600160a01b03163314610b4a5760405162461bcd60e51b81526004016101f2906147fa565b600d8190556040517fe46d9daf6d25f7615efa1d0183b90ac6759d85014b598e409aadf0fd918d59a690610b7f908390614da0565b60405180910390a150565b60026000541415610bad5760405162461bcd60e51b81526004016101f290614d69565b6002600055610bba613c17565b506001600160a01b03808416600090815260036020818152604080842087855282529283902083516101208101855281548616808252600183015487169382019390935260028201549481019490945291820154909316606083015260048101546080830152600581015460ff908116151560a0840152600682015460c0840152600782015416151560e08301526008015461010082015290610c6f5760405162461bcd60e51b81526004016101f290614c31565b6000610c908260e001518360c0015184606001518560a001511560016113df565b506001600160a01b0380871660009081526003602081815260408084208a8552825280842080546001600160a01b0319908116825560018201805482169055600282018690559381018054909416909355600480840185905560058401805460ff199081169091556006850186905560078501805490911690556008909301849055600a5488519289015160608a01518a84015160808c015160a08d01519551632662166b60e01b81529a9b5097999390981697632662166b97610d5f979395929491939092913091016144ef565b602060405180830381600087803b158015610d7957600080fd5b505af1158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db191906142d1565b60085460208501519192506001600160a01b0391821691161415610de257610ddd818460000151612f89565b610dff565b82516020840151610dff916001600160a01b039091169083612e22565b610e0e83610100015185612f89565b82600001516001600160a01b03167f9a382661d6573da86db000471303be6f0b2b1bb66089b08e3c16a85d7b6e94f88685602001518660400151876060015188608001518960a001518a60c001518b60e001518c61010001518c604051610e7e9a99989796959493929190614f37565b60405180910390a25050600160005550505050565b6007546001600160a01b031681565b60026000541415610ec55760405162461bcd60e51b81526004016101f290614d69565b6002600081905588511480610edb575087516003145b610ef75760405162461bcd60e51b81526004016101f290614b7d565b87600189510381518110610f0757fe5b60200260200101516001600160a01b031688600081518110610f2557fe5b60200260200101516001600160a01b03161415610f545760405162461bcd60e51b81526004016101f290614ab9565b60008711610f745760405162461bcd60e51b81526004016101f290614c68565b600c54831015610f965760405162461bcd60e51b81526004016101f290614a33565b610fa06000613003565b811561101d5760085488516001600160a01b03909116908990600090610fc257fe5b60200260200101516001600160a01b031614610ff05760405162461bcd60e51b81526004016101f2906149ee565b610ffa838861306c565b34146110185760405162461bcd60e51b81526004016101f290614b37565b6110bb565b82341461103c5760405162461bcd60e51b81526004016101f290614d1b565b600a5488516001600160a01b0390911690631b827878908a9060009061105e57fe5b602002602001015133308b6040518563ffffffff1660e01b81526004016110889493929190614434565b600060405180830381600087803b1580156110a257600080fd5b505af11580156110b6573d6000803e3d6000fd5b505050505b6110cb338989898989878a613091565b50506001600055505050505050565b6001602081815260009384526040808520909152918352912080549181015460028201546003830154600484015460058501546006860154600787015460088801546009909801546001600160a01b03998a1699978816989697958616969490951694929360ff92831693919216908a565b600e5460ff1681565b6008546001600160a01b031681565b600260005414156111875760405162461bcd60e51b81526004016101f290614d69565b6002600055611194613cd3565b5033600090815260016020818152604080842085855282529283902083516101408101855281546001600160a01b039081168083529483015481169382019390935260028201549481019490945260038101548216606085015260048101549091166080840152600581015460a0840152600681015460ff908116151560c0850152600782015460e08501526008820154161515610100840152600901546101208301526112545760405162461bcd60e51b81526004016101f290614c31565b3360009081526001602081815260408084208685528252832080546001600160a01b0319908116825592810180548416905560028101849055600381018054841690556004810180549093169092556005820183905560068201805460ff19908116909155600783018490556008808401805490921690915560099092019290925554908201516001600160a01b03908116911614156113185761131361130d826040015183610120015161306c90919063ffffffff16565b33612f89565b61134d565b61133e33826040015183602001516001600160a01b0316612e229092919063ffffffff16565b61134d81610120015133612f89565b80600001516001600160a01b03167fd500f34e0ec655b7614ae42e1d9c666d5e4dde909a1297829f8c5ecf00805d328383602001518460400151856060015186608001518760a001518860c001518960e001518a61010001518b61012001516040516113c29a99989796959493929190614de7565b60405180910390a250506001600055565b670de0b6b3a764000081565b60008060008461146e57600b546040516340d3096b60e11b81526001600160a01b03909116906381a612d690611419908990600401614406565b60206040518083038186803b15801561143157600080fd5b505afa158015611445573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146991906142d1565b6114ee565b600b54604051637092736960e11b81526001600160a01b039091169063e124e6d29061149e908990600401614406565b60206040518083038186803b1580156114b657600080fd5b505afa1580156114ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ee91906142d1565b90506000886114ff57878210611503565b8782115b9050841561152857806115285760405162461bcd60e51b81526004016101f290614bb4565b909890975095505050505050565b600c5481565b600560208181526000938452604080852090915291835291208054600282015460038301546004840154948401546006909401546001600160a01b03909316949193909260ff808316926101009004169087565b60005b83518110156115c0576115b88482815181106115ab57fe5b6020026020010151612b2b565b600101611593565b5060005b82518110156115f1576115e98382815181106115dc57fe5b6020026020010151611164565b6001016115c4565b5060005b81518110156116225761161a82828151811061160d57fe5b6020026020010151611cd9565b6001016115f5565b50505050565b600d5481565b600260005414156116515760405162461bcd60e51b81526004016101f290614d69565b600260009081556116628383613225565b905061166d81613003565b606061167985806150e1565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c54929350505061012086013510156116d45760405162461bcd60e51b81526004016101f290614a33565b6116e661016086016101408701614164565b156117745760085481516001600160a01b0390911690829060009061170757fe5b60200260200101516001600160a01b0316146117355760405162461bcd60e51b81526004016101f2906149ee565b611748610120860135602087013561306c565b61175234846133ba565b1461176f5760405162461bcd60e51b81526004016101f290614b37565b611835565b61012085013561178434846133ba565b146117a15760405162461bcd60e51b81526004016101f290614d1b565b600a546001600160a01b0316631b8278786117bc87806150e1565b60008181106117c757fe5b90506020020160208101906117dc9190613e95565b333089602001356040518563ffffffff1660e01b81526004016118029493929190614434565b600060405180830381600087803b15801561181c57600080fd5b505af1158015611830573d6000803e3d6000fd5b505050505b60006001825111156118d8578160018351038151811061185157fe5b60200260200101516001600160a01b03168260008151811061186f57fe5b60200260200101516001600160a01b0316141561189e5760405162461bcd60e51b81526004016101f290614ab9565b600b5482516118c2916001600160a01b03169060208901359085906000906109ed57fe5b6118d182876060013530612e7d565b90506118df565b5060208501355b600b5482516000916001600160a01b031690630a48d5a9908590600019810190811061190757fe5b6020026020010151846040518363ffffffff1660e01b815260040161192d929190614631565b60206040518083038186803b15801561194557600080fd5b505afa158015611959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197d91906142d1565b9050600d548110156119a15760405162461bcd60e51b81526004016101f290614828565b50611a1b33836001855103815181106119b657fe5b6020026020010151838960a00160208101906119d29190613e95565b6119e260608c0160408d01613e95565b60808c01356119f760e08e0160c08f01614164565b8d60e001358e610100016020810190611a109190614164565b8f61012001356133fc565b5050600160005550505050565b68327cb2734119d3b7a9601e1b81565b60026000541415611a5b5760405162461bcd60e51b81526004016101f290614d69565b60026000908155338152600160209081526040808320878452909152902080546001600160a01b0316611aa05760405162461bcd60e51b81526004016101f290614c31565b6007810183905560088101805460ff19168315151790556005810184905560038101546004820154600683015460405133937f0a0360dd5c354235bbf8d386ba3b24ef8134088e0785677de1504df219d9149a93610b0c938b936001600160a01b03938416939092169160ff909116908b908b908b90614da9565b600b54604051632c668ec160e01b815260009182916001600160a01b0390911690632c668ec190611b5a908690670de0b6b3a764000090600401614631565b60206040518083038186803b158015611b7257600080fd5b505afa158015611b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611baa91906142d1565b600b546040516340d3096b60e11b81529192506000916001600160a01b03909116906381a612d690611be0908790600401614406565b60206040518083038186803b158015611bf857600080fd5b505afa158015611c0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3091906142d1565b600b546040516323b95ceb60e21b81529192506000916001600160a01b0390911690638ee573ac90611c66908890600401614406565b60206040518083038186803b158015611c7e57600080fd5b505afa158015611c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb691906142d1565b9050611cd0600a82900a611cca85856135d3565b9061360d565b95945050505050565b60026000541415611cfc5760405162461bcd60e51b81526004016101f290614d69565b6002600055611d09613c17565b5033600090815260036020818152604080842085855282529283902083516101208101855281546001600160a01b03908116808352600184015482169483019490945260028301549582019590955292810154909316606083015260048301546080830152600583015460ff908116151560a0840152600684015460c0840152600784015416151560e083015260089092015461010082015290611dbf5760405162461bcd60e51b81526004016101f290614c31565b336000818152600360208181526040808420878552909152822080546001600160a01b03199081168255600182018054821690556002820184905591810180549092169091556004810182905560058101805460ff1990811690915560068201839055600782018054909116905560080155610100820151611e4091612f89565b80600001516001600160a01b03167f1154174c82984656b028c8021671988f60a346497e56fe02554761184f82a0758383602001518460400151856060015186608001518760a001518860c001518960e001518a61010001516040516113c299989796959493929190614ee7565b60026000541415611ed15760405162461bcd60e51b81526004016101f290614d69565b60026000908155338152600360209081526040808320888452909152902080546001600160a01b0316611f165760405162461bcd60e51b81526004016101f290614c31565b6006810183905560078101805460ff1916831515179055600481018490556002810185905560018101546003820154600583015460405133937f75781255bc71c83f89f29e5a2599f2c174a562d2cd8f2e818a47f132e728049893610e7e938c936001600160a01b03938416938d9316918c9160ff909116908c908c90614ea0565b60026020526000908152604090205481565b60026000541415611fcd5760405162461bcd60e51b81526004016101f290614d69565b60026000908155611fdd90613003565b600c543411611ffe5760405162461bcd60e51b81526004016101f290614a33565b61200e3386868a8a88888861364c565b505060016000555050505050565b600082516002148061202f575082516003145b61204b5760405162461bcd60e51b81526004016101f290614b7d565b60008360008151811061205a57fe5b6020026020010151905060008460018651038151811061207657fe5b602090810291909101015160095490915060009081906001600160a01b03858116911614156120c3576120bc876001815181106120af57fe5b6020026020010151611b1b565b9150612146565b600b546040516340d3096b60e11b81526001600160a01b03909116906381a612d6906120f3908790600401614406565b60206040518083038186803b15801561210b57600080fd5b505afa15801561211f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214391906142d1565b91505b6009546001600160a01b038481169116141561216f575068327cb2734119d3b7a9601e1b6121f2565b600b54604051637092736960e11b81526001600160a01b039091169063e124e6d29061219f908690600401614406565b60206040518083038186803b1580156121b757600080fd5b505afa1580156121cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ef91906142d1565b90505b600061220e83611cca8468327cb2734119d3b7a9601e1b6135d3565b8710955050505050505b92915050565b600260005414156122415760405162461bcd60e51b81526004016101f290614d69565b60026000908155338152600560209081526040808320878452909152902080546001600160a01b03166122865760405162461bcd60e51b81526004016101f290614c31565b600381018490556004810183905560058101805460ff191683151517908190556002820154600683015460405133937fa7f9f4a25eb76f5ec01b1a429d95d6a00833f0f137c88827c58799a1c1ff0dfe93610b0c938b9360018901938c928c928c9260ff610100909104169190615033565b6007546001600160a01b031633146123225760405162461bcd60e51b81526004016101f2906147fa565b600780546001600160a01b0319166001600160a01b0383161790556040517fe24c39186e9137521953beaa8446e71f55b8f12296984f9d4273ceb1af728d9090610b7f908390614406565b6000806000806000806000806000612383613c63565b6001600160a01b03808d1660009081526005602090815260408083208f84528252918290208251610100810184528154909416845260018101805484518185028101850190955280855291938584019390929083018282801561240f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116123f1575b505050918352505060028201546020808301919091526003830154604083015260048301546060830152600583015460ff8082161515608085015261010090910416151560a083015260069092015460c09091015281015151909150612476576000612490565b806020015160008151811061248757fe5b60200260200101515b6001826020015151116124a45760006124be565b81602001516001815181106124b557fe5b60200260200101515b6002836020015151116124d25760006124ec565b82602001516002815181106124e357fe5b60200260200101515b8360400151846060015185608001518660a001518760c001518860e00151995099509950995099509950995099509950509295985092959850929598565b6002600054141561254d5760405162461bcd60e51b81526004016101f290614d69565b600260005561255a613cd3565b506001600160a01b038084166000908152600160208181526040808420878552825292839020835161014081018552815486168082529382015486169281019290925260028101549382019390935260038301548416606082015260048301549093166080840152600582015460a0840152600682015460ff908116151560c0850152600783015460e0850152600883015416151561010084015260099091015461012083015261261d5760405162461bcd60e51b81526004016101f290614c31565b600061263e8261010001518360e0015184608001518560c0015160016113df565b506001600160a01b0380871660009081526001602081815260408084208a8552825280842080546001600160a01b0319908116825593810180548516905560028101859055600381018054851690556004810180549094169093556005830184905560068301805460ff19908116909155600784018590556008840180549091169055600990920192909255600b5490860151918601519394506126e6938316921690612e22565b81606001516001600160a01b031682602001516001600160a01b0316146127be57604080516002808252606080830184529260208301908036833701905050905082602001518160008151811061273957fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082606001518160018151811061276b57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600061279982600030612e7d565b600b5460608601519192506127bb916001600160a01b03908116911683612e22565b50505b600a5482516060840151608085015160a086015160c0870151604051630f8ee8bb60e11b81526001600160a01b0390961695631f1dd1769561280a9590949093909290916004016144bb565b600060405180830381600087803b15801561282457600080fd5b505af1158015612838573d6000803e3d6000fd5b5050505061284b82610120015184612f89565b81600001516001600160a01b03167f7fb1c74d1ea6aa1c9c585e17ce8274c8ff98745e85e7459b73f87d784494f58e8584602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c61012001518c604051610b0c9b9a99989796959493929190614e3e565b60008060008060008060008060006128d8613cd3565b505050506001600160a01b0397881660009081526001602081815260408084209a845299815291899020895161014081018b5281548c168152918101548b1692820183905260028101549982018a905260038101548b16606083018190526004820154909b1660808301819052600582015460a08401819052600683015460ff908116151560c08601819052600785015460e08701819052600886015490921615156101008701819052600990950154610120909601869052959e9c9d9c929b5090995093975092955093509150565b60046020526000908152604090205481565b6007546001600160a01b031633146129e45760405162461bcd60e51b81526004016101f2906147fa565b600e5460ff1615612a075760405162461bcd60e51b81526004016101f29061489f565b600e805460ff19166001179055600a80546001600160a01b038089166001600160a01b031992831617909255600b8054888416908316179055600880548784169083161790556009805492861692909116919091179055600c829055600d8190556040517fcfb7ef8749fafc8da2af1ba3d025479ffc4e58f7dc420113e112512a3bda596390612aa290889088908890889088908890614481565b60405180910390a1505050505050565b600360208181526000938452604080852090915291835291208054600182015460028301549383015460048401546005850154600686015460078701546008909701546001600160a01b039687169895871697959690941694929360ff9283169391929091169089565b6009546001600160a01b031681565b60026000541415612b4e5760405162461bcd60e51b81526004016101f290614d69565b6002600055612b5b613c63565b33600090815260056020908152604080832085845282529182902082516101008101845281546001600160a01b0316815260018201805485518186028101860190965280865291949293858101939290830182828015612be457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612bc6575b5050509183525050600282015460208201526003820154604082015260048201546060820152600582015460ff8082161515608084015261010090910416151560a082015260069091015460c09091015280519091506001600160a01b0316612c5f5760405162461bcd60e51b81526004016101f290614c31565b336000908152600560209081526040808320858452909152812080546001600160a01b031916815590612c956001830182613cb5565b50600060028201819055600382018190556004820181905560058201805461ffff191690556006909101819055600854602083015180516001600160a01b03909216929091612ce057fe5b60200260200101516001600160a01b03161415612d1a57612d1561130d82604001518360e0015161306c90919063ffffffff16565b612d42565b612d3433826040015183602001516000815181106109ed57fe5b612d428160e0015133612f89565b336001600160a01b03167fefd66d4f9c2f880c70aedeb5b26a44fb474cea07e5d6c533f2d27c303d5d94538383602001518460400151856060015186608001518760a001518860c001518960e001516040516113c2989796959493929190614f8d565b600a546001600160a01b031681565b600b546001600160a01b031681565b6007546001600160a01b03163314612ded5760405162461bcd60e51b81526004016101f2906147fa565b600c8190556040517fbde5eafdc37b81830d70124cddccaaa6d034e71dda3c8fc18a959ca76a7cbcfc90610b7f908390614da0565b612e788363a9059cbb60e01b8484604051602401612e41929190614631565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526137db565b505050565b6000835160021415612ec457612ebd84600081518110612e9957fe5b602002602001015185600181518110612eae57fe5b6020026020010151858561386a565b9050612f82565b835160031415612f6a576000612f0585600081518110612ee057fe5b602002602001015186600181518110612ef557fe5b602002602001015160003061386a565b9050612f2e600b60009054906101000a90046001600160a01b031682876001815181106109ed57fe5b612f6285600181518110612f3e57fe5b602002602001015186600281518110612f5357fe5b6020026020010151868661386a565b915050612f82565b60405162461bcd60e51b81526004016101f290614b7d565b9392505050565b600854604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90612fb9908590600401614da0565b600060405180830381600087803b158015612fd357600080fd5b505af1158015612fe7573d6000803e3d6000fd5b50612fff925050506001600160a01b03821683613a01565b5050565b3415613069576008546001600160a01b031663d0e30db061302434846133ba565b6040518263ffffffff1660e01b81526004016000604051808303818588803b15801561304f57600080fd5b505af1158015613063573d6000803e3d6000fd5b50505050505b50565b600082820183811015612f825760405162461bcd60e51b81526004016101f29061486a565b6001600160a01b0388166000908152600660205260409020546130b2613c63565b6040518061010001604052808b6001600160a01b031681526020018a81526020018981526020018881526020018781526020018615158152602001851515815260200184815250905061310f60018361306c90919063ffffffff16565b6001600160a01b038b8116600090815260066020908152604080832094909455600581528382208683528152929020835181546001600160a01b0319169216919091178155828201518051849361316d926001850192910190613d27565b506040828101516002830155606083015160038301556080830151600483015560a083015160058301805460c086015115156101000261ff001993151560ff19909216919091179290921691909117905560e090920151600690910155516001600160a01b038b16907fdf06bb56ffc4029dc0b62b68bb5bbadea93a38b530cefc9b81afb742a6555d88906132119085908d908d908d908d908d908d908d90614f8d565b60405180910390a250505050505050505050565b600080600b60009054906101000a90046001600160a01b03166001600160a01b03166378399b0b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561327657600080fd5b505afa15801561328a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ae9190614203565b60405163d47eed4560e01b81529091506001600160a01b0382169063d47eed45906132df9087908790600401614727565b60206040518083038186803b1580156132f757600080fd5b505afa15801561330b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332f91906142d1565b9150813410156133515760405162461bcd60e51b81526004016101f290614aeb565b604051631df3cbc560e31b81526001600160a01b0382169063ef9e5e289084906133819088908890600401614727565b6000604051808303818588803b15801561339a57600080fd5b505af11580156133ae573d6000803e3d6000fd5b50505050505092915050565b6000612f8283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613a9d565b33600090815260026020526040902054613414613cd3565b6040518061014001604052808d6001600160a01b031681526020018c6001600160a01b031681526020018b81526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018715158152602001868152602001851515815260200184815250905061349860018361306c90919063ffffffff16565b6001600160a01b03808e166000818152600260208181526040808420969096556001808252868420898552825292869020875181549087166001600160a01b0319918216178255918801519381018054948716948316949094179093558686015191830191909155606086015160038301805491861691831691909117905560808601516004830180549190951691161790925560a0840151600583015560c084015160068301805491151560ff1992831617905560e085015160078401556101008501516008840180549115159190921617905561012084015160099092019190915590517fb27b9afe3043b93788c40cfc3cc73f5d928a2e40f3ba01820b246426de8fa1b9906135bd9085908f908f908f908f908f908f908f908f908f90614de7565b60405180910390a2505050505050505050505050565b6000826135e257506000612218565b828202828482816135ef57fe5b0414612f825760405162461bcd60e51b81526004016101f290614a78565b6000612f8283836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250613ac9565b6001600160a01b03881660009081526004602052604090205461366d613c17565b5060408051610120810182526001600160a01b03808c1682528a8116602083015291810189905290871660608201526080810186905284151560a082015260c0810184905282151560e0820152346101008201526136cc82600161306c565b6001600160a01b03808c166000818152600460208181526040808420969096556003808252868420898552825292869020875181549087166001600160a01b0319918216178255918801516001820180549188169184169190911790558787015160028201556060880151938101805494909616939091169290921790935560808501519281019290925560a084015160058301805491151560ff1992831617905560c0850151600684015560e08501516007840180549115159190921617905561010084015160089092019190915590517f48ee333d2a65cc45fdb83bc012920d89181c3377390cd239d2b63f2bef67a02d906132119085908d908d908d908d908d908d908d903490614ee7565b6060613830826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613b009092919063ffffffff16565b805190915015612e78578080602001905181019061384e9190614180565b612e785760405162461bcd60e51b81526004016101f290614cd1565b60095460009081906001600160a01b038681169116141561391057600b5460405163817bb85760e01b81526001600160a01b039091169063817bb857906138b7908990879060040161441a565b602060405180830381600087803b1580156138d157600080fd5b505af11580156138e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390991906142d1565b90506139e1565b6009546001600160a01b038781169116141561395857600b54604051630711e61960e41b81526001600160a01b039091169063711e6190906138b7908890879060040161441a565b600b54604051634998b10960e11b81526001600160a01b039091169063933162129061398c9089908990889060040161445e565b602060405180830381600087803b1580156139a657600080fd5b505af11580156139ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139de91906142d1565b90505b83811015611cd05760405162461bcd60e51b81526004016101f2906149ad565b80471015613a215760405162461bcd60e51b81526004016101f290614930565b6000826001600160a01b031682604051613a3a90614403565b60006040518083038185875af1925050503d8060008114613a77576040519150601f19603f3d011682016040523d82523d6000602084013e613a7c565b606091505b5050905080612e785760405162461bcd60e51b81526004016101f2906148d6565b60008184841115613ac15760405162461bcd60e51b81526004016101f291906147c7565b505050900390565b60008183613aea5760405162461bcd60e51b81526004016101f291906147c7565b506000838581613af657fe5b0495945050505050565b6060613b0f8484600085613b17565b949350505050565b606082471015613b395760405162461bcd60e51b81526004016101f290614967565b613b4285613bd8565b613b5e5760405162461bcd60e51b81526004016101f290614bfa565b60006060866001600160a01b03168587604051613b7b91906143e7565b60006040518083038185875af1925050503d8060008114613bb8576040519150601f19603f3d011682016040523d82523d6000602084013e613bbd565b606091505b5091509150613bcd828286613bde565b979650505050505050565b3b151590565b60608315613bed575081612f82565b825115613bfd5782518084602001fd5b8160405162461bcd60e51b81526004016101f291906147c7565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b60405180610100016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600015158152602001600015158152602001600081525090565b50805460008255906000526020600020908101906130699190613d8c565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915290565b828054828255906000526020600020908101928215613d7c579160200282015b82811115613d7c57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613d47565b50613d88929150613da1565b5090565b5b80821115613d885760008155600101613d8d565b5b80821115613d885780546001600160a01b0319168155600101613da2565b600082601f830112613dd0578081fd5b8135613de3613dde82615154565b61512e565b818152915060208083019084810181840286018201871015613e0457600080fd5b60005b84811015613e2c578135613e1a8161519f565b84529282019290820190600101613e07565b505050505092915050565b600082601f830112613e47578081fd5b8135613e55613dde82615154565b818152915060208083019084810181840286018201871015613e7657600080fd5b60005b84811015613e2c57813584529282019290820190600101613e79565b600060208284031215613ea6578081fd5b8135612f828161519f565b60008060008060008060c08789031215613ec9578182fd5b8635613ed48161519f565b95506020870135613ee48161519f565b94506040870135613ef48161519f565b93506060870135613f048161519f565b9598949750929560808101359460a0909101359350915050565b60008060408385031215613f30578182fd5b8235613f3b8161519f565b946020939093013593505050565b600080600060608486031215613f5d578283fd5b8335613f688161519f565b9250602084013591506040840135613f7f8161519f565b809150509250925092565b600080600080600080600060e0888a031215613fa4578081fd5b8735613faf8161519f565b9650602088013595506040880135613fc68161519f565b9450606088013593506080880135613fdd816151b4565b925060a0880135915060c0880135613ff4816151b4565b8091505092959891949750929550565b60008060408385031215614016578182fd5b82356001600160401b0381111561402b578283fd5b61403785828601613dc0565b95602094909401359450505050565b600080600080600080600080610100898b031215614062578081fd5b88356001600160401b03811115614077578182fd5b6140838b828c01613dc0565b98505060208901359650604089013595506060890135945060808901356140a9816151b4565b935060a0890135925060c08901356140c0816151b4565b915060e08901356140d0816151b4565b809150509295985092959890939650565b6000806000606084860312156140f5578081fd5b83356001600160401b038082111561410b578283fd5b61411787838801613e37565b9450602086013591508082111561412c578283fd5b61413887838801613e37565b9350604086013591508082111561414d578283fd5b5061415a86828701613e37565b9150509250925092565b600060208284031215614175578081fd5b8135612f82816151b4565b600060208284031215614191578081fd5b8151612f82816151b4565b600080600080600060a086880312156141b3578283fd5b85356141be816151b4565b94506020860135935060408601356141d58161519f565b925060608601356141e5816151b4565b915060808601356141f5816151b4565b809150509295509295909350565b600060208284031215614214578081fd5b8151612f828161519f565b600080600060408486031215614233578081fd5b83356001600160401b0380821115614249578283fd5b90850190610160828803121561425d578283fd5b90935060208501359080821115614272578283fd5b818601915086601f830112614285578283fd5b813581811115614293578384fd5b87602080830285010111156142a6578384fd5b6020830194508093505050509250925092565b6000602082840312156142ca578081fd5b5035919050565b6000602082840312156142e2578081fd5b5051919050565b600080600080608085870312156142fe578182fd5b843593506020850135925060408501359150606085013561431e816151b4565b939692955090935050565b600080600080600060a08688031215614340578283fd5b8535945060208601359350604086013592506060860135915060808601356141f5816151b4565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156143ac5781516001600160a01b031687529582019590820190600101614387565b509495945050505050565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600082516143f9818460208701615173565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b6001600160a01b0396871681529486166020860152928516604085015293166060830152608082019290925260a081019190915260c00190565b6001600160a01b03958616815293851660208501529190931660408301526060820192909252901515608082015260a00190565b6001600160a01b0397881681529587166020870152938616604086015260608501929092526080840152151560a083015290911660c082015260e00190565b6001600160a01b03998a16815297891660208901529590971660408701526060860193909352608085019190915260a0840152151560c083015291151560e08201526101008101919091526101200190565b6001600160a01b039a8b168152988a1660208a01526040890197909752948816606088015292909616608086015260a085015293151560c084015260e08301939093529115156101008201526101208101919091526101400190565b6001600160a01b03998a168152978916602089015260408801969096529390961660608601526080850191909152151560a084015260c083019390935291151560e08201526101008101919091526101200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03998a168152602081019890985295881660408801529390961660608601526080850191909152151560a084015260c083019390935291151560e08201526101008101919091526101200190565b6001600160a01b039889168152602081019790975294909616604086015260608501929092521515608084015260a083015291151560c082015260e08101919091526101000190565b6001600160a01b0397909716875260208701959095526040860193909352606085019190915215156080840152151560a083015260c082015260e00190565b602080825281810183905260009060408482028401810190840186845b878110156147af57868403603f190183528135368a9003601e19018112614769578687fd5b890180356001600160401b03811115614780578788fd5b8036038b131561478e578788fd5b61479b86828985016143bd565b955050509184019190840190600101614744565b5091979650505050505050565b901515815260200190565b60006020825282518060208401526147e6816040850160208701615173565b601f01601f19169190910160400192915050565b60208082526014908201527327b93232b92137b7b59d103337b93134b23232b760611b604082015260600190565b60208082526022908201527f4f72646572426f6f6b3a20696e73756666696369656e7420636f6c6c61746572604082015261185b60f21b606082015260800190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b6020808252601e908201527f4f72646572426f6f6b3a20616c726561647920696e697469616c697a65640000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726040820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b60208082526021908201527f4f72646572426f6f6b3a20696e73756666696369656e7420616d6f756e744f756040820152601d60fa1b606082015260800190565b60208082526025908201527f4f72646572426f6f6b3a206f6e6c79207765746820636f756c64206265207772604082015264185c1c195960da1b606082015260800190565b60208082526025908201527f4f72646572426f6f6b3a20696e73756666696369656e7420657865637574696f6040820152646e2066656560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526018908201527709ee4c8cae484deded67440d2dcecc2d8d2c840bee0c2e8d60431b604082015260600190565b6020808252602c908201527f696e73756666696369656e74206d73672e76616c756520746f2075706461746560408201526b20707974682070726963657360a01b606082015260800190565b60208082526026908201527f4f72646572426f6f6b3a20696e636f72726563742076616c7565207472616e7360408201526519995c9c995960d21b606082015260800190565b6020808252601f908201527f4f72646572426f6f6b3a20696e76616c6964205f706174682e6c656e67746800604082015260600190565b60208082526026908201527f4f72646572426f6f6b3a20696e76616c696420707269636520666f722065786560408201526531baba34b7b760d11b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252601d908201527f4f72646572426f6f6b3a206e6f6e2d6578697374656e74206f72646572000000604082015260600190565b6020808252601c908201527b27b93232b92137b7b59d1034b73b30b634b2102fb0b6b7bab73a24b760211b604082015260600190565b60208082526019908201527827b93232b92137b7b59d1034b73b30b634b21039b2b73232b960391b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252602e908201527f4f72646572426f6f6b3a20696e636f727265637420657865637574696f6e206660408201526d1959481d1c985b9cd9995c9c995960921b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b90815260200190565b9687526001600160a01b0395861660208801529390941660408601529015156060850152608084015260a0830191909152151560c082015260e00190565b998a526001600160a01b0398891660208b015260408a0197909752948716606089015292909516608087015260a086015292151560c085015260e08401929092529015156101008301526101208201526101400190565b9a8b526001600160a01b03998a1660208c015260408b019890985295881660608a015293909616608088015260a0870191909152151560c086015260e08501939093529115156101008401526101208301919091526101408201526101600190565b9788526001600160a01b0396871660208901526040880195909552929094166060860152608085015291151560a084015260c0830191909152151560e08201526101000190565b9889526001600160a01b0397881660208a015260408901969096529390951660608701526080860191909152151560a085015260c084019290925290151560e08301526101008201526101200190565b998a526001600160a01b0398891660208b015260408a01979097529490961660608801526080870192909252151560a086015260c085015291151560e08401526101008301919091526101208201526101400190565b60006101008a8352806020840152614fa78184018b614374565b604084019990995250506060810195909552608085019390935290151560a0840152151560c083015260e09091015292915050565b60006101208b8352806020840152614ff68184018c614374565b604084019a909a5250506060810196909652608086019490945260a0850192909252151560c0840152151560e08301526101009091015292915050565b8881526101006020808301829052895491830182905260008a8152818120909261012085019290845b8181101561508a57835461507a9086906001600160a01b0316614367565b938201936001938401930161505c565b50505050809150508760408301528660608301528560808301526150b160a08301866143b7565b6150be60c08301856143b7565b8260e08301529998505050505050505050565b9182521515602082015260400190565b6000808335601e198436030181126150f7578283fd5b8301803591506001600160401b03821115615110578283fd5b602090810192508102360382131561512757600080fd5b9250929050565b6040518181016001600160401b038111828210171561514c57600080fd5b604052919050565b60006001600160401b03821115615169578081fd5b5060209081020190565b60005b8381101561518e578181015183820152602001615176565b838111156116225750506000910152565b6001600160a01b038116811461306957600080fd5b801515811461306957600080fdfea2646970667358221220a0d5f9a74d50848c3492cadbdbc7523ce5922a62071a5aac793c23bddc2f4b8964736f6c634300060c0033
Deployed Bytecode
0x6080604052600436106101c35760003560e01c8062cf066b14610202578063026032ee1461023857806307c7edc31461026c5780630d5cc9381461028c57806311d9444a146102ac57806312d43a51146102cc578063269ae6c2146102ee5780632b7d629014610301578063392e53cd146103375780633fc8cef31461035957806347e0bbd01461036e5780634a686d671461038e5780634c54f0b0146103a357806363ae2103146103d157806379221fa2146103e6578063807c5600146104195780638de10c2e14610439578063939d3b241461044e57806395082d25146104615780639983ee1b146104765780639e23de5c146104965780639e71b0f0146104b6578063a397ea54146104d6578063aec22455146104f6578063c16cde8a14610516578063c4a1821b14610529578063c86b0f7d14610549578063cfad57a214610569578063d0d40cd614610589578063d38ab519146105be578063d3bab1d1146105de578063d566d0ca14610613578063d7c41c7914610633578063f2d2e01b14610653578063f5b91b7b14610688578063f882ac071461069d578063f887ea40146106bd578063fbfa77cf146106d2578063fc2cee62146106e7576101fd565b366101fd576008546001600160a01b031633146101fb5760405162461bcd60e51b81526004016101f290614c9e565b60405180910390fd5b005b600080fd5b34801561020e57600080fd5b5061022261021d366004613e95565b610707565b60405161022f9190614da0565b60405180910390f35b34801561024457600080fd5b50610258610253366004613f1e565b610719565b60405161022f98979695949392919061469f565b34801561027857600080fd5b506101fb610287366004613f49565b6107ec565b34801561029857600080fd5b506101fb6102a73660046142b9565b610b20565b3480156102b857600080fd5b506101fb6102c7366004613f49565b610b8a565b3480156102d857600080fd5b506102e1610e93565b60405161022f9190614406565b6101fb6102fc366004614046565b610ea2565b34801561030d57600080fd5b5061032161031c366004613f1e565b6110da565b60405161022f9a99989796959493929190614580565b34801561034357600080fd5b5061034c61114c565b60405161022f91906147bc565b34801561036557600080fd5b506102e1611155565b34801561037a57600080fd5b506101fb6103893660046142b9565b611164565b34801561039a57600080fd5b506102226113d3565b3480156103af57600080fd5b506103c36103be36600461419c565b6113df565b60405161022f9291906150d1565b3480156103dd57600080fd5b50610222611536565b3480156103f257600080fd5b50610406610401366004613f1e565b61153c565b60405161022f97969594939291906146e8565b34801561042557600080fd5b506101fb6104343660046140e1565b611590565b34801561044557600080fd5b50610222611628565b6101fb61045c36600461421f565b61162e565b34801561046d57600080fd5b50610222611a28565b34801561048257600080fd5b506101fb6104913660046142e9565b611a38565b3480156104a257600080fd5b506102226104b1366004613e95565b611b1b565b3480156104c257600080fd5b506101fb6104d13660046142b9565b611cd9565b3480156104e257600080fd5b506101fb6104f1366004614329565b611eae565b34801561050257600080fd5b50610222610511366004613e95565b611f98565b6101fb610524366004613f8a565b611faa565b34801561053557600080fd5b5061034c610544366004614004565b61201c565b34801561055557600080fd5b506101fb6105643660046142e9565b61221e565b34801561057557600080fd5b506101fb610584366004613e95565b6122f8565b34801561059557600080fd5b506105a96105a4366004613f1e565b61236d565b60405161022f9998979695949392919061452e565b3480156105ca57600080fd5b506101fb6105d9366004613f49565b61252a565b3480156105ea57600080fd5b506105fe6105f9366004613f1e565b6128c2565b60405161022f9998979695949392919061464a565b34801561061f57600080fd5b5061022261062e366004613e95565b6129a8565b34801561063f57600080fd5b506101fb61064e366004613eb1565b6129ba565b34801561065f57600080fd5b5061067361066e366004613f1e565b612ab2565b60405161022f999897969594939291906145dc565b34801561069457600080fd5b506102e1612b1c565b3480156106a957600080fd5b506101fb6106b83660046142b9565b612b2b565b3480156106c957600080fd5b506102e1612da5565b3480156106de57600080fd5b506102e1612db4565b3480156106f357600080fd5b506101fb6107023660046142b9565b612dc3565b60066020526000908152604090205481565b60008060008060008060008061072d613c17565b505050506001600160a01b03968716600090815260036020818152604080842099845298815291889020885161012081018a5281548b16815260018201548b1693810184905260028201549981018a9052918101549099166060820181905260048a01546080830181905260058b015460ff908116151560a0850181905260068d015460c0860181905260078e0154909216151560e086018190526008909d0154610100909501859052949c9a9b929a91995093975092955093509150565b6002600054141561080f5760405162461bcd60e51b81526004016101f290614d69565b600260005561081c613c63565b6001600160a01b038085166000908152600560209081526040808320878452825291829020825161010081018452815490941684526001810180548451818502810185019095528085529193858401939092908301828280156108a857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161088a575b5050509183525050600282015460208201526003820154604082015260048201546060820152600582015460ff8082161515608084015261010090910416151560a082015260069091015460c09091015280519091506001600160a01b03166109235760405162461bcd60e51b81526004016101f290614c31565b8060a001511561095b5761093f8160200151826080015161201c565b61095b5760405162461bcd60e51b81526004016101f290614bb4565b6001600160a01b0384166000908152600560209081526040808320868452909152812080546001600160a01b03191681559061099a6001830182613cb5565b50600060028201819055600382018190556004820181905560058201805461ffff191690556006909101819055600b54604083015160208401518051610a0d946001600160a01b0390941693906109ed57fe5b60200260200101516001600160a01b0316612e229092919063ffffffff16565b600854602082015180516000926001600160a01b031691906000198101908110610a3357fe5b60200260200101516001600160a01b0316148015610a5257508160c001515b15610a7f57610a6a8260200151836060015130612e7d565b9050610a7a818360000151612f89565b610a99565b610a96826020015183606001518460000151612e7d565b90505b610aa78260e0015184612f89565b846001600160a01b03167f7e1fe496989eea92b738a562dbf9c0ae6aa6fcf3f1ef09e95ee4f7603721706b858460200151856040015186606001518688608001518960a001518a60c001518b60e00151604051610b0c99989796959493929190614fdc565b60405180910390a250506001600055505050565b6007546001600160a01b03163314610b4a5760405162461bcd60e51b81526004016101f2906147fa565b600d8190556040517fe46d9daf6d25f7615efa1d0183b90ac6759d85014b598e409aadf0fd918d59a690610b7f908390614da0565b60405180910390a150565b60026000541415610bad5760405162461bcd60e51b81526004016101f290614d69565b6002600055610bba613c17565b506001600160a01b03808416600090815260036020818152604080842087855282529283902083516101208101855281548616808252600183015487169382019390935260028201549481019490945291820154909316606083015260048101546080830152600581015460ff908116151560a0840152600682015460c0840152600782015416151560e08301526008015461010082015290610c6f5760405162461bcd60e51b81526004016101f290614c31565b6000610c908260e001518360c0015184606001518560a001511560016113df565b506001600160a01b0380871660009081526003602081815260408084208a8552825280842080546001600160a01b0319908116825560018201805482169055600282018690559381018054909416909355600480840185905560058401805460ff199081169091556006850186905560078501805490911690556008909301849055600a5488519289015160608a01518a84015160808c015160a08d01519551632662166b60e01b81529a9b5097999390981697632662166b97610d5f979395929491939092913091016144ef565b602060405180830381600087803b158015610d7957600080fd5b505af1158015610d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db191906142d1565b60085460208501519192506001600160a01b0391821691161415610de257610ddd818460000151612f89565b610dff565b82516020840151610dff916001600160a01b039091169083612e22565b610e0e83610100015185612f89565b82600001516001600160a01b03167f9a382661d6573da86db000471303be6f0b2b1bb66089b08e3c16a85d7b6e94f88685602001518660400151876060015188608001518960a001518a60c001518b60e001518c61010001518c604051610e7e9a99989796959493929190614f37565b60405180910390a25050600160005550505050565b6007546001600160a01b031681565b60026000541415610ec55760405162461bcd60e51b81526004016101f290614d69565b6002600081905588511480610edb575087516003145b610ef75760405162461bcd60e51b81526004016101f290614b7d565b87600189510381518110610f0757fe5b60200260200101516001600160a01b031688600081518110610f2557fe5b60200260200101516001600160a01b03161415610f545760405162461bcd60e51b81526004016101f290614ab9565b60008711610f745760405162461bcd60e51b81526004016101f290614c68565b600c54831015610f965760405162461bcd60e51b81526004016101f290614a33565b610fa06000613003565b811561101d5760085488516001600160a01b03909116908990600090610fc257fe5b60200260200101516001600160a01b031614610ff05760405162461bcd60e51b81526004016101f2906149ee565b610ffa838861306c565b34146110185760405162461bcd60e51b81526004016101f290614b37565b6110bb565b82341461103c5760405162461bcd60e51b81526004016101f290614d1b565b600a5488516001600160a01b0390911690631b827878908a9060009061105e57fe5b602002602001015133308b6040518563ffffffff1660e01b81526004016110889493929190614434565b600060405180830381600087803b1580156110a257600080fd5b505af11580156110b6573d6000803e3d6000fd5b505050505b6110cb338989898989878a613091565b50506001600055505050505050565b6001602081815260009384526040808520909152918352912080549181015460028201546003830154600484015460058501546006860154600787015460088801546009909801546001600160a01b03998a1699978816989697958616969490951694929360ff92831693919216908a565b600e5460ff1681565b6008546001600160a01b031681565b600260005414156111875760405162461bcd60e51b81526004016101f290614d69565b6002600055611194613cd3565b5033600090815260016020818152604080842085855282529283902083516101408101855281546001600160a01b039081168083529483015481169382019390935260028201549481019490945260038101548216606085015260048101549091166080840152600581015460a0840152600681015460ff908116151560c0850152600782015460e08501526008820154161515610100840152600901546101208301526112545760405162461bcd60e51b81526004016101f290614c31565b3360009081526001602081815260408084208685528252832080546001600160a01b0319908116825592810180548416905560028101849055600381018054841690556004810180549093169092556005820183905560068201805460ff19908116909155600783018490556008808401805490921690915560099092019290925554908201516001600160a01b03908116911614156113185761131361130d826040015183610120015161306c90919063ffffffff16565b33612f89565b61134d565b61133e33826040015183602001516001600160a01b0316612e229092919063ffffffff16565b61134d81610120015133612f89565b80600001516001600160a01b03167fd500f34e0ec655b7614ae42e1d9c666d5e4dde909a1297829f8c5ecf00805d328383602001518460400151856060015186608001518760a001518860c001518960e001518a61010001518b61012001516040516113c29a99989796959493929190614de7565b60405180910390a250506001600055565b670de0b6b3a764000081565b60008060008461146e57600b546040516340d3096b60e11b81526001600160a01b03909116906381a612d690611419908990600401614406565b60206040518083038186803b15801561143157600080fd5b505afa158015611445573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146991906142d1565b6114ee565b600b54604051637092736960e11b81526001600160a01b039091169063e124e6d29061149e908990600401614406565b60206040518083038186803b1580156114b657600080fd5b505afa1580156114ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ee91906142d1565b90506000886114ff57878210611503565b8782115b9050841561152857806115285760405162461bcd60e51b81526004016101f290614bb4565b909890975095505050505050565b600c5481565b600560208181526000938452604080852090915291835291208054600282015460038301546004840154948401546006909401546001600160a01b03909316949193909260ff808316926101009004169087565b60005b83518110156115c0576115b88482815181106115ab57fe5b6020026020010151612b2b565b600101611593565b5060005b82518110156115f1576115e98382815181106115dc57fe5b6020026020010151611164565b6001016115c4565b5060005b81518110156116225761161a82828151811061160d57fe5b6020026020010151611cd9565b6001016115f5565b50505050565b600d5481565b600260005414156116515760405162461bcd60e51b81526004016101f290614d69565b600260009081556116628383613225565b905061166d81613003565b606061167985806150e1565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c54929350505061012086013510156116d45760405162461bcd60e51b81526004016101f290614a33565b6116e661016086016101408701614164565b156117745760085481516001600160a01b0390911690829060009061170757fe5b60200260200101516001600160a01b0316146117355760405162461bcd60e51b81526004016101f2906149ee565b611748610120860135602087013561306c565b61175234846133ba565b1461176f5760405162461bcd60e51b81526004016101f290614b37565b611835565b61012085013561178434846133ba565b146117a15760405162461bcd60e51b81526004016101f290614d1b565b600a546001600160a01b0316631b8278786117bc87806150e1565b60008181106117c757fe5b90506020020160208101906117dc9190613e95565b333089602001356040518563ffffffff1660e01b81526004016118029493929190614434565b600060405180830381600087803b15801561181c57600080fd5b505af1158015611830573d6000803e3d6000fd5b505050505b60006001825111156118d8578160018351038151811061185157fe5b60200260200101516001600160a01b03168260008151811061186f57fe5b60200260200101516001600160a01b0316141561189e5760405162461bcd60e51b81526004016101f290614ab9565b600b5482516118c2916001600160a01b03169060208901359085906000906109ed57fe5b6118d182876060013530612e7d565b90506118df565b5060208501355b600b5482516000916001600160a01b031690630a48d5a9908590600019810190811061190757fe5b6020026020010151846040518363ffffffff1660e01b815260040161192d929190614631565b60206040518083038186803b15801561194557600080fd5b505afa158015611959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197d91906142d1565b9050600d548110156119a15760405162461bcd60e51b81526004016101f290614828565b50611a1b33836001855103815181106119b657fe5b6020026020010151838960a00160208101906119d29190613e95565b6119e260608c0160408d01613e95565b60808c01356119f760e08e0160c08f01614164565b8d60e001358e610100016020810190611a109190614164565b8f61012001356133fc565b5050600160005550505050565b68327cb2734119d3b7a9601e1b81565b60026000541415611a5b5760405162461bcd60e51b81526004016101f290614d69565b60026000908155338152600160209081526040808320878452909152902080546001600160a01b0316611aa05760405162461bcd60e51b81526004016101f290614c31565b6007810183905560088101805460ff19168315151790556005810184905560038101546004820154600683015460405133937f0a0360dd5c354235bbf8d386ba3b24ef8134088e0785677de1504df219d9149a93610b0c938b936001600160a01b03938416939092169160ff909116908b908b908b90614da9565b600b54604051632c668ec160e01b815260009182916001600160a01b0390911690632c668ec190611b5a908690670de0b6b3a764000090600401614631565b60206040518083038186803b158015611b7257600080fd5b505afa158015611b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611baa91906142d1565b600b546040516340d3096b60e11b81529192506000916001600160a01b03909116906381a612d690611be0908790600401614406565b60206040518083038186803b158015611bf857600080fd5b505afa158015611c0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3091906142d1565b600b546040516323b95ceb60e21b81529192506000916001600160a01b0390911690638ee573ac90611c66908890600401614406565b60206040518083038186803b158015611c7e57600080fd5b505afa158015611c92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb691906142d1565b9050611cd0600a82900a611cca85856135d3565b9061360d565b95945050505050565b60026000541415611cfc5760405162461bcd60e51b81526004016101f290614d69565b6002600055611d09613c17565b5033600090815260036020818152604080842085855282529283902083516101208101855281546001600160a01b03908116808352600184015482169483019490945260028301549582019590955292810154909316606083015260048301546080830152600583015460ff908116151560a0840152600684015460c0840152600784015416151560e083015260089092015461010082015290611dbf5760405162461bcd60e51b81526004016101f290614c31565b336000818152600360208181526040808420878552909152822080546001600160a01b03199081168255600182018054821690556002820184905591810180549092169091556004810182905560058101805460ff1990811690915560068201839055600782018054909116905560080155610100820151611e4091612f89565b80600001516001600160a01b03167f1154174c82984656b028c8021671988f60a346497e56fe02554761184f82a0758383602001518460400151856060015186608001518760a001518860c001518960e001518a61010001516040516113c299989796959493929190614ee7565b60026000541415611ed15760405162461bcd60e51b81526004016101f290614d69565b60026000908155338152600360209081526040808320888452909152902080546001600160a01b0316611f165760405162461bcd60e51b81526004016101f290614c31565b6006810183905560078101805460ff1916831515179055600481018490556002810185905560018101546003820154600583015460405133937f75781255bc71c83f89f29e5a2599f2c174a562d2cd8f2e818a47f132e728049893610e7e938c936001600160a01b03938416938d9316918c9160ff909116908c908c90614ea0565b60026020526000908152604090205481565b60026000541415611fcd5760405162461bcd60e51b81526004016101f290614d69565b60026000908155611fdd90613003565b600c543411611ffe5760405162461bcd60e51b81526004016101f290614a33565b61200e3386868a8a88888861364c565b505060016000555050505050565b600082516002148061202f575082516003145b61204b5760405162461bcd60e51b81526004016101f290614b7d565b60008360008151811061205a57fe5b6020026020010151905060008460018651038151811061207657fe5b602090810291909101015160095490915060009081906001600160a01b03858116911614156120c3576120bc876001815181106120af57fe5b6020026020010151611b1b565b9150612146565b600b546040516340d3096b60e11b81526001600160a01b03909116906381a612d6906120f3908790600401614406565b60206040518083038186803b15801561210b57600080fd5b505afa15801561211f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214391906142d1565b91505b6009546001600160a01b038481169116141561216f575068327cb2734119d3b7a9601e1b6121f2565b600b54604051637092736960e11b81526001600160a01b039091169063e124e6d29061219f908690600401614406565b60206040518083038186803b1580156121b757600080fd5b505afa1580156121cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ef91906142d1565b90505b600061220e83611cca8468327cb2734119d3b7a9601e1b6135d3565b8710955050505050505b92915050565b600260005414156122415760405162461bcd60e51b81526004016101f290614d69565b60026000908155338152600560209081526040808320878452909152902080546001600160a01b03166122865760405162461bcd60e51b81526004016101f290614c31565b600381018490556004810183905560058101805460ff191683151517908190556002820154600683015460405133937fa7f9f4a25eb76f5ec01b1a429d95d6a00833f0f137c88827c58799a1c1ff0dfe93610b0c938b9360018901938c928c928c9260ff610100909104169190615033565b6007546001600160a01b031633146123225760405162461bcd60e51b81526004016101f2906147fa565b600780546001600160a01b0319166001600160a01b0383161790556040517fe24c39186e9137521953beaa8446e71f55b8f12296984f9d4273ceb1af728d9090610b7f908390614406565b6000806000806000806000806000612383613c63565b6001600160a01b03808d1660009081526005602090815260408083208f84528252918290208251610100810184528154909416845260018101805484518185028101850190955280855291938584019390929083018282801561240f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116123f1575b505050918352505060028201546020808301919091526003830154604083015260048301546060830152600583015460ff8082161515608085015261010090910416151560a083015260069092015460c09091015281015151909150612476576000612490565b806020015160008151811061248757fe5b60200260200101515b6001826020015151116124a45760006124be565b81602001516001815181106124b557fe5b60200260200101515b6002836020015151116124d25760006124ec565b82602001516002815181106124e357fe5b60200260200101515b8360400151846060015185608001518660a001518760c001518860e00151995099509950995099509950995099509950509295985092959850929598565b6002600054141561254d5760405162461bcd60e51b81526004016101f290614d69565b600260005561255a613cd3565b506001600160a01b038084166000908152600160208181526040808420878552825292839020835161014081018552815486168082529382015486169281019290925260028101549382019390935260038301548416606082015260048301549093166080840152600582015460a0840152600682015460ff908116151560c0850152600783015460e0850152600883015416151561010084015260099091015461012083015261261d5760405162461bcd60e51b81526004016101f290614c31565b600061263e8261010001518360e0015184608001518560c0015160016113df565b506001600160a01b0380871660009081526001602081815260408084208a8552825280842080546001600160a01b0319908116825593810180548516905560028101859055600381018054851690556004810180549094169093556005830184905560068301805460ff19908116909155600784018590556008840180549091169055600990920192909255600b5490860151918601519394506126e6938316921690612e22565b81606001516001600160a01b031682602001516001600160a01b0316146127be57604080516002808252606080830184529260208301908036833701905050905082602001518160008151811061273957fe5b60200260200101906001600160a01b031690816001600160a01b03168152505082606001518160018151811061276b57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600061279982600030612e7d565b600b5460608601519192506127bb916001600160a01b03908116911683612e22565b50505b600a5482516060840151608085015160a086015160c0870151604051630f8ee8bb60e11b81526001600160a01b0390961695631f1dd1769561280a9590949093909290916004016144bb565b600060405180830381600087803b15801561282457600080fd5b505af1158015612838573d6000803e3d6000fd5b5050505061284b82610120015184612f89565b81600001516001600160a01b03167f7fb1c74d1ea6aa1c9c585e17ce8274c8ff98745e85e7459b73f87d784494f58e8584602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001518c61012001518c604051610b0c9b9a99989796959493929190614e3e565b60008060008060008060008060006128d8613cd3565b505050506001600160a01b0397881660009081526001602081815260408084209a845299815291899020895161014081018b5281548c168152918101548b1692820183905260028101549982018a905260038101548b16606083018190526004820154909b1660808301819052600582015460a08401819052600683015460ff908116151560c08601819052600785015460e08701819052600886015490921615156101008701819052600990950154610120909601869052959e9c9d9c929b5090995093975092955093509150565b60046020526000908152604090205481565b6007546001600160a01b031633146129e45760405162461bcd60e51b81526004016101f2906147fa565b600e5460ff1615612a075760405162461bcd60e51b81526004016101f29061489f565b600e805460ff19166001179055600a80546001600160a01b038089166001600160a01b031992831617909255600b8054888416908316179055600880548784169083161790556009805492861692909116919091179055600c829055600d8190556040517fcfb7ef8749fafc8da2af1ba3d025479ffc4e58f7dc420113e112512a3bda596390612aa290889088908890889088908890614481565b60405180910390a1505050505050565b600360208181526000938452604080852090915291835291208054600182015460028301549383015460048401546005850154600686015460078701546008909701546001600160a01b039687169895871697959690941694929360ff9283169391929091169089565b6009546001600160a01b031681565b60026000541415612b4e5760405162461bcd60e51b81526004016101f290614d69565b6002600055612b5b613c63565b33600090815260056020908152604080832085845282529182902082516101008101845281546001600160a01b0316815260018201805485518186028101860190965280865291949293858101939290830182828015612be457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612bc6575b5050509183525050600282015460208201526003820154604082015260048201546060820152600582015460ff8082161515608084015261010090910416151560a082015260069091015460c09091015280519091506001600160a01b0316612c5f5760405162461bcd60e51b81526004016101f290614c31565b336000908152600560209081526040808320858452909152812080546001600160a01b031916815590612c956001830182613cb5565b50600060028201819055600382018190556004820181905560058201805461ffff191690556006909101819055600854602083015180516001600160a01b03909216929091612ce057fe5b60200260200101516001600160a01b03161415612d1a57612d1561130d82604001518360e0015161306c90919063ffffffff16565b612d42565b612d3433826040015183602001516000815181106109ed57fe5b612d428160e0015133612f89565b336001600160a01b03167fefd66d4f9c2f880c70aedeb5b26a44fb474cea07e5d6c533f2d27c303d5d94538383602001518460400151856060015186608001518760a001518860c001518960e001516040516113c2989796959493929190614f8d565b600a546001600160a01b031681565b600b546001600160a01b031681565b6007546001600160a01b03163314612ded5760405162461bcd60e51b81526004016101f2906147fa565b600c8190556040517fbde5eafdc37b81830d70124cddccaaa6d034e71dda3c8fc18a959ca76a7cbcfc90610b7f908390614da0565b612e788363a9059cbb60e01b8484604051602401612e41929190614631565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526137db565b505050565b6000835160021415612ec457612ebd84600081518110612e9957fe5b602002602001015185600181518110612eae57fe5b6020026020010151858561386a565b9050612f82565b835160031415612f6a576000612f0585600081518110612ee057fe5b602002602001015186600181518110612ef557fe5b602002602001015160003061386a565b9050612f2e600b60009054906101000a90046001600160a01b031682876001815181106109ed57fe5b612f6285600181518110612f3e57fe5b602002602001015186600281518110612f5357fe5b6020026020010151868661386a565b915050612f82565b60405162461bcd60e51b81526004016101f290614b7d565b9392505050565b600854604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d90612fb9908590600401614da0565b600060405180830381600087803b158015612fd357600080fd5b505af1158015612fe7573d6000803e3d6000fd5b50612fff925050506001600160a01b03821683613a01565b5050565b3415613069576008546001600160a01b031663d0e30db061302434846133ba565b6040518263ffffffff1660e01b81526004016000604051808303818588803b15801561304f57600080fd5b505af1158015613063573d6000803e3d6000fd5b50505050505b50565b600082820183811015612f825760405162461bcd60e51b81526004016101f29061486a565b6001600160a01b0388166000908152600660205260409020546130b2613c63565b6040518061010001604052808b6001600160a01b031681526020018a81526020018981526020018881526020018781526020018615158152602001851515815260200184815250905061310f60018361306c90919063ffffffff16565b6001600160a01b038b8116600090815260066020908152604080832094909455600581528382208683528152929020835181546001600160a01b0319169216919091178155828201518051849361316d926001850192910190613d27565b506040828101516002830155606083015160038301556080830151600483015560a083015160058301805460c086015115156101000261ff001993151560ff19909216919091179290921691909117905560e090920151600690910155516001600160a01b038b16907fdf06bb56ffc4029dc0b62b68bb5bbadea93a38b530cefc9b81afb742a6555d88906132119085908d908d908d908d908d908d908d90614f8d565b60405180910390a250505050505050505050565b600080600b60009054906101000a90046001600160a01b03166001600160a01b03166378399b0b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561327657600080fd5b505afa15801561328a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ae9190614203565b60405163d47eed4560e01b81529091506001600160a01b0382169063d47eed45906132df9087908790600401614727565b60206040518083038186803b1580156132f757600080fd5b505afa15801561330b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332f91906142d1565b9150813410156133515760405162461bcd60e51b81526004016101f290614aeb565b604051631df3cbc560e31b81526001600160a01b0382169063ef9e5e289084906133819088908890600401614727565b6000604051808303818588803b15801561339a57600080fd5b505af11580156133ae573d6000803e3d6000fd5b50505050505092915050565b6000612f8283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613a9d565b33600090815260026020526040902054613414613cd3565b6040518061014001604052808d6001600160a01b031681526020018c6001600160a01b031681526020018b81526020018a6001600160a01b03168152602001896001600160a01b031681526020018881526020018715158152602001868152602001851515815260200184815250905061349860018361306c90919063ffffffff16565b6001600160a01b03808e166000818152600260208181526040808420969096556001808252868420898552825292869020875181549087166001600160a01b0319918216178255918801519381018054948716948316949094179093558686015191830191909155606086015160038301805491861691831691909117905560808601516004830180549190951691161790925560a0840151600583015560c084015160068301805491151560ff1992831617905560e085015160078401556101008501516008840180549115159190921617905561012084015160099092019190915590517fb27b9afe3043b93788c40cfc3cc73f5d928a2e40f3ba01820b246426de8fa1b9906135bd9085908f908f908f908f908f908f908f908f908f90614de7565b60405180910390a2505050505050505050505050565b6000826135e257506000612218565b828202828482816135ef57fe5b0414612f825760405162461bcd60e51b81526004016101f290614a78565b6000612f8283836040518060400160405280601a815260200179536166654d6174683a206469766973696f6e206279207a65726f60301b815250613ac9565b6001600160a01b03881660009081526004602052604090205461366d613c17565b5060408051610120810182526001600160a01b03808c1682528a8116602083015291810189905290871660608201526080810186905284151560a082015260c0810184905282151560e0820152346101008201526136cc82600161306c565b6001600160a01b03808c166000818152600460208181526040808420969096556003808252868420898552825292869020875181549087166001600160a01b0319918216178255918801516001820180549188169184169190911790558787015160028201556060880151938101805494909616939091169290921790935560808501519281019290925560a084015160058301805491151560ff1992831617905560c0850151600684015560e08501516007840180549115159190921617905561010084015160089092019190915590517f48ee333d2a65cc45fdb83bc012920d89181c3377390cd239d2b63f2bef67a02d906132119085908d908d908d908d908d908d908d903490614ee7565b6060613830826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613b009092919063ffffffff16565b805190915015612e78578080602001905181019061384e9190614180565b612e785760405162461bcd60e51b81526004016101f290614cd1565b60095460009081906001600160a01b038681169116141561391057600b5460405163817bb85760e01b81526001600160a01b039091169063817bb857906138b7908990879060040161441a565b602060405180830381600087803b1580156138d157600080fd5b505af11580156138e5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390991906142d1565b90506139e1565b6009546001600160a01b038781169116141561395857600b54604051630711e61960e41b81526001600160a01b039091169063711e6190906138b7908890879060040161441a565b600b54604051634998b10960e11b81526001600160a01b039091169063933162129061398c9089908990889060040161445e565b602060405180830381600087803b1580156139a657600080fd5b505af11580156139ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139de91906142d1565b90505b83811015611cd05760405162461bcd60e51b81526004016101f2906149ad565b80471015613a215760405162461bcd60e51b81526004016101f290614930565b6000826001600160a01b031682604051613a3a90614403565b60006040518083038185875af1925050503d8060008114613a77576040519150601f19603f3d011682016040523d82523d6000602084013e613a7c565b606091505b5050905080612e785760405162461bcd60e51b81526004016101f2906148d6565b60008184841115613ac15760405162461bcd60e51b81526004016101f291906147c7565b505050900390565b60008183613aea5760405162461bcd60e51b81526004016101f291906147c7565b506000838581613af657fe5b0495945050505050565b6060613b0f8484600085613b17565b949350505050565b606082471015613b395760405162461bcd60e51b81526004016101f290614967565b613b4285613bd8565b613b5e5760405162461bcd60e51b81526004016101f290614bfa565b60006060866001600160a01b03168587604051613b7b91906143e7565b60006040518083038185875af1925050503d8060008114613bb8576040519150601f19603f3d011682016040523d82523d6000602084013e613bbd565b606091505b5091509150613bcd828286613bde565b979650505050505050565b3b151590565b60608315613bed575081612f82565b825115613bfd5782518084602001fd5b8160405162461bcd60e51b81526004016101f291906147c7565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b60405180610100016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600015158152602001600015158152602001600081525090565b50805460008255906000526020600020908101906130699190613d8c565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915290565b828054828255906000526020600020908101928215613d7c579160200282015b82811115613d7c57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613d47565b50613d88929150613da1565b5090565b5b80821115613d885760008155600101613d8d565b5b80821115613d885780546001600160a01b0319168155600101613da2565b600082601f830112613dd0578081fd5b8135613de3613dde82615154565b61512e565b818152915060208083019084810181840286018201871015613e0457600080fd5b60005b84811015613e2c578135613e1a8161519f565b84529282019290820190600101613e07565b505050505092915050565b600082601f830112613e47578081fd5b8135613e55613dde82615154565b818152915060208083019084810181840286018201871015613e7657600080fd5b60005b84811015613e2c57813584529282019290820190600101613e79565b600060208284031215613ea6578081fd5b8135612f828161519f565b60008060008060008060c08789031215613ec9578182fd5b8635613ed48161519f565b95506020870135613ee48161519f565b94506040870135613ef48161519f565b93506060870135613f048161519f565b9598949750929560808101359460a0909101359350915050565b60008060408385031215613f30578182fd5b8235613f3b8161519f565b946020939093013593505050565b600080600060608486031215613f5d578283fd5b8335613f688161519f565b9250602084013591506040840135613f7f8161519f565b809150509250925092565b600080600080600080600060e0888a031215613fa4578081fd5b8735613faf8161519f565b9650602088013595506040880135613fc68161519f565b9450606088013593506080880135613fdd816151b4565b925060a0880135915060c0880135613ff4816151b4565b8091505092959891949750929550565b60008060408385031215614016578182fd5b82356001600160401b0381111561402b578283fd5b61403785828601613dc0565b95602094909401359450505050565b600080600080600080600080610100898b031215614062578081fd5b88356001600160401b03811115614077578182fd5b6140838b828c01613dc0565b98505060208901359650604089013595506060890135945060808901356140a9816151b4565b935060a0890135925060c08901356140c0816151b4565b915060e08901356140d0816151b4565b809150509295985092959890939650565b6000806000606084860312156140f5578081fd5b83356001600160401b038082111561410b578283fd5b61411787838801613e37565b9450602086013591508082111561412c578283fd5b61413887838801613e37565b9350604086013591508082111561414d578283fd5b5061415a86828701613e37565b9150509250925092565b600060208284031215614175578081fd5b8135612f82816151b4565b600060208284031215614191578081fd5b8151612f82816151b4565b600080600080600060a086880312156141b3578283fd5b85356141be816151b4565b94506020860135935060408601356141d58161519f565b925060608601356141e5816151b4565b915060808601356141f5816151b4565b809150509295509295909350565b600060208284031215614214578081fd5b8151612f828161519f565b600080600060408486031215614233578081fd5b83356001600160401b0380821115614249578283fd5b90850190610160828803121561425d578283fd5b90935060208501359080821115614272578283fd5b818601915086601f830112614285578283fd5b813581811115614293578384fd5b87602080830285010111156142a6578384fd5b6020830194508093505050509250925092565b6000602082840312156142ca578081fd5b5035919050565b6000602082840312156142e2578081fd5b5051919050565b600080600080608085870312156142fe578182fd5b843593506020850135925060408501359150606085013561431e816151b4565b939692955090935050565b600080600080600060a08688031215614340578283fd5b8535945060208601359350604086013592506060860135915060808601356141f5816151b4565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156143ac5781516001600160a01b031687529582019590820190600101614387565b509495945050505050565b15159052565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600082516143f9818460208701615173565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b6001600160a01b0396871681529486166020860152928516604085015293166060830152608082019290925260a081019190915260c00190565b6001600160a01b03958616815293851660208501529190931660408301526060820192909252901515608082015260a00190565b6001600160a01b0397881681529587166020870152938616604086015260608501929092526080840152151560a083015290911660c082015260e00190565b6001600160a01b03998a16815297891660208901529590971660408701526060860193909352608085019190915260a0840152151560c083015291151560e08201526101008101919091526101200190565b6001600160a01b039a8b168152988a1660208a01526040890197909752948816606088015292909616608086015260a085015293151560c084015260e08301939093529115156101008201526101208101919091526101400190565b6001600160a01b03998a168152978916602089015260408801969096529390961660608601526080850191909152151560a084015260c083019390935291151560e08201526101008101919091526101200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03998a168152602081019890985295881660408801529390961660608601526080850191909152151560a084015260c083019390935291151560e08201526101008101919091526101200190565b6001600160a01b039889168152602081019790975294909616604086015260608501929092521515608084015260a083015291151560c082015260e08101919091526101000190565b6001600160a01b0397909716875260208701959095526040860193909352606085019190915215156080840152151560a083015260c082015260e00190565b602080825281810183905260009060408482028401810190840186845b878110156147af57868403603f190183528135368a9003601e19018112614769578687fd5b890180356001600160401b03811115614780578788fd5b8036038b131561478e578788fd5b61479b86828985016143bd565b955050509184019190840190600101614744565b5091979650505050505050565b901515815260200190565b60006020825282518060208401526147e6816040850160208701615173565b601f01601f19169190910160400192915050565b60208082526014908201527327b93232b92137b7b59d103337b93134b23232b760611b604082015260600190565b60208082526022908201527f4f72646572426f6f6b3a20696e73756666696369656e7420636f6c6c61746572604082015261185b60f21b606082015260800190565b6020808252601b908201527a536166654d6174683a206164646974696f6e206f766572666c6f7760281b604082015260600190565b6020808252601e908201527f4f72646572426f6f6b3a20616c726561647920696e697469616c697a65640000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c20726040820152791958da5c1a595b9d081b585e481a185d99481c995d995c9d195960321b606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b60208082526021908201527f4f72646572426f6f6b3a20696e73756666696369656e7420616d6f756e744f756040820152601d60fa1b606082015260800190565b60208082526025908201527f4f72646572426f6f6b3a206f6e6c79207765746820636f756c64206265207772604082015264185c1c195960da1b606082015260800190565b60208082526025908201527f4f72646572426f6f6b3a20696e73756666696369656e7420657865637574696f6040820152646e2066656560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526018908201527709ee4c8cae484deded67440d2dcecc2d8d2c840bee0c2e8d60431b604082015260600190565b6020808252602c908201527f696e73756666696369656e74206d73672e76616c756520746f2075706461746560408201526b20707974682070726963657360a01b606082015260800190565b60208082526026908201527f4f72646572426f6f6b3a20696e636f72726563742076616c7565207472616e7360408201526519995c9c995960d21b606082015260800190565b6020808252601f908201527f4f72646572426f6f6b3a20696e76616c6964205f706174682e6c656e67746800604082015260600190565b60208082526026908201527f4f72646572426f6f6b3a20696e76616c696420707269636520666f722065786560408201526531baba34b7b760d11b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252601d908201527f4f72646572426f6f6b3a206e6f6e2d6578697374656e74206f72646572000000604082015260600190565b6020808252601c908201527b27b93232b92137b7b59d1034b73b30b634b2102fb0b6b7bab73a24b760211b604082015260600190565b60208082526019908201527827b93232b92137b7b59d1034b73b30b634b21039b2b73232b960391b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252602e908201527f4f72646572426f6f6b3a20696e636f727265637420657865637574696f6e206660408201526d1959481d1c985b9cd9995c9c995960921b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b90815260200190565b9687526001600160a01b0395861660208801529390941660408601529015156060850152608084015260a0830191909152151560c082015260e00190565b998a526001600160a01b0398891660208b015260408a0197909752948716606089015292909516608087015260a086015292151560c085015260e08401929092529015156101008301526101208201526101400190565b9a8b526001600160a01b03998a1660208c015260408b019890985295881660608a015293909616608088015260a0870191909152151560c086015260e08501939093529115156101008401526101208301919091526101408201526101600190565b9788526001600160a01b0396871660208901526040880195909552929094166060860152608085015291151560a084015260c0830191909152151560e08201526101000190565b9889526001600160a01b0397881660208a015260408901969096529390951660608701526080860191909152151560a085015260c084019290925290151560e08301526101008201526101200190565b998a526001600160a01b0398891660208b015260408a01979097529490961660608801526080870192909252151560a086015260c085015291151560e08401526101008301919091526101208201526101400190565b60006101008a8352806020840152614fa78184018b614374565b604084019990995250506060810195909552608085019390935290151560a0840152151560c083015260e09091015292915050565b60006101208b8352806020840152614ff68184018c614374565b604084019a909a5250506060810196909652608086019490945260a0850192909252151560c0840152151560e08301526101009091015292915050565b8881526101006020808301829052895491830182905260008a8152818120909261012085019290845b8181101561508a57835461507a9086906001600160a01b0316614367565b938201936001938401930161505c565b50505050809150508760408301528660608301528560808301526150b160a08301866143b7565b6150be60c08301856143b7565b8260e08301529998505050505050505050565b9182521515602082015260400190565b6000808335601e198436030181126150f7578283fd5b8301803591506001600160401b03821115615110578283fd5b602090810192508102360382131561512757600080fd5b9250929050565b6040518181016001600160401b038111828210171561514c57600080fd5b604052919050565b60006001600160401b03821115615169578081fd5b5060209081020190565b60005b8381101561518e578181015183820152602001615176565b838111156116225750506000910152565b6001600160a01b038116811461306957600080fd5b801515811461306957600080fdfea2646970667358221220a0d5f9a74d50848c3492cadbdbc7523ce5922a62071a5aac793c23bddc2f4b8964736f6c634300060c0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.