Overview
ETH Balance
0 ETH
ETH Value
$0.00Latest 25 from a total of 784 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Open Interes... | 154408441 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408428 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408415 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408397 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408379 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408359 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408324 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408305 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408288 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408270 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408253 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408236 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408219 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408202 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408185 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408167 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408156 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408138 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408121 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408105 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408089 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408074 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408055 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408020 | 808 days ago | IN | 0 ETH | 0.00006047 | ||||
| Set Open Interes... | 154408002 | 808 days ago | IN | 0 ETH | 0.00006047 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Options
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 5000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../utils/PermissionedMetaContext.sol";
import "../interfaces/ITradeNFT.sol";
import "../interfaces/IReferrals.sol";
import "../interfaces/IPairsContract.sol";
import "../interfaces/IStableVault.sol";
import "../interfaces/IGovernanceStaking.sol";
import "../interfaces/ITrading.sol";
interface IStable is IERC20 {
function burnFrom(address account, uint256 amount) external;
function mintFor(address account, uint256 amount) external;
}
interface ExtendedIERC20 is IERC20 {
function decimals() external view returns (uint8);
}
interface ILPStaking {
function distribute(address _tigAsset, uint256 _amount) external;
}
interface ERC20Permit is IERC20 {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
contract Options is PermissionedMetaContext {
using ECDSA for bytes32;
using SafeERC20 for IERC20;
uint256 constant private DIVISION_CONSTANT = 1e10;
struct ERC20PermitData {
uint256 deadline;
uint256 amount;
uint8 v;
bytes32 r;
bytes32 s;
bool usePermit;
}
struct TradeInfo {
uint256 collateral;
address collateralAsset;
address stableVault;
address receivedAsset;
bool direction;
uint256 asset;
uint256 duration;
address referrer;
}
struct TradedAsset {
uint maxCollateral;
uint minCollateral;
uint maxDuration;
uint minDuration;
uint maxOpen;
uint openInterest;
uint assetId;
uint winPercent;
uint closeFee;
uint botFee;
bool isForex;
}
struct MarketTime {
uint hrStart;
uint hrEnd;
uint minStart;
uint minEnd;
}
uint public validSignatureTimer;
bool public useSpread;
ITradeNFT public tradeNFT;
IGovernanceStaking public staking;
IReferrals public referrals;
IPairsContract public pairsContract;
ITrading public tradingContract;
ILPStaking public lpstaking;
uint256 public lpDistribution = 3e9;
uint256 public refMultiplier = 100;
mapping(address => bool) public allowedVault;
mapping(address => mapping(address => bool)) private marginApproved;
mapping(uint => TradedAsset) public tradedAssets;
mapping(address => bool) private isNode;
mapping(uint8 => MarketTime) public marketTimes;
mapping(uint8 => bool) public isForexHourClosed;
constructor(
address _tradeNFT,
address _staking,
address _referrals,
address _pairsContract,
address _trading,
address _lpstaking
)
{
if (
_tradeNFT == address(0) ||
_staking == address(0) ||
_referrals == address(0) ||
_pairsContract == address(0) ||
_trading == address(0) ||
_lpstaking == address(0)
) {
revert("!constructor");
}
tradeNFT = ITradeNFT(_tradeNFT);
staking = IGovernanceStaking(_staking);
referrals = IReferrals(_referrals);
pairsContract = IPairsContract(_pairsContract);
tradingContract = ITrading(_trading);
lpstaking = ILPStaking(_lpstaking);
}
// ===== END-USER FUNCTIONS =====
/**
* @param _tradeInfo Trade info
* @param _permitData data and signature needed for token approval
* @param _trader address the trade is initiated for
* @param _priceData verifiable off-chain price data
*/
function openTrade(
TradeInfo calldata _tradeInfo,
ERC20PermitData calldata _permitData,
address _trader,
PriceData calldata _priceData
)
external onlyTrustedForwarder
{
_validateProxy(_trader);
TradedAsset memory _asset = tradedAssets[_tradeInfo.asset];
require(_asset.openInterest + _tradeInfo.collateral <= _asset.maxOpen, "Open interest limit reached.");
require(_tradeInfo.collateral <= _asset.maxCollateral, "Maximum collateral exceeded.");
require(_tradeInfo.collateral >= _asset.minCollateral, "Collateral too low.");
require(_tradeInfo.duration <= _asset.maxDuration, "Maximum duration exceeded.");
require(_tradeInfo.duration >= _asset.minDuration, "Duration too low.");
if(_asset.isForex) require(canOpenForex(_tradeInfo.duration), "Market is closed.");
referrals.setReferred(_trader, _tradeInfo.referrer);
address _tigAsset = _checkVault(_tradeInfo.stableVault, _tradeInfo.collateralAsset, _tradeInfo.receivedAsset);
_handleDeposit(_tigAsset, _tradeInfo.collateralAsset, _tradeInfo.collateral, _tradeInfo.stableVault, _permitData, _trader);
uint256 _price = getVerifiedPrice(_tradeInfo.asset, _priceData, _tradeInfo.direction ? 1 : 2, block.timestamp);
tradedAssets[_tradeInfo.asset].openInterest += _tradeInfo.collateral;
ITradeNFT.MintTrade memory _mintTrade = ITradeNFT.MintTrade(
_trader,
_tradeInfo.collateral,
_tradeInfo.asset,
_tradeInfo.direction,
_tradeInfo.duration,
_price,
0,
_tigAsset,
_tradeInfo.receivedAsset,
_tradeInfo.stableVault
);
tradeNFT.mint(_mintTrade);
emit TradeOpened(_tradeInfo, _tradeInfo.duration + block.timestamp, 0, _price, tradeNFT.getCount()-1, _trader);
}
/**
* @param _tradeInfo Trade info
* @param _orderType type of limit order used to open the position
* @param _price limit price
* @param _permitData data and signature needed for token approval
* @param _trader address the trade is initiated for
*/
function initiateLimitOrder(
TradeInfo calldata _tradeInfo,
uint256 _orderType, // 1 limit, 2 stop
uint256 _price,
ERC20PermitData calldata _permitData,
address _trader
)
external onlyTrustedForwarder
{
TradedAsset memory _asset = tradedAssets[_tradeInfo.asset];
require(_asset.openInterest + _tradeInfo.collateral <= _asset.maxOpen, "Open interest limit reached.");
require(_tradeInfo.collateral <= _asset.maxCollateral, "Maximum collateral exceeded.");
require(_tradeInfo.collateral >= _asset.minCollateral, "Collateral too low.");
require(_tradeInfo.duration <= _asset.maxDuration, "Maximum duration exceeded.");
require(_tradeInfo.duration >= _asset.minDuration, "Duration too low.");
require(_orderType == 1 || _orderType == 2, "Invalid order type.");
referrals.setReferred(_trader, _tradeInfo.referrer);
_validateProxy(_trader);
address _tigAsset = _checkVault(_tradeInfo.stableVault, _tradeInfo.collateralAsset, _tradeInfo.receivedAsset);
if (_price == 0) revert("Price cannot be zero.");
_handleDeposit(_tigAsset, _tradeInfo.collateralAsset, _tradeInfo.collateral, _tradeInfo.stableVault, _permitData, _trader);
ITradeNFT.MintTrade memory _mintTrade = ITradeNFT.MintTrade(
_trader,
_tradeInfo.collateral,
_tradeInfo.asset,
_tradeInfo.direction,
_tradeInfo.duration,
_price,
_orderType,
_tigAsset,
_tradeInfo.receivedAsset,
_tradeInfo.stableVault
);
tradeNFT.mint(_mintTrade);
emit TradeOpened(_tradeInfo, type(uint).max, _orderType, _price, tradeNFT.getCount()-1, _trader);
}
/**
* @param _id position ID
* @param _trader address the trade is initiated for
*/
function cancelLimitOrder(
uint256 _id,
address _trader
)
external onlyTrustedForwarder
{
_validateProxy(_trader);
_checkOwner(_id, _trader);
ITradeNFT.Trade memory _trade = tradeNFT.trades(_id);
if (_trade.orderType == 0) revert("Not a limit order.");
IStable(_trade.tigAsset).mintFor(_trader, _trade.collateral);
tradeNFT.burn(_id);
emit OptionsLimitCancelled(_id, _trader);
}
/**
* @param _id position id
* @param _priceData verifiable off-chain price data
*/
function executeLimitOrder(
uint256 _id,
PriceData calldata _priceData
)
external notForwarder
{
ITradeNFT.Trade memory _trade = tradeNFT.trades(_id);
TradedAsset storage asset = tradedAssets[_trade.asset];
require(asset.openInterest + _trade.collateral <= asset.maxOpen, "Open interest limit reached.");
if(asset.isForex) require(canOpenForex(_trade.duration), "Market is closed.");
uint256 _price = getVerifiedPrice(_trade.asset, _priceData, _trade.direction ? 1 : 2, block.timestamp);
if (_trade.orderType == 0) revert("Not a limit order.");
if (_trade.direction && _trade.orderType == 1) {
if (_trade.openPrice < _price) revert("Limit price not met.");
} else if (!_trade.direction && _trade.orderType == 1) {
if (_trade.openPrice > _price) revert("Limit price not met.");
} else if (!_trade.direction && _trade.orderType == 2) {
if (_trade.openPrice < _price) revert("Limit price not met.");
_trade.openPrice = _price;
} else {
if (_trade.openPrice > _price) revert("Limit price not met.");
_trade.openPrice = _price;
}
asset.openInterest += _trade.collateral;
IStable(_trade.tigAsset).mintFor(_msgSender(), _trade.collateral * asset.botFee / DIVISION_CONSTANT);
tradeNFT.executeLimitOrder(_id, _trade.openPrice, _trade.collateral);
emit OptionsLimitOrderExecuted(_trade.asset, _trade.direction, _trade.duration, _trade.openPrice, _trade.collateral, _id, _trade.expires, _trade.trader, _msgSender());
}
/**
* @notice close trade
* @param _id id of the tradeNFT
* @param _priceData verifiable off-chain data
*/
function closeTrade(
uint256 _id,
PriceData calldata _priceData
)
external notForwarder
{
ITradeNFT.Trade memory _trade = tradeNFT.trades(_id);
require(_trade.trader != address(0), "Trade does not exist.");
TradedAsset storage _tradedAsset = tradedAssets[_trade.asset];
if (_trade.orderType != 0) revert("Cannot close a limit order.");
uint256 _price = getVerifiedPrice(_trade.asset, _priceData, 0, _trade.expires);
bool isWin;
if (_trade.direction && _price > _trade.openPrice) {
isWin = true;
} else if(!_trade.direction && _price <= _trade.openPrice) {
isWin = true;
}
uint toSend;
if(isWin) {
toSend = _trade.collateral + _trade.collateral * _tradedAsset.winPercent / DIVISION_CONSTANT;
if(_trade.tigAsset == _trade.receivedAsset) {
IStable(_trade.tigAsset).mintFor(address(_trade.trader), toSend);
} else {
IStable(_trade.tigAsset).mintFor(address(this), toSend);
IStableVault(_trade.stableVault).withdraw(_trade.receivedAsset, toSend);
IERC20(_trade.receivedAsset).safeTransfer(_trade.trader, toSend);
}
}
(address _referrer, uint _refFees) = getRef(_trade.trader);
if(_referrer != address(0)) {
IStable(_trade.tigAsset).mintFor(_referrer, _trade.collateral * _refFees * refMultiplier / DIVISION_CONSTANT);
}
IStable(_trade.tigAsset).mintFor(address(this), _trade.collateral * _tradedAsset.closeFee / DIVISION_CONSTANT);
IStable(_trade.tigAsset).mintFor(_msgSender(), _trade.collateral * _tradedAsset.botFee / DIVISION_CONSTANT);
uint balance = IStable(_trade.tigAsset).balanceOf(address(this));
uint256 _lpDistribution = balance * lpDistribution / DIVISION_CONSTANT;
IStable(_trade.tigAsset).approve(address(staking), balance - _lpDistribution);
staking.distribute(_trade.tigAsset, balance - _lpDistribution);
{
uint remBalance = IStable(_trade.tigAsset).balanceOf(address(this));
IStable(_trade.tigAsset).approve(address(lpstaking), remBalance);
lpstaking.distribute(_trade.tigAsset, remBalance);
}
emit OptionsFeesDistributed(_trade.tigAsset, balance, _referrer == address(0) ? 0 : _trade.collateral * _refFees / DIVISION_CONSTANT, _trade.collateral * _tradedAsset.botFee / DIVISION_CONSTANT, _referrer);
_tradedAsset.openInterest -= _trade.collateral;
tradeNFT.burn(_id);
emit TradeClosed(_id, _price, isWin ? _tradedAsset.winPercent : 0, toSend, _trade.trader, _msgSender(), _trade);
}
/**
* @notice verifies the signed price and returns it
* @param _asset id of position asset
* @param _priceData price data object came from the price oracle
* @param _withSpreadIsLong 0, 1, or 2 - to specify if we need the price returned to be after spread
* @param _timeFrom time from which the price is considered valid. Expiration when closing, current time when opening
* @return _price price after verification and with spread if _withSpreadIsLong is 1 or 2
*/
function getVerifiedPrice(
uint256 _asset,
PriceData calldata _priceData,
uint256 _withSpreadIsLong,
uint256 _timeFrom
)
private view
returns(uint256 _price)
{
address _provider = (
keccak256(abi.encode(
_priceData.provider,
_priceData.isClosed,
_priceData.asset,
_priceData.price,
_priceData.spread,
_priceData.timestamp
))
).toEthSignedMessageHash().recover(_priceData.signature);
require(_provider == _priceData.provider, "BadSig");
require(isNode[_provider], "!Node");
require(_asset == _priceData.asset, "!Asset");
require(!_priceData.isClosed, "Market is closed.");
if (_withSpreadIsLong == 0) {
// Closing
require(_timeFrom + validSignatureTimer >= _priceData.timestamp, "FutSig");
require(_timeFrom <= _priceData.timestamp, "Price has expired.");
} else {
// Opening
require(_timeFrom >= _priceData.timestamp, "FutSig");
require(_timeFrom <= _priceData.timestamp + validSignatureTimer, "Price has expired.");
}
require(_priceData.price > 0, "NoPrice");
_price = _priceData.price;
uint256 _spread = _priceData.spread;
if(_withSpreadIsLong == 1 && useSpread)
_price += _price * _spread / DIVISION_CONSTANT;
else if(_withSpreadIsLong == 2 && useSpread)
_price -= _price * _spread / DIVISION_CONSTANT;
}
function getRef(
address _trader
) private view returns(address, uint) {
return referrals.getReferred(_trader);
}
/**
* @dev handle stableVault deposits for different trading functions
* @param _tigAsset tigAsset token address
* @param _marginAsset token being deposited into stableVault
* @param _margin amount being deposited
* @param _stableVault StableVault address
* @param _permitData Data for approval via permit
* @param _trader Trader address to take tokens from
*/
function _handleDeposit(address _tigAsset, address _marginAsset, uint256 _margin, address _stableVault, ERC20PermitData calldata _permitData, address _trader) internal {
IStable tigAsset = IStable(_tigAsset);
if (_tigAsset != _marginAsset) {
if (_permitData.usePermit) {
ERC20Permit(_marginAsset).permit(_trader, address(this), _permitData.amount, _permitData.deadline, _permitData.v, _permitData.r, _permitData.s);
}
uint256 _balBefore = tigAsset.balanceOf(address(this));
uint256 _marginDecMultiplier = 10**(18-ExtendedIERC20(_marginAsset).decimals());
IERC20(_marginAsset).safeTransferFrom(_trader, address(this), _margin/_marginDecMultiplier);
if (!marginApproved[_marginAsset][_stableVault]) {
IERC20(_marginAsset).approve(_stableVault, type(uint).max);
marginApproved[_marginAsset][_stableVault] = true;
}
IStableVault(_stableVault).deposit(_marginAsset, _margin/_marginDecMultiplier);
if (tigAsset.balanceOf(address(this)) != _balBefore + _margin) revert("Error depositing into vault.");
tigAsset.burnFrom(address(this), tigAsset.balanceOf(address(this)));
} else {
tigAsset.burnFrom(_trader, _margin);
}
}
/**
* @dev check that trader address owns the position
* @param _id position id
* @param _trader trader address
*/
function _checkOwner(uint256 _id, address _trader) internal view {
if (tradeNFT.ownerOf(_id) != _trader) revert("Not position owner.");
}
/**
* @dev Check that the stableVault input is whitelisted and the margin asset is whitelisted in the vault
* @param _stableVault StableVault address
* @param _token Margin asset token address
* @param _token2 Received asset token address
*/
function _checkVault(address _stableVault, address _token, address _token2) internal view returns(address _stable) {
if (!allowedVault[_stableVault]) revert("Vault not whitelisted.");
_stable = IStableVault(_stableVault).stable();
if (_token != _stable && !IStableVault(_stableVault).allowed(_token)) revert("Token not approved in vault.");
if (_token2 != _stable && !IStableVault(_stableVault).allowed(_token2)) revert("Token not approved in vault.");
}
/**
* @dev Check that the trader has approved the proxy address to trade for it
* @param _trader Trader address
*/
function _validateProxy(address _trader) internal view {
if (_trader != _msgSender()) {
address _proxy = tradingContract.proxyApprovals(_trader);
if (_proxy != _msgSender()) revert("Proxy not approved.");
}
}
/**
* @dev Check if the trade will expire when market is closed for forex
* @param _duration trade duration
*/
function canOpenForex(uint _duration) internal view returns (bool) {
unchecked {
uint currentTime = block.timestamp;
uint currentDay = ((currentTime / 86400) + 4) % 7;
uint currentHr = (currentTime / 3600) % 24;
uint currentMin = (currentTime % 3600) / 60;
uint expHr = ((currentTime + _duration) / 3600) % 24;
uint expMin = ((currentTime + _duration) % 3600) / 60;
if(isForexHourClosed[uint8(expHr)]) return false;
MarketTime memory currentMarketTime = marketTimes[uint8(currentDay)];
return (
(currentHr > currentMarketTime.hrStart || (currentHr == currentMarketTime.hrStart && currentMin >= currentMarketTime.hrStart)) &&
(currentHr < currentMarketTime.hrEnd || (currentHr == currentMarketTime.hrEnd && currentMin < currentMarketTime.minEnd)) &&
(expHr < currentMarketTime.hrEnd || (expHr == currentMarketTime.hrEnd && expMin < currentMarketTime.minEnd))
);
}
}
/**
* @notice emergency close trade only by owner
* @param _id id of the tradeNFT
* @param isWin true if winning trade
*/
function emergencyCloseTrade(
uint256 _id,
bool isWin
)
external
onlyOwner
{
ITradeNFT.Trade memory _trade = tradeNFT.trades(_id);
require(_trade.trader != address(0), "!exists");
TradedAsset storage _tradedAsset = tradedAssets[_trade.asset];
if (_trade.orderType != 0) revert("Cannot close a limit order.");
uint256 _price = isWin ? type(uint).max : 0;
uint toSend;
if(isWin) {
toSend = _trade.collateral + _trade.collateral * _tradedAsset.winPercent / DIVISION_CONSTANT;
if(_trade.tigAsset == _trade.receivedAsset) {
IStable(_trade.tigAsset).mintFor(address(_trade.trader), toSend);
} else {
IStable(_trade.tigAsset).mintFor(address(this), toSend);
IStableVault(_trade.stableVault).withdraw(_trade.receivedAsset, toSend);
IERC20(_trade.receivedAsset).safeTransfer(_trade.trader, toSend);
}
}
(address _referrer, uint _refFees) = getRef(_trade.trader);
if(_referrer != address(0)) {
IStable(_trade.tigAsset).mintFor(_referrer, _trade.collateral * _refFees * refMultiplier / DIVISION_CONSTANT);
}
IStable(_trade.tigAsset).mintFor(address(this), _trade.collateral * _tradedAsset.closeFee / DIVISION_CONSTANT);
uint balance = IStable(_trade.tigAsset).balanceOf(address(this));
uint256 _lpDistribution = balance * lpDistribution / DIVISION_CONSTANT;
IStable(_trade.tigAsset).approve(address(staking), balance - _lpDistribution);
staking.distribute(_trade.tigAsset, balance - _lpDistribution);
{
uint remBalance = IStable(_trade.tigAsset).balanceOf(address(this));
IStable(_trade.tigAsset).approve(address(lpstaking), remBalance);
lpstaking.distribute(_trade.tigAsset, remBalance);
}
emit OptionsFeesDistributed(_trade.tigAsset, balance, _referrer == address(0) ? 0 : _trade.collateral * _refFees / DIVISION_CONSTANT, _trade.collateral * _tradedAsset.botFee / DIVISION_CONSTANT, _referrer);
_tradedAsset.openInterest -= _trade.collateral;
tradeNFT.burn(_id);
emit TradeClosed(_id, _price, isWin ? _tradedAsset.winPercent : 0, toSend, _trade.trader, _msgSender(), _trade);
}
/**
* @dev Set MarketTimes
* @param _day day to change
* @param _hrEnd end hour
* @param _hrStart start hour
* @param _minEnd end minute
* @param _minStart start minute
*/
function setMarketTime(
uint8 _day,
uint _hrEnd,
uint _hrStart,
uint _minEnd,
uint _minStart
)
external
onlyOwner
{
marketTimes[_day].hrEnd = _hrEnd;
marketTimes[_day].hrStart = _hrStart;
marketTimes[_day].minEnd = _minEnd;
marketTimes[_day].minStart = _minStart;
}
/**
* @dev edit a forex hour
* @param _hr hour to edit
* @param _isClosed true if closed
*/
function setIsForexHourClosed(
uint8 _hr,
bool _isClosed
)
external
onlyOwner
{
isForexHourClosed[_hr] = _isClosed;
}
/**
* @dev Sets the valid signature timer
* @param _timer valid signature timer
*/
function setValidSignatureTimer(
uint _timer
)
external
onlyOwner
{
validSignatureTimer = _timer;
}
/**
* @dev changes trading contract address
* @param _new new contract address
*/
function changeTradingContract(
address _new
)
external
onlyOwner
{
tradingContract = ITrading(_new);
emit TradingContractChange(_new);
}
/**
* @dev changes ref mulitplier
* @param _new new ref mulitplier
*/
function changeRefMultiplier(
uint _new
)
external
onlyOwner
{
refMultiplier = _new;
}
/**
* @dev changes use spread
* @param _use bool for use spread
*/
function setUseSpread(
bool _use
)
external
onlyOwner
{
useSpread = _use;
emit UseSpreadChange(_use);
}
/**
* @dev Whitelists a node address
* @param _node node address
* @param _bool true if allowed
*/
function setNode(
address _node,
bool _bool
)
external
onlyOwner
{
isNode[_node] = _bool;
}
/**
* @dev Whitelists a stableVault contract address
* @param _stableVault StableVault address
* @param _bool true if allowed
*/
function setAllowedVault(
address _stableVault,
bool _bool
)
external
onlyOwner
{
allowedVault[_stableVault] = _bool;
emit AllowedVaultChange(_stableVault, _bool);
}
function setTradedAsset(
uint _id,
uint _maxC,
uint _minC,
uint _maxD,
uint _minD,
uint _maxO,
uint _winP,
uint[] calldata _fees,
bool _isForex
) external onlyOwner {
require(_winP <= DIVISION_CONSTANT, "Win percent too high");
require(_maxD > 60, "!mD");
require(_maxC >= _minC, "!C");
require(_maxD >= _minD, "!D");
require(_fees[0] <= DIVISION_CONSTANT, "Close fee too high");
require(_fees[1] <= DIVISION_CONSTANT, "Bot fee too high");
TradedAsset storage _asset = tradedAssets[_id];
_asset.maxCollateral = _maxC;
_asset.minCollateral = _minC;
_asset.maxDuration = _maxD;
_asset.minDuration = _minD;
_asset.maxOpen = _maxO;
_asset.assetId = _id;
_asset.winPercent = _winP;
_asset.closeFee = _fees[0];
_asset.botFee = _fees[1];
_asset.isForex = _isForex;
}
function setMinMaxCollateral(
uint _id,
uint _maxC,
uint _minC
) external onlyOwner {
require(_maxC >= _minC, "!C");
TradedAsset storage _asset = tradedAssets[_id];
_asset.maxCollateral = _maxC;
_asset.minCollateral = _minC;
}
function setMinMaxDuration(
uint _id,
uint _maxD,
uint _minD
) external onlyOwner {
require(_maxD > 60, "!mD");
require(_maxD >= _minD, "!D");
TradedAsset storage _asset = tradedAssets[_id];
_asset.maxDuration = _maxD;
_asset.minDuration = _minD;
}
function setOpenInterest(
uint _id,
uint _maxO
) external onlyOwner {
TradedAsset storage _asset = tradedAssets[_id];
_asset.maxOpen = _maxO;
}
function setWinPercent(
uint _id,
uint _winP
) external onlyOwner {
require(_winP <= DIVISION_CONSTANT, "Win percent too high");
TradedAsset storage _asset = tradedAssets[_id];
_asset.winPercent = _winP;
}
function setFees(
uint _id,
uint[] calldata _fees
) external onlyOwner {
require(_fees[0] <= DIVISION_CONSTANT, "Close fee too high");
require(_fees[1] <= DIVISION_CONSTANT, "Bot fee too high");
TradedAsset storage _asset = tradedAssets[_id];
_asset.closeFee = _fees[0];
_asset.botFee = _fees[1];
}
function setIsForex(
uint _id,
bool _isForex
) external onlyOwner {
TradedAsset storage _asset = tradedAssets[_id];
_asset.isForex = _isForex;
}
function setLPDistribution(uint256 _percent) external onlyOwner {
require(_percent <= DIVISION_CONSTANT);
lpDistribution = _percent;
emit LPDistributionChange(_percent);
}
function setLPStaking(address _lpstaking) external onlyOwner {
lpstaking = ILPStaking(_lpstaking);
}
// ===== EVENTS =====
event TradeOpened(
TradeInfo tradeInfo,
uint256 expires,
uint256 orderType,
uint256 price,
uint256 id,
address trader
);
event TradeClosed(
uint256 id,
uint256 closePrice,
uint256 percent,
uint256 payout,
address trader,
address executor,
ITradeNFT.Trade trade
);
event OptionsLimitOrderExecuted(
uint256 asset,
bool direction,
uint duration,
uint256 openPrice,
uint256 collateral,
uint256 id,
uint256 expires,
address trader,
address executor
);
event OptionsLimitCancelled(
uint256 id,
address trader
);
event OptionsFeesDistributed(
address tigAsset,
uint256 daoFees,
uint256 refFees,
uint256 botFees,
address referrer
);
event LPDistributionChange(
uint256 percent
);
event AllowedVaultChange(
address vault,
bool allowed
);
event TradingContractChange(
address trading
);
event UseSpreadChange(
bool usingSpread
);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
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'
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) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://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");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../Strings.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV // Deprecated in v4.8
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IGovernanceStaking {
function stake(uint256 _amount, uint256 _duration) external;
function unstake(uint256 _amount) external;
function claim() external;
function distribute(address _token, uint256 _amount) external;
function whitelistReward(address _rewardToken) external;
function pending(address _user, address _token) external view returns (uint256);
function userStaked(address _user) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IPairsContract {
struct Asset {
string name;
address chainlinkFeed;
uint256 minLeverage;
uint256 maxLeverage;
uint256 feeMultiplier;
uint256 baseFundingRate;
}
struct OpenInterest {
uint256 longOi;
uint256 shortOi;
uint256 maxOi;
}
function allowedAsset(uint) external view returns (bool);
function idToAsset(uint256 _asset) external view returns (Asset memory);
function idToOi(uint256 _asset, address _tigAsset) external view returns (OpenInterest memory);
function setAssetBaseFundingRate(uint256 _asset, uint256 _baseFundingRate) external;
function modifyLongOi(uint256 _asset, address _tigAsset, bool _onOpen, uint256 _amount) external;
function modifyShortOi(uint256 _asset, address _tigAsset, bool _onOpen, uint256 _amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/TradingLibrary.sol";
interface IPermissionedForwarder {
struct ForwardRequest {
address from;
address to;
bytes32 salt;
uint256 deadline;
bytes data;
}
function fundAccount(address _account) external payable;
function fund() external payable;
function withdraw(uint256 _amount) external;
function withdrawAll() external;
function executeWithPrice(ForwardRequest calldata req, bytes calldata signature, PriceData calldata priceData) external returns (bool, bytes memory);
function executeWithoutPrice(ForwardRequest calldata req, bytes calldata signature) external returns (bool, bytes memory);
function setPrivateRelayer(address _relayer, bool _status) external;
function setGas(uint256 _gas) external;
function setAllowedTarget(address _target, bool _status) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IPosition {
struct Trade {
uint256 margin;
uint256 leverage;
uint256 asset;
bool direction;
uint256 price;
uint256 tpPrice;
uint256 slPrice;
uint256 orderType;
address trader;
uint256 id;
address tigAsset;
int accInterest;
}
struct MintTrade {
address account;
uint256 margin;
uint256 leverage;
uint256 asset;
bool direction;
uint256 price;
uint256 tp;
uint256 sl;
uint256 orderType;
address tigAsset;
}
function trades(uint256) external view returns (Trade memory);
function executeLimitOrder(uint256 _id, uint256 _price, uint256 _newMargin) external;
function modifyMargin(uint256 _id, uint256 _newMargin, uint256 _newLeverage) external;
function addToPosition(uint256 _id, uint256 _newMargin, uint256 _newPrice) external;
function reducePosition(uint256 _id, uint256 _newMargin) external;
function assetOpenPositions(uint256 _asset) external view returns (uint256[] calldata);
function assetOpenPositionsIndexes(uint256 _asset, uint256 _id) external view returns (uint256);
function limitOrders(uint256 _asset) external view returns (uint256[] memory);
function limitOrderIndexes(uint256 _asset, uint256 _id) external view returns (uint256);
function assetOpenPositionsLength(uint256 _asset) external view returns (uint256);
function limitOrdersLength(uint256 _asset) external view returns (uint256);
function ownerOf(uint256 _id) external view returns (address);
function mint(MintTrade memory _mintTrade) external;
function burn(uint256 _id) external;
function modifyTp(uint256 _id, uint256 _tpPrice) external;
function modifySl(uint256 _id, uint256 _slPrice) external;
function getCount() external view returns (uint);
function updateFunding(uint256 _asset, address _tigAsset, uint256 _longOi, uint256 _shortOi, uint256 _baseFundingRate, uint256 _vaultFundingPercent) external;
function setAccInterest(uint256 _id) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IReferrals {
function setReferred(address _referredTrader, address _referrer) external;
function getReferred(address _trader) external view returns (address, uint);
function addRefFees(address _trader, address _tigAsset, uint _fees) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IStableVault {
function deposit(address, uint) external;
function withdraw(address, uint) external returns (uint256);
function allowed(address) external view returns (bool);
function stable() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
interface ITradeNFT {
struct Trade {
uint256 collateral;
uint256 asset;
bool direction;
uint256 duration;
uint256 openPrice;
uint256 expires;
uint256 orderType;
address trader;
uint256 id;
address tigAsset;
address receivedAsset;
address stableVault;
}
struct MintTrade {
address account;
uint256 collateral;
uint256 asset;
bool direction;
uint256 duration;
uint256 price;
uint256 orderType;
address tigAsset;
address receivedAsset;
address stableVault;
}
function trades(uint256) external view returns (Trade memory);
function executeLimitOrder(uint256 _id, uint256 _price, uint256 _newMargin) external;
function assetOpenPositions(uint256 _asset) external view returns (uint256[] calldata);
function assetOpenPositionsIndexes(uint256 _asset, uint256 _id) external view returns (uint256);
function limitOrders(uint256 _asset) external view returns (uint256[] memory);
function limitOrderIndexes(uint256 _asset, uint256 _id) external view returns (uint256);
function assetOpenPositionsLength(uint256 _asset) external view returns (uint256);
function limitOrdersLength(uint256 _asset) external view returns (uint256);
function ownerOf(uint256 _id) external view returns (address);
function mint(MintTrade memory _mintTrade) external;
function burn(uint256 _id) external;
function getCount() external view returns (uint);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/TradingLibrary.sol";
interface ITrading {
struct TradeInfo {
uint256 margin;
address marginAsset;
address stableVault;
uint256 leverage;
uint256 asset;
bool direction;
uint256 tpPrice;
uint256 slPrice;
address referrer;
}
struct ERC20PermitData {
uint256 deadline;
uint256 amount;
uint8 v;
bytes32 r;
bytes32 s;
bool usePermit;
}
struct Fees {
uint256 daoFees;
uint256 burnFees;
uint256 refDiscount;
uint256 botFees;
}
struct Delay {
uint256 delay; // Block timestamp where delay ends
bool actionType; // True for open, False for close
}
error LimitNotSet();
error OnlyEOA();
error NotLiquidatable();
error TradingPaused();
error OldPriceData();
error OrderNotFound();
error TooEarlyToCancel();
error BadDeposit();
error BadWithdraw();
error BadStopLoss();
error IsLimit();
error ValueNotEqualToMargin();
error BadLeverage();
error NotMargin();
error NotAllowedInVault();
error NotVault();
error NotOwner();
error NotAllowedPair();
error WaitDelay();
error NotProxy();
error BelowMinPositionSize();
error BadClosePercent();
error NoPrice();
error LiqThreshold();
error CloseToMaxPnL();
error BadSetter();
error BadConstructor();
error NotLimit();
error LimitNotMet();
error NotEnoughGas();
function marketOpen(
TradeInfo calldata _tradeInfo,
ERC20PermitData calldata _permitData,
address _trader,
PriceData calldata _priceData
) external;
function marketClose(
uint256 _id,
uint256 _percent,
address _stableVault,
address _outputToken,
address _trader,
PriceData calldata _priceData
) external;
function addMargin(
uint256 _id,
address _stableVault,
address _marginAsset,
uint256 _addMargin,
ERC20PermitData calldata _permitData,
address _trader,
PriceData calldata _priceData
) external;
function removeMargin(
uint256 _id,
address _stableVault,
address _outputToken,
uint256 _removeMargin,
address _trader,
PriceData calldata _priceData
) external;
function addToPosition(
uint256 _id,
address _stableVault,
address _marginAsset,
uint256 _addMargin,
ERC20PermitData calldata _permitData,
address _trader,
PriceData calldata _priceData
) external;
function createLimitOrder(
TradeInfo calldata _tradeInfo,
uint256 _orderType, // 1 limit, 2 momentum
uint256 _price,
ERC20PermitData calldata _permitData,
address _trader
) external;
function cancelLimitOrder(
uint256 _id,
address _trader
) external;
function updateTpSl(
bool _type, // true is TP
uint256 _id,
uint256 _limitPrice,
address _trader,
PriceData calldata _priceData
) external;
function executeLimitOrder(
uint256 _id,
PriceData calldata _priceData
) external;
function liquidatePosition(
uint256 _id,
PriceData calldata _priceData
) external;
function limitClose(
uint256 _id,
bool _tp,
PriceData calldata _priceData
) external;
function proxyApprovals(address _account) external view returns(address);
}//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "../interfaces/IPermissionedForwarder.sol";
contract PermissionedMetaContext is Ownable {
IPermissionedForwarder public trustedForwarder;
modifier onlyTrustedForwarder() {
require(msg.sender == address(trustedForwarder), "!Forwarder");
_;
}
modifier notForwarder() {
require(msg.sender != address(trustedForwarder), "Forwarder not allowed");
_;
}
function setTrustedForwarder(address _forwarder) external onlyOwner {
trustedForwarder = IPermissionedForwarder(_forwarder);
}
function _msgSender() internal view virtual override returns (address sender) {
if (msg.sender == address(trustedForwarder)) {
// The assembly code is more direct than the Solidity version using `abi.decode`.
/// @solidity memory-safe-assembly
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return super._msgSender();
}
}
function _msgData() internal view virtual override returns (bytes calldata) {
if (msg.sender == address(trustedForwarder)) {
return msg.data[:msg.data.length - 20];
} else {
return super._msgData();
}
}
}//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "../interfaces/IPosition.sol";
import "../interfaces/ITrading.sol";
struct PriceData {
address provider;
bool isClosed;
uint256 asset;
uint256 price;
uint256 spread;
uint256 timestamp;
bytes signature;
}
library TradingLibrary {
using ECDSA for bytes32;
uint256 constant DIVISION_CONSTANT = 1e10;
/**
* @notice returns position profit or loss
* @param _direction true if long
* @param _currentPrice current price
* @param _price opening price
* @param _leverage position leverage
* @param _margin collateral amount
* @param accInterest funding fees
* @return _positionSize position size
* @return _payout payout trader should get
*/
function pnl(bool _direction, uint256 _currentPrice, uint256 _price, uint256 _margin, uint256 _leverage, int256 accInterest) external pure returns (uint256 _positionSize, int256 _payout) {
uint256 _initPositionSize = _margin * _leverage / 1e18;
if (_direction && _currentPrice >= _price) {
_payout = int256(_margin) + int256(_initPositionSize * (1e18 * _currentPrice / _price - 1e18)/1e18) + accInterest;
} else if (_direction && _currentPrice < _price) {
_payout = int256(_margin) - int256(_initPositionSize * (1e18 - 1e18 * _currentPrice / _price)/1e18) + accInterest;
} else if (!_direction && _currentPrice <= _price) {
_payout = int256(_margin) + int256(_initPositionSize * (1e18 - 1e18 * _currentPrice / _price)/1e18) + accInterest;
} else {
_payout = int256(_margin) - int256(_initPositionSize * (1e18 * _currentPrice / _price - 1e18)/1e18) + accInterest;
}
_positionSize = _direction ? _initPositionSize * _currentPrice / _price : _initPositionSize * _price / _currentPrice;
}
/**
* @notice returns position liquidation price
* @param _direction true if long
* @param _tradePrice opening price
* @param _leverage position leverage
* @param _margin collateral amount
* @param _accInterest funding fees
* @param _liqPercent liquidation percent
* @return _liqPrice liquidation price
*/
function liqPrice(bool _direction, uint256 _tradePrice, uint256 _leverage, uint256 _margin, int256 _accInterest, uint256 _liqPercent) public pure returns (uint256 _liqPrice) {
if (_direction) {
_liqPrice = uint256(int256(_tradePrice) - int256(_tradePrice) * (int256(_margin) * int256(_liqPercent) / int256(DIVISION_CONSTANT) + _accInterest) * 1e18 / int256(_margin) / int256(_leverage));
} else {
_liqPrice = uint256(int256(_tradePrice) + int256(_tradePrice) * (int256(_margin) * int256(_liqPercent) / int256(DIVISION_CONSTANT) + _accInterest) * 1e18 / int256(_margin) / int256(_leverage));
}
}
/**
* @notice uses liqPrice() and returns position liquidation price
* @param _positions positions contract address
* @param _id position id
* @param _liqPercent liquidation percent
*/
function getLiqPrice(address _positions, uint256 _id, uint256 _liqPercent) external view returns (uint256) {
IPosition.Trade memory _trade = IPosition(_positions).trades(_id);
return liqPrice(_trade.direction, _trade.price, _trade.leverage, _trade.margin, _trade.accInterest, _liqPercent);
}
/**
* @notice verifies that price is signed by a whitelisted node
* @param _validSignatureTimer seconds allowed before price is old
* @param _asset position asset
* @param _priceData PriceData object
* @param _isNode mapping of allowed nodes
*/
function verifyPrice(
uint256 _validSignatureTimer,
uint256 _asset,
PriceData calldata _priceData,
mapping(address => bool) storage _isNode
)
external view
{
require(block.timestamp <= _priceData.timestamp + _validSignatureTimer, "Price has expired.");
require(block.timestamp >= _priceData.timestamp, "FutSig");
require(!_priceData.isClosed, "Market is closed.");
require(_asset == _priceData.asset, "!Asset");
require(_priceData.price != 0, "NoPrice");
address _provider = (
keccak256(abi.encode(
_priceData.provider,
_priceData.isClosed,
_priceData.asset,
_priceData.price,
_priceData.spread,
_priceData.timestamp
))
).toEthSignedMessageHash().recover(_priceData.signature);
require(_provider == _priceData.provider, "BadSig");
require(_isNode[_provider], "!Node");
}
}{
"optimizer": {
"enabled": true,
"runs": 5000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_tradeNFT","type":"address"},{"internalType":"address","name":"_staking","type":"address"},{"internalType":"address","name":"_referrals","type":"address"},{"internalType":"address","name":"_pairsContract","type":"address"},{"internalType":"address","name":"_trading","type":"address"},{"internalType":"address","name":"_lpstaking","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"AllowedVaultChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"percent","type":"uint256"}],"name":"LPDistributionChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tigAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"daoFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refFees","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"botFees","type":"uint256"},{"indexed":false,"internalType":"address","name":"referrer","type":"address"}],"name":"OptionsFeesDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"trader","type":"address"}],"name":"OptionsLimitCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"asset","type":"uint256"},{"indexed":false,"internalType":"bool","name":"direction","type":"bool"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"openPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateral","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expires","type":"uint256"},{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"executor","type":"address"}],"name":"OptionsLimitOrderExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"percent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"executor","type":"address"},{"components":[{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"uint256","name":"asset","type":"uint256"},{"internalType":"bool","name":"direction","type":"bool"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"openPrice","type":"uint256"},{"internalType":"uint256","name":"expires","type":"uint256"},{"internalType":"uint256","name":"orderType","type":"uint256"},{"internalType":"address","name":"trader","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"tigAsset","type":"address"},{"internalType":"address","name":"receivedAsset","type":"address"},{"internalType":"address","name":"stableVault","type":"address"}],"indexed":false,"internalType":"struct ITradeNFT.Trade","name":"trade","type":"tuple"}],"name":"TradeClosed","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"address","name":"collateralAsset","type":"address"},{"internalType":"address","name":"stableVault","type":"address"},{"internalType":"address","name":"receivedAsset","type":"address"},{"internalType":"bool","name":"direction","type":"bool"},{"internalType":"uint256","name":"asset","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"indexed":false,"internalType":"struct Options.TradeInfo","name":"tradeInfo","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"expires","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"orderType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"trader","type":"address"}],"name":"TradeOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"trading","type":"address"}],"name":"TradingContractChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"usingSpread","type":"bool"}],"name":"UseSpreadChange","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_trader","type":"address"}],"name":"cancelLimitOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_new","type":"uint256"}],"name":"changeRefMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"changeTradingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"components":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"uint256","name":"asset","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"spread","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PriceData","name":"_priceData","type":"tuple"}],"name":"closeTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bool","name":"isWin","type":"bool"}],"name":"emergencyCloseTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"components":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"uint256","name":"asset","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"spread","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PriceData","name":"_priceData","type":"tuple"}],"name":"executeLimitOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"address","name":"collateralAsset","type":"address"},{"internalType":"address","name":"stableVault","type":"address"},{"internalType":"address","name":"receivedAsset","type":"address"},{"internalType":"bool","name":"direction","type":"bool"},{"internalType":"uint256","name":"asset","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"internalType":"struct Options.TradeInfo","name":"_tradeInfo","type":"tuple"},{"internalType":"uint256","name":"_orderType","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bool","name":"usePermit","type":"bool"}],"internalType":"struct Options.ERC20PermitData","name":"_permitData","type":"tuple"},{"internalType":"address","name":"_trader","type":"address"}],"name":"initiateLimitOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"isForexHourClosed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpstaking","outputs":[{"internalType":"contract ILPStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"marketTimes","outputs":[{"internalType":"uint256","name":"hrStart","type":"uint256"},{"internalType":"uint256","name":"hrEnd","type":"uint256"},{"internalType":"uint256","name":"minStart","type":"uint256"},{"internalType":"uint256","name":"minEnd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"address","name":"collateralAsset","type":"address"},{"internalType":"address","name":"stableVault","type":"address"},{"internalType":"address","name":"receivedAsset","type":"address"},{"internalType":"bool","name":"direction","type":"bool"},{"internalType":"uint256","name":"asset","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"internalType":"struct Options.TradeInfo","name":"_tradeInfo","type":"tuple"},{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bool","name":"usePermit","type":"bool"}],"internalType":"struct Options.ERC20PermitData","name":"_permitData","type":"tuple"},{"internalType":"address","name":"_trader","type":"address"},{"components":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"uint256","name":"asset","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"spread","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct PriceData","name":"_priceData","type":"tuple"}],"name":"openTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairsContract","outputs":[{"internalType":"contract IPairsContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referrals","outputs":[{"internalType":"contract IReferrals","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stableVault","type":"address"},{"internalType":"bool","name":"_bool","type":"bool"}],"name":"setAllowedVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256[]","name":"_fees","type":"uint256[]"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bool","name":"_isForex","type":"bool"}],"name":"setIsForex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_hr","type":"uint8"},{"internalType":"bool","name":"_isClosed","type":"bool"}],"name":"setIsForexHourClosed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_percent","type":"uint256"}],"name":"setLPDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpstaking","type":"address"}],"name":"setLPStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_day","type":"uint8"},{"internalType":"uint256","name":"_hrEnd","type":"uint256"},{"internalType":"uint256","name":"_hrStart","type":"uint256"},{"internalType":"uint256","name":"_minEnd","type":"uint256"},{"internalType":"uint256","name":"_minStart","type":"uint256"}],"name":"setMarketTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_maxC","type":"uint256"},{"internalType":"uint256","name":"_minC","type":"uint256"}],"name":"setMinMaxCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_maxD","type":"uint256"},{"internalType":"uint256","name":"_minD","type":"uint256"}],"name":"setMinMaxDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_node","type":"address"},{"internalType":"bool","name":"_bool","type":"bool"}],"name":"setNode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_maxO","type":"uint256"}],"name":"setOpenInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_maxC","type":"uint256"},{"internalType":"uint256","name":"_minC","type":"uint256"},{"internalType":"uint256","name":"_maxD","type":"uint256"},{"internalType":"uint256","name":"_minD","type":"uint256"},{"internalType":"uint256","name":"_maxO","type":"uint256"},{"internalType":"uint256","name":"_winP","type":"uint256"},{"internalType":"uint256[]","name":"_fees","type":"uint256[]"},{"internalType":"bool","name":"_isForex","type":"bool"}],"name":"setTradedAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forwarder","type":"address"}],"name":"setTrustedForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_use","type":"bool"}],"name":"setUseSpread","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timer","type":"uint256"}],"name":"setValidSignatureTimer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_winP","type":"uint256"}],"name":"setWinPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staking","outputs":[{"internalType":"contract IGovernanceStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeNFT","outputs":[{"internalType":"contract ITradeNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tradedAssets","outputs":[{"internalType":"uint256","name":"maxCollateral","type":"uint256"},{"internalType":"uint256","name":"minCollateral","type":"uint256"},{"internalType":"uint256","name":"maxDuration","type":"uint256"},{"internalType":"uint256","name":"minDuration","type":"uint256"},{"internalType":"uint256","name":"maxOpen","type":"uint256"},{"internalType":"uint256","name":"openInterest","type":"uint256"},{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"uint256","name":"winPercent","type":"uint256"},{"internalType":"uint256","name":"closeFee","type":"uint256"},{"internalType":"uint256","name":"botFee","type":"uint256"},{"internalType":"bool","name":"isForex","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingContract","outputs":[{"internalType":"contract ITrading","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"trustedForwarder","outputs":[{"internalType":"contract IPermissionedForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"useSpread","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validSignatureTimer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405263b2d05e006009556064600a553480156200001e57600080fd5b506040516200609338038062006093833981016040819052620000419162000213565b620000556200004f6200017e565b620001a6565b6001600160a01b03861615806200007357506001600160a01b038516155b806200008657506001600160a01b038416155b806200009957506001600160a01b038316155b80620000ac57506001600160a01b038216155b80620000bf57506001600160a01b038116155b15620001005760405162461bcd60e51b815260206004820152600c60248201526b10b1b7b739ba393ab1ba37b960a11b604482015260640160405180910390fd5b600380546001600160a01b0397881661010002610100600160a81b0319909116179055600480549587166001600160a01b031996871617905560058054948716948616949094179093556006805492861692851692909217909155600780549185169184169190911790556008805491909316911617905562000294565b6001546000906001600160a01b03163303620001a1575060131936013560601c90565b503390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200020e57600080fd5b919050565b60008060008060008060c087890312156200022d57600080fd5b6200023887620001f6565b95506200024860208801620001f6565b94506200025860408801620001f6565b93506200026860608801620001f6565b92506200027860808801620001f6565b91506200028860a08801620001f6565b90509295509295509295565b615def80620002a46000396000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a088b49911610186578063d3dc7539116100e3578063e8e97e2911610097578063f2fde38b11610071578063f2fde38b146106f1578063f9f98af614610704578063ff849db51461071757600080fd5b8063e8e97e29146106b8578063f0632619146106cb578063f0eab0ca146106de57600080fd5b8063da742228116100c8578063da7422281461067f578063dc49d2e814610692578063def061cc146106a557600080fd5b8063d3dc753914610649578063d62515cf1461065c57600080fd5b8063c80caf2c1161013a578063ccf845e21161011f578063ccf845e2146105fb578063d10e683f1461061e578063d232e1ff1461063157600080fd5b8063c80caf2c146105d5578063cae82b2e146105e857600080fd5b8063afcca2f11161016b578063afcca2f1146105a6578063b3113b2a146105b9578063bf5d598d146105cc57600080fd5b8063a088b49914610580578063ac6b2da41461059357600080fd5b80636c704fac1161023f5780637da0a877116101f35780639251ae27116101cd5780639251ae27146105475780639e4bd2e91461055a578063a05dc07c1461056d57600080fd5b80637da0a877146105105780638715746d146105235780638da5cb5b1461053657600080fd5b8063715018a611610224578063715018a6146104e2578063797b371e146104ea5780637c0c4797146104fd57600080fd5b80636c704fac14610476578063706dfd36146104cb57600080fd5b806343d975de116102965780635b14f3161161027b5780635b14f3161461043d5780636450f9cc146104505780636bbdc24b1461046357600080fd5b806343d975de146104175780634cf088d91461042a57600080fd5b806327426de4116102c757806327426de41461032857806337b2b9d7146103e757806341addb7b1461040457600080fd5b80630dfc1f4c146102e35780631c13c466146102f8575b600080fd5b6102f66102f136600461525a565b610720565b005b60085461030b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610392610336366004615293565b600d60205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600a909a01549899979896979596949593949293919290919060ff168b565b604080519b8c5260208c019a909a52988a01979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015215156101408201526101600161031f565b6003546103f49060ff1681565b604051901515815260200161031f565b6102f66104123660046152d1565b61074d565b6102f66104253660046152ef565b610780565b60045461030b906001600160a01b031681565b6102f661044b366004615333565b6107b1565b6102f661045e36600461539d565b610a4c565b6102f66104713660046152d1565b610d0e565b6104ab610484366004615439565b600f6020526000908152604090208054600182015460028301546003909301549192909184565b60408051948552602085019390935291830152606082015260800161031f565b6104d460095481565b60405190815260200161031f565b6102f6610d79565b6102f66104f8366004615293565b610d8d565b60065461030b906001600160a01b031681565b60015461030b906001600160a01b031681565b6102f6610531366004615481565b610d9a565b6000546001600160a01b031661030b565b6102f66105553660046154e3565b6113d6565b60075461030b906001600160a01b031681565b6102f661057b366004615508565b611401565b6102f661058e366004615293565b6114c6565b6102f66105a1366004615293565b61151c565b6102f66105b4366004615534565b611529565b6102f66105c7366004615556565b61159b565b6104d460025481565b6102f66105e3366004615585565b6115dd565b6102f66105f6366004615556565b611c2c565b6103f4610609366004615556565b600b6020526000908152604090205460ff1681565b6102f661062c3660046155fc565b611c9a565b60035461030b9061010090046001600160a01b031681565b60055461030b906001600160a01b031681565b6103f461066a366004615439565b60106020526000908152604090205460ff1681565b6102f661068d366004615556565b6127ae565b6102f66106a03660046154e3565b6127f0565b6102f66106b3366004615643565b6131cf565b6102f66106c6366004615508565b613218565b6102f66106d9366004615534565b613288565b6102f66106ec3660046155fc565b6132a5565b6102f66106ff366004615556565b613886565b6102f6610712366004615660565b613916565b6104d4600a5481565b610728613a50565b60ff919091166000908152601060205260409020805460ff1916911515919091179055565b610755613a50565b6001600160a01b03919091166000908152600e60205260409020805460ff1916911515919091179055565b610788613a50565b60ff9094166000908152600f602052604090206001810193909355908255600382015560020155565b6001546001600160a01b031633146108105760405162461bcd60e51b815260206004820152600a60248201527f21466f727761726465720000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61081981613ac9565b6108238282613bdf565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa15801561088c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b09190615713565b90508060c001516000036109065760405162461bcd60e51b815260206004820152601260248201527f4e6f742061206c696d6974206f726465722e00000000000000000000000000006044820152606401610807565b61012081015181516040517fda1919b30000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482019290925291169063da1919b390604401600060405180830381600087803b15801561097257600080fd5b505af1158015610986573d6000803e3d6000fd5b50506003546040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018790526101009091046001600160a01b031692506342966c689150602401600060405180830381600087803b1580156109ed57600080fd5b505af1158015610a01573d6000803e3d6000fd5b5050604080518681526001600160a01b03861660208201527f65e9cd59862cf801cf6b537eb6db1b2aa79ee35a677765915c850f7665f57771935001905060405180910390a1505050565b610a54613a50565b6402540be400841115610aa95760405162461bcd60e51b815260206004820152601460248201527f57696e2070657263656e7420746f6f20686967680000000000000000000000006044820152606401610807565b603c8711610af95760405162461bcd60e51b815260206004820152600360248201527f216d4400000000000000000000000000000000000000000000000000000000006044820152606401610807565b87891015610b495760405162461bcd60e51b815260206004820152600260248201527f21430000000000000000000000000000000000000000000000000000000000006044820152606401610807565b85871015610b995760405162461bcd60e51b815260206004820152600260248201527f21440000000000000000000000000000000000000000000000000000000000006044820152606401610807565b6402540be40083836000818110610bb257610bb26157ce565b905060200201351115610c075760405162461bcd60e51b815260206004820152601260248201527f436c6f73652066656520746f6f206869676800000000000000000000000000006044820152606401610807565b6402540be40083836001818110610c2057610c206157ce565b905060200201351115610c755760405162461bcd60e51b815260206004820152601060248201527f426f742066656520746f6f2068696768000000000000000000000000000000006044820152606401610807565b60008a8152600d602052604081208a8155600181018a9055600281018990556003810188905560048101879055600681018c905560078101869055908490849081610cc257610cc26157ce565b602002919091013560088301555083836001818110610ce357610ce36157ce565b6020029190910135600983015550600a01805460ff1916911515919091179055505050505050505050565b610d16613a50565b6001600160a01b0382166000818152600b6020908152604091829020805460ff19168515159081179091558251938452908301527f97e3e14419501104b30f00cb285807bb4dea790a51cd81dc173e30647e45aa11910160405180910390a15050565b610d81613a50565b610d8b6000613cc2565b565b610d95613a50565b600255565b6001546001600160a01b03163314610df45760405162461bcd60e51b815260206004820152600a60248201527f21466f72776172646572000000000000000000000000000000000000000000006044820152606401610807565b60a0808601356000908152600d602090815260409182902082516101608101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082018190526005830154938201849052600683015460c0830152600783015460e083015260088301546101008301526009830154610120830152600a9092015460ff16151561014082015291610e9a9088359061582c565b1115610ee85760405162461bcd60e51b815260206004820152601c60248201527f4f70656e20696e746572657374206c696d697420726561636865642e000000006044820152606401610807565b805186351115610f3a5760405162461bcd60e51b815260206004820152601c60248201527f4d6178696d756d20636f6c6c61746572616c2065786365656465642e000000006044820152606401610807565b602081015186351015610f8f5760405162461bcd60e51b815260206004820152601360248201527f436f6c6c61746572616c20746f6f206c6f772e000000000000000000000000006044820152606401610807565b80604001518660c001351115610fe75760405162461bcd60e51b815260206004820152601a60248201527f4d6178696d756d206475726174696f6e2065786365656465642e0000000000006044820152606401610807565b80606001518660c00135101561103f5760405162461bcd60e51b815260206004820152601160248201527f4475726174696f6e20746f6f206c6f772e0000000000000000000000000000006044820152606401610807565b846001148061104e5750846002145b61109a5760405162461bcd60e51b815260206004820152601360248201527f496e76616c6964206f7264657220747970652e000000000000000000000000006044820152606401610807565b6005546001600160a01b0316630443e9ef836110bd6101008a0160e08b01615556565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401600060405180830381600087803b15801561110557600080fd5b505af1158015611119573d6000803e3d6000fd5b5050505061112682613ac9565b600061116061113b6060890160408a01615556565b61114b60408a0160208b01615556565b61115b60808b0160608c01615556565b613d2a565b9050846000036111b25760405162461bcd60e51b815260206004820152601560248201527f50726963652063616e6e6f74206265207a65726f2e00000000000000000000006044820152606401610807565b6111df816111c660408a0160208b01615556565b89356111d860608c0160408d01615556565b8888613fdb565b6000604051806101400160405280856001600160a01b03168152602001896000013581526020018960a0013581526020018960800160208101906112239190615643565b151581526020018960c001358152602001878152602001888152602001836001600160a01b031681526020018960600160208101906112629190615556565b6001600160a01b0316815260200161128060608b0160408c01615556565b6001600160a01b039081169091526003546040517f346f67750000000000000000000000000000000000000000000000000000000081529293506101009004169063346f6775906112d590849060040161583f565b600060405180830381600087803b1580156112ef57600080fd5b505af1158015611303573d6000803e3d6000fd5b505050507f34e1eb5d71d806d6f4d0769e7d1cd099ced2c567e74bf35d53e8c1d7d2c236e38860001989896001600360019054906101000a90046001600160a01b03166001600160a01b031663a87d942c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a791906158de565b6113b191906158f7565b896040516113c4969594939291906159a3565b60405180910390a15050505050505050565b6113de613a50565b6000918252600d6020526040909120600a01805460ff1916911515919091179055565b611409613a50565b603c82116114595760405162461bcd60e51b815260206004820152600360248201527f216d4400000000000000000000000000000000000000000000000000000000006044820152606401610807565b808210156114a95760405162461bcd60e51b815260206004820152600260248201527f21440000000000000000000000000000000000000000000000000000000000006044820152606401610807565b6000928352600d6020526040909220600281019190915560030155565b6114ce613a50565b6402540be4008111156114e057600080fd5b60098190556040518181527ff54bed1d7fd947844c687e55a908aca81e51c67dc188ac1e5f436d646ce267bf906020015b60405180910390a150565b611524613a50565b600a55565b611531613a50565b6402540be4008111156115865760405162461bcd60e51b815260206004820152601460248201527f57696e2070657263656e7420746f6f20686967680000000000000000000000006044820152606401610807565b6000918252600d602052604090912060070155565b6115a3613a50565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001546001600160a01b031633146116375760405162461bcd60e51b815260206004820152600a60248201527f21466f72776172646572000000000000000000000000000000000000000000006044820152606401610807565b61164082613ac9565b60a0808501356000908152600d602090815260409182902082516101608101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082018190526005830154938201849052600683015460c0830152600783015460e083015260088301546101008301526009830154610120830152600a9092015460ff161515610140820152916116e69087359061582c565b11156117345760405162461bcd60e51b815260206004820152601c60248201527f4f70656e20696e746572657374206c696d697420726561636865642e000000006044820152606401610807565b8051853511156117865760405162461bcd60e51b815260206004820152601c60248201527f4d6178696d756d20636f6c6c61746572616c2065786365656465642e000000006044820152606401610807565b6020810151853510156117db5760405162461bcd60e51b815260206004820152601360248201527f436f6c6c61746572616c20746f6f206c6f772e000000000000000000000000006044820152606401610807565b80604001518560c0013511156118335760405162461bcd60e51b815260206004820152601a60248201527f4d6178696d756d206475726174696f6e2065786365656465642e0000000000006044820152606401610807565b80606001518560c00135101561188b5760405162461bcd60e51b815260206004820152601160248201527f4475726174696f6e20746f6f206c6f772e0000000000000000000000000000006044820152606401610807565b806101400151156118ef576118a38560c00135614544565b6118ef5760405162461bcd60e51b815260206004820152601160248201527f4d61726b657420697320636c6f7365642e0000000000000000000000000000006044820152606401610807565b6005546001600160a01b0316630443e9ef84611912610100890160e08a01615556565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401600060405180830381600087803b15801561195a57600080fd5b505af115801561196e573d6000803e3d6000fd5b5050505060006119aa86604001602081019061198a9190615556565b61199a6040890160208a01615556565b61115b60808a0160608b01615556565b90506119d9816119c06040890160208a01615556565b88356119d260608b0160408c01615556565b8989613fdb565b6000611a0b60a0880180359086906119f49060808c01615643565b6119ff576002611a02565b60015b60ff164261465f565b60a08801356000908152600d602052604081206005018054929350893592909190611a3790849061582c565b909155505060408051610140810182526001600160a01b03871681528835602082015260a089018035928201929092526000916060820190611a7c9060808c01615643565b151581526020018960c00135815260200183815260200160008152602001846001600160a01b03168152602001896060016020810190611abc9190615556565b6001600160a01b03168152602001611ada60608b0160408c01615556565b6001600160a01b039081169091526003546040517f346f67750000000000000000000000000000000000000000000000000000000081529293506101009004169063346f677590611b2f90849060040161583f565b600060405180830381600087803b158015611b4957600080fd5b505af1158015611b5d573d6000803e3d6000fd5b505050507f34e1eb5d71d806d6f4d0769e7d1cd099ced2c567e74bf35d53e8c1d7d2c236e388428a60c00135611b93919061582c565b6000856001600360019054906101000a90046001600160a01b03166001600160a01b031663a87d942c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0f91906158de565b611c1991906158f7565b8b6040516113c4969594939291906159a3565b611c34613a50565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f2b3d3800b704d91b74611daa96930c9d508a38bbb0650bac8d72629df8ba096890602001611511565b6001546001600160a01b03163303611cf45760405162461bcd60e51b815260206004820152601560248201527f466f72776172646572206e6f7420616c6c6f77656400000000000000000000006044820152606401610807565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa158015611d5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d819190615713565b60e08101519091506001600160a01b0316611dde5760405162461bcd60e51b815260206004820152601560248201527f547261646520646f6573206e6f742065786973742e00000000000000000000006044820152606401610807565b6020808201516000908152600d9091526040902060c082015115611e445760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420636c6f73652061206c696d6974206f726465722e00000000006044820152606401610807565b6000611e5b83602001518560008660a0015161465f565b9050600083604001518015611e735750836080015182115b15611e8057506001611e9f565b8360400151158015611e96575083608001518211155b15611e9f575060015b600081156120c457600784015485516402540be40091611ebe916159e8565b611ec891906159ff565b8551611ed4919061582c565b90508461014001516001600160a01b03168561012001516001600160a01b031603611f845761012085015160e08601516040517fda1919b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063da1919b390604401600060405180830381600087803b158015611f6757600080fd5b505af1158015611f7b573d6000803e3d6000fd5b505050506120c4565b6101208501516040517fda1919b3000000000000000000000000000000000000000000000000000000008152306004820152602481018390526001600160a01b039091169063da1919b390604401600060405180830381600087803b158015611fec57600080fd5b505af1158015612000573d6000803e3d6000fd5b5050506101608601516101408701516040517ff3fef3a30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152602481018590529116915063f3fef3a3906044016020604051808303816000875af1158015612078573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209c91906158de565b506120c48560e00151828761014001516001600160a01b0316614b689092919063ffffffff16565b6000806120d48760e00151614bfe565b90925090506001600160a01b03821615612189578661012001516001600160a01b031663da1919b3836402540be400600a54858c6000015161211691906159e8565b61212091906159e8565b61212a91906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561217057600080fd5b505af1158015612184573d6000803e3d6000fd5b505050505b8661012001516001600160a01b031663da1919b3306402540be40089600801548b600001516121b891906159e8565b6121c291906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561220857600080fd5b505af115801561221c573d6000803e3d6000fd5b505050508661012001516001600160a01b031663da1919b361223c614c91565b60098901548a516402540be40091612253916159e8565b61225d91906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156122a357600080fd5b505af11580156122b7573d6000803e3d6000fd5b505050506101208701516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232b91906158de565b905060006402540be4006009548361234391906159e8565b61234d91906159ff565b6101208a01516004549192506001600160a01b039081169163095ea7b3911661237684866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156123c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e59190615a3a565b506004546101208a01516001600160a01b039091169063fb9321089061240b84866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561245157600080fd5b505af1158015612465573d6000803e3d6000fd5b505050506101208901516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156124b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d991906158de565b6101208b01516008546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af115801561254c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125709190615a3a565b506008546101208b01516040517ffb9321080000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063fb93210890604401600060405180830381600087803b1580156125dd57600080fd5b505af11580156125f1573d6000803e3d6000fd5b505050506101208a01517f5146a00d88bc8d5b51da0a31b8b0163c52d08795010875de4612d9ca5b7ac2e79150836001600160a01b03871615612651578b516402540be400906126429088906159e8565b61264c91906159ff565b612654565b60005b60098c01548d516402540be4009161266b916159e8565b61267591906159ff565b604080516001600160a01b03958616815260208101949094528301919091526060820152908616608082015260a00160405180910390a188516005890180546000906126c29084906158f7565b90915550506003546040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018d90526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561272a57600080fd5b505af115801561273e573d6000803e3d6000fd5b505050507f902e822853f2af7f3aa893464f511b02ce01640df53bdc607f15065003141be38b8888612771576000612777565b8a600701545b888d60e00151612785614c91565b8f6040516127999796959493929190615a57565b60405180910390a15050505050505050505050565b6127b6613a50565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6127f8613a50565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa158015612861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128859190615713565b60e08101519091506001600160a01b03166128e25760405162461bcd60e51b815260206004820152600760248201527f21657869737473000000000000000000000000000000000000000000000000006044820152606401610807565b6020808201516000908152600d9091526040902060c0820151156129485760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420636c6f73652061206c696d6974206f726465722e00000000006044820152606401610807565b60008361295657600061295a565b6000195b905060008415612b8157600783015484516402540be4009161297b916159e8565b61298591906159ff565b8451612991919061582c565b90508361014001516001600160a01b03168461012001516001600160a01b031603612a415761012084015160e08501516040517fda1919b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063da1919b390604401600060405180830381600087803b158015612a2457600080fd5b505af1158015612a38573d6000803e3d6000fd5b50505050612b81565b6101208401516040517fda1919b3000000000000000000000000000000000000000000000000000000008152306004820152602481018390526001600160a01b039091169063da1919b390604401600060405180830381600087803b158015612aa957600080fd5b505af1158015612abd573d6000803e3d6000fd5b5050506101608501516101408601516040517ff3fef3a30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152602481018590529116915063f3fef3a3906044016020604051808303816000875af1158015612b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5991906158de565b50612b818460e00151828661014001516001600160a01b0316614b689092919063ffffffff16565b600080612b918660e00151614bfe565b90925090506001600160a01b03821615612c46578561012001516001600160a01b031663da1919b3836402540be400600a54858b60000151612bd391906159e8565b612bdd91906159e8565b612be791906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b505050505b8561012001516001600160a01b031663da1919b3306402540be40088600801548a60000151612c7591906159e8565b612c7f91906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612cc557600080fd5b505af1158015612cd9573d6000803e3d6000fd5b505050506101208601516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612d29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4d91906158de565b905060006402540be40060095483612d6591906159e8565b612d6f91906159ff565b6101208901516004549192506001600160a01b039081169163095ea7b39116612d9884866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015612de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e079190615a3a565b506004546101208901516001600160a01b039091169063fb93210890612e2d84866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612e7357600080fd5b505af1158015612e87573d6000803e3d6000fd5b505050506101208801516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612ed7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efb91906158de565b6101208a01516008546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af1158015612f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f929190615a3a565b506008546101208a01516040517ffb9321080000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063fb93210890604401600060405180830381600087803b158015612fff57600080fd5b505af1158015613013573d6000803e3d6000fd5b505050506101208901517f5146a00d88bc8d5b51da0a31b8b0163c52d08795010875de4612d9ca5b7ac2e79150836001600160a01b03871615613073578a516402540be400906130649088906159e8565b61306e91906159ff565b613076565b60005b60098b01548c516402540be4009161308d916159e8565b61309791906159ff565b604080516001600160a01b03958616815260208101949094528301919091526060820152908616608082015260a00160405180910390a187516005880180546000906130e49084906158f7565b90915550506003546040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018c90526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561314c57600080fd5b505af1158015613160573d6000803e3d6000fd5b505050507f902e822853f2af7f3aa893464f511b02ce01640df53bdc607f15065003141be38a878b613193576000613199565b89600701545b888c60e001516131a7614c91565b8e6040516131bb9796959493929190615a57565b60405180910390a150505050505050505050565b6131d7613a50565b6003805460ff19168215159081179091556040519081527f04c6d89864a325932580d13c4bf8c2fd961d8e92ecd4842372d539cca50a91dc90602001611511565b613220613a50565b808210156132705760405162461bcd60e51b815260206004820152600260248201527f21430000000000000000000000000000000000000000000000000000000000006044820152606401610807565b6000928352600d602052604090922090815560010155565b613290613a50565b6000918252600d602052604090912060040155565b6001546001600160a01b031633036132ff5760405162461bcd60e51b815260206004820152601560248201527f466f72776172646572206e6f7420616c6c6f77656400000000000000000000006044820152606401610807565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa158015613368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338c9190615713565b6020808201516000908152600d90915260409020600481015482516005830154939450919290916133bc9161582c565b111561340a5760405162461bcd60e51b815260206004820152601c60248201527f4f70656e20696e746572657374206c696d697420726561636865642e000000006044820152606401610807565b600a81015460ff1615613470576134248260600151614544565b6134705760405162461bcd60e51b815260206004820152601160248201527f4d61726b657420697320636c6f7365642e0000000000000000000000000000006044820152606401610807565b600061348b83602001518585604001516119ff576002611a02565b90508260c001516000036134e15760405162461bcd60e51b815260206004820152601260248201527f4e6f742061206c696d6974206f726465722e00000000000000000000000000006044820152606401610807565b826040015180156134f657508260c001516001145b1561355457808360800151101561354f5760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b61369a565b826040015115801561356a57508260c001516001145b156135c357808360800151111561354f5760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b82604001511580156135d957508260c001516002145b1561363e5780836080015110156136325760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b6080830181905261369a565b80836080015111156136925760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b608083018190525b82516005830180546000906136b090849061582c565b90915550506101208301516001600160a01b031663da1919b36136d1614c91565b600985015486516402540be400916136e8916159e8565b6136f291906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561373857600080fd5b505af115801561374c573d6000803e3d6000fd5b5050600354608086015186516040517fd19a8a4a000000000000000000000000000000000000000000000000000000008152600481018b9052602481019290925260448201526101009091046001600160a01b0316925063d19a8a4a9150606401600060405180830381600087803b1580156137c757600080fd5b505af11580156137db573d6000803e3d6000fd5b505050507ffb127b06de5db41afe60a161b295176d2502dab32d7ad5ec9fdf6eaed1dd896e836020015184604001518560600151866080015187600001518a8960a001518a60e0015161382c614c91565b60408051998a5297151560208a0152968801959095526060870193909352608086019190915260a085015260c08401526001600160a01b0390811660e0840152166101008201526101200160405180910390a15050505050565b61388e613a50565b6001600160a01b03811661390a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610807565b61391381613cc2565b50565b61391e613a50565b6402540be40082826000818110613937576139376157ce565b90506020020135111561398c5760405162461bcd60e51b815260206004820152601260248201527f436c6f73652066656520746f6f206869676800000000000000000000000000006044820152606401610807565b6402540be400828260018181106139a5576139a56157ce565b9050602002013511156139fa5760405162461bcd60e51b815260206004820152601060248201527f426f742066656520746f6f2068696768000000000000000000000000000000006044820152606401610807565b6000838152600d60205260408120908390839081613a1a57613a1a6157ce565b602002919091013560088301555082826001818110613a3b57613a3b6157ce565b90506020020135816009018190555050505050565b613a58614c91565b6001600160a01b0316613a736000546001600160a01b031690565b6001600160a01b031614610d8b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610807565b613ad1614c91565b6001600160a01b0316816001600160a01b031614613913576007546040517f88520fb50000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260009216906388520fb590602401602060405180830381865afa158015613b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b719190615b3e565b9050613b7b614c91565b6001600160a01b0316816001600160a01b031614613bdb5760405162461bcd60e51b815260206004820152601360248201527f50726f7879206e6f7420617070726f7665642e000000000000000000000000006044820152606401610807565b5050565b6003546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b038381169261010090041690636352211e90602401602060405180830381865afa158015613c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c6c9190615b3e565b6001600160a01b031614613bdb5760405162461bcd60e51b815260206004820152601360248201527f4e6f7420706f736974696f6e206f776e65722e000000000000000000000000006044820152606401610807565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0383166000908152600b602052604081205460ff16613d925760405162461bcd60e51b815260206004820152601660248201527f5661756c74206e6f742077686974656c69737465642e000000000000000000006044820152606401610807565b836001600160a01b03166322be3de16040518163ffffffff1660e01b8152600401602060405180830381865afa158015613dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613df49190615b3e565b9050806001600160a01b0316836001600160a01b031614158015613e9857506040517fd63a8e110000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015285169063d63a8e1190602401602060405180830381865afa158015613e72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e969190615a3a565b155b15613ee55760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e206e6f7420617070726f76656420696e207661756c742e000000006044820152606401610807565b806001600160a01b0316826001600160a01b031614158015613f8757506040517fd63a8e110000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015285169063d63a8e1190602401602060405180830381865afa158015613f61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f859190615a3a565b155b15613fd45760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e206e6f7420617070726f76656420696e207661756c742e000000006044820152606401610807565b9392505050565b856001600160a01b03808216908716146144bf57613fff60c0840160a08501615643565b156140b8576001600160a01b03861663d505accf83306020870135873561402c60608a0160408b01615439565b6040516001600160e01b031960e088901b1681526001600160a01b0395861660048201529490931660248501526044840191909152606483015260ff166084820152606086013560a4820152608086013560c482015260e401600060405180830381600087803b15801561409f57600080fd5b505af11580156140b3573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156140ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061412391906158de565b90506000876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614165573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141899190615b5b565b614194906012615b78565b61419f90600a615c75565b90506141c284306141b0848b6159ff565b6001600160a01b038c16929190614cd6565b6001600160a01b038089166000908152600c60209081526040808320938a168352929052205460ff166142ae576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152600019602483015289169063095ea7b3906044016020604051808303816000875af1158015614258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061427c9190615a3a565b506001600160a01b038089166000908152600c60209081526040808320938a16835292905220805460ff191660011790555b6001600160a01b0386166347e7ef24896142c8848b6159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561430e57600080fd5b505af1158015614322573d6000803e3d6000fd5b505050508682614332919061582c565b6040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015614376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061439a91906158de565b146143e75760405162461bcd60e51b815260206004820152601c60248201527f4572726f72206465706f736974696e6720696e746f207661756c742e000000006044820152606401610807565b6040516370a0823160e01b815230600482018190526001600160a01b038516916379cc6790919083906370a0823190602401602060405180830381865afa158015614436573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061445a91906158de565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156144a057600080fd5b505af11580156144b4573d6000803e3d6000fd5b50505050505061453b565b6040517f79cc67900000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018790528216906379cc679090604401600060405180830381600087803b15801561452257600080fd5b505af1158015614536573d6000803e3d6000fd5b505050505b50505050505050565b6018610e104283810182810484900660ff81811660009081526010602052604081205490969495600760046201518089040106958188040694603c828906819004959492909106049116156145a157506000979650505050505050565b60ff85166000908152600f6020908152604091829020825160808101845281548082526001830154938201939093526002820154938101939093526003015460608301528511806145fe57508051851480156145fe575080518410155b80156146285750806020015185108061462857508060200151851480156146285750806060015184105b80156146525750806020015183108061465257508060200151831480156146525750806060015182105b9998505050505050505050565b60008061478161467260c0870187615c84565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061477b92506146b89150506020890189615556565b6146c860408a0160208b01615643565b604080516001600160a01b0390931660208401529015158282015289013560608281019190915289013560808281019190915289013560a08281019190915289013560c082015260e001604051602081830303815290604052805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90614d2d565b90506147906020860186615556565b6001600160a01b0316816001600160a01b0316146147f05760405162461bcd60e51b815260206004820152600660248201527f42616453696700000000000000000000000000000000000000000000000000006044820152606401610807565b6001600160a01b0381166000908152600e602052604090205460ff166148585760405162461bcd60e51b815260206004820152600560248201527f214e6f64650000000000000000000000000000000000000000000000000000006044820152606401610807565b846040013586146148ab5760405162461bcd60e51b815260206004820152600660248201527f21417373657400000000000000000000000000000000000000000000000000006044820152606401610807565b6148bb6040860160208701615643565b156149085760405162461bcd60e51b815260206004820152601160248201527f4d61726b657420697320636c6f7365642e0000000000000000000000000000006044820152606401610807565b836000036149ca578460a0013560025484614923919061582c565b10156149715760405162461bcd60e51b815260206004820152600660248201527f46757453696700000000000000000000000000000000000000000000000000006044820152606401610807565b8460a001358311156149c55760405162461bcd60e51b815260206004820152601260248201527f50726963652068617320657870697265642e00000000000000000000000000006044820152606401610807565b614a7e565b8460a00135831015614a1e5760405162461bcd60e51b815260206004820152600660248201527f46757453696700000000000000000000000000000000000000000000000000006044820152606401610807565b600254614a2f9060a087013561582c565b831115614a7e5760405162461bcd60e51b815260206004820152601260248201527f50726963652068617320657870697265642e00000000000000000000000000006044820152606401610807565b6000856060013511614ad25760405162461bcd60e51b815260206004820152600760248201527f4e6f5072696365000000000000000000000000000000000000000000000000006044820152606401610807565b606085013591506080850135600185148015614af0575060035460ff165b15614b20576402540be400614b0582856159e8565b614b0f91906159ff565b614b19908461582c565b9250614b5e565b846002148015614b32575060035460ff165b15614b5e576402540be400614b4782856159e8565b614b5191906159ff565b614b5b90846158f7565b92505b5050949350505050565b6040516001600160a01b038316602482015260448101829052614bf99084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152614d53565b505050565b6005546040517fd113f04c0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092839291169063d113f04c906024016040805180830381865afa158015614c64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c889190615ce9565b91509150915091565b6001546000906001600160a01b03163303614cd157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b6040516001600160a01b0380851660248301528316604482015260648101829052614d279085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401614bad565b50505050565b6000806000614d3c8585614e38565b91509150614d4981614e7d565b5090505b92915050565b6000614da8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614fe29092919063ffffffff16565b805190915015614bf95780806020019051810190614dc69190615a3a565b614bf95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610807565b6000808251604103614e6e5760208301516040840151606085015160001a614e6287828585614ff9565b94509450505050614e76565b506000905060025b9250929050565b6000816004811115614e9157614e91615d17565b03614e995750565b6001816004811115614ead57614ead615d17565b03614efa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610807565b6002816004811115614f0e57614f0e615d17565b03614f5b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610807565b6003816004811115614f6f57614f6f615d17565b036139135760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610807565b6060614ff184846000856150bd565b949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561503057506000905060036150b4565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015615084573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166150ad576000600192509250506150b4565b9150600090505b94509492505050565b6060824710156151355760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610807565b600080866001600160a01b031685876040516151519190615d6a565b60006040518083038185875af1925050503d806000811461518e576040519150601f19603f3d011682016040523d82523d6000602084013e615193565b606091505b5091509150614b5b878383876060831561520e578251600003615207576001600160a01b0385163b6152075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610807565b5081614ff1565b614ff183838151156152235781518083602001fd5b8060405162461bcd60e51b81526004016108079190615d86565b60ff8116811461391357600080fd5b801515811461391357600080fd5b6000806040838503121561526d57600080fd5b82356152788161523d565b915060208301356152888161524c565b809150509250929050565b6000602082840312156152a557600080fd5b5035919050565b6001600160a01b038116811461391357600080fd5b80356152cc816152ac565b919050565b600080604083850312156152e457600080fd5b8235615278816152ac565b600080600080600060a0868803121561530757600080fd5b85356153128161523d565b97602087013597506040870135966060810135965060800135945092505050565b6000806040838503121561534657600080fd5b823591506020830135615288816152ac565b60008083601f84011261536a57600080fd5b50813567ffffffffffffffff81111561538257600080fd5b6020830191508360208260051b8501011115614e7657600080fd5b6000806000806000806000806000806101208b8d0312156153bd57600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135935060e08b013567ffffffffffffffff81111561540557600080fd5b6154118d828e01615358565b9094509250506101008b01356154268161524c565b809150509295989b9194979a5092959850565b60006020828403121561544b57600080fd5b8135613fd48161523d565b6000610100828403121561546957600080fd5b50919050565b600060c0828403121561546957600080fd5b6000806000806000610220868803121561549a57600080fd5b6154a48787615456565b9450610100860135935061012086013592506154c487610140880161546f565b91506102008601356154d5816152ac565b809150509295509295909350565b600080604083850312156154f657600080fd5b8235915060208301356152888161524c565b60008060006060848603121561551d57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561554757600080fd5b50508035926020909101359150565b60006020828403121561556857600080fd5b8135613fd4816152ac565b600060e0828403121561546957600080fd5b600080600080610200858703121561559c57600080fd5b6155a68686615456565b93506155b686610100870161546f565b92506101c08501356155c7816152ac565b91506101e085013567ffffffffffffffff8111156155e457600080fd5b6155f087828801615573565b91505092959194509250565b6000806040838503121561560f57600080fd5b82359150602083013567ffffffffffffffff81111561562d57600080fd5b61563985828601615573565b9150509250929050565b60006020828403121561565557600080fd5b8135613fd48161524c565b60008060006040848603121561567557600080fd5b83359250602084013567ffffffffffffffff81111561569357600080fd5b61569f86828701615358565b9497909650939450505050565b604051610180810167ffffffffffffffff811182821017156156f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b80516152cc8161524c565b80516152cc816152ac565b6000610180828403121561572657600080fd5b61572e6156ac565b8251815260208301516020820152615748604084016156fd565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015261578160e08401615708565b60e0820152610100838101519082015261012061579f818501615708565b908201526101406157b1848201615708565b908201526101606157c3848201615708565b908201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115614d4d57614d4d6157fd565b81516001600160a01b03168152610140810160208301516020830152604083015160408301526060830151615878606084018215159052565b506080830151608083015260a083015160a083015260c083015160c083015260e08301516158b160e08401826001600160a01b03169052565b50610100838101516001600160a01b03908116918401919091526101209384015116929091019190915290565b6000602082840312156158f057600080fd5b5051919050565b81810381811115614d4d57614d4d6157fd565b80358252602081013561591c816152ac565b6001600160a01b03908116602084015260408201359061593b826152ac565b9081166040840152606082013590615952826152ac565b16606083015260808101356159668161524c565b80151560808401525060a081013560a083015260c081013560c083015261598f60e082016152c1565b6001600160a01b03811660e0840152505050565b6101a081016159b2828961590a565b6101008201969096526101208101949094526101408401929092526101608301526001600160a01b031661018090910152919050565b8082028115828204841417614d4d57614d4d6157fd565b600082615a35577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215615a4c57600080fd5b8151613fd48161524c565b6000610240820190508882528760208301528660408301528560608301526001600160a01b03808616608084015280851660a084015250825160c0830152602083015160e08301526040830151610100615ab48185018315159052565b60608501516101208581019190915260808601516101408087019190915260a08701516101608088019190915260c088015161018088015260e08801516001600160a01b039081166101a0890152938801516101c08801529187015183166101e0870152860151821661020086015285015190811661022085015290505098975050505050505050565b600060208284031215615b5057600080fd5b8151613fd4816152ac565b600060208284031215615b6d57600080fd5b8151613fd48161523d565b60ff8281168282160390811115614d4d57614d4d6157fd565b600181815b80851115615bcc578160001904821115615bb257615bb26157fd565b80851615615bbf57918102915b93841c9390800290615b96565b509250929050565b600082615be357506001614d4d565b81615bf057506000614d4d565b8160018114615c065760028114615c1057615c2c565b6001915050614d4d565b60ff841115615c2157615c216157fd565b50506001821b614d4d565b5060208310610133831016604e8410600b8410161715615c4f575081810a614d4d565b615c598383615b91565b8060001904821115615c6d57615c6d6157fd565b029392505050565b6000613fd460ff841683615bd4565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615cb957600080fd5b83018035915067ffffffffffffffff821115615cd457600080fd5b602001915036819003821315614e7657600080fd5b60008060408385031215615cfc57600080fd5b8251615d07816152ac565b6020939093015192949293505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60005b83811015615d61578181015183820152602001615d49565b50506000910152565b60008251615d7c818460208701615d46565b9190910192915050565b6020815260008251806020840152615da5816040850160208701615d46565b601f01601f1916919091016040019291505056fea26469706673582212202b2a62f8219ea36e253da9c8c69f4392e5d52403d08b7632cf31638235d7a98464736f6c634300081300330000000000000000000000004e0bb7b156eb236260c18f98fb7f83f647f9c1dd0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f4000000000000000000000000a0304eced4926e7c1f49b1693c71fcbf6a498ff7000000000000000000000000b93e43c81ce6d23209932ff25e0953b1e4cd204300000000000000000000000018e285202856128c63add907650fc9cb4bcd44950000000000000000000000002349443d0cb8fab1e40cc6acd3c0eb25bc7abf7d
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102de5760003560e01c8063a088b49911610186578063d3dc7539116100e3578063e8e97e2911610097578063f2fde38b11610071578063f2fde38b146106f1578063f9f98af614610704578063ff849db51461071757600080fd5b8063e8e97e29146106b8578063f0632619146106cb578063f0eab0ca146106de57600080fd5b8063da742228116100c8578063da7422281461067f578063dc49d2e814610692578063def061cc146106a557600080fd5b8063d3dc753914610649578063d62515cf1461065c57600080fd5b8063c80caf2c1161013a578063ccf845e21161011f578063ccf845e2146105fb578063d10e683f1461061e578063d232e1ff1461063157600080fd5b8063c80caf2c146105d5578063cae82b2e146105e857600080fd5b8063afcca2f11161016b578063afcca2f1146105a6578063b3113b2a146105b9578063bf5d598d146105cc57600080fd5b8063a088b49914610580578063ac6b2da41461059357600080fd5b80636c704fac1161023f5780637da0a877116101f35780639251ae27116101cd5780639251ae27146105475780639e4bd2e91461055a578063a05dc07c1461056d57600080fd5b80637da0a877146105105780638715746d146105235780638da5cb5b1461053657600080fd5b8063715018a611610224578063715018a6146104e2578063797b371e146104ea5780637c0c4797146104fd57600080fd5b80636c704fac14610476578063706dfd36146104cb57600080fd5b806343d975de116102965780635b14f3161161027b5780635b14f3161461043d5780636450f9cc146104505780636bbdc24b1461046357600080fd5b806343d975de146104175780634cf088d91461042a57600080fd5b806327426de4116102c757806327426de41461032857806337b2b9d7146103e757806341addb7b1461040457600080fd5b80630dfc1f4c146102e35780631c13c466146102f8575b600080fd5b6102f66102f136600461525a565b610720565b005b60085461030b906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610392610336366004615293565b600d60205260009081526040902080546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600a909a01549899979896979596949593949293919290919060ff168b565b604080519b8c5260208c019a909a52988a01979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015215156101408201526101600161031f565b6003546103f49060ff1681565b604051901515815260200161031f565b6102f66104123660046152d1565b61074d565b6102f66104253660046152ef565b610780565b60045461030b906001600160a01b031681565b6102f661044b366004615333565b6107b1565b6102f661045e36600461539d565b610a4c565b6102f66104713660046152d1565b610d0e565b6104ab610484366004615439565b600f6020526000908152604090208054600182015460028301546003909301549192909184565b60408051948552602085019390935291830152606082015260800161031f565b6104d460095481565b60405190815260200161031f565b6102f6610d79565b6102f66104f8366004615293565b610d8d565b60065461030b906001600160a01b031681565b60015461030b906001600160a01b031681565b6102f6610531366004615481565b610d9a565b6000546001600160a01b031661030b565b6102f66105553660046154e3565b6113d6565b60075461030b906001600160a01b031681565b6102f661057b366004615508565b611401565b6102f661058e366004615293565b6114c6565b6102f66105a1366004615293565b61151c565b6102f66105b4366004615534565b611529565b6102f66105c7366004615556565b61159b565b6104d460025481565b6102f66105e3366004615585565b6115dd565b6102f66105f6366004615556565b611c2c565b6103f4610609366004615556565b600b6020526000908152604090205460ff1681565b6102f661062c3660046155fc565b611c9a565b60035461030b9061010090046001600160a01b031681565b60055461030b906001600160a01b031681565b6103f461066a366004615439565b60106020526000908152604090205460ff1681565b6102f661068d366004615556565b6127ae565b6102f66106a03660046154e3565b6127f0565b6102f66106b3366004615643565b6131cf565b6102f66106c6366004615508565b613218565b6102f66106d9366004615534565b613288565b6102f66106ec3660046155fc565b6132a5565b6102f66106ff366004615556565b613886565b6102f6610712366004615660565b613916565b6104d4600a5481565b610728613a50565b60ff919091166000908152601060205260409020805460ff1916911515919091179055565b610755613a50565b6001600160a01b03919091166000908152600e60205260409020805460ff1916911515919091179055565b610788613a50565b60ff9094166000908152600f602052604090206001810193909355908255600382015560020155565b6001546001600160a01b031633146108105760405162461bcd60e51b815260206004820152600a60248201527f21466f727761726465720000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61081981613ac9565b6108238282613bdf565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa15801561088c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b09190615713565b90508060c001516000036109065760405162461bcd60e51b815260206004820152601260248201527f4e6f742061206c696d6974206f726465722e00000000000000000000000000006044820152606401610807565b61012081015181516040517fda1919b30000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482019290925291169063da1919b390604401600060405180830381600087803b15801561097257600080fd5b505af1158015610986573d6000803e3d6000fd5b50506003546040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018790526101009091046001600160a01b031692506342966c689150602401600060405180830381600087803b1580156109ed57600080fd5b505af1158015610a01573d6000803e3d6000fd5b5050604080518681526001600160a01b03861660208201527f65e9cd59862cf801cf6b537eb6db1b2aa79ee35a677765915c850f7665f57771935001905060405180910390a1505050565b610a54613a50565b6402540be400841115610aa95760405162461bcd60e51b815260206004820152601460248201527f57696e2070657263656e7420746f6f20686967680000000000000000000000006044820152606401610807565b603c8711610af95760405162461bcd60e51b815260206004820152600360248201527f216d4400000000000000000000000000000000000000000000000000000000006044820152606401610807565b87891015610b495760405162461bcd60e51b815260206004820152600260248201527f21430000000000000000000000000000000000000000000000000000000000006044820152606401610807565b85871015610b995760405162461bcd60e51b815260206004820152600260248201527f21440000000000000000000000000000000000000000000000000000000000006044820152606401610807565b6402540be40083836000818110610bb257610bb26157ce565b905060200201351115610c075760405162461bcd60e51b815260206004820152601260248201527f436c6f73652066656520746f6f206869676800000000000000000000000000006044820152606401610807565b6402540be40083836001818110610c2057610c206157ce565b905060200201351115610c755760405162461bcd60e51b815260206004820152601060248201527f426f742066656520746f6f2068696768000000000000000000000000000000006044820152606401610807565b60008a8152600d602052604081208a8155600181018a9055600281018990556003810188905560048101879055600681018c905560078101869055908490849081610cc257610cc26157ce565b602002919091013560088301555083836001818110610ce357610ce36157ce565b6020029190910135600983015550600a01805460ff1916911515919091179055505050505050505050565b610d16613a50565b6001600160a01b0382166000818152600b6020908152604091829020805460ff19168515159081179091558251938452908301527f97e3e14419501104b30f00cb285807bb4dea790a51cd81dc173e30647e45aa11910160405180910390a15050565b610d81613a50565b610d8b6000613cc2565b565b610d95613a50565b600255565b6001546001600160a01b03163314610df45760405162461bcd60e51b815260206004820152600a60248201527f21466f72776172646572000000000000000000000000000000000000000000006044820152606401610807565b60a0808601356000908152600d602090815260409182902082516101608101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082018190526005830154938201849052600683015460c0830152600783015460e083015260088301546101008301526009830154610120830152600a9092015460ff16151561014082015291610e9a9088359061582c565b1115610ee85760405162461bcd60e51b815260206004820152601c60248201527f4f70656e20696e746572657374206c696d697420726561636865642e000000006044820152606401610807565b805186351115610f3a5760405162461bcd60e51b815260206004820152601c60248201527f4d6178696d756d20636f6c6c61746572616c2065786365656465642e000000006044820152606401610807565b602081015186351015610f8f5760405162461bcd60e51b815260206004820152601360248201527f436f6c6c61746572616c20746f6f206c6f772e000000000000000000000000006044820152606401610807565b80604001518660c001351115610fe75760405162461bcd60e51b815260206004820152601a60248201527f4d6178696d756d206475726174696f6e2065786365656465642e0000000000006044820152606401610807565b80606001518660c00135101561103f5760405162461bcd60e51b815260206004820152601160248201527f4475726174696f6e20746f6f206c6f772e0000000000000000000000000000006044820152606401610807565b846001148061104e5750846002145b61109a5760405162461bcd60e51b815260206004820152601360248201527f496e76616c6964206f7264657220747970652e000000000000000000000000006044820152606401610807565b6005546001600160a01b0316630443e9ef836110bd6101008a0160e08b01615556565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401600060405180830381600087803b15801561110557600080fd5b505af1158015611119573d6000803e3d6000fd5b5050505061112682613ac9565b600061116061113b6060890160408a01615556565b61114b60408a0160208b01615556565b61115b60808b0160608c01615556565b613d2a565b9050846000036111b25760405162461bcd60e51b815260206004820152601560248201527f50726963652063616e6e6f74206265207a65726f2e00000000000000000000006044820152606401610807565b6111df816111c660408a0160208b01615556565b89356111d860608c0160408d01615556565b8888613fdb565b6000604051806101400160405280856001600160a01b03168152602001896000013581526020018960a0013581526020018960800160208101906112239190615643565b151581526020018960c001358152602001878152602001888152602001836001600160a01b031681526020018960600160208101906112629190615556565b6001600160a01b0316815260200161128060608b0160408c01615556565b6001600160a01b039081169091526003546040517f346f67750000000000000000000000000000000000000000000000000000000081529293506101009004169063346f6775906112d590849060040161583f565b600060405180830381600087803b1580156112ef57600080fd5b505af1158015611303573d6000803e3d6000fd5b505050507f34e1eb5d71d806d6f4d0769e7d1cd099ced2c567e74bf35d53e8c1d7d2c236e38860001989896001600360019054906101000a90046001600160a01b03166001600160a01b031663a87d942c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a791906158de565b6113b191906158f7565b896040516113c4969594939291906159a3565b60405180910390a15050505050505050565b6113de613a50565b6000918252600d6020526040909120600a01805460ff1916911515919091179055565b611409613a50565b603c82116114595760405162461bcd60e51b815260206004820152600360248201527f216d4400000000000000000000000000000000000000000000000000000000006044820152606401610807565b808210156114a95760405162461bcd60e51b815260206004820152600260248201527f21440000000000000000000000000000000000000000000000000000000000006044820152606401610807565b6000928352600d6020526040909220600281019190915560030155565b6114ce613a50565b6402540be4008111156114e057600080fd5b60098190556040518181527ff54bed1d7fd947844c687e55a908aca81e51c67dc188ac1e5f436d646ce267bf906020015b60405180910390a150565b611524613a50565b600a55565b611531613a50565b6402540be4008111156115865760405162461bcd60e51b815260206004820152601460248201527f57696e2070657263656e7420746f6f20686967680000000000000000000000006044820152606401610807565b6000918252600d602052604090912060070155565b6115a3613a50565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001546001600160a01b031633146116375760405162461bcd60e51b815260206004820152600a60248201527f21466f72776172646572000000000000000000000000000000000000000000006044820152606401610807565b61164082613ac9565b60a0808501356000908152600d602090815260409182902082516101608101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082018190526005830154938201849052600683015460c0830152600783015460e083015260088301546101008301526009830154610120830152600a9092015460ff161515610140820152916116e69087359061582c565b11156117345760405162461bcd60e51b815260206004820152601c60248201527f4f70656e20696e746572657374206c696d697420726561636865642e000000006044820152606401610807565b8051853511156117865760405162461bcd60e51b815260206004820152601c60248201527f4d6178696d756d20636f6c6c61746572616c2065786365656465642e000000006044820152606401610807565b6020810151853510156117db5760405162461bcd60e51b815260206004820152601360248201527f436f6c6c61746572616c20746f6f206c6f772e000000000000000000000000006044820152606401610807565b80604001518560c0013511156118335760405162461bcd60e51b815260206004820152601a60248201527f4d6178696d756d206475726174696f6e2065786365656465642e0000000000006044820152606401610807565b80606001518560c00135101561188b5760405162461bcd60e51b815260206004820152601160248201527f4475726174696f6e20746f6f206c6f772e0000000000000000000000000000006044820152606401610807565b806101400151156118ef576118a38560c00135614544565b6118ef5760405162461bcd60e51b815260206004820152601160248201527f4d61726b657420697320636c6f7365642e0000000000000000000000000000006044820152606401610807565b6005546001600160a01b0316630443e9ef84611912610100890160e08a01615556565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401600060405180830381600087803b15801561195a57600080fd5b505af115801561196e573d6000803e3d6000fd5b5050505060006119aa86604001602081019061198a9190615556565b61199a6040890160208a01615556565b61115b60808a0160608b01615556565b90506119d9816119c06040890160208a01615556565b88356119d260608b0160408c01615556565b8989613fdb565b6000611a0b60a0880180359086906119f49060808c01615643565b6119ff576002611a02565b60015b60ff164261465f565b60a08801356000908152600d602052604081206005018054929350893592909190611a3790849061582c565b909155505060408051610140810182526001600160a01b03871681528835602082015260a089018035928201929092526000916060820190611a7c9060808c01615643565b151581526020018960c00135815260200183815260200160008152602001846001600160a01b03168152602001896060016020810190611abc9190615556565b6001600160a01b03168152602001611ada60608b0160408c01615556565b6001600160a01b039081169091526003546040517f346f67750000000000000000000000000000000000000000000000000000000081529293506101009004169063346f677590611b2f90849060040161583f565b600060405180830381600087803b158015611b4957600080fd5b505af1158015611b5d573d6000803e3d6000fd5b505050507f34e1eb5d71d806d6f4d0769e7d1cd099ced2c567e74bf35d53e8c1d7d2c236e388428a60c00135611b93919061582c565b6000856001600360019054906101000a90046001600160a01b03166001600160a01b031663a87d942c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0f91906158de565b611c1991906158f7565b8b6040516113c4969594939291906159a3565b611c34613a50565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f2b3d3800b704d91b74611daa96930c9d508a38bbb0650bac8d72629df8ba096890602001611511565b6001546001600160a01b03163303611cf45760405162461bcd60e51b815260206004820152601560248201527f466f72776172646572206e6f7420616c6c6f77656400000000000000000000006044820152606401610807565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa158015611d5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d819190615713565b60e08101519091506001600160a01b0316611dde5760405162461bcd60e51b815260206004820152601560248201527f547261646520646f6573206e6f742065786973742e00000000000000000000006044820152606401610807565b6020808201516000908152600d9091526040902060c082015115611e445760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420636c6f73652061206c696d6974206f726465722e00000000006044820152606401610807565b6000611e5b83602001518560008660a0015161465f565b9050600083604001518015611e735750836080015182115b15611e8057506001611e9f565b8360400151158015611e96575083608001518211155b15611e9f575060015b600081156120c457600784015485516402540be40091611ebe916159e8565b611ec891906159ff565b8551611ed4919061582c565b90508461014001516001600160a01b03168561012001516001600160a01b031603611f845761012085015160e08601516040517fda1919b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063da1919b390604401600060405180830381600087803b158015611f6757600080fd5b505af1158015611f7b573d6000803e3d6000fd5b505050506120c4565b6101208501516040517fda1919b3000000000000000000000000000000000000000000000000000000008152306004820152602481018390526001600160a01b039091169063da1919b390604401600060405180830381600087803b158015611fec57600080fd5b505af1158015612000573d6000803e3d6000fd5b5050506101608601516101408701516040517ff3fef3a30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152602481018590529116915063f3fef3a3906044016020604051808303816000875af1158015612078573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209c91906158de565b506120c48560e00151828761014001516001600160a01b0316614b689092919063ffffffff16565b6000806120d48760e00151614bfe565b90925090506001600160a01b03821615612189578661012001516001600160a01b031663da1919b3836402540be400600a54858c6000015161211691906159e8565b61212091906159e8565b61212a91906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561217057600080fd5b505af1158015612184573d6000803e3d6000fd5b505050505b8661012001516001600160a01b031663da1919b3306402540be40089600801548b600001516121b891906159e8565b6121c291906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561220857600080fd5b505af115801561221c573d6000803e3d6000fd5b505050508661012001516001600160a01b031663da1919b361223c614c91565b60098901548a516402540be40091612253916159e8565b61225d91906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156122a357600080fd5b505af11580156122b7573d6000803e3d6000fd5b505050506101208701516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232b91906158de565b905060006402540be4006009548361234391906159e8565b61234d91906159ff565b6101208a01516004549192506001600160a01b039081169163095ea7b3911661237684866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156123c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e59190615a3a565b506004546101208a01516001600160a01b039091169063fb9321089061240b84866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561245157600080fd5b505af1158015612465573d6000803e3d6000fd5b505050506101208901516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156124b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d991906158de565b6101208b01516008546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af115801561254c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125709190615a3a565b506008546101208b01516040517ffb9321080000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063fb93210890604401600060405180830381600087803b1580156125dd57600080fd5b505af11580156125f1573d6000803e3d6000fd5b505050506101208a01517f5146a00d88bc8d5b51da0a31b8b0163c52d08795010875de4612d9ca5b7ac2e79150836001600160a01b03871615612651578b516402540be400906126429088906159e8565b61264c91906159ff565b612654565b60005b60098c01548d516402540be4009161266b916159e8565b61267591906159ff565b604080516001600160a01b03958616815260208101949094528301919091526060820152908616608082015260a00160405180910390a188516005890180546000906126c29084906158f7565b90915550506003546040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018d90526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561272a57600080fd5b505af115801561273e573d6000803e3d6000fd5b505050507f902e822853f2af7f3aa893464f511b02ce01640df53bdc607f15065003141be38b8888612771576000612777565b8a600701545b888d60e00151612785614c91565b8f6040516127999796959493929190615a57565b60405180910390a15050505050505050505050565b6127b6613a50565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6127f8613a50565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa158015612861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128859190615713565b60e08101519091506001600160a01b03166128e25760405162461bcd60e51b815260206004820152600760248201527f21657869737473000000000000000000000000000000000000000000000000006044820152606401610807565b6020808201516000908152600d9091526040902060c0820151156129485760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420636c6f73652061206c696d6974206f726465722e00000000006044820152606401610807565b60008361295657600061295a565b6000195b905060008415612b8157600783015484516402540be4009161297b916159e8565b61298591906159ff565b8451612991919061582c565b90508361014001516001600160a01b03168461012001516001600160a01b031603612a415761012084015160e08501516040517fda1919b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063da1919b390604401600060405180830381600087803b158015612a2457600080fd5b505af1158015612a38573d6000803e3d6000fd5b50505050612b81565b6101208401516040517fda1919b3000000000000000000000000000000000000000000000000000000008152306004820152602481018390526001600160a01b039091169063da1919b390604401600060405180830381600087803b158015612aa957600080fd5b505af1158015612abd573d6000803e3d6000fd5b5050506101608501516101408601516040517ff3fef3a30000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152602481018590529116915063f3fef3a3906044016020604051808303816000875af1158015612b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b5991906158de565b50612b818460e00151828661014001516001600160a01b0316614b689092919063ffffffff16565b600080612b918660e00151614bfe565b90925090506001600160a01b03821615612c46578561012001516001600160a01b031663da1919b3836402540be400600a54858b60000151612bd391906159e8565b612bdd91906159e8565b612be791906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612c2d57600080fd5b505af1158015612c41573d6000803e3d6000fd5b505050505b8561012001516001600160a01b031663da1919b3306402540be40088600801548a60000151612c7591906159e8565b612c7f91906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612cc557600080fd5b505af1158015612cd9573d6000803e3d6000fd5b505050506101208601516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612d29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4d91906158de565b905060006402540be40060095483612d6591906159e8565b612d6f91906159ff565b6101208901516004549192506001600160a01b039081169163095ea7b39116612d9884866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015612de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e079190615a3a565b506004546101208901516001600160a01b039091169063fb93210890612e2d84866158f7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015612e7357600080fd5b505af1158015612e87573d6000803e3d6000fd5b505050506101208801516040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612ed7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efb91906158de565b6101208a01516008546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af1158015612f6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f929190615a3a565b506008546101208a01516040517ffb9321080000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063fb93210890604401600060405180830381600087803b158015612fff57600080fd5b505af1158015613013573d6000803e3d6000fd5b505050506101208901517f5146a00d88bc8d5b51da0a31b8b0163c52d08795010875de4612d9ca5b7ac2e79150836001600160a01b03871615613073578a516402540be400906130649088906159e8565b61306e91906159ff565b613076565b60005b60098b01548c516402540be4009161308d916159e8565b61309791906159ff565b604080516001600160a01b03958616815260208101949094528301919091526060820152908616608082015260a00160405180910390a187516005880180546000906130e49084906158f7565b90915550506003546040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018c90526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561314c57600080fd5b505af1158015613160573d6000803e3d6000fd5b505050507f902e822853f2af7f3aa893464f511b02ce01640df53bdc607f15065003141be38a878b613193576000613199565b89600701545b888c60e001516131a7614c91565b8e6040516131bb9796959493929190615a57565b60405180910390a150505050505050505050565b6131d7613a50565b6003805460ff19168215159081179091556040519081527f04c6d89864a325932580d13c4bf8c2fd961d8e92ecd4842372d539cca50a91dc90602001611511565b613220613a50565b808210156132705760405162461bcd60e51b815260206004820152600260248201527f21430000000000000000000000000000000000000000000000000000000000006044820152606401610807565b6000928352600d602052604090922090815560010155565b613290613a50565b6000918252600d602052604090912060040155565b6001546001600160a01b031633036132ff5760405162461bcd60e51b815260206004820152601560248201527f466f72776172646572206e6f7420616c6c6f77656400000000000000000000006044820152606401610807565b6003546040517f1e6c598e0000000000000000000000000000000000000000000000000000000081526004810184905260009161010090046001600160a01b031690631e6c598e9060240161018060405180830381865afa158015613368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338c9190615713565b6020808201516000908152600d90915260409020600481015482516005830154939450919290916133bc9161582c565b111561340a5760405162461bcd60e51b815260206004820152601c60248201527f4f70656e20696e746572657374206c696d697420726561636865642e000000006044820152606401610807565b600a81015460ff1615613470576134248260600151614544565b6134705760405162461bcd60e51b815260206004820152601160248201527f4d61726b657420697320636c6f7365642e0000000000000000000000000000006044820152606401610807565b600061348b83602001518585604001516119ff576002611a02565b90508260c001516000036134e15760405162461bcd60e51b815260206004820152601260248201527f4e6f742061206c696d6974206f726465722e00000000000000000000000000006044820152606401610807565b826040015180156134f657508260c001516001145b1561355457808360800151101561354f5760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b61369a565b826040015115801561356a57508260c001516001145b156135c357808360800151111561354f5760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b82604001511580156135d957508260c001516002145b1561363e5780836080015110156136325760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b6080830181905261369a565b80836080015111156136925760405162461bcd60e51b815260206004820152601460248201527f4c696d6974207072696365206e6f74206d65742e0000000000000000000000006044820152606401610807565b608083018190525b82516005830180546000906136b090849061582c565b90915550506101208301516001600160a01b031663da1919b36136d1614c91565b600985015486516402540be400916136e8916159e8565b6136f291906159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561373857600080fd5b505af115801561374c573d6000803e3d6000fd5b5050600354608086015186516040517fd19a8a4a000000000000000000000000000000000000000000000000000000008152600481018b9052602481019290925260448201526101009091046001600160a01b0316925063d19a8a4a9150606401600060405180830381600087803b1580156137c757600080fd5b505af11580156137db573d6000803e3d6000fd5b505050507ffb127b06de5db41afe60a161b295176d2502dab32d7ad5ec9fdf6eaed1dd896e836020015184604001518560600151866080015187600001518a8960a001518a60e0015161382c614c91565b60408051998a5297151560208a0152968801959095526060870193909352608086019190915260a085015260c08401526001600160a01b0390811660e0840152166101008201526101200160405180910390a15050505050565b61388e613a50565b6001600160a01b03811661390a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610807565b61391381613cc2565b50565b61391e613a50565b6402540be40082826000818110613937576139376157ce565b90506020020135111561398c5760405162461bcd60e51b815260206004820152601260248201527f436c6f73652066656520746f6f206869676800000000000000000000000000006044820152606401610807565b6402540be400828260018181106139a5576139a56157ce565b9050602002013511156139fa5760405162461bcd60e51b815260206004820152601060248201527f426f742066656520746f6f2068696768000000000000000000000000000000006044820152606401610807565b6000838152600d60205260408120908390839081613a1a57613a1a6157ce565b602002919091013560088301555082826001818110613a3b57613a3b6157ce565b90506020020135816009018190555050505050565b613a58614c91565b6001600160a01b0316613a736000546001600160a01b031690565b6001600160a01b031614610d8b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610807565b613ad1614c91565b6001600160a01b0316816001600160a01b031614613913576007546040517f88520fb50000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260009216906388520fb590602401602060405180830381865afa158015613b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b719190615b3e565b9050613b7b614c91565b6001600160a01b0316816001600160a01b031614613bdb5760405162461bcd60e51b815260206004820152601360248201527f50726f7879206e6f7420617070726f7665642e000000000000000000000000006044820152606401610807565b5050565b6003546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b038381169261010090041690636352211e90602401602060405180830381865afa158015613c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c6c9190615b3e565b6001600160a01b031614613bdb5760405162461bcd60e51b815260206004820152601360248201527f4e6f7420706f736974696f6e206f776e65722e000000000000000000000000006044820152606401610807565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0383166000908152600b602052604081205460ff16613d925760405162461bcd60e51b815260206004820152601660248201527f5661756c74206e6f742077686974656c69737465642e000000000000000000006044820152606401610807565b836001600160a01b03166322be3de16040518163ffffffff1660e01b8152600401602060405180830381865afa158015613dd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613df49190615b3e565b9050806001600160a01b0316836001600160a01b031614158015613e9857506040517fd63a8e110000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015285169063d63a8e1190602401602060405180830381865afa158015613e72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e969190615a3a565b155b15613ee55760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e206e6f7420617070726f76656420696e207661756c742e000000006044820152606401610807565b806001600160a01b0316826001600160a01b031614158015613f8757506040517fd63a8e110000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015285169063d63a8e1190602401602060405180830381865afa158015613f61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f859190615a3a565b155b15613fd45760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e206e6f7420617070726f76656420696e207661756c742e000000006044820152606401610807565b9392505050565b856001600160a01b03808216908716146144bf57613fff60c0840160a08501615643565b156140b8576001600160a01b03861663d505accf83306020870135873561402c60608a0160408b01615439565b6040516001600160e01b031960e088901b1681526001600160a01b0395861660048201529490931660248501526044840191909152606483015260ff166084820152606086013560a4820152608086013560c482015260e401600060405180830381600087803b15801561409f57600080fd5b505af11580156140b3573d6000803e3d6000fd5b505050505b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa1580156140ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061412391906158de565b90506000876001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614165573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141899190615b5b565b614194906012615b78565b61419f90600a615c75565b90506141c284306141b0848b6159ff565b6001600160a01b038c16929190614cd6565b6001600160a01b038089166000908152600c60209081526040808320938a168352929052205460ff166142ae576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152600019602483015289169063095ea7b3906044016020604051808303816000875af1158015614258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061427c9190615a3a565b506001600160a01b038089166000908152600c60209081526040808320938a16835292905220805460ff191660011790555b6001600160a01b0386166347e7ef24896142c8848b6159ff565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561430e57600080fd5b505af1158015614322573d6000803e3d6000fd5b505050508682614332919061582c565b6040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa158015614376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061439a91906158de565b146143e75760405162461bcd60e51b815260206004820152601c60248201527f4572726f72206465706f736974696e6720696e746f207661756c742e000000006044820152606401610807565b6040516370a0823160e01b815230600482018190526001600160a01b038516916379cc6790919083906370a0823190602401602060405180830381865afa158015614436573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061445a91906158de565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156144a057600080fd5b505af11580156144b4573d6000803e3d6000fd5b50505050505061453b565b6040517f79cc67900000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018790528216906379cc679090604401600060405180830381600087803b15801561452257600080fd5b505af1158015614536573d6000803e3d6000fd5b505050505b50505050505050565b6018610e104283810182810484900660ff81811660009081526010602052604081205490969495600760046201518089040106958188040694603c828906819004959492909106049116156145a157506000979650505050505050565b60ff85166000908152600f6020908152604091829020825160808101845281548082526001830154938201939093526002820154938101939093526003015460608301528511806145fe57508051851480156145fe575080518410155b80156146285750806020015185108061462857508060200151851480156146285750806060015184105b80156146525750806020015183108061465257508060200151831480156146525750806060015182105b9998505050505050505050565b60008061478161467260c0870187615c84565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061477b92506146b89150506020890189615556565b6146c860408a0160208b01615643565b604080516001600160a01b0390931660208401529015158282015289013560608281019190915289013560808281019190915289013560a08281019190915289013560c082015260e001604051602081830303815290604052805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90614d2d565b90506147906020860186615556565b6001600160a01b0316816001600160a01b0316146147f05760405162461bcd60e51b815260206004820152600660248201527f42616453696700000000000000000000000000000000000000000000000000006044820152606401610807565b6001600160a01b0381166000908152600e602052604090205460ff166148585760405162461bcd60e51b815260206004820152600560248201527f214e6f64650000000000000000000000000000000000000000000000000000006044820152606401610807565b846040013586146148ab5760405162461bcd60e51b815260206004820152600660248201527f21417373657400000000000000000000000000000000000000000000000000006044820152606401610807565b6148bb6040860160208701615643565b156149085760405162461bcd60e51b815260206004820152601160248201527f4d61726b657420697320636c6f7365642e0000000000000000000000000000006044820152606401610807565b836000036149ca578460a0013560025484614923919061582c565b10156149715760405162461bcd60e51b815260206004820152600660248201527f46757453696700000000000000000000000000000000000000000000000000006044820152606401610807565b8460a001358311156149c55760405162461bcd60e51b815260206004820152601260248201527f50726963652068617320657870697265642e00000000000000000000000000006044820152606401610807565b614a7e565b8460a00135831015614a1e5760405162461bcd60e51b815260206004820152600660248201527f46757453696700000000000000000000000000000000000000000000000000006044820152606401610807565b600254614a2f9060a087013561582c565b831115614a7e5760405162461bcd60e51b815260206004820152601260248201527f50726963652068617320657870697265642e00000000000000000000000000006044820152606401610807565b6000856060013511614ad25760405162461bcd60e51b815260206004820152600760248201527f4e6f5072696365000000000000000000000000000000000000000000000000006044820152606401610807565b606085013591506080850135600185148015614af0575060035460ff165b15614b20576402540be400614b0582856159e8565b614b0f91906159ff565b614b19908461582c565b9250614b5e565b846002148015614b32575060035460ff165b15614b5e576402540be400614b4782856159e8565b614b5191906159ff565b614b5b90846158f7565b92505b5050949350505050565b6040516001600160a01b038316602482015260448101829052614bf99084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152614d53565b505050565b6005546040517fd113f04c0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092839291169063d113f04c906024016040805180830381865afa158015614c64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c889190615ce9565b91509150915091565b6001546000906001600160a01b03163303614cd157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b6040516001600160a01b0380851660248301528316604482015260648101829052614d279085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401614bad565b50505050565b6000806000614d3c8585614e38565b91509150614d4981614e7d565b5090505b92915050565b6000614da8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614fe29092919063ffffffff16565b805190915015614bf95780806020019051810190614dc69190615a3a565b614bf95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610807565b6000808251604103614e6e5760208301516040840151606085015160001a614e6287828585614ff9565b94509450505050614e76565b506000905060025b9250929050565b6000816004811115614e9157614e91615d17565b03614e995750565b6001816004811115614ead57614ead615d17565b03614efa5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610807565b6002816004811115614f0e57614f0e615d17565b03614f5b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610807565b6003816004811115614f6f57614f6f615d17565b036139135760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610807565b6060614ff184846000856150bd565b949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561503057506000905060036150b4565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015615084573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166150ad576000600192509250506150b4565b9150600090505b94509492505050565b6060824710156151355760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610807565b600080866001600160a01b031685876040516151519190615d6a565b60006040518083038185875af1925050503d806000811461518e576040519150601f19603f3d011682016040523d82523d6000602084013e615193565b606091505b5091509150614b5b878383876060831561520e578251600003615207576001600160a01b0385163b6152075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610807565b5081614ff1565b614ff183838151156152235781518083602001fd5b8060405162461bcd60e51b81526004016108079190615d86565b60ff8116811461391357600080fd5b801515811461391357600080fd5b6000806040838503121561526d57600080fd5b82356152788161523d565b915060208301356152888161524c565b809150509250929050565b6000602082840312156152a557600080fd5b5035919050565b6001600160a01b038116811461391357600080fd5b80356152cc816152ac565b919050565b600080604083850312156152e457600080fd5b8235615278816152ac565b600080600080600060a0868803121561530757600080fd5b85356153128161523d565b97602087013597506040870135966060810135965060800135945092505050565b6000806040838503121561534657600080fd5b823591506020830135615288816152ac565b60008083601f84011261536a57600080fd5b50813567ffffffffffffffff81111561538257600080fd5b6020830191508360208260051b8501011115614e7657600080fd5b6000806000806000806000806000806101208b8d0312156153bd57600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135935060e08b013567ffffffffffffffff81111561540557600080fd5b6154118d828e01615358565b9094509250506101008b01356154268161524c565b809150509295989b9194979a5092959850565b60006020828403121561544b57600080fd5b8135613fd48161523d565b6000610100828403121561546957600080fd5b50919050565b600060c0828403121561546957600080fd5b6000806000806000610220868803121561549a57600080fd5b6154a48787615456565b9450610100860135935061012086013592506154c487610140880161546f565b91506102008601356154d5816152ac565b809150509295509295909350565b600080604083850312156154f657600080fd5b8235915060208301356152888161524c565b60008060006060848603121561551d57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561554757600080fd5b50508035926020909101359150565b60006020828403121561556857600080fd5b8135613fd4816152ac565b600060e0828403121561546957600080fd5b600080600080610200858703121561559c57600080fd5b6155a68686615456565b93506155b686610100870161546f565b92506101c08501356155c7816152ac565b91506101e085013567ffffffffffffffff8111156155e457600080fd5b6155f087828801615573565b91505092959194509250565b6000806040838503121561560f57600080fd5b82359150602083013567ffffffffffffffff81111561562d57600080fd5b61563985828601615573565b9150509250929050565b60006020828403121561565557600080fd5b8135613fd48161524c565b60008060006040848603121561567557600080fd5b83359250602084013567ffffffffffffffff81111561569357600080fd5b61569f86828701615358565b9497909650939450505050565b604051610180810167ffffffffffffffff811182821017156156f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b80516152cc8161524c565b80516152cc816152ac565b6000610180828403121561572657600080fd5b61572e6156ac565b8251815260208301516020820152615748604084016156fd565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015261578160e08401615708565b60e0820152610100838101519082015261012061579f818501615708565b908201526101406157b1848201615708565b908201526101606157c3848201615708565b908201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115614d4d57614d4d6157fd565b81516001600160a01b03168152610140810160208301516020830152604083015160408301526060830151615878606084018215159052565b506080830151608083015260a083015160a083015260c083015160c083015260e08301516158b160e08401826001600160a01b03169052565b50610100838101516001600160a01b03908116918401919091526101209384015116929091019190915290565b6000602082840312156158f057600080fd5b5051919050565b81810381811115614d4d57614d4d6157fd565b80358252602081013561591c816152ac565b6001600160a01b03908116602084015260408201359061593b826152ac565b9081166040840152606082013590615952826152ac565b16606083015260808101356159668161524c565b80151560808401525060a081013560a083015260c081013560c083015261598f60e082016152c1565b6001600160a01b03811660e0840152505050565b6101a081016159b2828961590a565b6101008201969096526101208101949094526101408401929092526101608301526001600160a01b031661018090910152919050565b8082028115828204841417614d4d57614d4d6157fd565b600082615a35577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215615a4c57600080fd5b8151613fd48161524c565b6000610240820190508882528760208301528660408301528560608301526001600160a01b03808616608084015280851660a084015250825160c0830152602083015160e08301526040830151610100615ab48185018315159052565b60608501516101208581019190915260808601516101408087019190915260a08701516101608088019190915260c088015161018088015260e08801516001600160a01b039081166101a0890152938801516101c08801529187015183166101e0870152860151821661020086015285015190811661022085015290505098975050505050505050565b600060208284031215615b5057600080fd5b8151613fd4816152ac565b600060208284031215615b6d57600080fd5b8151613fd48161523d565b60ff8281168282160390811115614d4d57614d4d6157fd565b600181815b80851115615bcc578160001904821115615bb257615bb26157fd565b80851615615bbf57918102915b93841c9390800290615b96565b509250929050565b600082615be357506001614d4d565b81615bf057506000614d4d565b8160018114615c065760028114615c1057615c2c565b6001915050614d4d565b60ff841115615c2157615c216157fd565b50506001821b614d4d565b5060208310610133831016604e8410600b8410161715615c4f575081810a614d4d565b615c598383615b91565b8060001904821115615c6d57615c6d6157fd565b029392505050565b6000613fd460ff841683615bd4565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615cb957600080fd5b83018035915067ffffffffffffffff821115615cd457600080fd5b602001915036819003821315614e7657600080fd5b60008060408385031215615cfc57600080fd5b8251615d07816152ac565b6020939093015192949293505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60005b83811015615d61578181015183820152602001615d49565b50506000910152565b60008251615d7c818460208701615d46565b9190910192915050565b6020815260008251806020840152615da5816040850160208701615d46565b601f01601f1916919091016040019291505056fea26469706673582212202b2a62f8219ea36e253da9c8c69f4392e5d52403d08b7632cf31638235d7a98464736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004e0bb7b156eb236260c18f98fb7f83f647f9c1dd0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f4000000000000000000000000a0304eced4926e7c1f49b1693c71fcbf6a498ff7000000000000000000000000b93e43c81ce6d23209932ff25e0953b1e4cd204300000000000000000000000018e285202856128c63add907650fc9cb4bcd44950000000000000000000000002349443d0cb8fab1e40cc6acd3c0eb25bc7abf7d
-----Decoded View---------------
Arg [0] : _tradeNFT (address): 0x4E0bb7b156eb236260C18F98fB7f83F647F9C1Dd
Arg [1] : _staking (address): 0x6E8BFBb31A46D0F5502426050Ea28b19F8E761f4
Arg [2] : _referrals (address): 0xA0304eCeD4926E7c1F49B1693c71Fcbf6A498Ff7
Arg [3] : _pairsContract (address): 0xB93e43C81CE6D23209932ff25E0953b1e4cd2043
Arg [4] : _trading (address): 0x18e285202856128C63AdD907650Fc9cB4Bcd4495
Arg [5] : _lpstaking (address): 0x2349443D0CB8FaB1E40cC6aCD3C0eB25bc7ABf7D
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000004e0bb7b156eb236260c18f98fb7f83f647f9c1dd
Arg [1] : 0000000000000000000000006e8bfbb31a46d0f5502426050ea28b19f8e761f4
Arg [2] : 000000000000000000000000a0304eced4926e7c1f49b1693c71fcbf6a498ff7
Arg [3] : 000000000000000000000000b93e43c81ce6d23209932ff25e0953b1e4cd2043
Arg [4] : 00000000000000000000000018e285202856128c63add907650fc9cb4bcd4495
Arg [5] : 0000000000000000000000002349443d0cb8fab1e40cc6acd3c0eb25bc7abf7d
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.