Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
Vault
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "../tokens/interfaces/IMintable.sol"; import "../tokens/interfaces/INSUSD.sol"; import "../tokens/interfaces/INSLP.sol"; import "./interfaces/IPositionVault.sol"; import "./interfaces/ILiquidateVault.sol"; import "./interfaces/IOrderVault.sol"; import "./interfaces/IPriceManager.sol"; import "./interfaces/ISettingsManager.sol"; import "./interfaces/IVault.sol"; import "./interfaces/IOperators.sol"; import {Constants} from "../access/Constants.sol"; import {Position, OrderStatus, OrderType} from "./structs.sol"; contract Vault is Constants, Initializable, ReentrancyGuardUpgradeable, IVault { using SafeERC20Upgradeable for IERC20Upgradeable; // constants IPositionVault private positionVault; IOrderVault private orderVault; ILiquidateVault private liquidateVault; IOperators public operators; IPriceManager private priceManager; ISettingsManager private settingsManager; address private nslp; address private nsusd; bool private isInitialized; // variables uint256 public totalUSD; mapping(address => uint256) public override lastStakedAt; IERC20Upgradeable private USDC; mapping(address => uint256) public lastStakedBlockAt; mapping(address => address) public platformUsed; // trader address => address of platform used event Deposit(address indexed account, address indexed token, uint256 amount); event Withdraw(address indexed account, address indexed token, uint256 amount); event Stake(address indexed account, address token, uint256 amount, uint256 mintAmount); event Unstake(address indexed account, address token, uint256 nslpAmount, uint256 amountOut); event ForceClose(uint256 indexed posId, address indexed account, uint256 exceededPnl); event ReferFeeTransfer(address indexed account, uint256 amount); event ReferFeeTraderRebate(address indexed account, uint256 amount, address indexed trader, uint256 rebate); event PlatformFeeTransfer(address indexed account, uint256 amount, address indexed trader); modifier onlyVault() { _onlyVault(); _; } function _onlyVault() private view { require( msg.sender == address(positionVault) || msg.sender == address(liquidateVault) || msg.sender == address(orderVault), "Only vault" ); } modifier preventBanners(address _account) { _preventBanners(_account); _; } function _preventBanners(address _account) private view { require(!settingsManager.checkBanList(_account), "Account banned"); } modifier onlyOperator(uint256 level) { _onlyOperator(level); _; } function _onlyOperator(uint256 level) private view { require(operators.getOperatorLevel(msg.sender) >= level, "invalid operator"); } /* ========== INITIALIZE FUNCTIONS ========== */ function initialize(address _operators, address _nslp, address _nsusd) public initializer { require(AddressUpgradeable.isContract(_operators), "operators invalid"); __ReentrancyGuard_init(); operators = IOperators(_operators); nslp = _nslp; nsusd = _nsusd; } function setVaultSettings( IPriceManager _priceManager, ISettingsManager _settingsManager, IPositionVault _positionVault, IOrderVault _orderVault, ILiquidateVault _liquidateVault ) external onlyOperator(4) { require(!isInitialized, "initialized"); require(AddressUpgradeable.isContract(address(_priceManager)), "priceManager invalid"); require(AddressUpgradeable.isContract(address(_settingsManager)), "settingsManager invalid"); require(AddressUpgradeable.isContract(address(_positionVault)), "positionVault invalid"); require(AddressUpgradeable.isContract(address(_orderVault)), "orderVault invalid"); require(AddressUpgradeable.isContract(address(_liquidateVault)), "liquidateVault invalid"); priceManager = _priceManager; settingsManager = _settingsManager; positionVault = _positionVault; orderVault = _orderVault; liquidateVault = _liquidateVault; isInitialized = true; } function setUSDC(IERC20Upgradeable _token) external onlyOperator(3) { USDC = _token; } /* ========== CORE FUNCTIONS ========== */ // deposit stablecoin to mint nsusd function deposit(address _account, address _token, uint256 _amount) public nonReentrant preventBanners(msg.sender) { require(settingsManager.isDeposit(_token), "deposit not allowed"); require(_amount > 0, "zero amount"); if (_account != msg.sender) { require(settingsManager.checkDelegation(_account, msg.sender), "Not allowed"); } IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); uint256 usdAmount = priceManager.tokenToUsd(_token, _amount); uint256 depositFee = (usdAmount * settingsManager.depositFee(_token)) / BASIS_POINTS_DIVISOR; _distributeFee(depositFee, address(0), address(0)); INSUSD(nsusd).mint(_account, usdAmount - depositFee); emit Deposit(_account, _token, _amount); } function depositSelf(address _token, uint256 _amount) external { deposit(msg.sender, _token, _amount); } function depositSelfUSDC(uint256 _amount) external { deposit(msg.sender, address(USDC), _amount); } function depositSelfAllUSDC() external { deposit(msg.sender, address(USDC), USDC.balanceOf(msg.sender)); } // burn nsusd to withdraw stablecoin function withdraw(address _token, uint256 _amount) public nonReentrant preventBanners(msg.sender) { require(settingsManager.isWithdraw(_token), "withdraw not allowed"); require(_amount > 0, "zero amount"); INSUSD(nsusd).burn(address(msg.sender), _amount); uint256 withdrawFee = (_amount * settingsManager.withdrawFee(_token)) / BASIS_POINTS_DIVISOR; _distributeFee(withdrawFee, address(0), address(0)); uint256 tokenAmount = priceManager.usdToToken(_token, _amount - withdrawFee); IERC20Upgradeable(_token).safeTransfer(msg.sender, tokenAmount); emit Withdraw(address(msg.sender), _token, tokenAmount); } function withdrawUSDC(uint256 _amount) external { withdraw(address(USDC), _amount); } function withdrawAllUSDC() external { withdraw(address(USDC), INSUSD(nsusd).balanceOf(msg.sender)); } // stake stablecoin to mint nslp function stake(address _account, address _token, uint256 _amount) public nonReentrant preventBanners(msg.sender) returns (uint256) { require(settingsManager.isStakingEnabled(_token), "staking disabled"); require(_amount > 0, "zero amount"); if (_account != msg.sender) require(settingsManager.checkDelegation(_account, msg.sender), "Not allowed"); IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); uint256 usdAmount = priceManager.tokenToUsd(_token, _amount); uint256 stakingFee = (usdAmount * settingsManager.stakingFee(_token)) / BASIS_POINTS_DIVISOR; uint256 usdAmountAfterFee = usdAmount - stakingFee; uint256 mintAmount; uint256 totalNSLP = IERC20Upgradeable(nslp).totalSupply(); if (totalNSLP == 0) { mintAmount = (usdAmountAfterFee * DEFAULT_NSLP_PRICE * (10 ** NSLP_DECIMALS)) / (PRICE_PRECISION * BASIS_POINTS_DIVISOR); } else { mintAmount = (usdAmountAfterFee * totalNSLP) / totalUSD; } require(totalNSLP + mintAmount <= settingsManager.maxTotalNslp(), "max total nslp exceeded"); _distributeFee(stakingFee, address(0), address(0)); totalUSD += usdAmountAfterFee; lastStakedAt[_account] = block.timestamp; IMintable(nslp).mint(_account, mintAmount); emit Stake(_account, _token, _amount, mintAmount); return mintAmount; } function stakeSelf(address _token, uint256 _amount) external { stake(msg.sender, _token, _amount); } function stakeSelfUSDC(uint256 _amount) external { stake(msg.sender, address(USDC), _amount); } function stakeSelfAllUSDC() external { stake(msg.sender, address(USDC), USDC.balanceOf(msg.sender)); } // burn nslp to unstake stablecoin // nslp cannot be unstaked or transferred within cooldown period, except whitelisted contracts function unstake(address _tokenOut, uint256 _nslpAmount) public returns (uint256) { return unstake(msg.sender, _tokenOut, _nslpAmount); } // burn nslp to unstake stablecoin // nslp cannot be unstaked or transferred within cooldown period, except whitelisted contracts function unstake(address _account, address _tokenOut, uint256 _nslpAmount) public nonReentrant preventBanners(msg.sender) returns (uint256) { require(settingsManager.isUnstakingEnabled(_tokenOut), "unstaking disabled"); uint256 totalNSLP = IERC20Upgradeable(nslp).totalSupply(); require(_nslpAmount > 0 && _nslpAmount <= totalNSLP, "nslpAmount error"); if (_account != msg.sender) require(settingsManager.checkDelegation(_account, msg.sender), "Not allowed"); if (settingsManager.isWhitelistedFromCooldown(_account) == false) { require( lastStakedAt[_account] + settingsManager.cooldownDuration() <= block.timestamp, "cooldown duration not yet passed" ); } IMintable(nslp).burn(_account, _nslpAmount); uint256 usdAmount = (_nslpAmount * totalUSD) / totalNSLP; uint256 unstakingFee = (usdAmount * settingsManager.unstakingFee(_tokenOut)) / BASIS_POINTS_DIVISOR; _distributeFee(unstakingFee, address(0), address(0)); totalUSD -= usdAmount; uint256 tokenAmountOut = priceManager.usdToToken(_tokenOut, usdAmount - unstakingFee); IERC20Upgradeable(_tokenOut).safeTransfer(_account, tokenAmountOut); emit Unstake(_account, _tokenOut, _nslpAmount, tokenAmountOut); return tokenAmountOut; } function unstakeUSDC(uint256 _nslpAmount) external { unstake(address(USDC), _nslpAmount); } function unstakeAllUSDC() external { unstake(address(USDC), IERC20Upgradeable(nslp).balanceOf(msg.sender)); } // submit order to create a new position function newPositionOrder( uint256 _tokenId, bool _isLong, OrderType _orderType, // 0 -> market order // 1 -> limit order // 2 -> stop-market order // 3 -> stop-limit order uint256[] memory _params, // for market order: _params[0] -> allowed price (revert if exceeded) // for limit order: _params[0] -> limit price // In stop-market order: _params[1] -> stop price, // In stop-limit order: _params[0] -> limit price, _params[1] -> stop price // for all orders: _params[2] -> collateral // for all orders: _params[3] -> size address _refer ) public payable nonReentrant preventBanners(msg.sender) { if (_orderType == OrderType.MARKET) { require(msg.value == settingsManager.marketOrderGasFee(), "invalid marketOrderGasFee"); } else { require(msg.value == settingsManager.triggerGasFee(), "invalid triggerGasFee"); } (bool success, ) = payable(settingsManager.feeManager()).call{value: msg.value}(""); require(success, "failed to send fee"); require(_refer != msg.sender, "Refer error"); positionVault.newPositionOrder(msg.sender, _tokenId, _isLong, _orderType, _params, _refer); } function newPositionOrderPacked(uint256 a, uint256 b, uint256 c) external payable { uint256 tokenId = a / 2 ** 240; //16 bits for tokenId uint256 tmp = (a % 2 ** 240) / 2 ** 232; bool isLong = tmp / 2 ** 7 == 1; // 1 bit for isLong OrderType orderType = OrderType(tmp % 2 ** 7); // 7 bits for orderType address refer = address(uint160(a)); //last 160 bit for refer uint256[] memory params = new uint256[](4); params[0] = b / 2 ** 128; //price params[1] = b % 2 ** 128; //price params[2] = c / 2 ** 128; //collateral params[3] = c % 2 ** 128; //size newPositionOrder(tokenId, isLong, orderType, params, refer); } // submit order to create a new position with take profit / stop loss orders function newPositionOrderWithTPSL( uint256 _tokenId, bool _isLong, OrderType _orderType, // 0 -> market order // 1 -> limit order // 2 -> stop-market order // 3 -> stop-limit order uint256[] memory _params, // for market order: _params[0] -> allowed price (revert if exceeded) // for limit order: _params[0] -> limit price // In stop-market order: _params[1] -> stop price, // In stop-limit order: _params[0] -> limit price, _params[1] -> stop price // for all orders: _params[2] -> collateral // for all orders: _params[3] -> size address _refer, bool[] memory _isTPs, uint256[] memory _prices, uint256[] memory _amountPercents ) external payable nonReentrant preventBanners(msg.sender) { if (_orderType == OrderType.MARKET) { require( msg.value == settingsManager.marketOrderGasFee() + _prices.length * settingsManager.triggerGasFee(), "invalid marketOrderGasFee" ); } else { require(msg.value == (_prices.length + 1) * settingsManager.triggerGasFee(), "invalid triggerGasFee"); } (bool success, ) = payable(settingsManager.feeManager()).call{value: msg.value}(""); require(success, "failed to send fee"); require(_refer != msg.sender, "Refer error"); positionVault.newPositionOrder(msg.sender, _tokenId, _isLong, _orderType, _params, _refer); orderVault.addTriggerOrders(positionVault.lastPosId() - 1, msg.sender, _isTPs, _prices, _amountPercents); } // submit market order to increase size of exisiting position function addPosition( uint256 _posId, uint256 _collateralDelta, uint256 _sizeDelta, uint256 _allowedPrice ) public payable nonReentrant preventBanners(msg.sender) { require(msg.value == settingsManager.marketOrderGasFee(), "invalid triggerGasFee"); (bool success, ) = payable(settingsManager.feeManager()).call{value: msg.value}(""); require(success, "failed to send fee"); positionVault.createAddPositionOrder(msg.sender, _posId, _collateralDelta, _sizeDelta, _allowedPrice); } function addPositionPacked(uint256 a, uint256 b) external payable { uint256 posId = a / 2 ** 128; uint256 collateralDelta = a % 2 ** 128; uint256 sizeDelta = b / 2 ** 128; uint256 allowedPrice = b % 2 ** 128; addPosition(posId, collateralDelta, sizeDelta, allowedPrice); } // add collateral to reduce leverage function addCollateral(uint256 _posId, uint256 _amount) public nonReentrant preventBanners(msg.sender) { positionVault.addOrRemoveCollateral(msg.sender, _posId, true, _amount); } // remove collateral to increase leverage function removeCollateral(uint256 _posId, uint256 _amount) public payable nonReentrant preventBanners(msg.sender) { require(msg.value == settingsManager.marketOrderGasFee(), "invalid triggerGasFee"); (bool success, ) = payable(settingsManager.feeManager()).call{value: msg.value}(""); require(success, "failed to send fee"); positionVault.addOrRemoveCollateral(msg.sender, _posId, false, _amount); } function addOrRemoveCollateralPacked(uint256 a) external { uint256 posId = a >> 128; bool isPlus = (a >> 127) % 2 == 1; uint256 amount = a % 2 ** 127; if (isPlus) { return addCollateral(posId, amount); } else { return removeCollateral(posId, amount); } } // submit market order to decrease size of exisiting position function decreasePosition( uint256 _sizeDelta, uint256 _allowedPrice, uint256 _posId ) public payable nonReentrant preventBanners(msg.sender) { require(msg.value == settingsManager.marketOrderGasFee(), "invalid marketOrderGasFee"); (bool success, ) = payable(settingsManager.feeManager()).call{value: msg.value}(""); require(success, "failed to send fee"); positionVault.createDecreasePositionOrder(_posId, msg.sender, _sizeDelta, _allowedPrice); } function decreasePositionPacked(uint256 a, uint256 _posId) external payable { uint256 sizeDelta = a / 2 ** 128; uint256 allowedPrice = a % 2 ** 128; return decreasePosition(sizeDelta, allowedPrice, _posId); } function addTPSL( uint256 _posId, bool[] memory _isTPs, uint256[] memory _prices, uint256[] memory _amountPercents ) public payable nonReentrant preventBanners(msg.sender) { require(msg.value == settingsManager.triggerGasFee() * _prices.length, "invalid triggerGasFee"); (bool success, ) = payable(settingsManager.feeManager()).call{value: msg.value}(""); require(success, "failed to send fee"); orderVault.addTriggerOrders(_posId, msg.sender, _isTPs, _prices, _amountPercents); } function addTPSLPacked(uint256 a, uint256[] calldata _tps) external payable { uint256 posId = a / 2 ** 128; uint256 length = _tps.length; bool[] memory isTPs = new bool[](length); uint256[] memory prices = new uint256[](length); uint256[] memory amountPercents = new uint256[](length); for (uint i; i < length; ++i) { prices[i] = _tps[i] / 2 ** 128; isTPs[i] = (_tps[i] / 2 ** 127) % 2 == 1; amountPercents[i] = _tps[i] % 2 ** 127; } addTPSL(posId, isTPs, prices, amountPercents); } // submit trailing stop order to decrease size of exisiting position function addTrailingStop( uint256 _posId, uint256[] memory _params ) external payable nonReentrant preventBanners(msg.sender) { require(msg.value == settingsManager.triggerGasFee(), "invalid triggerGasFee"); (bool success, ) = payable(settingsManager.feeManager()).call{value: msg.value}(""); require(success, "failed to send fee"); orderVault.addTrailingStop(msg.sender, _posId, _params); } // cancel pending newPositionOrder / trailingStopOrder function cancelPendingOrder(uint256 _posId) public nonReentrant preventBanners(msg.sender) { orderVault.cancelPendingOrder(msg.sender, _posId); } // cancel multiple pending newPositionOrder / trailingStopOrder function cancelPendingOrders(uint256[] memory _posIds) external preventBanners(msg.sender) { for (uint i = 0; i < _posIds.length; ++i) { orderVault.cancelPendingOrder(msg.sender, _posIds[i]); } } function setPlatformUsed(address _platform) external { platformUsed[msg.sender] = _platform; } /* ========== HELPER FUNCTIONS ========== */ // account trader's profit / loss into vault function accountDeltaIntoTotalUSD(bool _isIncrease, uint256 _delta) external override onlyVault { if (_delta > 0) { if (_isIncrease) { totalUSD += _delta; } else { require(totalUSD >= _delta, "exceeded NSLP bottom"); totalUSD -= _delta; } } } function distributeFee(uint256 _fee, address _refer, address _trader) external override onlyVault { _distributeFee(_fee, _refer, _trader); } // to distribute fee among referrer, vault and feeManager function _distributeFee(uint256 _fee, address _refer, address _trader) internal { if (_fee > 0) { if (_refer != address(0)) { (uint256 referFee, uint256 traderRebate) = settingsManager.getReferFeeAndTraderRebate(_refer); referFee = (_fee * referFee) / BASIS_POINTS_DIVISOR; traderRebate = (_fee * traderRebate) / BASIS_POINTS_DIVISOR; INSUSD(nsusd).mint(_refer, referFee); if (traderRebate > 0) INSUSD(nsusd).mint(_trader, traderRebate); _fee -= referFee + traderRebate; emit ReferFeeTraderRebate(_refer, referFee, _trader, traderRebate); } if (_trader != address(0)) { address platform = platformUsed[_trader]; uint256 platformFee = settingsManager.platformFees(platform); if (platformFee > 0) { platformFee = (_fee * platformFee) / BASIS_POINTS_DIVISOR; INSUSD(nsusd).mint(platform, platformFee); _fee -= platformFee; emit PlatformFeeTransfer(platform, platformFee, _trader); } } uint256 feeForNSLP = (_fee * settingsManager.feeRewardBasisPoints()) / BASIS_POINTS_DIVISOR; totalUSD += feeForNSLP; INSUSD(nsusd).mint(settingsManager.feeManager(), _fee - feeForNSLP); } } function takeNSUSDIn(address _account, uint256 _amount) external override onlyVault { INSUSD(nsusd).burn(_account, _amount); } function takeNSUSDOut(address _account, uint256 _amount) external override onlyVault { INSUSD(nsusd).mint(_account, _amount); } /* ========== OPERATOR FUNCTIONS ========== */ // allow admin to force close a user's position if the position profit > max profit % of totalUSD function forceClosePosition(uint256 _posId) external payable nonReentrant onlyOperator(1) { Position memory position = positionVault.getPosition(_posId); uint256 price = priceManager.getLastPrice(position.tokenId); (int256 pnl, , ) = settingsManager.getPnl( position.tokenId, position.isLong, position.size, position.averagePrice, price, position.lastIncreasedTime, position.accruedBorrowFee, position.fundingIndex ); uint256 _maxProfitPercent = settingsManager.maxProfitPercent(position.tokenId) == 0 ? settingsManager.defaultMaxProfitPercent() : settingsManager.maxProfitPercent(position.tokenId); uint256 maxPnl = (totalUSD * _maxProfitPercent) / BASIS_POINTS_DIVISOR; require(pnl > int256(maxPnl), "not allowed"); positionVault.decreasePosition(_posId, price, position.size); uint256 exceededPnl = uint256(pnl) - maxPnl; INSUSD(nsusd).burn(position.owner, exceededPnl); // cap user's pnl to maxPnl totalUSD += exceededPnl; // send pnl back to vault emit ForceClose(_posId, position.owner, exceededPnl); } /* ========== VIEW FUNCTIONS ========== */ function getNSLPPrice() external view returns (uint256) { uint256 totalNSLP = IERC20Upgradeable(nslp).totalSupply(); if (totalNSLP == 0) { return DEFAULT_NSLP_PRICE; } else { return (BASIS_POINTS_DIVISOR * (10 ** NSLP_DECIMALS) * totalUSD) / (totalNSLP * PRICE_PRECISION); } } function getVaultUSDBalance() external view override returns (uint256) { return totalUSD; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20PermitUpgradeable { /** * @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]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; import "../extensions/IERC20PermitUpgradeable.sol"; import "../../../utils/AddressUpgradeable.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 SafeERC20Upgradeable { using AddressUpgradeable for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20Upgradeable 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(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20PermitUpgradeable 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(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; import "./PythStructs.sol"; import "./IPythEvents.sol"; /// @title Consume prices from the Pyth Network (https://pyth.network/). /// @dev Please refer to the guidance at https://docs.pyth.network/documentation/pythnet-price-feeds/best-practices for how to consume prices safely. /// @author Pyth Data Association interface IPyth is IPythEvents { /// @notice Returns the period (in seconds) that a price feed is considered valid since its publish time function getValidTimePeriod() external view returns (uint validTimePeriod); /// @notice Returns the price and confidence interval. /// @dev Reverts if the price has not been updated within the last `getValidTimePeriod()` seconds. /// @param id The Pyth Price Feed ID of which to fetch the price and confidence interval. /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely. function getPrice( bytes32 id ) external view returns (PythStructs.Price memory price); /// @notice Returns the exponentially-weighted moving average price and confidence interval. /// @dev Reverts if the EMA price is not available. /// @param id The Pyth Price Feed ID of which to fetch the EMA price and confidence interval. /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely. function getEmaPrice( bytes32 id ) external view returns (PythStructs.Price memory price); /// @notice Returns the price of a price feed without any sanity checks. /// @dev This function returns the most recent price update in this contract without any recency checks. /// This function is unsafe as the returned price update may be arbitrarily far in the past. /// /// Users of this function should check the `publishTime` in the price to ensure that the returned price is /// sufficiently recent for their application. If you are considering using this function, it may be /// safer / easier to use either `getPrice` or `getPriceNoOlderThan`. /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely. function getPriceUnsafe( bytes32 id ) external view returns (PythStructs.Price memory price); /// @notice Returns the price that is no older than `age` seconds of the current time. /// @dev This function is a sanity-checked version of `getPriceUnsafe` which is useful in /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently /// recently. /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely. function getPriceNoOlderThan( bytes32 id, uint age ) external view returns (PythStructs.Price memory price); /// @notice Returns the exponentially-weighted moving average price of a price feed without any sanity checks. /// @dev This function returns the same price as `getEmaPrice` in the case where the price is available. /// However, if the price is not recent this function returns the latest available price. /// /// The returned price can be from arbitrarily far in the past; this function makes no guarantees that /// the returned price is recent or useful for any particular application. /// /// Users of this function should check the `publishTime` in the price to ensure that the returned price is /// sufficiently recent for their application. If you are considering using this function, it may be /// safer / easier to use either `getEmaPrice` or `getEmaPriceNoOlderThan`. /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely. function getEmaPriceUnsafe( bytes32 id ) external view returns (PythStructs.Price memory price); /// @notice Returns the exponentially-weighted moving average price that is no older than `age` seconds /// of the current time. /// @dev This function is a sanity-checked version of `getEmaPriceUnsafe` which is useful in /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently /// recently. /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely. function getEmaPriceNoOlderThan( bytes32 id, uint age ) external view returns (PythStructs.Price memory price); /// @notice Update price feeds with given update messages. /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling /// `getUpdateFee` with the length of the `updateData` array. /// Prices will be updated if they are more recent than the current stored prices. /// The call will succeed even if the update is not the most recent. /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid. /// @param updateData Array of price update data. function updatePriceFeeds(bytes[] calldata updateData) external payable; /// @notice Wrapper around updatePriceFeeds that rejects fast if a price update is not necessary. A price update is /// necessary if the current on-chain publishTime is older than the given publishTime. It relies solely on the /// given `publishTimes` for the price feeds and does not read the actual price update publish time within `updateData`. /// /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling /// `getUpdateFee` with the length of the `updateData` array. /// /// `priceIds` and `publishTimes` are two arrays with the same size that correspond to senders known publishTime /// of each priceId when calling this method. If all of price feeds within `priceIds` have updated and have /// a newer or equal publish time than the given publish time, it will reject the transaction to save gas. /// Otherwise, it calls updatePriceFeeds method to update the prices. /// /// @dev Reverts if update is not needed or the transferred fee is not sufficient or the updateData is invalid. /// @param updateData Array of price update data. /// @param priceIds Array of price ids. /// @param publishTimes Array of publishTimes. `publishTimes[i]` corresponds to known `publishTime` of `priceIds[i]` function updatePriceFeedsIfNecessary( bytes[] calldata updateData, bytes32[] calldata priceIds, uint64[] calldata publishTimes ) external payable; /// @notice Returns the required fee to update an array of price updates. /// @param updateData Array of price update data. /// @return feeAmount The required fee in Wei. function getUpdateFee( bytes[] calldata updateData ) external view returns (uint feeAmount); /// @notice Parse `updateData` and return price feeds of the given `priceIds` if they are all published /// within `minPublishTime` and `maxPublishTime`. /// /// You can use this method if you want to use a Pyth price at a fixed time and not the most recent price; /// otherwise, please consider using `updatePriceFeeds`. This method may store the price updates on-chain, if they /// are more recent than the current stored prices. /// /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling /// `getUpdateFee` with the length of the `updateData` array. /// /// /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is /// no update for any of the given `priceIds` within the given time range. /// @param updateData Array of price update data. /// @param priceIds Array of price ids. /// @param minPublishTime minimum acceptable publishTime for the given `priceIds`. /// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`. /// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order). function parsePriceFeedUpdates( bytes[] calldata updateData, bytes32[] calldata priceIds, uint64 minPublishTime, uint64 maxPublishTime ) external payable returns (PythStructs.PriceFeed[] memory priceFeeds); /// @notice Similar to `parsePriceFeedUpdates` but ensures the updates returned are /// the first updates published in minPublishTime. That is, if there are multiple updates for a given timestamp, /// this method will return the first update. This method may store the price updates on-chain, if they /// are more recent than the current stored prices. /// /// /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid or there is /// no update for any of the given `priceIds` within the given time range and uniqueness condition. /// @param updateData Array of price update data. /// @param priceIds Array of price ids. /// @param minPublishTime minimum acceptable publishTime for the given `priceIds`. /// @param maxPublishTime maximum acceptable publishTime for the given `priceIds`. /// @return priceFeeds Array of the price feeds corresponding to the given `priceIds` (with the same order). function parsePriceFeedUpdatesUnique( bytes[] calldata updateData, bytes32[] calldata priceIds, uint64 minPublishTime, uint64 maxPublishTime ) external payable returns (PythStructs.PriceFeed[] memory priceFeeds); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; /// @title IPythEvents contains the events that Pyth contract emits. /// @dev This interface can be used for listening to the updates for off-chain and testing purposes. interface IPythEvents { /// @dev Emitted when the price feed with `id` has received a fresh update. /// @param id The Pyth Price Feed ID. /// @param publishTime Publish time of the given price update. /// @param price Price of the given price update. /// @param conf Confidence interval of the given price update. event PriceFeedUpdate( bytes32 indexed id, uint64 publishTime, int64 price, uint64 conf ); /// @dev Emitted when a batch price update is processed successfully. /// @param chainId ID of the source chain that the batch price update comes from. /// @param sequenceNumber Sequence number of the batch price update. event BatchPriceFeedUpdate(uint16 chainId, uint64 sequenceNumber); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; contract PythStructs { // A price with a degree of uncertainty, represented as a price +- a confidence interval. // // The confidence interval roughly corresponds to the standard error of a normal distribution. // Both the price and confidence are stored in a fixed-point numeric representation, // `x * (10^expo)`, where `expo` is the exponent. // // Please refer to the documentation at https://docs.pyth.network/documentation/pythnet-price-feeds/best-practices for how // to how this price safely. struct Price { // Price int64 price; // Confidence interval around the price uint64 conf; // Price exponent int32 expo; // Unix timestamp describing when the price was published uint publishTime; } // PriceFeed represents a current aggregate price from pyth publisher feeds. struct PriceFeed { // The price ID. bytes32 id; // Latest available price Price price; // Latest available exponentially-weighted moving average price Price emaPrice; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; contract Constants { uint8 internal constant STAKING_PID_FOR_CHARGE_FEE = 1; uint256 internal constant BASIS_POINTS_DIVISOR = 100000; uint256 internal constant LIQUIDATE_THRESHOLD_DIVISOR = 10 * BASIS_POINTS_DIVISOR; uint256 internal constant DEFAULT_NSLP_PRICE = 100000; uint256 internal constant FUNDING_RATE_PRECISION = BASIS_POINTS_DIVISOR ** 3; // 1e15 uint256 internal constant MAX_DEPOSIT_WITHDRAW_FEE = 10000; // 10% uint256 internal constant MAX_DELTA_TIME = 24 hours; uint256 internal constant MAX_COOLDOWN_DURATION = 30 days; uint256 internal constant MAX_FEE_BASIS_POINTS = 5000; // 5% uint256 internal constant MAX_PRICE_MOVEMENT_PERCENT = 10000; // 10% uint256 internal constant MAX_BORROW_FEE_FACTOR = 500; // 0.5% per hour uint256 internal constant MAX_FUNDING_RATE = FUNDING_RATE_PRECISION / 10; // 10% per hour uint256 internal constant MAX_STAKING_UNSTAKING_FEE = 10000; // 10% uint256 internal constant MAX_EXPIRY_DURATION = 60; // 60 seconds uint256 internal constant MAX_SELF_EXECUTE_COOLDOWN = 300; // 5 minutes uint256 internal constant MAX_TOKENFARM_COOLDOWN_DURATION = 4 weeks; uint256 internal constant MAX_TRIGGER_GAS_FEE = 1e8 gwei; uint256 internal constant MAX_MARKET_ORDER_GAS_FEE = 1e8 gwei; uint256 internal constant MAX_VESTING_DURATION = 700 days; uint256 internal constant MIN_LEVERAGE = 10000; // 1x uint256 internal constant POSITION_MARKET = 0; uint256 internal constant POSITION_LIMIT = 1; uint256 internal constant POSITION_STOP_MARKET = 2; uint256 internal constant POSITION_STOP_LIMIT = 3; uint256 internal constant POSITION_TRAILING_STOP = 4; uint256 internal constant PRICE_PRECISION = 10 ** 30; uint256 internal constant TRAILING_STOP_TYPE_AMOUNT = 0; uint256 internal constant TRAILING_STOP_TYPE_PERCENT = 1; uint256 internal constant NSLP_DECIMALS = 18; function uintToBytes(uint v) internal pure returns (bytes32 ret) { if (v == 0) { ret = "0"; } else { while (v > 0) { ret = bytes32(uint(ret) / (2 ** 8)); ret |= bytes32(((v % 10) + 48) * 2 ** (8 * 31)); v /= 10; } } return ret; } function checkSlippage(bool isLong, uint256 allowedPrice, uint256 actualMarketPrice) internal pure { if (isLong) { require( actualMarketPrice <= allowedPrice, string( abi.encodePacked( "long: slippage exceeded ", uintToBytes(actualMarketPrice), " ", uintToBytes(allowedPrice) ) ) ); } else { require( actualMarketPrice >= allowedPrice, string( abi.encodePacked( "short: slippage exceeded ", uintToBytes(actualMarketPrice), " ", uintToBytes(allowedPrice) ) ) ); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import {Position, Order, OrderType} from "../structs.sol"; interface ILiquidateVault { function validateLiquidationWithPosid(uint256 _posId) external view returns (bool, int256, int256, int256); function liquidatePosition(uint256 _posId) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IOperators { function getOperatorLevel(address op) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import {Order, OrderType, OrderStatus, AddPositionOrder, DecreasePositionOrder, PositionTrigger} from "../structs.sol"; interface IOrderVault { function addTrailingStop(address _account, uint256 _posId, uint256[] memory _params) external; function addTriggerOrders( uint256 _posId, address _account, bool[] memory _isTPs, uint256[] memory _prices, uint256[] memory _amountPercents ) external; function cancelPendingOrder(address _account, uint256 _posId) external; function updateOrder( uint256 _posId, uint256 _positionType, uint256 _collateral, uint256 _size, OrderStatus _status ) external; function cancelMarketOrder(uint256 _posId) external; function createNewOrder( uint256 _posId, address _accout, bool _isLong, uint256 _tokenId, uint256 _positionType, uint256[] memory _params, address _refer ) external; function createAddPositionOrder( address _owner, uint256 _posId, uint256 _collateralDelta, uint256 _sizeDelta, uint256 _allowedPrice, uint256 _fee ) external; function createDecreasePositionOrder(uint256 _posId, uint256 _sizeDelta, uint256 _allowedPrice) external; function cancelAddPositionOrder(uint256 _posId) external; function deleteAddPositionOrder(uint256 _posId) external; function deleteDecreasePositionOrder(uint256 _posId) external; function getOrder(uint256 _posId) external view returns (Order memory); function getAddPositionOrder(uint256 _posId) external view returns (AddPositionOrder memory); function getDecreasePositionOrder(uint256 _posId) external view returns (DecreasePositionOrder memory); function getTriggerOrderInfo(uint256 _posId) external view returns (PositionTrigger memory); function triggerForOpenOrders(uint256 _posId) external; function triggerForTPSL(uint256 _posId) external; function updateTrailingStop(uint256 _posId) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import {Position, Order, OrderType, PaidFees} from "../structs.sol"; interface IPositionVault { function newPositionOrder( address _account, uint256 _tokenId, bool _isLong, OrderType _orderType, uint256[] memory _params, address _refer ) external; function addOrRemoveCollateral(address _account, uint256 _posId, bool isPlus, uint256 _amount) external; function createAddPositionOrder( address _account, uint256 _posId, uint256 _collateralDelta, uint256 _sizeDelta, uint256 _allowedPrice ) external; function createDecreasePositionOrder( uint256 _posId, address _account, uint256 _sizeDelta, uint256 _allowedPrice ) external; function increasePosition( uint256 _posId, address _account, uint256 _tokenId, bool _isLong, uint256 _price, uint256 _collateralDelta, uint256 _sizeDelta, uint256 _fee ) external; function decreasePosition(uint256 _posId, uint256 _price, uint256 _sizeDelta) external; function decreasePositionByOrderVault(uint256 _posId, uint256 _price, uint256 _sizeDelta) external; function removeUserAlivePosition(address _user, uint256 _posId) external; function removeUserOpenOrder(address _user, uint256 _posId) external; function lastPosId() external view returns (uint256); function queueIndex() external view returns (uint256); function getNumOfUnexecuted() external view returns (uint256); function queuePosIds(uint256 _id) external view returns (uint256); function getPosition(uint256 _posId) external view returns (Position memory); function getUserPositionIds(address _account) external view returns (uint256[] memory); function getUserOpenOrderIds(address _account) external view returns (uint256[] memory); function getPaidFees(uint256 _posId) external view returns (PaidFees memory); function getVaultUSDBalance() external view returns (uint256); function executeOrders(uint256 numOfOrders) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@pythnetwork/pyth-sdk-solidity/IPyth.sol"; interface IPriceManager { function assets(uint256 _assetId) external view returns ( string memory symbol, bytes32 pythId, uint256 price, uint256 timestamp, uint256 allowedStaleness, uint256 allowedDeviation, uint256 maxLeverage, uint256 tokenDecimals ); function getLastPrice(uint256 _tokenId) external view returns (uint256); function getPythLastPrice(uint256 _assetId, bool _requireFreshness) external view returns (uint256); function pyth() external view returns (IPyth); function maxLeverage(uint256 _tokenId) external view returns (uint256); function tokenToUsd(address _token, uint256 _tokenAmount) external view returns (uint256); function usdToToken(address _token, uint256 _usdAmount) external view returns (uint256); function setPrice(uint256 _assetId, uint256 _price, uint256 _ts) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface ISettingsManager { function decreaseOpenInterest(uint256 _tokenId, address _sender, bool _isLong, uint256 _amount) external; function increaseOpenInterest(uint256 _tokenId, address _sender, bool _isLong, uint256 _amount) external; function openInterestPerAssetPerSide(uint256 _tokenId, bool _isLong) external view returns (uint256); function openInterestPerUser(address _sender) external view returns (uint256); function bountyPercent() external view returns (uint32, uint32); function checkBanList(address _delegate) external view returns (bool); function checkDelegation(address _master, address _delegate) external view returns (bool); function minCollateral() external view returns (uint256); function closeDeltaTime() external view returns (uint256); function expiryDuration() external view returns (uint256); function selfExecuteCooldown() external view returns (uint256); function cooldownDuration() external view returns (uint256); function liquidationPendingTime() external view returns (uint256); function depositFee(address token) external view returns (uint256); function withdrawFee(address token) external view returns (uint256); function feeManager() external view returns (address); function feeRewardBasisPoints() external view returns (uint256); function defaultBorrowFeeFactor() external view returns (uint256); function borrowFeeFactor(uint256 tokenId) external view returns (uint256); function totalOpenInterest() external view returns (uint256); function basisFundingRateFactor() external view returns (uint256); function deductFeePercent(address _account) external view returns (uint256); function referrerTiers(address _referrer) external view returns (uint256); function tierFees(uint256 _tier) external view returns (uint256); function fundingIndex(uint256 _tokenId) external view returns (int256); function fundingRateFactor(uint256 _tokenId) external view returns (uint256); function slippageFactor(uint256 _tokenId) external view returns (uint256); function getFundingFee( uint256 _tokenId, bool _isLong, uint256 _size, int256 _fundingIndex ) external view returns (int256); function getFundingChange(uint256 _tokenId) external view returns (int256); function getBorrowRate(uint256 _tokenId, bool _isLong) external view returns (uint256); function getFundingRate(uint256 _tokenId) external view returns (int256); function getTradingFee( address _account, uint256 _tokenId, bool _isLong, uint256 _sizeDelta ) external view returns (uint256); function getPnl( uint256 _tokenId, bool _isLong, uint256 _size, uint256 _averagePrice, uint256 _lastPrice, uint256 _lastIncreasedTime, uint256 _accruedBorrowFee, int256 _fundingIndex ) external view returns (int256, int256, int256); function updateFunding(uint256 _tokenId) external; function getBorrowFee( uint256 _borrowedSize, uint256 _lastIncreasedTime, uint256 _tokenId, bool _isLong ) external view returns (uint256); function getUndiscountedTradingFee( uint256 _tokenId, bool _isLong, uint256 _sizeDelta ) external view returns (uint256); function getReferFee(address _refer) external view returns (uint256); function getReferFeeAndTraderRebate(address _refer) external view returns (uint256 referFee, uint256 traderRebate); function platformFees(address _platform) external view returns (uint256); function getPriceWithSlippage( uint256 _tokenId, bool _isLong, uint256 _size, uint256 _price ) external view returns (uint256); function getDelegates(address _master) external view returns (address[] memory); function isDeposit(address _token) external view returns (bool); function isStakingEnabled(address _token) external view returns (bool); function isUnstakingEnabled(address _token) external view returns (bool); function isIncreasingPositionDisabled(uint256 _tokenId) external view returns (bool); function isDecreasingPositionDisabled(uint256 _tokenId) external view returns (bool); function isWhitelistedFromCooldown(address _addr) external view returns (bool); function isWhitelistedFromTransferCooldown(address _addr) external view returns (bool); function isWithdraw(address _token) external view returns (bool); function lastFundingTimes(uint256 _tokenId) external view returns (uint256); function liquidateThreshold(uint256) external view returns (uint256); function tradingFee(uint256 _tokenId, bool _isLong) external view returns (uint256); function defaultMaxOpenInterestPerUser() external view returns (uint256); function maxProfitPercent(uint256 _tokenId) external view returns (uint256); function defaultMaxProfitPercent() external view returns (uint256); function maxOpenInterestPerAssetPerSide(uint256 _tokenId, bool _isLong) external view returns (uint256); function priceMovementPercent() external view returns (uint256); function maxOpenInterestPerUser(address _account) external view returns (uint256); function stakingFee(address token) external view returns (uint256); function unstakingFee(address token) external view returns (uint256); function triggerGasFee() external view returns (uint256); function marketOrderGasFee() external view returns (uint256); function maxTriggerPerPosition() external view returns (uint256); function maxFundingRate() external view returns (uint256); function maxTotalNslp() external view returns (uint256); function minProfitDurations(uint256 tokenId) external view returns (uint256); function maxCloseProfits(uint256 tokenId) external view returns (uint256); function maxCloseProfitPercents(uint256 tokenId) external view returns (uint256); function getTierInfo(address _account) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IVault { function accountDeltaIntoTotalUSD(bool _isIncrease, uint256 _delta) external; function distributeFee(uint256 _fee, address _refer, address _trader) external; function takeNSUSDIn(address _account, uint256 _amount) external; function takeNSUSDOut(address _account, uint256 _amount) external; function lastStakedAt(address _account) external view returns (uint256); function getVaultUSDBalance() external view returns (uint256); function getNSLPPrice() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; enum OrderType { MARKET, LIMIT, STOP, STOP_LIMIT } enum OrderStatus { NONE, PENDING, FILLED, CANCELED } enum TriggerStatus { NONE, PENDING, OPEN, TRIGGERED, CANCELLED } struct Order { OrderStatus status; uint256 lmtPrice; uint256 size; uint256 collateral; uint256 positionType; uint256 stepAmount; uint256 stepType; uint256 stpPrice; uint256 timestamp; } struct AddPositionOrder { address owner; uint256 collateral; uint256 size; uint256 allowedPrice; uint256 timestamp; uint256 fee; } struct DecreasePositionOrder { uint256 size; uint256 allowedPrice; uint256 timestamp; } struct Position { address owner; address refer; bool isLong; uint256 tokenId; uint256 averagePrice; uint256 collateral; int256 fundingIndex; uint256 lastIncreasedTime; uint256 size; uint256 accruedBorrowFee; } struct PaidFees { uint256 paidPositionFee; uint256 paidBorrowFee; int256 paidFundingFee; } struct Temp { uint256 a; uint256 b; uint256 c; uint256 d; uint256 e; } struct TriggerInfo { bool isTP; uint256 amountPercent; uint256 createdAt; uint256 price; uint256 triggeredAmount; uint256 triggeredAt; TriggerStatus status; } struct PositionTrigger { TriggerInfo[] triggers; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IMintable { function burn(address _account, uint256 _amount) external; function mint(address _account, uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface INSLP { function initialize(address _vault, address _settingsManager) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface INSUSD { function burn(address _account, uint256 _amount) external; function mint(address _account, uint256 _amount) external; function balanceOf(address _account) external view returns (uint256); }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"posId","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"exceededPnl","type":"uint256"}],"name":"ForceClose","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"trader","type":"address"}],"name":"PlatformFeeTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"uint256","name":"rebate","type":"uint256"}],"name":"ReferFeeTraderRebate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReferFeeTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"nslpAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"bool","name":"_isIncrease","type":"bool"},{"internalType":"uint256","name":"_delta","type":"uint256"}],"name":"accountDeltaIntoTotalUSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_posId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"addOrRemoveCollateralPacked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_posId","type":"uint256"},{"internalType":"uint256","name":"_collateralDelta","type":"uint256"},{"internalType":"uint256","name":"_sizeDelta","type":"uint256"},{"internalType":"uint256","name":"_allowedPrice","type":"uint256"}],"name":"addPosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"addPositionPacked","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_posId","type":"uint256"},{"internalType":"bool[]","name":"_isTPs","type":"bool[]"},{"internalType":"uint256[]","name":"_prices","type":"uint256[]"},{"internalType":"uint256[]","name":"_amountPercents","type":"uint256[]"}],"name":"addTPSL","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"_tps","type":"uint256[]"}],"name":"addTPSLPacked","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_posId","type":"uint256"},{"internalType":"uint256[]","name":"_params","type":"uint256[]"}],"name":"addTrailingStop","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_posId","type":"uint256"}],"name":"cancelPendingOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_posIds","type":"uint256[]"}],"name":"cancelPendingOrders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sizeDelta","type":"uint256"},{"internalType":"uint256","name":"_allowedPrice","type":"uint256"},{"internalType":"uint256","name":"_posId","type":"uint256"}],"name":"decreasePosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"_posId","type":"uint256"}],"name":"decreasePositionPacked","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositSelf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositSelfAllUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositSelfUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_refer","type":"address"},{"internalType":"address","name":"_trader","type":"address"}],"name":"distributeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_posId","type":"uint256"}],"name":"forceClosePosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getNSLPPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVaultUSDBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operators","type":"address"},{"internalType":"address","name":"_nslp","type":"address"},{"internalType":"address","name":"_nsusd","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastStakedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastStakedBlockAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_isLong","type":"bool"},{"internalType":"enum OrderType","name":"_orderType","type":"uint8"},{"internalType":"uint256[]","name":"_params","type":"uint256[]"},{"internalType":"address","name":"_refer","type":"address"}],"name":"newPositionOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"newPositionOrderPacked","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_isLong","type":"bool"},{"internalType":"enum OrderType","name":"_orderType","type":"uint8"},{"internalType":"uint256[]","name":"_params","type":"uint256[]"},{"internalType":"address","name":"_refer","type":"address"},{"internalType":"bool[]","name":"_isTPs","type":"bool[]"},{"internalType":"uint256[]","name":"_prices","type":"uint256[]"},{"internalType":"uint256[]","name":"_amountPercents","type":"uint256[]"}],"name":"newPositionOrderWithTPSL","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"operators","outputs":[{"internalType":"contract IOperators","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"platformUsed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_posId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"removeCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_platform","type":"address"}],"name":"setPlatformUsed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"_token","type":"address"}],"name":"setUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPriceManager","name":"_priceManager","type":"address"},{"internalType":"contract ISettingsManager","name":"_settingsManager","type":"address"},{"internalType":"contract IPositionVault","name":"_positionVault","type":"address"},{"internalType":"contract IOrderVault","name":"_orderVault","type":"address"},{"internalType":"contract ILiquidateVault","name":"_liquidateVault","type":"address"}],"name":"setVaultSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeSelf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeSelfAllUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeSelfUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"takeNSUSDIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"takeNSUSDOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_nslpAmount","type":"uint256"}],"name":"unstake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_nslpAmount","type":"uint256"}],"name":"unstake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unstakeAllUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nslpAmount","type":"uint256"}],"name":"unstakeUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAllUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061585580620000216000396000f3fe60806040526004361061027c5760003560e01c8063a8f35adf1161014f578063da36992a116100c1578063e673df8a1161007a578063e673df8a146106fd578063eb3188871461071d578063f10df24c14610767578063f11b54941461077c578063f3fef3a31461079c578063fe9ffb04146107bc57600080fd5b8063da36992a14610662578063db81f99b14610675578063dc509f6914610695578063df33dc16146106b5578063df83f611146106c8578063e616847f146106e857600080fd5b8063c2a672e011610113578063c2a672e0146105c7578063cabf4709146105e7578063cf7c7215146105fa578063cfdcdfc91461061a578063d66389b81461062f578063d6dac8ad1461064257600080fd5b8063a8f35adf14610527578063b3e089a214610547578063bdd056a614610567578063bf6eac2f14610587578063c0c53b8b146105a757600080fd5b8063444a91e0116101f3578063703914dc116101ac578063703914dc1461046f57806377a46edd146104845780637abadb59146104b15780638340f549146104d15780638b50fde7146104f1578063a3ae88a01461051157600080fd5b8063444a91e0146103d65780635543576a146103e957806359dfabd41461040957806360829f8a1461041c5780636a26c8861461043c5780636a9b18911461045c57600080fd5b80632bc61ec4116102455780632bc61ec41461033d5780632eaff8841461035057806333adf7241461036357806333eba70c1461037657806333f9c265146103895780633ee7b5b3146103b657600080fd5b80626c09e814610281578063061e56b5146102965780631cc75b88146102ba578063234653e0146102da57806326df6e9114610328575b600080fd5b61029461028f366004614cc8565b6107dc565b005b3480156102a257600080fd5b50603b545b6040519081526020015b60405180910390f35b3480156102c657600080fd5b506102946102d5366004614db1565b610cb3565b3480156102e657600080fd5b506103106102f5366004614ddd565b603f602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016102b1565b34801561033457600080fd5b50610294610cc2565b61029461034b366004614dfa565b610d48565b61029461035e366004614e13565b611294565b610294610371366004614e35565b6112c9565b610294610384366004614e67565b6114f1565b34801561039557600080fd5b506102a76103a4366004614ddd565b603e6020526000908152604090205481565b3480156103c257600080fd5b506102946103d1366004614dfa565b6116e5565b6102946103e4366004614e13565b6116fd565b3480156103f557600080fd5b50610294610404366004614dfa565b611759565b610294610417366004614ee6565b611771565b34801561042857600080fd5b506102a7610437366004614f78565b611958565b34801561044857600080fd5b50610294610457366004614dfa565b611f5a565b61029461046a366004614e13565b611f70565b34801561047b57600080fd5b50610294612191565b34801561049057600080fd5b506102a761049f366004614ddd565b603c6020526000908152604090205481565b3480156104bd57600080fd5b506102946104cc366004614fb9565b612216565b3480156104dd57600080fd5b506102946104ec366004614f78565b6122ab565b3480156104fd57600080fd5b5061029461050c366004614dfa565b612654565b34801561051d57600080fd5b506102a7603b5481565b34801561053357600080fd5b50610294610542366004614e13565b6126d4565b34801561055357600080fd5b50610294610562366004614ddd565b612762565b34801561057357600080fd5b50610294610582366004614dfa565b612790565b34801561059357600080fd5b506102a76105a2366004614f78565b6127d7565b3480156105b357600080fd5b506102946105c2366004614fd7565b612d88565b3480156105d357600080fd5b506102a76105e2366004614db1565b612f23565b6102946105f5366004615022565b612f39565b34801561060657600080fd5b50610294610615366004614db1565b613264565b34801561062657600080fd5b506102946132cc565b61029461063d3660046150a1565b613350565b34801561064e57600080fd5b5061029461065d3660046150e8565b613527565b61029461067036600461511d565b6135d0565b34801561068157600080fd5b50610294610690366004614dfa565b6137f0565b3480156106a157600080fd5b506102946106b0366004615149565b613806565b6102946106c336600461511d565b613a5d565b3480156106d457600080fd5b506102946106e33660046151ac565b613bb1565b3480156106f457600080fd5b50610294613bc4565b34801561070957600080fd5b50603654610310906001600160a01b031681565b34801561072957600080fd5b50610294610738366004614ddd565b336000908152603f6020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b34801561077357600080fd5b506102a7613c49565b34801561078857600080fd5b50610294610797366004614db1565b613d30565b3480156107a857600080fd5b506102946107b7366004614db1565b613d6a565b3480156107c857600080fd5b506102946107d7366004614db1565b614055565b6107e4614060565b336107ee816140ba565b6000876003811115610802576108026151d3565b141561095657603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561085657600080fd5b505afa15801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e91906151e9565b835161089a9190615218565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b1580156108e857600080fd5b505afa1580156108fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092091906151e9565b61092a9190615237565b34146109515760405162461bcd60e51b81526004016109489061524f565b60405180910390fd5b610a11565b603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109a457600080fd5b505afa1580156109b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dc91906151e9565b83516109e9906001615237565b6109f39190615218565b3414610a115760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b158015610a5657600080fd5b505afa158015610a6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8e91906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114610ad8576040519150601f19603f3d011682016040523d82523d6000602084013e610add565b606091505b5050905080610afe5760405162461bcd60e51b8152600401610948906152dd565b6001600160a01b038616331415610b455760405162461bcd60e51b815260206004820152600b60248201526a2932b332b91032b93937b960a91b6044820152606401610948565b6033546040516304abc43b60e11b81526001600160a01b0390911690630957887690610b7f9033908e908e908e908e908e90600401615344565b600060405180830381600087803b158015610b9957600080fd5b505af1158015610bad573d6000803e3d6000fd5b505060345460335460408051630df2cf1760e41b815290516001600160a01b03938416955063a1ccbf6494506001939092169163df2cf17091600480820192602092909190829003018186803b158015610c0657600080fd5b505afa158015610c1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3e91906151e9565b610c4891906153b1565b338888886040518663ffffffff1660e01b8152600401610c6c9594939291906153c8565b600060405180830381600087803b158015610c8657600080fd5b505af1158015610c9a573d6000803e3d6000fd5b505050505050610ca960018055565b5050505050505050565b610cbe3383836122ab565b5050565b603d54603a546040516370a0823160e01b8152336004820152610d46926001600160a01b039081169216906370a082319060240160206040518083038186803b158015610d0e57600080fd5b505afa158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b791906151e9565b565b610d50614060565b6001610d5b8161417b565b60335460405163eb02c30160e01b8152600481018490526000916001600160a01b03169063eb02c301906024016101406040518083038186803b158015610da157600080fd5b505afa158015610db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd9919061545c565b60375460608201516040516365fa2f7f60e01b81529293506000926001600160a01b03909216916365fa2f7f91610e169160040190815260200190565b60206040518083038186803b158015610e2e57600080fd5b505afa158015610e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6691906151e9565b6038546060840151604080860151610100870151608088015160e08901516101208a015160c08b0151955163d136545b60e01b815260048101979097529315156024870152604486019290925260648501526084840186905260a484015260c483015260e48201529192506000916001600160a01b039091169063d136545b906101040160606040518083038186803b158015610f0257600080fd5b505afa158015610f16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3a91906154f8565b5050603854606085015160405163307726ef60e01b81529293506000926001600160a01b039092169163307726ef91610f799160040190815260200190565b60206040518083038186803b158015610f9157600080fd5b505afa158015610fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc991906151e9565b1561105a57603854606085015160405163307726ef60e01b81526001600160a01b039092169163307726ef916110059160040190815260200190565b60206040518083038186803b15801561101d57600080fd5b505afa158015611031573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105591906151e9565b6110e0565b603860009054906101000a90046001600160a01b03166001600160a01b0316631c8444d06040518163ffffffff1660e01b815260040160206040518083038186803b1580156110a857600080fd5b505afa1580156110bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e091906151e9565b90506000620186a082603b546110f69190615218565b611100919061553c565b905080831361113f5760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b6044820152606401610948565b603354610100860151604051636d1b4c9560e11b8152600481018a90526024810187905260448101919091526001600160a01b039091169063da36992a90606401600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b50505050600081846111c091906153b1565b603a548751604051632770a7eb60e21b81529293506001600160a01b0390911691639dc29fac916111f5918590600401615550565b600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b5050505080603b60008282546112399190615237565b909155505085516040518281526001600160a01b039091169089907f7e3ad6234556318d663482d0da4392a6898037f43df2a506bc602357af1ff59a9060200160405180910390a35050505050505061129160018055565b50565b60006112a4600160801b8461553c565b905060006112b6600160801b85615569565b90506112c38282856135d0565b50505050565b6112d1614060565b336112db816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b15801561132957600080fd5b505afa15801561133d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136191906151e9565b341461137f5760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b1580156113c457600080fd5b505afa1580156113d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fc91906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114611446576040519150601f19603f3d011682016040523d82523d6000602084013e61144b565b606091505b505090508061146c5760405162461bcd60e51b8152600401610948906152dd565b6033546040516329e05f7560e21b8152336004820152602481018890526044810187905260648101869052608481018590526001600160a01b039091169063a7817dd49060a4015b600060405180830381600087803b1580156114ce57600080fd5b505af11580156114e2573d6000803e3d6000fd5b5050505050506112c360018055565b6000611501600160801b8561553c565b90508160008167ffffffffffffffff81111561151f5761151f614b44565b604051908082528060200260200182016040528015611548578160200160208202803683370190505b50905060008267ffffffffffffffff81111561156657611566614b44565b60405190808252806020026020018201604052801561158f578160200160208202803683370190505b50905060008367ffffffffffffffff8111156115ad576115ad614b44565b6040519080825280602002602001820160405280156115d6578160200160208202803683370190505b50905060005b848110156116d857600160801b8888838181106115fb576115fb61557d565b9050602002013561160c919061553c565b83828151811061161e5761161e61557d565b60200260200101818152505060026001607f1b8989848181106116435761164361557d565b90506020020135611654919061553c565b61165e9190615569565b6001148482815181106116735761167361557d565b911515602092830291909101909101526001607f1b88888381811061169a5761169a61557d565b905060200201356116ab9190615569565b8282815181106116bd576116bd61557d565b60209081029190910101526116d181615593565b90506115dc565b50610ca985848484611771565b603d54610cbe9033906001600160a01b0316836127d7565b600061170d600160801b8461553c565b9050600061171f600160801b85615569565b90506000611731600160801b8561553c565b90506000611743600160801b86615569565b9050611751848484846112c9565b505050505050565b603d546112919033906001600160a01b0316836122ab565b611779614060565b33611783816140ba565b8251603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117d357600080fd5b505afa1580156117e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180b91906151e9565b6118159190615218565b34146118335760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b15801561187857600080fd5b505afa15801561188c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b091906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d80600081146118fa576040519150601f19603f3d011682016040523d82523d6000602084013e6118ff565b606091505b50509050806119205760405162461bcd60e51b8152600401610948906152dd565b6034546040516328732fd960e21b81526001600160a01b039091169063a1ccbf64906114b490899033908a908a908a906004016153c8565b6000611962614060565b3361196c816140ba565b603854604051632e79aba560e01b81526001600160a01b03868116600483015290911690632e79aba59060240160206040518083038186803b1580156119b157600080fd5b505afa1580156119c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e991906155ae565b611a2a5760405162461bcd60e51b81526020600482015260126024820152711d5b9cdd185ada5b99c8191a5cd8589b195960721b6044820152606401610948565b603954604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611a6f57600080fd5b505afa158015611a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa791906151e9565b9050600084118015611ab95750808411155b611af85760405162461bcd60e51b815260206004820152601060248201526f3739b63820b6b7bab73a1032b93937b960811b6044820152606401610948565b6001600160a01b0386163314611ba757603854604051630519e01b60e41b81526001600160a01b0388811660048301523360248301529091169063519e01b09060440160206040518083038186803b158015611b5357600080fd5b505afa158015611b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8b91906155ae565b611ba75760405162461bcd60e51b8152600401610948906155cb565b60385460405163cb28bbeb60e01b81526001600160a01b0388811660048301529091169063cb28bbeb9060240160206040518083038186803b158015611bec57600080fd5b505afa158015611c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2491906155ae565b611d155760385460408051633526931560e01b8152905142926001600160a01b0316916335269315916004808301926020929190829003018186803b158015611c6c57600080fd5b505afa158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca491906151e9565b6001600160a01b0388166000908152603c6020526040902054611cc79190615237565b1115611d155760405162461bcd60e51b815260206004820181905260248201527f636f6f6c646f776e206475726174696f6e206e6f7420796574207061737365646044820152606401610948565b603954604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90611d479089908890600401615550565b600060405180830381600087803b158015611d6157600080fd5b505af1158015611d75573d6000803e3d6000fd5b50505050600081603b5486611d8a9190615218565b611d94919061553c565b603854604051638113dba560e01b81526001600160a01b038981166004830152929350600092620186a0921690638113dba59060240160206040518083038186803b158015611de257600080fd5b505afa158015611df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1a91906151e9565b611e249084615218565b611e2e919061553c565b9050611e3c81600080614237565b81603b6000828254611e4e91906153b1565b90915550506037546000906001600160a01b03166368ce13d689611e7285876153b1565b6040518363ffffffff1660e01b8152600401611e8f929190615550565b60206040518083038186803b158015611ea757600080fd5b505afa158015611ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edf91906151e9565b9050611ef56001600160a01b0389168a83614760565b604080516001600160a01b038a81168252602082018a9052918101839052908a16907f18edd09e80386cd99df397e2e0d87d2bb259423eae08645e776321a36fe680ef9060600160405180910390a2945050505050611f5360018055565b9392505050565b603d54610cbe906001600160a01b031682612f23565b611f78614060565b33611f82816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b158015611fd057600080fd5b505afa158015611fe4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200891906151e9565b34146120265760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b15801561206b57600080fd5b505afa15801561207f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a391906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d80600081146120ed576040519150601f19603f3d011682016040523d82523d6000602084013e6120f2565b606091505b50509050806121135760405162461bcd60e51b8152600401610948906152dd565b603354604051633f832a5f60e21b81523360048201526024810186905260006044820152606481018590526001600160a01b039091169063fe0ca97c906084015b600060405180830381600087803b15801561216e57600080fd5b505af1158015612182573d6000803e3d6000fd5b505050505050610cbe60018055565b603d546040516370a0823160e01b81523360048201819052610d469290916001600160a01b039091169081906370a082319060240160206040518083038186803b1580156121de57600080fd5b505afa1580156121f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ec91906151e9565b61221e6147b6565b8015610cbe5781156122475780603b600082825461223c9190615237565b90915550610cbe9050565b80603b5410156122905760405162461bcd60e51b81526020600482015260146024820152736578636565646564204e534c5020626f74746f6d60601b6044820152606401610948565b80603b60008282546122a291906153b1565b90915550505050565b6122b3614060565b336122bd816140ba565b60385460405163f690a3a360e01b81526001600160a01b0385811660048301529091169063f690a3a39060240160206040518083038186803b15801561230257600080fd5b505afa158015612316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233a91906155ae565b61237c5760405162461bcd60e51b815260206004820152601360248201527219195c1bdcda5d081b9bdd08185b1b1bddd959606a1b6044820152606401610948565b6000821161239c5760405162461bcd60e51b8152600401610948906155f0565b6001600160a01b038416331461244b57603854604051630519e01b60e41b81526001600160a01b0386811660048301523360248301529091169063519e01b09060440160206040518083038186803b1580156123f757600080fd5b505afa15801561240b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242f91906155ae565b61244b5760405162461bcd60e51b8152600401610948906155cb565b6124606001600160a01b038416333085614827565b6037546040516317a3625360e31b81526000916001600160a01b03169063bd1b1298906124939087908790600401615550565b60206040518083038186803b1580156124ab57600080fd5b505afa1580156124bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e391906151e9565b6038546040516380352cfd60e01b81526001600160a01b038781166004830152929350600092620186a09216906380352cfd9060240160206040518083038186803b15801561253157600080fd5b505afa158015612545573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256991906151e9565b6125739084615218565b61257d919061553c565b905061258b81600080614237565b603a546001600160a01b03166340c10f19876125a784866153b1565b6040518363ffffffff1660e01b81526004016125c4929190615550565b600060405180830381600087803b1580156125de57600080fd5b505af11580156125f2573d6000803e3d6000fd5b50505050846001600160a01b0316866001600160a01b03167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f628660405161263b91815260200190565b60405180910390a350505061264f60018055565b505050565b61265c614060565b33612666816140ba565b6034546040516303d8dd0d60e61b81526001600160a01b039091169063f6374340906126989033908690600401615550565b600060405180830381600087803b1580156126b257600080fd5b505af11580156126c6573d6000803e3d6000fd5b505050505061129160018055565b6126dc614060565b336126e6816140ba565b603354604051633f832a5f60e21b81523360048201526024810185905260016044820152606481018490526001600160a01b039091169063fe0ca97c90608401600060405180830381600087803b15801561274057600080fd5b505af1158015612754573d6000803e3d6000fd5b5050505050610cbe60018055565b600361276d8161417b565b50603d80546001600160a01b0319166001600160a01b0392909216919091179055565b608081901c60006127a66002607f85901c615569565b600114905060006127bb6001607f1b85615569565b905081156127cd576112c383826126d4565b6112c38382611f70565b60006127e1614060565b336127eb816140ba565b60385460405163e0c7845560e01b81526001600160a01b0386811660048301529091169063e0c784559060240160206040518083038186803b15801561283057600080fd5b505afa158015612844573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286891906155ae565b6128a75760405162461bcd60e51b815260206004820152601060248201526f1cdd185ada5b99c8191a5cd8589b195960821b6044820152606401610948565b600083116128c75760405162461bcd60e51b8152600401610948906155f0565b6001600160a01b038516331461297657603854604051630519e01b60e41b81526001600160a01b0387811660048301523360248301529091169063519e01b09060440160206040518083038186803b15801561292257600080fd5b505afa158015612936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295a91906155ae565b6129765760405162461bcd60e51b8152600401610948906155cb565b61298b6001600160a01b038516333086614827565b6037546040516317a3625360e31b81526000916001600160a01b03169063bd1b1298906129be9088908890600401615550565b60206040518083038186803b1580156129d657600080fd5b505afa1580156129ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0e91906151e9565b6038546040516385a848ff60e01b81526001600160a01b038881166004830152929350600092620186a09216906385a848ff9060240160206040518083038186803b158015612a5c57600080fd5b505afa158015612a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9491906151e9565b612a9e9084615218565b612aa8919061553c565b90506000612ab682846153b1565b9050600080603960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b0957600080fd5b505afa158015612b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4191906151e9565b905080612b9657612b62620186a06c0c9f2c9cd04674edea40000000615218565b612b6e6012600a6156f9565b612b7b620186a086615218565b612b859190615218565b612b8f919061553c565b9150612bb0565b603b54612ba38285615218565b612bad919061553c565b91505b603860009054906101000a90046001600160a01b03166001600160a01b031663cdbde18f6040518163ffffffff1660e01b815260040160206040518083038186803b158015612bfe57600080fd5b505afa158015612c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3691906151e9565b612c408383615237565b1115612c8e5760405162461bcd60e51b815260206004820152601760248201527f6d617820746f74616c206e736c702065786365656465640000000000000000006044820152606401610948565b612c9a84600080614237565b82603b6000828254612cac9190615237565b90915550506001600160a01b03808b166000908152603c60205260409081902042905560395490516340c10f1960e01b81529116906340c10f1990612cf7908d908690600401615550565b600060405180830381600087803b158015612d1157600080fd5b505af1158015612d25573d6000803e3d6000fd5b5050604080516001600160a01b038d81168252602082018d9052918101869052908d1692507f63602d0ecc7b3a0ef7ff1a116e23056662d64280355ba8031b6d0d767c4b4458915060600160405180910390a250945050505050611f5360018055565b600054610100900460ff1615808015612da85750600054600160ff909116105b80612dc25750303b158015612dc2575060005460ff166001145b612e255760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610948565b6000805460ff191660011790558015612e48576000805461ff0019166101001790555b6001600160a01b0384163b612e935760405162461bcd60e51b81526020600482015260116024820152701bdc195c985d1bdc9cc81a5b9d985b1a59607a1b6044820152606401610948565b612e9b61485f565b603680546001600160a01b038087166001600160a01b03199283161790925560398054868416908316179055603a80549285169290911691909117905580156112c3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6000612f30338484611958565b90505b92915050565b612f41614060565b33612f4b816140ba565b6000846003811115612f5f57612f5f6151d3565b141561300e57603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b158015612fb357600080fd5b505afa158015612fc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612feb91906151e9565b34146130095760405162461bcd60e51b81526004016109489061524f565b6130b2565b603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561305c57600080fd5b505afa158015613070573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309491906151e9565b34146130b25760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b1580156130f757600080fd5b505afa15801561310b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312f91906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114613179576040519150601f19603f3d011682016040523d82523d6000602084013e61317e565b606091505b505090508061319f5760405162461bcd60e51b8152600401610948906152dd565b6001600160a01b0383163314156131e65760405162461bcd60e51b815260206004820152600b60248201526a2932b332b91032b93937b960a91b6044820152606401610948565b6033546040516304abc43b60e11b81526001600160a01b03909116906309578876906132209033908b908b908b908b908b90600401615344565b600060405180830381600087803b15801561323a57600080fd5b505af115801561324e573d6000803e3d6000fd5b50505050505061325d60018055565b5050505050565b61326c6147b6565b603a546040516340c10f1960e01b81526001600160a01b03909116906340c10f199061329e9085908590600401615550565b600060405180830381600087803b1580156132b857600080fd5b505af1158015611751573d6000803e3d6000fd5b603d546039546040516370a0823160e01b8152336004820152611291926001600160a01b039081169216906370a082319060240160206040518083038186803b15801561331857600080fd5b505afa15801561332c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e291906151e9565b613358614060565b33613362816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133b057600080fd5b505afa1580156133c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133e891906151e9565b34146134065760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b15801561344b57600080fd5b505afa15801561345f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348391906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d80600081146134cd576040519150601f19603f3d011682016040523d82523d6000602084013e6134d2565b606091505b50509050806134f35760405162461bcd60e51b8152600401610948906152dd565b60345460405163860a19f160e01b81526001600160a01b039091169063860a19f19061215490339088908890600401615705565b33613531816140ba565b60005b825181101561264f5760345483516001600160a01b039091169063f63743409033908690859081106135685761356861557d565b60200260200101516040518363ffffffff1660e01b815260040161358d929190615550565b600060405180830381600087803b1580156135a757600080fd5b505af11580156135bb573d6000803e3d6000fd5b50505050806135c990615593565b9050613534565b6135d8614060565b336135e2816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b15801561363057600080fd5b505afa158015613644573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061366891906151e9565b34146136865760405162461bcd60e51b81526004016109489061524f565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b1580156136cb57600080fd5b505afa1580156136df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370391906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d806000811461374d576040519150601f19603f3d011682016040523d82523d6000602084013e613752565b606091505b50509050806137735760405162461bcd60e51b8152600401610948906152dd565b6033546040516329f054e360e11b81526004810185905233602482015260448101879052606481018690526001600160a01b03909116906353e0a9c690608401600060405180830381600087803b1580156137cd57600080fd5b505af11580156137e1573d6000803e3d6000fd5b50505050505061264f60018055565b603d54611291906001600160a01b031682613d6a565b60046138118161417b565b603a54600160a01b900460ff16156138595760405162461bcd60e51b815260206004820152600b60248201526a1a5b9a5d1a585b1a5e995960aa1b6044820152606401610948565b6001600160a01b0386163b6138a75760405162461bcd60e51b81526020600482015260146024820152731c1c9a58d953585b9859d95c881a5b9d985b1a5960621b6044820152606401610948565b6001600160a01b0385163b6138fe5760405162461bcd60e51b815260206004820152601760248201527f73657474696e67734d616e6167657220696e76616c69640000000000000000006044820152606401610948565b6001600160a01b0384163b61394d5760405162461bcd60e51b81526020600482015260156024820152741c1bdcda5d1a5bdb95985d5b1d081a5b9d985b1a59605a1b6044820152606401610948565b6001600160a01b0383163b6139995760405162461bcd60e51b81526020600482015260126024820152711bdc99195c95985d5b1d081a5b9d985b1a5960721b6044820152606401610948565b6001600160a01b0382163b6139e95760405162461bcd60e51b81526020600482015260166024820152751b1a5c5d5a59185d1955985d5b1d081a5b9d985b1a5960521b6044820152606401610948565b50603780546001600160a01b039687166001600160a01b031991821617909155603880549587169582169590951790945560338054938616938516939093179092556034805491851691841691909117905560358054919093169116179055603a805460ff60a01b1916600160a01b179055565b6000613a6d600160f01b8561553c565b90506000600160e81b613a84600160f01b87615569565b613a8e919061553c565b90506000613a9d60808361553c565b60011490506000613aaf608084615569565b6003811115613ac057613ac06151d3565b60408051600480825260a08201909252919250889160009160208201608080368337019050509050613af6600160801b8961553c565b81600081518110613b0957613b0961557d565b6020908102919091010152613b22600160801b89615569565b81600181518110613b3557613b3561557d565b6020908102919091010152613b4e600160801b8861553c565b81600281518110613b6157613b6161557d565b6020908102919091010152613b7a600160801b88615569565b81600381518110613b8d57613b8d61557d565b602002602001018181525050613ba68685858486612f39565b505050505050505050565b613bb96147b6565b61264f838383614237565b603d546040516370a0823160e01b815233600482018190526112919290916001600160a01b039091169081906370a082319060240160206040518083038186803b158015613c1157600080fd5b505afa158015613c25573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a291906151e9565b600080603960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c9a57600080fd5b505afa158015613cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd291906151e9565b905080613ce357620186a091505090565b613cfa6c0c9f2c9cd04674edea4000000082615218565b603b54613d096012600a6156f9565b613d1690620186a0615218565b613d209190615218565b613d2a919061553c565b91505090565b613d386147b6565b603a54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac9061329e9085908590600401615550565b613d72614060565b33613d7c816140ba565b603854604051633394ce3b60e21b81526001600160a01b0385811660048301529091169063ce5338ec9060240160206040518083038186803b158015613dc157600080fd5b505afa158015613dd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613df991906155ae565b613e3c5760405162461bcd60e51b81526020600482015260146024820152731dda5d1a191c985dc81b9bdd08185b1b1bddd95960621b6044820152606401610948565b60008211613e5c5760405162461bcd60e51b8152600401610948906155f0565b603a54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90613e8e9033908690600401615550565b600060405180830381600087803b158015613ea857600080fd5b505af1158015613ebc573d6000803e3d6000fd5b5050603854604051631ac3ddeb60e01b81526001600160a01b03878116600483015260009450620186a0935090911690631ac3ddeb9060240160206040518083038186803b158015613f0d57600080fd5b505afa158015613f21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4591906151e9565b613f4f9085615218565b613f59919061553c565b9050613f6781600080614237565b6037546000906001600160a01b03166368ce13d686613f8685886153b1565b6040518363ffffffff1660e01b8152600401613fa3929190615550565b60206040518083038186803b158015613fbb57600080fd5b505afa158015613fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ff391906151e9565b90506140096001600160a01b0386163383614760565b6040518181526001600160a01b0386169033907f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060200160405180910390a3505050610cbe60018055565b61264f3383836127d7565b600260015414156140b35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610948565b6002600155565b60385460405163a9b9e38960e01b81526001600160a01b0383811660048301529091169063a9b9e3899060240160206040518083038186803b1580156140ff57600080fd5b505afa158015614113573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061413791906155ae565b156112915760405162461bcd60e51b815260206004820152600e60248201526d1058d8dbdd5b9d0818985b9b995960921b6044820152606401610948565b60018055565b60365460405163df07560560e01b815233600482015282916001600160a01b03169063df0756059060240160206040518083038186803b1580156141be57600080fd5b505afa1580156141d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f691906151e9565b10156112915760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b21037b832b930ba37b960811b6044820152606401610948565b821561264f576001600160a01b038216156144455760385460405163594ca01560e01b81526001600160a01b038481166004830152600092839291169063594ca01590602401604080518083038186803b15801561429457600080fd5b505afa1580156142a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142cc9190615735565b9092509050620186a06142df8387615218565b6142e9919061553c565b9150620186a06142f98287615218565b614303919061553c565b603a546040516340c10f1960e01b81529192506001600160a01b0316906340c10f19906143369087908690600401615550565b600060405180830381600087803b15801561435057600080fd5b505af1158015614364573d6000803e3d6000fd5b5050505060008111156143d657603a546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906143a39086908590600401615550565b600060405180830381600087803b1580156143bd57600080fd5b505af11580156143d1573d6000803e3d6000fd5b505050505b6143e08183615237565b6143ea90866153b1565b9450826001600160a01b0316846001600160a01b03167f2210da9c25406cac50a7846052db53d49ec84390f83867c61e4091ac87ec9397848460405161443a929190918252602082015260400190565b60405180910390a350505b6001600160a01b038116156145cb576001600160a01b038181166000908152603f60205260408082205460385491516319745e3960e11b8152908416600482018190529391909116906332e8bc729060240160206040518083038186803b1580156144af57600080fd5b505afa1580156144c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144e791906151e9565b905080156145c857620186a06144fd8287615218565b614507919061553c565b603a546040516340c10f1960e01b81529192506001600160a01b0316906340c10f199061453a9085908590600401615550565b600060405180830381600087803b15801561455457600080fd5b505af1158015614568573d6000803e3d6000fd5b50505050808561457891906153b1565b9450826001600160a01b0316826001600160a01b03167fa9d92ab9f19faecc65e4b397da6701d094f08143f98b735b7cd6332184bec0f1836040516145bf91815260200190565b60405180910390a35b50505b6000620186a0603860009054906101000a90046001600160a01b03166001600160a01b031663018f2d826040518163ffffffff1660e01b815260040160206040518083038186803b15801561461f57600080fd5b505afa158015614633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061465791906151e9565b6146619086615218565b61466b919061553c565b905080603b600082825461467f9190615237565b9091555050603a546038546040805163d0fb020360e01b815290516001600160a01b03938416936340c10f1993169163d0fb0203916004808301926020929190829003018186803b1580156146d357600080fd5b505afa1580156146e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061470b91906152c0565b61471584886153b1565b6040518363ffffffff1660e01b8152600401614732929190615550565b600060405180830381600087803b15801561474c57600080fd5b505af1158015610ca9573d6000803e3d6000fd5b61264f8363a9059cbb60e01b848460405160240161477f929190615550565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261488e565b6033546001600160a01b03163314806147d957506035546001600160a01b031633145b806147ee57506034546001600160a01b031633145b610d465760405162461bcd60e51b815260206004820152600a60248201526913db9b1e481d985d5b1d60b21b6044820152606401610948565b6040516001600160a01b03808516602483015283166044820152606481018290526112c39085906323b872dd60e01b9060840161477f565b600054610100900460ff166148865760405162461bcd60e51b815260040161094890615759565b610d46614963565b60006148e3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661498a9092919063ffffffff16565b905080516000148061490457508080602001905181019061490491906155ae565b61264f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610948565b600054610100900460ff166141755760405162461bcd60e51b815260040161094890615759565b606061499984846000856149a1565b949350505050565b606082471015614a025760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610948565b600080866001600160a01b03168587604051614a1e91906157d0565b60006040518083038185875af1925050503d8060008114614a5b576040519150601f19603f3d011682016040523d82523d6000602084013e614a60565b606091505b5091509150614a7187838387614a7c565b979650505050505050565b60608315614ae8578251614ae1576001600160a01b0385163b614ae15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610948565b5081614999565b6149998383815115614afd5781518083602001fd5b8060405162461bcd60e51b815260040161094891906157ec565b801515811461129157600080fd5b8035614b3081614b17565b919050565b803560048110614b3057600080fd5b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614b7e57614b7e614b44565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614bad57614bad614b44565b604052919050565b600067ffffffffffffffff821115614bcf57614bcf614b44565b5060051b60200190565b600082601f830112614bea57600080fd5b81356020614bff614bfa83614bb5565b614b84565b82815260059290921b84018101918181019086841115614c1e57600080fd5b8286015b84811015614c395780358352918301918301614c22565b509695505050505050565b6001600160a01b038116811461129157600080fd5b8035614b3081614c44565b600082601f830112614c7557600080fd5b81356020614c85614bfa83614bb5565b82815260059290921b84018101918181019086841115614ca457600080fd5b8286015b84811015614c39578035614cbb81614b17565b8352918301918301614ca8565b600080600080600080600080610100898b031215614ce557600080fd5b88359750614cf560208a01614b25565b9650614d0360408a01614b35565b9550606089013567ffffffffffffffff80821115614d2057600080fd5b614d2c8c838d01614bd9565b9650614d3a60808c01614c59565b955060a08b0135915080821115614d5057600080fd5b614d5c8c838d01614c64565b945060c08b0135915080821115614d7257600080fd5b614d7e8c838d01614bd9565b935060e08b0135915080821115614d9457600080fd5b50614da18b828c01614bd9565b9150509295985092959890939650565b60008060408385031215614dc457600080fd5b8235614dcf81614c44565b946020939093013593505050565b600060208284031215614def57600080fd5b8135611f5381614c44565b600060208284031215614e0c57600080fd5b5035919050565b60008060408385031215614e2657600080fd5b50508035926020909101359150565b60008060008060808587031215614e4b57600080fd5b5050823594602084013594506040840135936060013592509050565b600080600060408486031215614e7c57600080fd5b83359250602084013567ffffffffffffffff80821115614e9b57600080fd5b818601915086601f830112614eaf57600080fd5b813581811115614ebe57600080fd5b8760208260051b8501011115614ed357600080fd5b6020830194508093505050509250925092565b60008060008060808587031215614efc57600080fd5b84359350602085013567ffffffffffffffff80821115614f1b57600080fd5b614f2788838901614c64565b94506040870135915080821115614f3d57600080fd5b614f4988838901614bd9565b93506060870135915080821115614f5f57600080fd5b50614f6c87828801614bd9565b91505092959194509250565b600080600060608486031215614f8d57600080fd5b8335614f9881614c44565b92506020840135614fa881614c44565b929592945050506040919091013590565b60008060408385031215614fcc57600080fd5b8235614dcf81614b17565b600080600060608486031215614fec57600080fd5b8335614ff781614c44565b9250602084013561500781614c44565b9150604084013561501781614c44565b809150509250925092565b600080600080600060a0868803121561503a57600080fd5b85359450602086013561504c81614b17565b935061505a60408701614b35565b9250606086013567ffffffffffffffff81111561507657600080fd5b61508288828901614bd9565b925050608086013561509381614c44565b809150509295509295909350565b600080604083850312156150b457600080fd5b82359150602083013567ffffffffffffffff8111156150d257600080fd5b6150de85828601614bd9565b9150509250929050565b6000602082840312156150fa57600080fd5b813567ffffffffffffffff81111561511157600080fd5b61499984828501614bd9565b60008060006060848603121561513257600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561516157600080fd5b853561516c81614c44565b9450602086013561517c81614c44565b9350604086013561518c81614c44565b9250606086013561519c81614c44565b9150608086013561509381614c44565b6000806000606084860312156151c157600080fd5b83359250602084013561500781614c44565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156151fb57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561523257615232615202565b500290565b6000821982111561524a5761524a615202565b500190565b60208082526019908201527f696e76616c6964206d61726b65744f7264657247617346656500000000000000604082015260600190565b602080825260159082015274696e76616c6964207472696767657247617346656560581b604082015260600190565b8051614b3081614c44565b6000602082840312156152d257600080fd5b8151611f5381614c44565b6020808252601290820152716661696c656420746f2073656e642066656560701b604082015260600190565b600081518084526020808501945080840160005b838110156153395781518752958201959082019060010161531d565b509495945050505050565b6001600160a01b0387811682526020820187905285151560408301526000906004861061538157634e487b7160e01b600052602160045260246000fd5b85606084015260c0608084015261539b60c0840186615309565b915080841660a084015250979650505050505050565b6000828210156153c3576153c3615202565b500390565b8581526001600160a01b03851660208083019190915260a06040830181905285519083018190526000918681019160c0850190845b8181101561541b5784511515835293830193918301916001016153fd565b5050848103606086015261542f8188615309565b9250505082810360808401526154458185615309565b98975050505050505050565b8051614b3081614b17565b6000610140828403121561546f57600080fd5b615477614b5a565b615480836152b5565b815261548e602084016152b5565b602082015261549f60408401615451565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015181830152508091505092915050565b60008060006060848603121561550d57600080fd5b8351925060208401519150604084015190509250925092565b634e487b7160e01b600052601260045260246000fd5b60008261554b5761554b615526565b500490565b6001600160a01b03929092168252602082015260400190565b60008261557857615578615526565b500690565b634e487b7160e01b600052603260045260246000fd5b60006000198214156155a7576155a7615202565b5060010190565b6000602082840312156155c057600080fd5b8151611f5381614b17565b6020808252600b908201526a139bdd08185b1b1bddd95960aa1b604082015260600190565b6020808252600b908201526a1e995c9bc8185b5bdd5b9d60aa1b604082015260600190565b600181815b8085111561565057816000190482111561563657615636615202565b8085161561564357918102915b93841c939080029061561a565b509250929050565b60008261566757506001612f33565b8161567457506000612f33565b816001811461568a5760028114615694576156b0565b6001915050612f33565b60ff8411156156a5576156a5615202565b50506001821b612f33565b5060208310610133831016604e8410600b84101617156156d3575081810a612f33565b6156dd8383615615565b80600019048211156156f1576156f1615202565b029392505050565b6000612f308383615658565b60018060a01b038416815282602082015260606040820152600061572c6060830184615309565b95945050505050565b6000806040838503121561574857600080fd5b505080516020909101519092909150565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b838110156157bf5781810151838201526020016157a7565b838111156112c35750506000910152565b600082516157e28184602087016157a4565b9190910192915050565b602081526000825180602084015261580b8160408501602087016157a4565b601f01601f1916919091016040019291505056fea26469706673582212205cc4650e61ca73aca2cb86d0441f6682ff80dbb26a27faff2c8c7fe3d2f8f11764736f6c63430008090033
Deployed Bytecode
0x60806040526004361061027c5760003560e01c8063a8f35adf1161014f578063da36992a116100c1578063e673df8a1161007a578063e673df8a146106fd578063eb3188871461071d578063f10df24c14610767578063f11b54941461077c578063f3fef3a31461079c578063fe9ffb04146107bc57600080fd5b8063da36992a14610662578063db81f99b14610675578063dc509f6914610695578063df33dc16146106b5578063df83f611146106c8578063e616847f146106e857600080fd5b8063c2a672e011610113578063c2a672e0146105c7578063cabf4709146105e7578063cf7c7215146105fa578063cfdcdfc91461061a578063d66389b81461062f578063d6dac8ad1461064257600080fd5b8063a8f35adf14610527578063b3e089a214610547578063bdd056a614610567578063bf6eac2f14610587578063c0c53b8b146105a757600080fd5b8063444a91e0116101f3578063703914dc116101ac578063703914dc1461046f57806377a46edd146104845780637abadb59146104b15780638340f549146104d15780638b50fde7146104f1578063a3ae88a01461051157600080fd5b8063444a91e0146103d65780635543576a146103e957806359dfabd41461040957806360829f8a1461041c5780636a26c8861461043c5780636a9b18911461045c57600080fd5b80632bc61ec4116102455780632bc61ec41461033d5780632eaff8841461035057806333adf7241461036357806333eba70c1461037657806333f9c265146103895780633ee7b5b3146103b657600080fd5b80626c09e814610281578063061e56b5146102965780631cc75b88146102ba578063234653e0146102da57806326df6e9114610328575b600080fd5b61029461028f366004614cc8565b6107dc565b005b3480156102a257600080fd5b50603b545b6040519081526020015b60405180910390f35b3480156102c657600080fd5b506102946102d5366004614db1565b610cb3565b3480156102e657600080fd5b506103106102f5366004614ddd565b603f602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016102b1565b34801561033457600080fd5b50610294610cc2565b61029461034b366004614dfa565b610d48565b61029461035e366004614e13565b611294565b610294610371366004614e35565b6112c9565b610294610384366004614e67565b6114f1565b34801561039557600080fd5b506102a76103a4366004614ddd565b603e6020526000908152604090205481565b3480156103c257600080fd5b506102946103d1366004614dfa565b6116e5565b6102946103e4366004614e13565b6116fd565b3480156103f557600080fd5b50610294610404366004614dfa565b611759565b610294610417366004614ee6565b611771565b34801561042857600080fd5b506102a7610437366004614f78565b611958565b34801561044857600080fd5b50610294610457366004614dfa565b611f5a565b61029461046a366004614e13565b611f70565b34801561047b57600080fd5b50610294612191565b34801561049057600080fd5b506102a761049f366004614ddd565b603c6020526000908152604090205481565b3480156104bd57600080fd5b506102946104cc366004614fb9565b612216565b3480156104dd57600080fd5b506102946104ec366004614f78565b6122ab565b3480156104fd57600080fd5b5061029461050c366004614dfa565b612654565b34801561051d57600080fd5b506102a7603b5481565b34801561053357600080fd5b50610294610542366004614e13565b6126d4565b34801561055357600080fd5b50610294610562366004614ddd565b612762565b34801561057357600080fd5b50610294610582366004614dfa565b612790565b34801561059357600080fd5b506102a76105a2366004614f78565b6127d7565b3480156105b357600080fd5b506102946105c2366004614fd7565b612d88565b3480156105d357600080fd5b506102a76105e2366004614db1565b612f23565b6102946105f5366004615022565b612f39565b34801561060657600080fd5b50610294610615366004614db1565b613264565b34801561062657600080fd5b506102946132cc565b61029461063d3660046150a1565b613350565b34801561064e57600080fd5b5061029461065d3660046150e8565b613527565b61029461067036600461511d565b6135d0565b34801561068157600080fd5b50610294610690366004614dfa565b6137f0565b3480156106a157600080fd5b506102946106b0366004615149565b613806565b6102946106c336600461511d565b613a5d565b3480156106d457600080fd5b506102946106e33660046151ac565b613bb1565b3480156106f457600080fd5b50610294613bc4565b34801561070957600080fd5b50603654610310906001600160a01b031681565b34801561072957600080fd5b50610294610738366004614ddd565b336000908152603f6020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b34801561077357600080fd5b506102a7613c49565b34801561078857600080fd5b50610294610797366004614db1565b613d30565b3480156107a857600080fd5b506102946107b7366004614db1565b613d6a565b3480156107c857600080fd5b506102946107d7366004614db1565b614055565b6107e4614060565b336107ee816140ba565b6000876003811115610802576108026151d3565b141561095657603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561085657600080fd5b505afa15801561086a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088e91906151e9565b835161089a9190615218565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b1580156108e857600080fd5b505afa1580156108fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092091906151e9565b61092a9190615237565b34146109515760405162461bcd60e51b81526004016109489061524f565b60405180910390fd5b610a11565b603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109a457600080fd5b505afa1580156109b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dc91906151e9565b83516109e9906001615237565b6109f39190615218565b3414610a115760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b158015610a5657600080fd5b505afa158015610a6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8e91906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114610ad8576040519150601f19603f3d011682016040523d82523d6000602084013e610add565b606091505b5050905080610afe5760405162461bcd60e51b8152600401610948906152dd565b6001600160a01b038616331415610b455760405162461bcd60e51b815260206004820152600b60248201526a2932b332b91032b93937b960a91b6044820152606401610948565b6033546040516304abc43b60e11b81526001600160a01b0390911690630957887690610b7f9033908e908e908e908e908e90600401615344565b600060405180830381600087803b158015610b9957600080fd5b505af1158015610bad573d6000803e3d6000fd5b505060345460335460408051630df2cf1760e41b815290516001600160a01b03938416955063a1ccbf6494506001939092169163df2cf17091600480820192602092909190829003018186803b158015610c0657600080fd5b505afa158015610c1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3e91906151e9565b610c4891906153b1565b338888886040518663ffffffff1660e01b8152600401610c6c9594939291906153c8565b600060405180830381600087803b158015610c8657600080fd5b505af1158015610c9a573d6000803e3d6000fd5b505050505050610ca960018055565b5050505050505050565b610cbe3383836122ab565b5050565b603d54603a546040516370a0823160e01b8152336004820152610d46926001600160a01b039081169216906370a082319060240160206040518083038186803b158015610d0e57600080fd5b505afa158015610d22573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b791906151e9565b565b610d50614060565b6001610d5b8161417b565b60335460405163eb02c30160e01b8152600481018490526000916001600160a01b03169063eb02c301906024016101406040518083038186803b158015610da157600080fd5b505afa158015610db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd9919061545c565b60375460608201516040516365fa2f7f60e01b81529293506000926001600160a01b03909216916365fa2f7f91610e169160040190815260200190565b60206040518083038186803b158015610e2e57600080fd5b505afa158015610e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6691906151e9565b6038546060840151604080860151610100870151608088015160e08901516101208a015160c08b0151955163d136545b60e01b815260048101979097529315156024870152604486019290925260648501526084840186905260a484015260c483015260e48201529192506000916001600160a01b039091169063d136545b906101040160606040518083038186803b158015610f0257600080fd5b505afa158015610f16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3a91906154f8565b5050603854606085015160405163307726ef60e01b81529293506000926001600160a01b039092169163307726ef91610f799160040190815260200190565b60206040518083038186803b158015610f9157600080fd5b505afa158015610fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc991906151e9565b1561105a57603854606085015160405163307726ef60e01b81526001600160a01b039092169163307726ef916110059160040190815260200190565b60206040518083038186803b15801561101d57600080fd5b505afa158015611031573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105591906151e9565b6110e0565b603860009054906101000a90046001600160a01b03166001600160a01b0316631c8444d06040518163ffffffff1660e01b815260040160206040518083038186803b1580156110a857600080fd5b505afa1580156110bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e091906151e9565b90506000620186a082603b546110f69190615218565b611100919061553c565b905080831361113f5760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08185b1b1bddd95960aa1b6044820152606401610948565b603354610100860151604051636d1b4c9560e11b8152600481018a90526024810187905260448101919091526001600160a01b039091169063da36992a90606401600060405180830381600087803b15801561119a57600080fd5b505af11580156111ae573d6000803e3d6000fd5b50505050600081846111c091906153b1565b603a548751604051632770a7eb60e21b81529293506001600160a01b0390911691639dc29fac916111f5918590600401615550565b600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b5050505080603b60008282546112399190615237565b909155505085516040518281526001600160a01b039091169089907f7e3ad6234556318d663482d0da4392a6898037f43df2a506bc602357af1ff59a9060200160405180910390a35050505050505061129160018055565b50565b60006112a4600160801b8461553c565b905060006112b6600160801b85615569565b90506112c38282856135d0565b50505050565b6112d1614060565b336112db816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b15801561132957600080fd5b505afa15801561133d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136191906151e9565b341461137f5760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b1580156113c457600080fd5b505afa1580156113d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fc91906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114611446576040519150601f19603f3d011682016040523d82523d6000602084013e61144b565b606091505b505090508061146c5760405162461bcd60e51b8152600401610948906152dd565b6033546040516329e05f7560e21b8152336004820152602481018890526044810187905260648101869052608481018590526001600160a01b039091169063a7817dd49060a4015b600060405180830381600087803b1580156114ce57600080fd5b505af11580156114e2573d6000803e3d6000fd5b5050505050506112c360018055565b6000611501600160801b8561553c565b90508160008167ffffffffffffffff81111561151f5761151f614b44565b604051908082528060200260200182016040528015611548578160200160208202803683370190505b50905060008267ffffffffffffffff81111561156657611566614b44565b60405190808252806020026020018201604052801561158f578160200160208202803683370190505b50905060008367ffffffffffffffff8111156115ad576115ad614b44565b6040519080825280602002602001820160405280156115d6578160200160208202803683370190505b50905060005b848110156116d857600160801b8888838181106115fb576115fb61557d565b9050602002013561160c919061553c565b83828151811061161e5761161e61557d565b60200260200101818152505060026001607f1b8989848181106116435761164361557d565b90506020020135611654919061553c565b61165e9190615569565b6001148482815181106116735761167361557d565b911515602092830291909101909101526001607f1b88888381811061169a5761169a61557d565b905060200201356116ab9190615569565b8282815181106116bd576116bd61557d565b60209081029190910101526116d181615593565b90506115dc565b50610ca985848484611771565b603d54610cbe9033906001600160a01b0316836127d7565b600061170d600160801b8461553c565b9050600061171f600160801b85615569565b90506000611731600160801b8561553c565b90506000611743600160801b86615569565b9050611751848484846112c9565b505050505050565b603d546112919033906001600160a01b0316836122ab565b611779614060565b33611783816140ba565b8251603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117d357600080fd5b505afa1580156117e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061180b91906151e9565b6118159190615218565b34146118335760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b15801561187857600080fd5b505afa15801561188c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b091906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d80600081146118fa576040519150601f19603f3d011682016040523d82523d6000602084013e6118ff565b606091505b50509050806119205760405162461bcd60e51b8152600401610948906152dd565b6034546040516328732fd960e21b81526001600160a01b039091169063a1ccbf64906114b490899033908a908a908a906004016153c8565b6000611962614060565b3361196c816140ba565b603854604051632e79aba560e01b81526001600160a01b03868116600483015290911690632e79aba59060240160206040518083038186803b1580156119b157600080fd5b505afa1580156119c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e991906155ae565b611a2a5760405162461bcd60e51b81526020600482015260126024820152711d5b9cdd185ada5b99c8191a5cd8589b195960721b6044820152606401610948565b603954604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015611a6f57600080fd5b505afa158015611a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa791906151e9565b9050600084118015611ab95750808411155b611af85760405162461bcd60e51b815260206004820152601060248201526f3739b63820b6b7bab73a1032b93937b960811b6044820152606401610948565b6001600160a01b0386163314611ba757603854604051630519e01b60e41b81526001600160a01b0388811660048301523360248301529091169063519e01b09060440160206040518083038186803b158015611b5357600080fd5b505afa158015611b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8b91906155ae565b611ba75760405162461bcd60e51b8152600401610948906155cb565b60385460405163cb28bbeb60e01b81526001600160a01b0388811660048301529091169063cb28bbeb9060240160206040518083038186803b158015611bec57600080fd5b505afa158015611c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2491906155ae565b611d155760385460408051633526931560e01b8152905142926001600160a01b0316916335269315916004808301926020929190829003018186803b158015611c6c57600080fd5b505afa158015611c80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca491906151e9565b6001600160a01b0388166000908152603c6020526040902054611cc79190615237565b1115611d155760405162461bcd60e51b815260206004820181905260248201527f636f6f6c646f776e206475726174696f6e206e6f7420796574207061737365646044820152606401610948565b603954604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90611d479089908890600401615550565b600060405180830381600087803b158015611d6157600080fd5b505af1158015611d75573d6000803e3d6000fd5b50505050600081603b5486611d8a9190615218565b611d94919061553c565b603854604051638113dba560e01b81526001600160a01b038981166004830152929350600092620186a0921690638113dba59060240160206040518083038186803b158015611de257600080fd5b505afa158015611df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1a91906151e9565b611e249084615218565b611e2e919061553c565b9050611e3c81600080614237565b81603b6000828254611e4e91906153b1565b90915550506037546000906001600160a01b03166368ce13d689611e7285876153b1565b6040518363ffffffff1660e01b8152600401611e8f929190615550565b60206040518083038186803b158015611ea757600080fd5b505afa158015611ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edf91906151e9565b9050611ef56001600160a01b0389168a83614760565b604080516001600160a01b038a81168252602082018a9052918101839052908a16907f18edd09e80386cd99df397e2e0d87d2bb259423eae08645e776321a36fe680ef9060600160405180910390a2945050505050611f5360018055565b9392505050565b603d54610cbe906001600160a01b031682612f23565b611f78614060565b33611f82816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b158015611fd057600080fd5b505afa158015611fe4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200891906151e9565b34146120265760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b15801561206b57600080fd5b505afa15801561207f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a391906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d80600081146120ed576040519150601f19603f3d011682016040523d82523d6000602084013e6120f2565b606091505b50509050806121135760405162461bcd60e51b8152600401610948906152dd565b603354604051633f832a5f60e21b81523360048201526024810186905260006044820152606481018590526001600160a01b039091169063fe0ca97c906084015b600060405180830381600087803b15801561216e57600080fd5b505af1158015612182573d6000803e3d6000fd5b505050505050610cbe60018055565b603d546040516370a0823160e01b81523360048201819052610d469290916001600160a01b039091169081906370a082319060240160206040518083038186803b1580156121de57600080fd5b505afa1580156121f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ec91906151e9565b61221e6147b6565b8015610cbe5781156122475780603b600082825461223c9190615237565b90915550610cbe9050565b80603b5410156122905760405162461bcd60e51b81526020600482015260146024820152736578636565646564204e534c5020626f74746f6d60601b6044820152606401610948565b80603b60008282546122a291906153b1565b90915550505050565b6122b3614060565b336122bd816140ba565b60385460405163f690a3a360e01b81526001600160a01b0385811660048301529091169063f690a3a39060240160206040518083038186803b15801561230257600080fd5b505afa158015612316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233a91906155ae565b61237c5760405162461bcd60e51b815260206004820152601360248201527219195c1bdcda5d081b9bdd08185b1b1bddd959606a1b6044820152606401610948565b6000821161239c5760405162461bcd60e51b8152600401610948906155f0565b6001600160a01b038416331461244b57603854604051630519e01b60e41b81526001600160a01b0386811660048301523360248301529091169063519e01b09060440160206040518083038186803b1580156123f757600080fd5b505afa15801561240b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242f91906155ae565b61244b5760405162461bcd60e51b8152600401610948906155cb565b6124606001600160a01b038416333085614827565b6037546040516317a3625360e31b81526000916001600160a01b03169063bd1b1298906124939087908790600401615550565b60206040518083038186803b1580156124ab57600080fd5b505afa1580156124bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e391906151e9565b6038546040516380352cfd60e01b81526001600160a01b038781166004830152929350600092620186a09216906380352cfd9060240160206040518083038186803b15801561253157600080fd5b505afa158015612545573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256991906151e9565b6125739084615218565b61257d919061553c565b905061258b81600080614237565b603a546001600160a01b03166340c10f19876125a784866153b1565b6040518363ffffffff1660e01b81526004016125c4929190615550565b600060405180830381600087803b1580156125de57600080fd5b505af11580156125f2573d6000803e3d6000fd5b50505050846001600160a01b0316866001600160a01b03167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f628660405161263b91815260200190565b60405180910390a350505061264f60018055565b505050565b61265c614060565b33612666816140ba565b6034546040516303d8dd0d60e61b81526001600160a01b039091169063f6374340906126989033908690600401615550565b600060405180830381600087803b1580156126b257600080fd5b505af11580156126c6573d6000803e3d6000fd5b505050505061129160018055565b6126dc614060565b336126e6816140ba565b603354604051633f832a5f60e21b81523360048201526024810185905260016044820152606481018490526001600160a01b039091169063fe0ca97c90608401600060405180830381600087803b15801561274057600080fd5b505af1158015612754573d6000803e3d6000fd5b5050505050610cbe60018055565b600361276d8161417b565b50603d80546001600160a01b0319166001600160a01b0392909216919091179055565b608081901c60006127a66002607f85901c615569565b600114905060006127bb6001607f1b85615569565b905081156127cd576112c383826126d4565b6112c38382611f70565b60006127e1614060565b336127eb816140ba565b60385460405163e0c7845560e01b81526001600160a01b0386811660048301529091169063e0c784559060240160206040518083038186803b15801561283057600080fd5b505afa158015612844573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286891906155ae565b6128a75760405162461bcd60e51b815260206004820152601060248201526f1cdd185ada5b99c8191a5cd8589b195960821b6044820152606401610948565b600083116128c75760405162461bcd60e51b8152600401610948906155f0565b6001600160a01b038516331461297657603854604051630519e01b60e41b81526001600160a01b0387811660048301523360248301529091169063519e01b09060440160206040518083038186803b15801561292257600080fd5b505afa158015612936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295a91906155ae565b6129765760405162461bcd60e51b8152600401610948906155cb565b61298b6001600160a01b038516333086614827565b6037546040516317a3625360e31b81526000916001600160a01b03169063bd1b1298906129be9088908890600401615550565b60206040518083038186803b1580156129d657600080fd5b505afa1580156129ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0e91906151e9565b6038546040516385a848ff60e01b81526001600160a01b038881166004830152929350600092620186a09216906385a848ff9060240160206040518083038186803b158015612a5c57600080fd5b505afa158015612a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9491906151e9565b612a9e9084615218565b612aa8919061553c565b90506000612ab682846153b1565b9050600080603960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612b0957600080fd5b505afa158015612b1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4191906151e9565b905080612b9657612b62620186a06c0c9f2c9cd04674edea40000000615218565b612b6e6012600a6156f9565b612b7b620186a086615218565b612b859190615218565b612b8f919061553c565b9150612bb0565b603b54612ba38285615218565b612bad919061553c565b91505b603860009054906101000a90046001600160a01b03166001600160a01b031663cdbde18f6040518163ffffffff1660e01b815260040160206040518083038186803b158015612bfe57600080fd5b505afa158015612c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3691906151e9565b612c408383615237565b1115612c8e5760405162461bcd60e51b815260206004820152601760248201527f6d617820746f74616c206e736c702065786365656465640000000000000000006044820152606401610948565b612c9a84600080614237565b82603b6000828254612cac9190615237565b90915550506001600160a01b03808b166000908152603c60205260409081902042905560395490516340c10f1960e01b81529116906340c10f1990612cf7908d908690600401615550565b600060405180830381600087803b158015612d1157600080fd5b505af1158015612d25573d6000803e3d6000fd5b5050604080516001600160a01b038d81168252602082018d9052918101869052908d1692507f63602d0ecc7b3a0ef7ff1a116e23056662d64280355ba8031b6d0d767c4b4458915060600160405180910390a250945050505050611f5360018055565b600054610100900460ff1615808015612da85750600054600160ff909116105b80612dc25750303b158015612dc2575060005460ff166001145b612e255760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610948565b6000805460ff191660011790558015612e48576000805461ff0019166101001790555b6001600160a01b0384163b612e935760405162461bcd60e51b81526020600482015260116024820152701bdc195c985d1bdc9cc81a5b9d985b1a59607a1b6044820152606401610948565b612e9b61485f565b603680546001600160a01b038087166001600160a01b03199283161790925560398054868416908316179055603a80549285169290911691909117905580156112c3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6000612f30338484611958565b90505b92915050565b612f41614060565b33612f4b816140ba565b6000846003811115612f5f57612f5f6151d3565b141561300e57603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b158015612fb357600080fd5b505afa158015612fc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612feb91906151e9565b34146130095760405162461bcd60e51b81526004016109489061524f565b6130b2565b603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561305c57600080fd5b505afa158015613070573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309491906151e9565b34146130b25760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b1580156130f757600080fd5b505afa15801561310b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312f91906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114613179576040519150601f19603f3d011682016040523d82523d6000602084013e61317e565b606091505b505090508061319f5760405162461bcd60e51b8152600401610948906152dd565b6001600160a01b0383163314156131e65760405162461bcd60e51b815260206004820152600b60248201526a2932b332b91032b93937b960a91b6044820152606401610948565b6033546040516304abc43b60e11b81526001600160a01b03909116906309578876906132209033908b908b908b908b908b90600401615344565b600060405180830381600087803b15801561323a57600080fd5b505af115801561324e573d6000803e3d6000fd5b50505050505061325d60018055565b5050505050565b61326c6147b6565b603a546040516340c10f1960e01b81526001600160a01b03909116906340c10f199061329e9085908590600401615550565b600060405180830381600087803b1580156132b857600080fd5b505af1158015611751573d6000803e3d6000fd5b603d546039546040516370a0823160e01b8152336004820152611291926001600160a01b039081169216906370a082319060240160206040518083038186803b15801561331857600080fd5b505afa15801561332c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e291906151e9565b613358614060565b33613362816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b03166364c8bb7e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133b057600080fd5b505afa1580156133c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133e891906151e9565b34146134065760405162461bcd60e51b815260040161094890615286565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b15801561344b57600080fd5b505afa15801561345f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061348391906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d80600081146134cd576040519150601f19603f3d011682016040523d82523d6000602084013e6134d2565b606091505b50509050806134f35760405162461bcd60e51b8152600401610948906152dd565b60345460405163860a19f160e01b81526001600160a01b039091169063860a19f19061215490339088908890600401615705565b33613531816140ba565b60005b825181101561264f5760345483516001600160a01b039091169063f63743409033908690859081106135685761356861557d565b60200260200101516040518363ffffffff1660e01b815260040161358d929190615550565b600060405180830381600087803b1580156135a757600080fd5b505af11580156135bb573d6000803e3d6000fd5b50505050806135c990615593565b9050613534565b6135d8614060565b336135e2816140ba565b603860009054906101000a90046001600160a01b03166001600160a01b031663ce9e80096040518163ffffffff1660e01b815260040160206040518083038186803b15801561363057600080fd5b505afa158015613644573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061366891906151e9565b34146136865760405162461bcd60e51b81526004016109489061524f565b6038546040805163d0fb020360e01b815290516000926001600160a01b03169163d0fb0203916004808301926020929190829003018186803b1580156136cb57600080fd5b505afa1580156136df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370391906152c0565b6001600160a01b03163460405160006040518083038185875af1925050503d806000811461374d576040519150601f19603f3d011682016040523d82523d6000602084013e613752565b606091505b50509050806137735760405162461bcd60e51b8152600401610948906152dd565b6033546040516329f054e360e11b81526004810185905233602482015260448101879052606481018690526001600160a01b03909116906353e0a9c690608401600060405180830381600087803b1580156137cd57600080fd5b505af11580156137e1573d6000803e3d6000fd5b50505050505061264f60018055565b603d54611291906001600160a01b031682613d6a565b60046138118161417b565b603a54600160a01b900460ff16156138595760405162461bcd60e51b815260206004820152600b60248201526a1a5b9a5d1a585b1a5e995960aa1b6044820152606401610948565b6001600160a01b0386163b6138a75760405162461bcd60e51b81526020600482015260146024820152731c1c9a58d953585b9859d95c881a5b9d985b1a5960621b6044820152606401610948565b6001600160a01b0385163b6138fe5760405162461bcd60e51b815260206004820152601760248201527f73657474696e67734d616e6167657220696e76616c69640000000000000000006044820152606401610948565b6001600160a01b0384163b61394d5760405162461bcd60e51b81526020600482015260156024820152741c1bdcda5d1a5bdb95985d5b1d081a5b9d985b1a59605a1b6044820152606401610948565b6001600160a01b0383163b6139995760405162461bcd60e51b81526020600482015260126024820152711bdc99195c95985d5b1d081a5b9d985b1a5960721b6044820152606401610948565b6001600160a01b0382163b6139e95760405162461bcd60e51b81526020600482015260166024820152751b1a5c5d5a59185d1955985d5b1d081a5b9d985b1a5960521b6044820152606401610948565b50603780546001600160a01b039687166001600160a01b031991821617909155603880549587169582169590951790945560338054938616938516939093179092556034805491851691841691909117905560358054919093169116179055603a805460ff60a01b1916600160a01b179055565b6000613a6d600160f01b8561553c565b90506000600160e81b613a84600160f01b87615569565b613a8e919061553c565b90506000613a9d60808361553c565b60011490506000613aaf608084615569565b6003811115613ac057613ac06151d3565b60408051600480825260a08201909252919250889160009160208201608080368337019050509050613af6600160801b8961553c565b81600081518110613b0957613b0961557d565b6020908102919091010152613b22600160801b89615569565b81600181518110613b3557613b3561557d565b6020908102919091010152613b4e600160801b8861553c565b81600281518110613b6157613b6161557d565b6020908102919091010152613b7a600160801b88615569565b81600381518110613b8d57613b8d61557d565b602002602001018181525050613ba68685858486612f39565b505050505050505050565b613bb96147b6565b61264f838383614237565b603d546040516370a0823160e01b815233600482018190526112919290916001600160a01b039091169081906370a082319060240160206040518083038186803b158015613c1157600080fd5b505afa158015613c25573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a291906151e9565b600080603960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613c9a57600080fd5b505afa158015613cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cd291906151e9565b905080613ce357620186a091505090565b613cfa6c0c9f2c9cd04674edea4000000082615218565b603b54613d096012600a6156f9565b613d1690620186a0615218565b613d209190615218565b613d2a919061553c565b91505090565b613d386147b6565b603a54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac9061329e9085908590600401615550565b613d72614060565b33613d7c816140ba565b603854604051633394ce3b60e21b81526001600160a01b0385811660048301529091169063ce5338ec9060240160206040518083038186803b158015613dc157600080fd5b505afa158015613dd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613df991906155ae565b613e3c5760405162461bcd60e51b81526020600482015260146024820152731dda5d1a191c985dc81b9bdd08185b1b1bddd95960621b6044820152606401610948565b60008211613e5c5760405162461bcd60e51b8152600401610948906155f0565b603a54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90613e8e9033908690600401615550565b600060405180830381600087803b158015613ea857600080fd5b505af1158015613ebc573d6000803e3d6000fd5b5050603854604051631ac3ddeb60e01b81526001600160a01b03878116600483015260009450620186a0935090911690631ac3ddeb9060240160206040518083038186803b158015613f0d57600080fd5b505afa158015613f21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4591906151e9565b613f4f9085615218565b613f59919061553c565b9050613f6781600080614237565b6037546000906001600160a01b03166368ce13d686613f8685886153b1565b6040518363ffffffff1660e01b8152600401613fa3929190615550565b60206040518083038186803b158015613fbb57600080fd5b505afa158015613fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ff391906151e9565b90506140096001600160a01b0386163383614760565b6040518181526001600160a01b0386169033907f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060200160405180910390a3505050610cbe60018055565b61264f3383836127d7565b600260015414156140b35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610948565b6002600155565b60385460405163a9b9e38960e01b81526001600160a01b0383811660048301529091169063a9b9e3899060240160206040518083038186803b1580156140ff57600080fd5b505afa158015614113573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061413791906155ae565b156112915760405162461bcd60e51b815260206004820152600e60248201526d1058d8dbdd5b9d0818985b9b995960921b6044820152606401610948565b60018055565b60365460405163df07560560e01b815233600482015282916001600160a01b03169063df0756059060240160206040518083038186803b1580156141be57600080fd5b505afa1580156141d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f691906151e9565b10156112915760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b21037b832b930ba37b960811b6044820152606401610948565b821561264f576001600160a01b038216156144455760385460405163594ca01560e01b81526001600160a01b038481166004830152600092839291169063594ca01590602401604080518083038186803b15801561429457600080fd5b505afa1580156142a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142cc9190615735565b9092509050620186a06142df8387615218565b6142e9919061553c565b9150620186a06142f98287615218565b614303919061553c565b603a546040516340c10f1960e01b81529192506001600160a01b0316906340c10f19906143369087908690600401615550565b600060405180830381600087803b15801561435057600080fd5b505af1158015614364573d6000803e3d6000fd5b5050505060008111156143d657603a546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906143a39086908590600401615550565b600060405180830381600087803b1580156143bd57600080fd5b505af11580156143d1573d6000803e3d6000fd5b505050505b6143e08183615237565b6143ea90866153b1565b9450826001600160a01b0316846001600160a01b03167f2210da9c25406cac50a7846052db53d49ec84390f83867c61e4091ac87ec9397848460405161443a929190918252602082015260400190565b60405180910390a350505b6001600160a01b038116156145cb576001600160a01b038181166000908152603f60205260408082205460385491516319745e3960e11b8152908416600482018190529391909116906332e8bc729060240160206040518083038186803b1580156144af57600080fd5b505afa1580156144c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144e791906151e9565b905080156145c857620186a06144fd8287615218565b614507919061553c565b603a546040516340c10f1960e01b81529192506001600160a01b0316906340c10f199061453a9085908590600401615550565b600060405180830381600087803b15801561455457600080fd5b505af1158015614568573d6000803e3d6000fd5b50505050808561457891906153b1565b9450826001600160a01b0316826001600160a01b03167fa9d92ab9f19faecc65e4b397da6701d094f08143f98b735b7cd6332184bec0f1836040516145bf91815260200190565b60405180910390a35b50505b6000620186a0603860009054906101000a90046001600160a01b03166001600160a01b031663018f2d826040518163ffffffff1660e01b815260040160206040518083038186803b15801561461f57600080fd5b505afa158015614633573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061465791906151e9565b6146619086615218565b61466b919061553c565b905080603b600082825461467f9190615237565b9091555050603a546038546040805163d0fb020360e01b815290516001600160a01b03938416936340c10f1993169163d0fb0203916004808301926020929190829003018186803b1580156146d357600080fd5b505afa1580156146e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061470b91906152c0565b61471584886153b1565b6040518363ffffffff1660e01b8152600401614732929190615550565b600060405180830381600087803b15801561474c57600080fd5b505af1158015610ca9573d6000803e3d6000fd5b61264f8363a9059cbb60e01b848460405160240161477f929190615550565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261488e565b6033546001600160a01b03163314806147d957506035546001600160a01b031633145b806147ee57506034546001600160a01b031633145b610d465760405162461bcd60e51b815260206004820152600a60248201526913db9b1e481d985d5b1d60b21b6044820152606401610948565b6040516001600160a01b03808516602483015283166044820152606481018290526112c39085906323b872dd60e01b9060840161477f565b600054610100900460ff166148865760405162461bcd60e51b815260040161094890615759565b610d46614963565b60006148e3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661498a9092919063ffffffff16565b905080516000148061490457508080602001905181019061490491906155ae565b61264f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610948565b600054610100900460ff166141755760405162461bcd60e51b815260040161094890615759565b606061499984846000856149a1565b949350505050565b606082471015614a025760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610948565b600080866001600160a01b03168587604051614a1e91906157d0565b60006040518083038185875af1925050503d8060008114614a5b576040519150601f19603f3d011682016040523d82523d6000602084013e614a60565b606091505b5091509150614a7187838387614a7c565b979650505050505050565b60608315614ae8578251614ae1576001600160a01b0385163b614ae15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610948565b5081614999565b6149998383815115614afd5781518083602001fd5b8060405162461bcd60e51b815260040161094891906157ec565b801515811461129157600080fd5b8035614b3081614b17565b919050565b803560048110614b3057600080fd5b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614b7e57614b7e614b44565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614bad57614bad614b44565b604052919050565b600067ffffffffffffffff821115614bcf57614bcf614b44565b5060051b60200190565b600082601f830112614bea57600080fd5b81356020614bff614bfa83614bb5565b614b84565b82815260059290921b84018101918181019086841115614c1e57600080fd5b8286015b84811015614c395780358352918301918301614c22565b509695505050505050565b6001600160a01b038116811461129157600080fd5b8035614b3081614c44565b600082601f830112614c7557600080fd5b81356020614c85614bfa83614bb5565b82815260059290921b84018101918181019086841115614ca457600080fd5b8286015b84811015614c39578035614cbb81614b17565b8352918301918301614ca8565b600080600080600080600080610100898b031215614ce557600080fd5b88359750614cf560208a01614b25565b9650614d0360408a01614b35565b9550606089013567ffffffffffffffff80821115614d2057600080fd5b614d2c8c838d01614bd9565b9650614d3a60808c01614c59565b955060a08b0135915080821115614d5057600080fd5b614d5c8c838d01614c64565b945060c08b0135915080821115614d7257600080fd5b614d7e8c838d01614bd9565b935060e08b0135915080821115614d9457600080fd5b50614da18b828c01614bd9565b9150509295985092959890939650565b60008060408385031215614dc457600080fd5b8235614dcf81614c44565b946020939093013593505050565b600060208284031215614def57600080fd5b8135611f5381614c44565b600060208284031215614e0c57600080fd5b5035919050565b60008060408385031215614e2657600080fd5b50508035926020909101359150565b60008060008060808587031215614e4b57600080fd5b5050823594602084013594506040840135936060013592509050565b600080600060408486031215614e7c57600080fd5b83359250602084013567ffffffffffffffff80821115614e9b57600080fd5b818601915086601f830112614eaf57600080fd5b813581811115614ebe57600080fd5b8760208260051b8501011115614ed357600080fd5b6020830194508093505050509250925092565b60008060008060808587031215614efc57600080fd5b84359350602085013567ffffffffffffffff80821115614f1b57600080fd5b614f2788838901614c64565b94506040870135915080821115614f3d57600080fd5b614f4988838901614bd9565b93506060870135915080821115614f5f57600080fd5b50614f6c87828801614bd9565b91505092959194509250565b600080600060608486031215614f8d57600080fd5b8335614f9881614c44565b92506020840135614fa881614c44565b929592945050506040919091013590565b60008060408385031215614fcc57600080fd5b8235614dcf81614b17565b600080600060608486031215614fec57600080fd5b8335614ff781614c44565b9250602084013561500781614c44565b9150604084013561501781614c44565b809150509250925092565b600080600080600060a0868803121561503a57600080fd5b85359450602086013561504c81614b17565b935061505a60408701614b35565b9250606086013567ffffffffffffffff81111561507657600080fd5b61508288828901614bd9565b925050608086013561509381614c44565b809150509295509295909350565b600080604083850312156150b457600080fd5b82359150602083013567ffffffffffffffff8111156150d257600080fd5b6150de85828601614bd9565b9150509250929050565b6000602082840312156150fa57600080fd5b813567ffffffffffffffff81111561511157600080fd5b61499984828501614bd9565b60008060006060848603121561513257600080fd5b505081359360208301359350604090920135919050565b600080600080600060a0868803121561516157600080fd5b853561516c81614c44565b9450602086013561517c81614c44565b9350604086013561518c81614c44565b9250606086013561519c81614c44565b9150608086013561509381614c44565b6000806000606084860312156151c157600080fd5b83359250602084013561500781614c44565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156151fb57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561523257615232615202565b500290565b6000821982111561524a5761524a615202565b500190565b60208082526019908201527f696e76616c6964206d61726b65744f7264657247617346656500000000000000604082015260600190565b602080825260159082015274696e76616c6964207472696767657247617346656560581b604082015260600190565b8051614b3081614c44565b6000602082840312156152d257600080fd5b8151611f5381614c44565b6020808252601290820152716661696c656420746f2073656e642066656560701b604082015260600190565b600081518084526020808501945080840160005b838110156153395781518752958201959082019060010161531d565b509495945050505050565b6001600160a01b0387811682526020820187905285151560408301526000906004861061538157634e487b7160e01b600052602160045260246000fd5b85606084015260c0608084015261539b60c0840186615309565b915080841660a084015250979650505050505050565b6000828210156153c3576153c3615202565b500390565b8581526001600160a01b03851660208083019190915260a06040830181905285519083018190526000918681019160c0850190845b8181101561541b5784511515835293830193918301916001016153fd565b5050848103606086015261542f8188615309565b9250505082810360808401526154458185615309565b98975050505050505050565b8051614b3081614b17565b6000610140828403121561546f57600080fd5b615477614b5a565b615480836152b5565b815261548e602084016152b5565b602082015261549f60408401615451565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015181830152508091505092915050565b60008060006060848603121561550d57600080fd5b8351925060208401519150604084015190509250925092565b634e487b7160e01b600052601260045260246000fd5b60008261554b5761554b615526565b500490565b6001600160a01b03929092168252602082015260400190565b60008261557857615578615526565b500690565b634e487b7160e01b600052603260045260246000fd5b60006000198214156155a7576155a7615202565b5060010190565b6000602082840312156155c057600080fd5b8151611f5381614b17565b6020808252600b908201526a139bdd08185b1b1bddd95960aa1b604082015260600190565b6020808252600b908201526a1e995c9bc8185b5bdd5b9d60aa1b604082015260600190565b600181815b8085111561565057816000190482111561563657615636615202565b8085161561564357918102915b93841c939080029061561a565b509250929050565b60008261566757506001612f33565b8161567457506000612f33565b816001811461568a5760028114615694576156b0565b6001915050612f33565b60ff8411156156a5576156a5615202565b50506001821b612f33565b5060208310610133831016604e8410600b84101617156156d3575081810a612f33565b6156dd8383615615565b80600019048211156156f1576156f1615202565b029392505050565b6000612f308383615658565b60018060a01b038416815282602082015260606040820152600061572c6060830184615309565b95945050505050565b6000806040838503121561574857600080fd5b505080516020909101519092909150565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60005b838110156157bf5781810151838201526020016157a7565b838111156112c35750506000910152565b600082516157e28184602087016157a4565b9190910192915050565b602081526000825180602084015261580b8160408501602087016157a4565b601f01601f1916919091016040019291505056fea26469706673582212205cc4650e61ca73aca2cb86d0441f6682ff80dbb26a27faff2c8c7fe3d2f8f11764736f6c63430008090033
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.