Address Details
contract
0x89CaD7C7f2326bbEC22e433422B8B6276fe528D3
- Contract Name
- Dex
- Creator
- 0xd3c2ab–ffc681 at 0x410a72–351b35
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 47 Transactions
- Transfers
- 5,634 Transfers
- Gas Used
- 3,547,252
- Last Balance Update
- 21752525
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- Dex
- Optimization enabled
- true
- Compiler version
- v0.8.16+commit.07a7930e
- Optimization runs
- 800
- EVM Version
- london
- Verified at
- 2023-03-10T15:37:55.696597Z
contracts/core/Dex.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "../access/Governable.sol"; import "../interfaces/IOracle.sol"; import "../interfaces/IVaultRewardRouter.sol"; import "../interfaces/IReferralManager.sol"; import "../interfaces/IOrderManager.sol"; contract Dex is ReentrancyGuard, Governable { using SafeERC20 for IERC20; struct Vault { uint256 cap; uint256 balance; uint256 amount; uint256 shares; uint256 minTime; } struct Stake { address owner; uint256 amount; uint256 shares; uint256 timestamp; } struct Product { bool isActive; uint256 maxLeverage; uint256 fee; uint256 weight; uint256 reserve; uint256 openInterestLong; uint256 openInterestShort; } struct Funding { int256 total; uint256 timestamp; uint256 multiplier; } struct Position { address owner; bool isLong; uint256 productId; uint256 margin; uint256 leverage; uint256 price; int256 funding; uint256 timestamp; } address public oracle; address public referralManager; address public positionManager; address public orderManager; address public vaultRewardReceiver; address public stakingRewardReceiver; address public treasuryRewardReceiver; address public vaultRewardRouter; address public immutable token; uint256 public totalProducts; uint256 public totalWeight; uint256 public totalOpenInterest; uint256 public minMargin = 25 * BASE; uint256 public minLeverage = 1 * BASE; uint256 public maxShift = 0.002e8; uint256 public shiftDivider = 20; uint256 public utilizationMultiplier = 10000; uint256 public exposureMultiplier = 12000; uint256 public maxExposureMultiplier = 30000; uint256 public liquidationThreshold = 9850; uint256 public maxFundingRate = 10 * FUNDING_BASE; uint256 public vaultRewardRatio = 6000; uint256 public stakingRewardRatio = 4000; uint256 public treasuryRewardRatio; uint256 private pendingVaultReward; uint256 private pendingStakingReward; uint256 private pendingTreasuryReward; uint256 private immutable tokenBase; uint256 private constant BASE = 10 ** 8; uint256 private constant PARAM_BASE = 10 ** 4; uint256 private constant TRADEFEE_BASE = 10 ** 5; uint256 private constant FUNDING_BASE = 10 ** 12; bool public isStakeEnabled = true; bool public isOpenPositionEnabled = true; mapping(address => Stake) private stakes; mapping(uint256 => Product) private products; mapping(uint256 => Funding) private fundings; mapping(bytes32 => Position) public positions; mapping(address => uint256) public totalReferrerRebates; mapping(address => uint256) public totalTraderRebates; mapping(address => uint256) public claimedReferrerRebates; mapping(address => uint256) public claimedTraderRebates; mapping(address => bool) public liquidators; mapping(address => bool) public guardians; Vault private vault; event StakeVault(address indexed user, uint256 amount, uint256 shares); event UnstakeVault(address indexed user, uint256 amount, uint256 shares, uint256 shareBalance, bool isFullRedeem); event OpenPosition( bytes32 indexed positionKey, address indexed user, bool isLong, uint256 productId, uint256 margin, uint256 leverage, uint256 price, uint256 fee, int256 funding ); event ClosePosition( bytes32 indexed positionKey, address indexed user, bool isLiquidated, uint256 productId, uint256 price, uint256 entryPrice, uint256 margin, uint256 leverage, int256 pnl, int256 fundingFee ); event UpdateFunding(uint256 productId, int256 total, int256 fundingRate); event AddMargin( bytes32 indexed positionKey, address indexed user, bool isLong, uint256 productId, uint256 margin, uint256 newMargin, uint256 leverage, uint256 newLeverage ); event LiquidationError(bytes32 indexed positionKey, string executionError); event ClaimReferrerRebates(address indexed user, uint256 amount); event ClaimTraderRebates(address indexed user, uint256 amount); event ReferralVolume(address referrer, address trader, uint256 volume); event DistributeVaultReward(uint256 amount); event DistributeStakingReward(uint256 amount); event DistributeTreasuryReward(uint256 amount); event SetPeripheralContracts( address oracle, address referralManager, address positionManager, address orderManager, address vaultRewardReceiver, address stakingRewardReceiver, address treasuryRewardReceiver, address vaultRewardRouter ); event UpdateVault(Vault vault); event AddProduct(uint256 productId, Product product); event UpdateProduct(uint256 productId, Product product); event SetFundingMultiplier(uint256 productId, uint256 multiplier); event SetParameter(uint256 index, uint256 value); event SetRewardRatio(uint256 vaultRewardRatio, uint256 stakingRewardRatio, uint256 treasuryRewardRatio); event SetLiquidator(address indexed account, bool isActive); event SetGuardian(address indexed account, bool isActive); event EmergencyPause(uint256 timestamp); event Unpause(uint256 timestamp); constructor(address _token, uint256 _tokenBase) { token = _token; tokenBase = _tokenBase; guardians[msg.sender] = true; } function stakeVault(uint256 amount) external nonReentrant { _stakeVault(msg.sender, amount); } function stakeVaultToCompound(address user, uint256 amount) external nonReentrant { require(msg.sender == vaultRewardReceiver, "!vaultRewardReceiver"); _stakeVault(user, amount); } function _stakeVault(address user, uint256 amount) private { require(isStakeEnabled, "staking is disabled"); require(amount > 0, "amount cannot be zero"); require(vault.amount + amount <= vault.cap, "vault cap exceeded"); if (msg.sender != vaultRewardReceiver) IVaultRewardRouter(vaultRewardRouter).updateRewards(user); IERC20(token).safeTransferFrom(msg.sender, address(this), (amount * tokenBase) / BASE); uint256 shares = vault.amount > 0 ? (amount * vault.shares) / vault.balance : amount; vault.shares += shares; vault.balance += amount; vault.amount += amount; if (stakes[user].amount == 0) { stakes[user] = Stake({owner: user, amount: amount, shares: shares, timestamp: block.timestamp}); } else { stakes[user].shares += shares; stakes[user].amount += amount; if (msg.sender != vaultRewardReceiver) stakes[user].timestamp = block.timestamp; } emit StakeVault(user, amount, shares); } function unstakeVault(uint256 shares) external nonReentrant { _unstakeVault(msg.sender, shares); } function _unstakeVault(address user, uint256 shares) private { require(shares > 0, "shares cannot be zero"); Stake storage stake = stakes[user]; require(stake.amount > 0, "user no staked amount"); require(block.timestamp > vault.minTime + stake.timestamp, "!vault.minTime"); IVaultRewardRouter(vaultRewardRouter).updateRewards(user); bool isFullRedeem = shares >= stake.shares; if (isFullRedeem) { shares = stake.shares; } uint256 balance = (shares * vault.balance) / vault.shares; uint256 amount = (shares * stake.amount) / stake.shares; vault.shares -= shares; vault.balance -= balance; vault.amount -= amount; if (isFullRedeem) { delete stakes[user]; } else { stake.shares -= shares; stake.amount -= amount; } requireVaultNotOverutilized(); IERC20(token).safeTransfer(user, (balance * tokenBase) / BASE); emit UnstakeVault(user, amount, shares, balance, isFullRedeem); } function openPosition(address user, uint256 productId, bool isLong, uint256 margin, uint256 leverage) external { require(isOpenPositionEnabled, "open position is disabled"); require(msg.sender == positionManager || msg.sender == orderManager, "!manager"); require(margin >= minMargin && margin < type(uint64).max, "!margin"); require(leverage >= minLeverage, "!minLeverage"); Product memory product = products[productId]; require(product.isActive, "!active"); require(leverage <= product.maxLeverage, "!maxLeverage"); uint256 size = (margin * leverage) / BASE; uint256 tradeFee = (size * product.fee) / TRADEFEE_BASE; IERC20(token).safeTransferFrom(msg.sender, address(this), ((margin + tradeFee) * tokenBase) / BASE); _updateFeeWithReferral(user, tradeFee, size); uint256 price = _calculatePrice( productId, isLong, product.openInterestLong, product.openInterestShort, getMaxExposure(product.weight), product.reserve, size ); _updateFundingAndOpenInterest(productId, size, isLong, true); int256 funding = fundings[productId].total; bytes32 positionKey = getPositionKey(user, productId, isLong); Position memory position = positions[positionKey]; if (position.margin > 0) { price = (position.margin * position.leverage * position.price + margin * leverage * price) / (position.margin * position.leverage + margin * leverage); funding = (int256(position.margin * position.leverage) * position.funding + int256(margin * leverage) * funding) / int256(position.margin * position.leverage + margin * leverage); leverage = (position.margin * position.leverage + margin * leverage) / (position.margin + margin); margin = position.margin + margin; } positions[positionKey] = Position({ owner: user, isLong: isLong, productId: productId, margin: margin, leverage: leverage, price: price, funding: funding, timestamp: block.timestamp }); emit OpenPosition(positionKey, user, isLong, productId, margin, leverage, price, tradeFee, funding); } function addMargin(uint256 productId, bool isLong, uint256 margin) external nonReentrant { bytes32 positionKey = getPositionKey(msg.sender, productId, isLong); Position storage position = positions[positionKey]; uint256 newMargin = position.margin + margin; uint256 leverage = position.leverage; uint256 newLeverage = (leverage * position.margin) / newMargin; require(newLeverage >= minLeverage, "!minleverage"); IERC20(token).safeTransferFrom(msg.sender, address(this), (margin * tokenBase) / BASE); position.margin = newMargin; position.leverage = newLeverage; emit AddMargin(positionKey, msg.sender, isLong, productId, margin, newMargin, leverage, newLeverage); } function closePosition(address user, uint256 productId, bool isLong, uint256 margin) external { _closePosition(getPositionKey(user, productId, isLong), margin); } function _closePosition(bytes32 positionKey, uint256 margin) private { require(msg.sender == positionManager || msg.sender == orderManager, "!manager"); if (margin == 0) return; Position storage position = positions[positionKey]; if (position.owner == address(0)) return; // position does not exist Product memory product = products[position.productId]; if (margin > position.margin) { margin = position.margin; } uint256 size = (margin * position.leverage) / BASE; uint256 price = _calculatePrice( position.productId, !position.isLong, product.openInterestLong, product.openInterestShort, getMaxExposure(product.weight), product.reserve, size ); _updateFundingAndOpenInterest(position.productId, size, position.isLong, false); int256 fundingFee = getFundingFee(position.isLong, position.productId, size, position.funding); int256 pnl = getPnl(position.isLong, position.price, position.leverage, margin, price) - fundingFee; if (pnl < 0) { require(uint256(-1 * pnl) < (margin * liquidationThreshold) / PARAM_BASE, "position should be liquidated"); } uint256 tradeFee = (size * product.fee) / TRADEFEE_BASE; int256 pnlAfterFee = pnl - int256(tradeFee); if (pnlAfterFee < 0) { uint256 _pnlAfterFee = uint256(-1 * pnlAfterFee); if (_pnlAfterFee < margin) { IERC20(token).safeTransfer(position.owner, ((margin - _pnlAfterFee) * tokenBase) / BASE); vault.balance += _pnlAfterFee; } else { vault.balance += margin; } } else { uint256 _pnlAfterFee = uint256(pnlAfterFee); require(vault.balance >= _pnlAfterFee, "insufficient vault balance"); IERC20(token).safeTransfer(position.owner, ((margin + _pnlAfterFee) * tokenBase) / BASE); vault.balance -= _pnlAfterFee; } _updateFeeWithReferral(position.owner, tradeFee, size); vault.balance -= tradeFee; emit ClosePosition( positionKey, position.owner, false, position.productId, price, position.price, margin, position.leverage, pnl, fundingFee ); if (margin == position.margin) { IOrderManager(orderManager).cancelActiveCloseOrders(position.owner, position.productId, position.isLong); delete positions[positionKey]; } else { position.margin -= margin; } } function liquidatePositions(bytes32[] calldata positionKeys) external { require(liquidators[msg.sender], "!liquidator"); for (uint256 i = 0; i < positionKeys.length; ++i) { try this.liquidatePosition(positionKeys[i]) {} catch Error(string memory errorMessage) { emit LiquidationError(positionKeys[i], errorMessage); } catch (bytes memory) {} } } function liquidatePosition(bytes32 positionKey) external { require(msg.sender == address(this), "invalid liquidator"); Position memory position = positions[positionKey]; if (position.owner == address(0)) return; // position does not exist Product memory product = products[position.productId]; uint256 size = (position.margin * position.leverage) / BASE; uint256 price = IOracle(oracle).getPrice(position.productId); _updateFundingAndOpenInterest(position.productId, size, position.isLong, false); int256 fundingFee = getFundingFee(position.isLong, position.productId, size, position.funding); int256 pnl = getPnl(position.isLong, position.price, position.leverage, position.margin, price) - fundingFee; require( pnl < 0 && uint256(-1 * pnl) >= (position.margin * liquidationThreshold) / PARAM_BASE, "position is not liquidatable" ); uint256 tradeFee = (size * product.fee) / TRADEFEE_BASE; _updateFeeWithReferral(position.owner, tradeFee, size); vault.balance += position.margin - tradeFee; emit ClosePosition( positionKey, position.owner, true, position.productId, price, position.price, position.margin, position.leverage, -1 * int256(position.margin), fundingFee ); IOrderManager(orderManager).cancelActiveCloseOrders(position.owner, position.productId, position.isLong); delete positions[positionKey]; } function claimReferrerRebates() external nonReentrant { uint256 claimableReferrerRebates = totalReferrerRebates[msg.sender] - claimedReferrerRebates[msg.sender]; require(claimableReferrerRebates > 0, "Not claimable"); claimedReferrerRebates[msg.sender] += claimableReferrerRebates; IERC20(token).safeTransfer(msg.sender, claimableReferrerRebates); emit ClaimReferrerRebates(msg.sender, claimableReferrerRebates); } function claimTraderRebates() external nonReentrant { uint256 claimableTraderRebates = totalTraderRebates[msg.sender] - claimedTraderRebates[msg.sender]; require(claimableTraderRebates > 0, "Not claimable"); claimedTraderRebates[msg.sender] += claimableTraderRebates; IERC20(token).safeTransfer(msg.sender, claimableTraderRebates); emit ClaimTraderRebates(msg.sender, claimableTraderRebates); } function distributeVaultReward() external returns (uint256) { address _vaultRewardReceiver = vaultRewardReceiver; uint256 _pendingVaultReward = pendingVaultReward; require(msg.sender == _vaultRewardReceiver, "!vaultRewardReceiver"); if (_pendingVaultReward > 0) { pendingVaultReward = 0; IERC20(token).safeTransfer(_vaultRewardReceiver, _pendingVaultReward); emit DistributeVaultReward(_pendingVaultReward); } return _pendingVaultReward; } function distributeStakingReward() external returns (uint256) { address _stakingRewardReceiver = stakingRewardReceiver; uint256 _pendingStakingReward = pendingStakingReward; require(msg.sender == _stakingRewardReceiver, "!stakingRewardReceiver"); if (_pendingStakingReward > 0) { pendingStakingReward = 0; IERC20(token).safeTransfer(_stakingRewardReceiver, _pendingStakingReward); emit DistributeStakingReward(_pendingStakingReward); } return _pendingStakingReward; } function distributeTreasuryReward() external returns (uint256) { address _treasuryRewardReceiver = treasuryRewardReceiver; uint256 _pendingTreasuryReward = pendingTreasuryReward; require(msg.sender == _treasuryRewardReceiver, "!treasuryRewardReceiver"); if (_pendingTreasuryReward > 0) { pendingTreasuryReward = 0; IERC20(token).safeTransfer(_treasuryRewardReceiver, _pendingTreasuryReward); emit DistributeTreasuryReward(_pendingTreasuryReward); } return _pendingTreasuryReward; } function getMaxExposure(uint256 productWeight) public view returns (uint256) { return (vault.balance * productWeight * exposureMultiplier) / totalWeight / PARAM_BASE; } function getFundingRate(uint256 productId) public view returns (int256) { uint256 openInterestLong = products[productId].openInterestLong; uint256 openInterestShort = products[productId].openInterestShort; uint256 maxExposure = getMaxExposure(products[productId].weight); uint256 fundingMultiplier = fundings[productId].multiplier; uint256 _maxFundingRate = maxFundingRate; if (openInterestLong >= openInterestShort) { uint256 fundingRate = ((openInterestLong - openInterestShort) * fundingMultiplier) / maxExposure; if (fundingRate < _maxFundingRate) { return int256(fundingRate); } else { return int256(_maxFundingRate); } } else { uint256 fundingRate = ((openInterestShort - openInterestLong) * fundingMultiplier) / maxExposure; if (fundingRate < _maxFundingRate) { return -1 * int256(fundingRate); } else { return -1 * int256(_maxFundingRate); } } } function _calculatePrice( uint256 productId, bool isLong, uint256 openInterestLong, uint256 openInterestShort, uint256 maxExposure, uint256 reserve, uint256 amount ) private view returns (uint256) { uint256 oraclePrice = IOracle(oracle).getPrice(productId, isLong); if (reserve > 0) { int256 shift = ((int256(openInterestLong) - int256(openInterestShort)) * int256(maxShift)) / int256(maxExposure); if (isLong) { uint256 slippage = (((reserve * reserve) / (reserve - amount) - reserve) * BASE) / amount; slippage = shift >= 0 ? slippage + uint256(shift) : slippage - (uint256(-1 * shift) / shiftDivider); return (oraclePrice * slippage) / BASE; } else { uint256 slippage = ((reserve - (reserve * reserve) / (reserve + amount)) * BASE) / amount; slippage = shift >= 0 ? slippage + (uint256(shift) / shiftDivider) : slippage - uint256(-1 * shift); return (oraclePrice * slippage) / BASE; } } else { return oraclePrice; } } function _updateFundingAndOpenInterest(uint256 productId, uint256 amount, bool isLong, bool isIncrease) private { Funding storage funding = fundings[productId]; if (funding.timestamp != 0) { int256 fundingRate = getFundingRate(productId); funding.total += (fundingRate * int256(block.timestamp - funding.timestamp)) / int256(365 days); emit UpdateFunding(productId, funding.total, fundingRate); } funding.timestamp = block.timestamp; Product storage product = products[productId]; if (isIncrease) { totalOpenInterest += amount; requireVaultNotOverutilized(); uint256 maxExposure = getMaxExposure(product.weight); require( product.openInterestLong + product.openInterestShort + amount < (maxExposureMultiplier * maxExposure) / 10000, "!productOpenInterest" ); if (isLong) { product.openInterestLong += amount; require(product.openInterestLong <= product.openInterestShort + maxExposure, "!openInterestLong"); } else { product.openInterestShort += amount; require(product.openInterestShort <= product.openInterestLong + maxExposure, "!openInterestShort"); } } else { totalOpenInterest -= amount; if (isLong) { if (product.openInterestLong >= amount) { product.openInterestLong -= amount; } else { product.openInterestLong = 0; } } else { if (product.openInterestShort >= amount) { product.openInterestShort -= amount; } else { product.openInterestShort = 0; } } } } function requireVaultNotOverutilized() public view { require(totalOpenInterest <= (vault.balance * utilizationMultiplier) / PARAM_BASE, "vault is overutilized"); } function getFundingFee(bool isLong, uint256 productId, uint256 size, int256 funding) public view returns (int256) { return isLong ? (int256(size) * (fundings[productId].total - funding)) / int256(FUNDING_BASE) : (int256(size) * (funding - fundings[productId].total)) / int256(FUNDING_BASE); } function getPnl( bool isLong, uint256 positionPrice, uint256 positionLeverage, uint256 margin, uint256 price ) public pure returns (int256) { if (isLong) { if (price >= positionPrice) { return int256((margin * positionLeverage * (price - positionPrice)) / positionPrice / BASE); } else { return -1 * int256((margin * positionLeverage * (positionPrice - price)) / positionPrice / BASE); } } else { if (price > positionPrice) { return -1 * int256((margin * positionLeverage * (price - positionPrice)) / positionPrice / BASE); } else { return int256((margin * positionLeverage * (positionPrice - price)) / positionPrice / BASE); } } } function _updateFeeWithReferral(address user, uint256 tradeFee, uint256 size) private { (address referrer, uint256 referrerRebate, uint256 traderRebate) = IReferralManager(referralManager) .getReferrerInfo(user); uint256 _tradeFee = (tradeFee * tokenBase) / BASE; if (referrer != address(0)) { uint256 referrerRebateAmount = (_tradeFee * referrerRebate) / PARAM_BASE; uint256 traderRebateAmount = (_tradeFee * traderRebate) / PARAM_BASE; totalReferrerRebates[referrer] += referrerRebateAmount; totalTraderRebates[user] += traderRebateAmount; emit ReferralVolume(referrer, user, size); _updatePendingRewards(_tradeFee - referrerRebateAmount - traderRebateAmount); } else { _updatePendingRewards(_tradeFee); } } function _updatePendingRewards(uint256 reward) private { uint256 vaultReward = (reward * vaultRewardRatio) / PARAM_BASE; uint256 stakingReward = (reward * stakingRewardRatio) / PARAM_BASE; pendingVaultReward += vaultReward; pendingStakingReward += stakingReward; pendingTreasuryReward += reward - vaultReward - stakingReward; } function validateOpenPositionRequirements(uint256 margin, uint256 leverage, uint256 productId) external view { require(isOpenPositionEnabled, "open position is disabled"); require(margin >= minMargin && margin < type(uint64).max, "!margin"); require(leverage >= minLeverage, "!minLeverage"); require(products[productId].isActive, "!active"); require(leverage <= products[productId].maxLeverage, "!maxLeverage"); } function getVault() external view returns (Vault memory) { return vault; } function getVaultShares() external view returns (uint256) { return vault.shares; } function getStake(address user) external view returns (Stake memory) { return stakes[user]; } function getStakeShares(address user) external view returns (uint256) { return stakes[user].shares; } function getProduct(uint256 productId) external view returns (Product memory) { return products[productId]; } function getFunding(uint256 productId) external view returns (Funding memory) { return fundings[productId]; } function getPositionKey(address account, uint256 productId, bool isLong) public pure returns (bytes32) { return keccak256(abi.encodePacked(account, productId, isLong)); } function getPosition(address account, uint256 productId, bool isLong) external view returns (Position memory) { return positions[getPositionKey(account, productId, isLong)]; } function getPositionLeverage(address account, uint256 productId, bool isLong) external view returns (uint256) { return positions[getPositionKey(account, productId, isLong)].leverage; } function getUserPositions( address user, uint256 startId, uint256 endId ) external view returns (Position[] memory userPositions) { require(startId > 0, "!startId"); if (endId > totalProducts) endId = totalProducts; userPositions = new Position[]((endId - startId + 1) * 2); bytes32 positionKey; uint256 count; for (uint256 i = startId; i <= endId; ++i) { positionKey = getPositionKey(user, i, true); if (positions[positionKey].owner != address(0)) userPositions[count++] = positions[positionKey]; positionKey = getPositionKey(user, i, false); if (positions[positionKey].owner != address(0)) userPositions[count++] = positions[positionKey]; } } function getFundingData( uint256 startId, uint256 endId ) external view returns (int256[] memory fundingRates, int256[] memory fundingTotals) { require(startId > 0, "!startId"); if (endId > totalProducts) endId = totalProducts; fundingRates = new int256[]((endId - startId + 1) * 2); fundingTotals = new int256[]((endId - startId + 1) * 2); for (uint256 i = startId; i <= endId; ++i) { fundingRates[i - 1] = getFundingRate(i); fundingTotals[i - 1] = fundings[i].total; } } function getTradeFee(uint256 margin, uint256 leverage, uint256 productId) external view returns (uint256) { return (margin * leverage * products[productId].fee) / (BASE * TRADEFEE_BASE); } function getPendingVaultReward() external view returns (uint256) { return pendingVaultReward; } function getPendingStakingReward() external view returns (uint256) { return pendingStakingReward; } function getPendingTreasuryReward() external view returns (uint256) { return pendingTreasuryReward; } function setPeripheralContracts( address _oracle, address _referralManager, address _positionManager, address _orderManager, address _vaultRewardReceiver, address _stakingRewardReceiver, address _treasuryRewardReceiver, address _vaultRewardRouter ) external onlyGov { oracle = _oracle; referralManager = _referralManager; positionManager = _positionManager; orderManager = _orderManager; vaultRewardReceiver = _vaultRewardReceiver; stakingRewardReceiver = _stakingRewardReceiver; treasuryRewardReceiver = _treasuryRewardReceiver; vaultRewardRouter = _vaultRewardRouter; emit SetPeripheralContracts( _oracle, _referralManager, _positionManager, _orderManager, _vaultRewardReceiver, _stakingRewardReceiver, _treasuryRewardReceiver, _vaultRewardRouter ); } function updateVault(uint256 _cap, uint256 _minTime) external onlyGov { require(_minTime <= 3 days, "!minTime"); vault.cap = _cap; vault.minTime = _minTime; emit UpdateVault(vault); } function addProduct( uint256 productId, uint256 _maxLeverage, uint256 _fee, uint256 _weight, uint256 _reserve ) external onlyGov { require(productId > 0, "invalid productId"); Product memory product = products[productId]; require(product.maxLeverage == 0, "product exists"); require(_maxLeverage >= 1 * BASE && _fee <= 10 ** 3, "invalid product"); products[productId] = Product({ isActive: true, maxLeverage: _maxLeverage, fee: _fee, weight: _weight, reserve: _reserve, openInterestLong: 0, openInterestShort: 0 }); totalWeight += _weight; totalProducts += 1; emit AddProduct(productId, products[productId]); } function updateProduct( uint256 productId, bool _isActive, uint256 _maxLeverage, uint256 _fee, uint256 _weight, uint256 _reserve ) external onlyGov { require(productId > 0, "invalid productId"); Product storage product = products[productId]; require(product.maxLeverage > 0, "product not exists"); require(_maxLeverage >= 1 * BASE && _fee <= 10 ** 3, "invalid product"); totalWeight = totalWeight - product.weight + _weight; product.isActive = _isActive; product.maxLeverage = _maxLeverage; product.fee = _fee; product.weight = _weight; product.reserve = _reserve; emit UpdateProduct(productId, product); } function setFundingMultiplier(uint256 productId, uint256 multiplier) external onlyGov { fundings[productId].multiplier = multiplier; emit SetFundingMultiplier(productId, multiplier); } function setParameter(uint256 index, uint256 value) external onlyGov { require(index >= 1 && index <= 9, "invalid index for parameter"); if (index == 1) { require(value >= 25 * BASE, "invalid minMargin"); minMargin = value; } else if (index == 2) { require(value <= 1 * BASE, "invalid minLeverage"); minLeverage = value; } else if (index == 3) { require(value < 0.01e8, "invalid maxShift"); maxShift = value; } else if (index == 4) { require(value > 0, "invalid shiftDivider"); shiftDivider = value; } else if (index == 5) { require(value > 0, "invalid utilizationMultiplier"); utilizationMultiplier = value; } else if (index == 6) { require(value > 0, "invalid exposureMultiplier"); exposureMultiplier = value; } else if (index == 7) { require(value > 0, "invalid maxExposureMultiplier"); maxExposureMultiplier = value; } else if (index == 8) { require(value >= 9500, "invalid liquidationThreshold"); liquidationThreshold = value; } else if (index == 9) { require(value <= 10 * FUNDING_BASE, "invalid maxFundingRate"); maxFundingRate = value; } emit SetParameter(index, value); } function setRewardRatio(uint256 _vaultRewardRatio, uint256 _stakingRewardRatio) external onlyGov { require(_vaultRewardRatio + _stakingRewardRatio <= 10000); vaultRewardRatio = _vaultRewardRatio; stakingRewardRatio = _stakingRewardRatio; treasuryRewardRatio = 10000 - _vaultRewardRatio - _stakingRewardRatio; emit SetRewardRatio(vaultRewardRatio, stakingRewardRatio, treasuryRewardRatio); } function setLiquidator(address _liquidator, bool _isActive) external onlyGov { liquidators[_liquidator] = _isActive; emit SetLiquidator(_liquidator, _isActive); } function setGuardian(address _guardian, bool _isActive) external onlyGov { guardians[_guardian] = _isActive; emit SetGuardian(_guardian, _isActive); } function emergencyPause() external { require(guardians[msg.sender], "!guardian"); isOpenPositionEnabled = false; isStakeEnabled = false; emit EmergencyPause(block.timestamp); } function unpause() external onlyGov { isOpenPositionEnabled = true; isStakeEnabled = true; emit Unpause(block.timestamp); } }
/_openzeppelin/contracts/security/ReentrancyGuard.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @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 ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _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() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
/_openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
/_openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
/_openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
/_openzeppelin/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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); } } } }
/contracts/access/Governable.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Governable { address public gov; event SetGov(address indexed newGov); constructor() { gov = msg.sender; } modifier onlyGov() { require(msg.sender == gov, "Governable: forbidden"); _; } function setGov(address _gov) external onlyGov { gov = _gov; emit SetGov(_gov); } }
/contracts/interfaces/IOracle.sol
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IOracle { function getPrice(uint256 productId) external view returns (uint256); function getPrice(uint256 productId, bool isLong) external view returns (uint256); function setPrices(uint256[] memory productIds, uint256[] memory prices) external; }
/contracts/interfaces/IOrderManager.sol
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IOrderManager { function createCloseOrderForTPSL( address account, bool isLong, bool isTriggerAbove, uint256 productId, uint256 size, uint256 triggerPrice ) external payable; function cancelActiveCloseOrders( address account, uint256 productId, bool isLong ) external; }
/contracts/interfaces/IReferralManager.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IReferralManager { function getReferrerInfo(address _account) external view returns ( address, uint256, uint256 ); }
/contracts/interfaces/IVaultRewardRouter.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IVaultRewardRouter { function updateRewards(address account) external; }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_tokenBase","internalType":"uint256"}]},{"type":"event","name":"AddMargin","inputs":[{"type":"bytes32","name":"positionKey","internalType":"bytes32","indexed":true},{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"bool","name":"isLong","internalType":"bool","indexed":false},{"type":"uint256","name":"productId","internalType":"uint256","indexed":false},{"type":"uint256","name":"margin","internalType":"uint256","indexed":false},{"type":"uint256","name":"newMargin","internalType":"uint256","indexed":false},{"type":"uint256","name":"leverage","internalType":"uint256","indexed":false},{"type":"uint256","name":"newLeverage","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AddProduct","inputs":[{"type":"uint256","name":"productId","internalType":"uint256","indexed":false},{"type":"tuple","name":"product","internalType":"struct Dex.Product","indexed":false,"components":[{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint256","name":"maxLeverage","internalType":"uint256"},{"type":"uint256","name":"fee","internalType":"uint256"},{"type":"uint256","name":"weight","internalType":"uint256"},{"type":"uint256","name":"reserve","internalType":"uint256"},{"type":"uint256","name":"openInterestLong","internalType":"uint256"},{"type":"uint256","name":"openInterestShort","internalType":"uint256"}]}],"anonymous":false},{"type":"event","name":"ClaimReferrerRebates","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimTraderRebates","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ClosePosition","inputs":[{"type":"bytes32","name":"positionKey","internalType":"bytes32","indexed":true},{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"bool","name":"isLiquidated","internalType":"bool","indexed":false},{"type":"uint256","name":"productId","internalType":"uint256","indexed":false},{"type":"uint256","name":"price","internalType":"uint256","indexed":false},{"type":"uint256","name":"entryPrice","internalType":"uint256","indexed":false},{"type":"uint256","name":"margin","internalType":"uint256","indexed":false},{"type":"uint256","name":"leverage","internalType":"uint256","indexed":false},{"type":"int256","name":"pnl","internalType":"int256","indexed":false},{"type":"int256","name":"fundingFee","internalType":"int256","indexed":false}],"anonymous":false},{"type":"event","name":"DistributeStakingReward","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DistributeTreasuryReward","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DistributeVaultReward","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"EmergencyPause","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LiquidationError","inputs":[{"type":"bytes32","name":"positionKey","internalType":"bytes32","indexed":true},{"type":"string","name":"executionError","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"OpenPosition","inputs":[{"type":"bytes32","name":"positionKey","internalType":"bytes32","indexed":true},{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"bool","name":"isLong","internalType":"bool","indexed":false},{"type":"uint256","name":"productId","internalType":"uint256","indexed":false},{"type":"uint256","name":"margin","internalType":"uint256","indexed":false},{"type":"uint256","name":"leverage","internalType":"uint256","indexed":false},{"type":"uint256","name":"price","internalType":"uint256","indexed":false},{"type":"uint256","name":"fee","internalType":"uint256","indexed":false},{"type":"int256","name":"funding","internalType":"int256","indexed":false}],"anonymous":false},{"type":"event","name":"ReferralVolume","inputs":[{"type":"address","name":"referrer","internalType":"address","indexed":false},{"type":"address","name":"trader","internalType":"address","indexed":false},{"type":"uint256","name":"volume","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetFundingMultiplier","inputs":[{"type":"uint256","name":"productId","internalType":"uint256","indexed":false},{"type":"uint256","name":"multiplier","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetGov","inputs":[{"type":"address","name":"newGov","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"SetGuardian","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"bool","name":"isActive","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"SetLiquidator","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"bool","name":"isActive","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"SetParameter","inputs":[{"type":"uint256","name":"index","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetPeripheralContracts","inputs":[{"type":"address","name":"oracle","internalType":"address","indexed":false},{"type":"address","name":"referralManager","internalType":"address","indexed":false},{"type":"address","name":"positionManager","internalType":"address","indexed":false},{"type":"address","name":"orderManager","internalType":"address","indexed":false},{"type":"address","name":"vaultRewardReceiver","internalType":"address","indexed":false},{"type":"address","name":"stakingRewardReceiver","internalType":"address","indexed":false},{"type":"address","name":"treasuryRewardReceiver","internalType":"address","indexed":false},{"type":"address","name":"vaultRewardRouter","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetRewardRatio","inputs":[{"type":"uint256","name":"vaultRewardRatio","internalType":"uint256","indexed":false},{"type":"uint256","name":"stakingRewardRatio","internalType":"uint256","indexed":false},{"type":"uint256","name":"treasuryRewardRatio","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"StakeVault","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Unpause","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"UnstakeVault","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"uint256","name":"shareBalance","internalType":"uint256","indexed":false},{"type":"bool","name":"isFullRedeem","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateFunding","inputs":[{"type":"uint256","name":"productId","internalType":"uint256","indexed":false},{"type":"int256","name":"total","internalType":"int256","indexed":false},{"type":"int256","name":"fundingRate","internalType":"int256","indexed":false}],"anonymous":false},{"type":"event","name":"UpdateProduct","inputs":[{"type":"uint256","name":"productId","internalType":"uint256","indexed":false},{"type":"tuple","name":"product","internalType":"struct Dex.Product","indexed":false,"components":[{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint256","name":"maxLeverage","internalType":"uint256"},{"type":"uint256","name":"fee","internalType":"uint256"},{"type":"uint256","name":"weight","internalType":"uint256"},{"type":"uint256","name":"reserve","internalType":"uint256"},{"type":"uint256","name":"openInterestLong","internalType":"uint256"},{"type":"uint256","name":"openInterestShort","internalType":"uint256"}]}],"anonymous":false},{"type":"event","name":"UpdateVault","inputs":[{"type":"tuple","name":"vault","internalType":"struct Dex.Vault","indexed":false,"components":[{"type":"uint256","name":"cap","internalType":"uint256"},{"type":"uint256","name":"balance","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"shares","internalType":"uint256"},{"type":"uint256","name":"minTime","internalType":"uint256"}]}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addMargin","inputs":[{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"margin","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addProduct","inputs":[{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"uint256","name":"_maxLeverage","internalType":"uint256"},{"type":"uint256","name":"_fee","internalType":"uint256"},{"type":"uint256","name":"_weight","internalType":"uint256"},{"type":"uint256","name":"_reserve","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimReferrerRebates","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimTraderRebates","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimedReferrerRebates","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimedTraderRebates","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"closePosition","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"margin","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"distributeStakingReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"distributeTreasuryReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"distributeVaultReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"emergencyPause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"exposureMultiplier","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Dex.Funding","components":[{"type":"int256","name":"total","internalType":"int256"},{"type":"uint256","name":"timestamp","internalType":"uint256"},{"type":"uint256","name":"multiplier","internalType":"uint256"}]}],"name":"getFunding","inputs":[{"type":"uint256","name":"productId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256[]","name":"fundingRates","internalType":"int256[]"},{"type":"int256[]","name":"fundingTotals","internalType":"int256[]"}],"name":"getFundingData","inputs":[{"type":"uint256","name":"startId","internalType":"uint256"},{"type":"uint256","name":"endId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"getFundingFee","inputs":[{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"uint256","name":"size","internalType":"uint256"},{"type":"int256","name":"funding","internalType":"int256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"getFundingRate","inputs":[{"type":"uint256","name":"productId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getMaxExposure","inputs":[{"type":"uint256","name":"productWeight","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPendingStakingReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPendingTreasuryReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPendingVaultReward","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"getPnl","inputs":[{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"positionPrice","internalType":"uint256"},{"type":"uint256","name":"positionLeverage","internalType":"uint256"},{"type":"uint256","name":"margin","internalType":"uint256"},{"type":"uint256","name":"price","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Dex.Position","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"uint256","name":"margin","internalType":"uint256"},{"type":"uint256","name":"leverage","internalType":"uint256"},{"type":"uint256","name":"price","internalType":"uint256"},{"type":"int256","name":"funding","internalType":"int256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}]}],"name":"getPosition","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"bool","name":"isLong","internalType":"bool"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getPositionKey","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"bool","name":"isLong","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPositionLeverage","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"bool","name":"isLong","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Dex.Product","components":[{"type":"bool","name":"isActive","internalType":"bool"},{"type":"uint256","name":"maxLeverage","internalType":"uint256"},{"type":"uint256","name":"fee","internalType":"uint256"},{"type":"uint256","name":"weight","internalType":"uint256"},{"type":"uint256","name":"reserve","internalType":"uint256"},{"type":"uint256","name":"openInterestLong","internalType":"uint256"},{"type":"uint256","name":"openInterestShort","internalType":"uint256"}]}],"name":"getProduct","inputs":[{"type":"uint256","name":"productId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Dex.Stake","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"shares","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}]}],"name":"getStake","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getStakeShares","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTradeFee","inputs":[{"type":"uint256","name":"margin","internalType":"uint256"},{"type":"uint256","name":"leverage","internalType":"uint256"},{"type":"uint256","name":"productId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"userPositions","internalType":"struct Dex.Position[]","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"uint256","name":"margin","internalType":"uint256"},{"type":"uint256","name":"leverage","internalType":"uint256"},{"type":"uint256","name":"price","internalType":"uint256"},{"type":"int256","name":"funding","internalType":"int256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}]}],"name":"getUserPositions","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"startId","internalType":"uint256"},{"type":"uint256","name":"endId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Dex.Vault","components":[{"type":"uint256","name":"cap","internalType":"uint256"},{"type":"uint256","name":"balance","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"shares","internalType":"uint256"},{"type":"uint256","name":"minTime","internalType":"uint256"}]}],"name":"getVault","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getVaultShares","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"gov","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"guardians","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOpenPositionEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isStakeEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"liquidatePosition","inputs":[{"type":"bytes32","name":"positionKey","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"liquidatePositions","inputs":[{"type":"bytes32[]","name":"positionKeys","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidationThreshold","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"liquidators","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxExposureMultiplier","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxFundingRate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxShift","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minLeverage","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minMargin","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"openPosition","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"margin","internalType":"uint256"},{"type":"uint256","name":"leverage","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"oracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"orderManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"positionManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"bool","name":"isLong","internalType":"bool"},{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"uint256","name":"margin","internalType":"uint256"},{"type":"uint256","name":"leverage","internalType":"uint256"},{"type":"uint256","name":"price","internalType":"uint256"},{"type":"int256","name":"funding","internalType":"int256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"positions","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"referralManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[],"name":"requireVaultNotOverutilized","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFundingMultiplier","inputs":[{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"uint256","name":"multiplier","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGov","inputs":[{"type":"address","name":"_gov","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGuardian","inputs":[{"type":"address","name":"_guardian","internalType":"address"},{"type":"bool","name":"_isActive","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLiquidator","inputs":[{"type":"address","name":"_liquidator","internalType":"address"},{"type":"bool","name":"_isActive","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setParameter","inputs":[{"type":"uint256","name":"index","internalType":"uint256"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPeripheralContracts","inputs":[{"type":"address","name":"_oracle","internalType":"address"},{"type":"address","name":"_referralManager","internalType":"address"},{"type":"address","name":"_positionManager","internalType":"address"},{"type":"address","name":"_orderManager","internalType":"address"},{"type":"address","name":"_vaultRewardReceiver","internalType":"address"},{"type":"address","name":"_stakingRewardReceiver","internalType":"address"},{"type":"address","name":"_treasuryRewardReceiver","internalType":"address"},{"type":"address","name":"_vaultRewardRouter","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRewardRatio","inputs":[{"type":"uint256","name":"_vaultRewardRatio","internalType":"uint256"},{"type":"uint256","name":"_stakingRewardRatio","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"shiftDivider","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stakeVault","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stakeVaultToCompound","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakingRewardRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"stakingRewardReceiver","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"token","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalOpenInterest","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalProducts","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalReferrerRebates","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalTraderRebates","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalWeight","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"treasuryRewardRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"treasuryRewardReceiver","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unstakeVault","inputs":[{"type":"uint256","name":"shares","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateProduct","inputs":[{"type":"uint256","name":"productId","internalType":"uint256"},{"type":"bool","name":"_isActive","internalType":"bool"},{"type":"uint256","name":"_maxLeverage","internalType":"uint256"},{"type":"uint256","name":"_fee","internalType":"uint256"},{"type":"uint256","name":"_weight","internalType":"uint256"},{"type":"uint256","name":"_reserve","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateVault","inputs":[{"type":"uint256","name":"_cap","internalType":"uint256"},{"type":"uint256","name":"_minTime","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"utilizationMultiplier","inputs":[]},{"type":"function","stateMutability":"view","outputs":[],"name":"validateOpenPositionRequirements","inputs":[{"type":"uint256","name":"margin","internalType":"uint256"},{"type":"uint256","name":"leverage","internalType":"uint256"},{"type":"uint256","name":"productId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"vaultRewardRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"vaultRewardReceiver","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"vaultRewardRouter","inputs":[]}]
Contract Creation Code
0x60c0604052620000156305f5e1006019620000fd565b600d55620000296305f5e1006001620000fd565b600e5562030d40600f556014601055612710601155612ee060125561753060135561267a60145564e8d4a51000600a620000649190620000fd565b601555611770601655610fa0601755601c805461ffff19166101011790553480156200008f57600080fd5b50604051620060dd380380620060dd833981016040819052620000b2916200012b565b6001600081815581546001600160a01b0319163390811783556001600160a01b039490941660805260a092909252918152602660205260409020805460ff1916909117905562000167565b60008160001904831182151516156200012657634e487b7160e01b600052601160045260246000fd5b500290565b600080604083850312156200013f57600080fd5b82516001600160a01b03811681146200015757600080fd5b6020939093015192949293505050565b60805160a051615ef5620001e860003960008181611daf01528181612259015281816141010152818161421a015281816146c6015281816148c90152614c21015260008181610c8501528181611bb901528181611de801528181612a0d01528181612ed50152818161378701528181613de401526141480152615ef56000f3fe608060405234801561001057600080fd5b506004361061057f5760003560e01c80638d928af8116102d7578063be10ad6711610186578063db16e989116100e3578063f90cdb3611610097578063fbb48bc11161007c578063fbb48bc114610c78578063fc0c546a14610c80578063fcea330214610ca757600080fd5b8063f90cdb3614610c42578063f9b6117f14610c6557600080fd5b8063ebed4bd4116100c8578063ebed4bd414610be8578063f41807bd14610c1d578063f71f02b414610c2f57600080fd5b8063db16e98914610bcc578063eaf7762c14610bd557600080fd5b8063cf499b9d1161013a578063d468e2a91161011f578063d468e2a914610bb2578063d593f3a214610bbb578063d5c73dab14610bc357600080fd5b8063cf499b9d14610b96578063cfad57a214610b9f57600080fd5b8063c5dc77af1161016b578063c5dc77af14610b63578063c9063d4614610b76578063cd643e1914610b8957600080fd5b8063be10ad6714610b3d578063c04c0f5814610b5057600080fd5b8063a0448fc511610234578063b4f3cdbe116101e8578063b9db15b4116101cd578063b9db15b414610aa9578063bc95baad14610b14578063bdced6d514610b3457600080fd5b8063b4f3cdbe14610a81578063b6b74a4714610a8957600080fd5b8063a9b7fe5e11610219578063a9b7fe5e14610a2f578063b1d4d09814610a5b578063b27cdeaf14610a6e57600080fd5b8063a0448fc514610a13578063a881167814610a1c57600080fd5b806396cebadf1161028b5780639bf00b26116102705780639bf00b26146109e55780639d7c85b8146109f85780639f52a26114610a0057600080fd5b806396cebadf146109c95780639b9d326d146109dc57600080fd5b806393324cc0116102bc57806393324cc01461098d5780639676a9bc146109ad57806396c82e57146109c057600080fd5b80638d928af8146109305780639267fbbd1461097a57600080fd5b80634031234c116104335780635d1183b7116103905780637a76646011610344578063841a4b5111610329578063841a4b5114610901578063898c4e291461090a5780638b60a3ee1461091d57600080fd5b80637a7664601461089f5780637dc0d1d0146108ee57600080fd5b80636519c9d5116103755780636519c9d514610871578063719181f114610884578063791b98bc1461088c57600080fd5b80635d1183b71461083e57806361814d041461085157600080fd5b806351858e27116103e75780635828a437116103cc5780635828a4371461080f5780635941dfbd146108225780635b3829891461083557600080fd5b806351858e27146107e65780635387b1b9146107ee57600080fd5b80634453a374116104185780634453a37414610717578063467405011461072a578063514ea4bf1461074a57600080fd5b80634031234c146106ee5780634353d7d4146106f757600080fd5b80632b8a1c5a116104e157806336b1b89f116104955780633b836ddc1161047a5780633b836ddc146106cb5780633ee19763146106de5780633f4ba83a146106e657600080fd5b806336b1b89f146106ba57806339c294be146106c257600080fd5b80632ccd9623116104c65780632ccd96231461068b578063314d794d1461069e5780633504c47b146106a757600080fd5b80632b8a1c5a1461066f5780632c35e7691461068257600080fd5b806312ee63f31161053857806314d8353f1161051d57806314d8353f1461064057806320f6f76f1461065357806321707f301461065c57600080fd5b806312ee63f314610625578063142d80d81461063857600080fd5b80630599a400116105695780630599a400146105bf5780630633b14a146105c757806312d43a51146105fa57600080fd5b80621b7934146105845780630298e27314610599575b600080fd5b6105976105923660046154dc565b610caf565b005b6105ac6105a7366004615524565b610d91565b6040519081526020015b60405180910390f35b610597610de5565b6105ea6105d5366004615566565b60266020526000908152604090205460ff1681565b60405190151581526020016105b6565b60015461060d906001600160a01b031681565b6040516001600160a01b0390911681526020016105b6565b6105976106333660046154dc565b610e55565b601b546105ac565b61059761064e366004615583565b6112d8565b6105ac600e5481565b61059761066a3660046155cb565b6112f2565b61059761067d3660046155f7565b611476565b6105ac60165481565b60035461060d906001600160a01b031681565b6105ac60175481565b60085461060d906001600160a01b031681565b601a546105ac565b6105ac600d5481565b6105976106d9366004615630565b611528565b6019546105ac565b610597611591565b6105ac60145481565b6105ac610705366004615566565b60216020526000908152604090205481565b6105976107253660046155f7565b611628565b6105ac610738366004615566565b60246020526000908152604090205481565b6107a1610758366004615630565b602080526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b03861696600160a01b90960460ff16959088565b604080516001600160a01b0390991689529615156020890152958701949094526060860192909252608085015260a084015260c083015260e0820152610100016105b6565b6105976116d2565b6108016107fc3660046154dc565b61176c565b6040516105b6929190615684565b6105ac61081d366004615630565b61190d565b6105976108303660046156a9565b61194d565b6105ac60115481565b61059761084c366004615630565b611a93565b6105ac61085f366004615566565b60236020526000908152604090205481565b6105ac61087f3660046155cb565b611af4565b6105ac611b3f565b60045461060d906001600160a01b031681565b6108b26108ad366004615566565b611c1a565b6040516105b6919081516001600160a01b0316815260208083015190820152604080830151908201526060918201519181019190915260800190565b60025461060d906001600160a01b031681565b6105ac60125481565b610597610918366004615752565b611c9f565b61059761092b3660046154dc565b611e89565b610938611f8a565b6040516105b69190600060a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015292915050565b61059761098836600461578a565b611ff1565b6109a061099b3660046157dc565b61261d565b6040516105b69190615811565b60075461060d906001600160a01b031681565b6105ac600b5481565b6105ac6109d73660046158b4565b6128e9565b6105ac600a5481565b6105ac6109f3366004615524565b612967565b6105ac612993565b6105ac610a0e366004615630565b612a64565b6105ac600f5481565b6105ac610a2a3660046158ef565b612b42565b6105ac610a3d366004615566565b6001600160a01b03166000908152601d602052604090206002015490565b610597610a69366004615933565b612bfc565b60065461060d906001600160a01b031681565b610597612de6565b6105ac610a97366004615566565b60226020526000908152604090205481565b610abc610ab7366004615630565b612f3a565b6040516105b69190600060e0820190508251151582526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015292915050565b610b27610b22366004615524565b612fe4565b6040516105b69190615983565b6105ac60105481565b60095461060d906001600160a01b031681565b610597610b5e3660046159e6565b6130c8565b610597610b71366004615a5b565b61325f565b610597610b84366004615a96565b613538565b601c546105ea9060ff1681565b6105ac60185481565b610597610bad366004615566565b6135fc565b6105ac600c5481565b610597613698565b6105ac60135481565b6105ac60155481565b610597610be3366004615630565b6137e0565b610bfb610bf6366004615630565b613c70565b60408051825181526020808401519082015291810151908201526060016105b6565b601c546105ea90610100900460ff1681565b610597610c3d3660046154dc565b613ccd565b6105ea610c50366004615566565b60256020526000908152604090205460ff1681565b60055461060d906001600160a01b031681565b6105ac613d6a565b61060d7f000000000000000000000000000000000000000000000000000000000000000081565b602a546105ac565b6001546001600160a01b03163314610d065760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b60448201526064015b60405180910390fd5b612710610d138284615ad8565b1115610d1e57600080fd5b6016829055601781905580610d3583612710615aeb565b610d3f9190615aeb565b60188190556016546017546040805192835260208301919091528101919091527fda6a2f16e321508fdfc20dc87c11fd48f45b93b4367ca5346d783f894b3640a4906060015b60405180910390a15050565b6040516bffffffffffffffffffffffff19606085901b1660208201526034810183905281151560f81b60548201526000906055016040516020818303038152906040528051906020012090505b9392505050565b60115460285461271091610df891615afe565b610e029190615b33565b600c541115610e535760405162461bcd60e51b815260206004820152601560248201527f7661756c74206973206f7665727574696c697a656400000000000000000000006044820152606401610cfd565b565b6001546001600160a01b03163314610ea75760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b60018210158015610eb9575060098211155b610f055760405162461bcd60e51b815260206004820152601b60248201527f696e76616c696420696e64657820666f7220706172616d6574657200000000006044820152606401610cfd565b81600103610f7557610f1c6305f5e1006019615afe565b811015610f6b5760405162461bcd60e51b815260206004820152601160248201527f696e76616c6964206d696e4d617267696e0000000000000000000000000000006044820152606401610cfd565b600d8190556112a2565b81600203610fe557610f8c6305f5e1006001615afe565b811115610fdb5760405162461bcd60e51b815260206004820152601360248201527f696e76616c6964206d696e4c65766572616765000000000000000000000000006044820152606401610cfd565b600e8190556112a2565b8160030361104957620f4240811061103f5760405162461bcd60e51b815260206004820152601060248201527f696e76616c6964206d61785368696674000000000000000000000000000000006044820152606401610cfd565b600f8190556112a2565b816004036110ab57600081116110a15760405162461bcd60e51b815260206004820152601460248201527f696e76616c6964207368696674446976696465720000000000000000000000006044820152606401610cfd565b60108190556112a2565b8160050361110d57600081116111035760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964207574696c697a6174696f6e4d756c7469706c6965720000006044820152606401610cfd565b60118190556112a2565b8160060361116f57600081116111655760405162461bcd60e51b815260206004820152601a60248201527f696e76616c6964206578706f737572654d756c7469706c6965720000000000006044820152606401610cfd565b60128190556112a2565b816007036111d157600081116111c75760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964206d61784578706f737572654d756c7469706c6965720000006044820152606401610cfd565b60138190556112a2565b816008036112355761251c81101561122b5760405162461bcd60e51b815260206004820152601c60248201527f696e76616c6964206c69717569646174696f6e5468726573686f6c64000000006044820152606401610cfd565b60148190556112a2565b816009036112a25761124d64e8d4a51000600a615afe565b81111561129c5760405162461bcd60e51b815260206004820152601660248201527f696e76616c6964206d617846756e64696e6752617465000000000000000000006044820152606401610cfd565b60158190555b60408051838152602081018390527f7f10293466b199a9daa697555ec2f3510429f81493f7b208907e0f63f811cd9d9101610d85565b6112ec6112e6858585610d91565b82613e3b565b50505050565b601c54610100900460ff166113495760405162461bcd60e51b815260206004820152601960248201527f6f70656e20706f736974696f6e2069732064697361626c6564000000000000006044820152606401610cfd565b600d548310158015611362575067ffffffffffffffff83105b6113985760405162461bcd60e51b815260206004820152600760248201526610b6b0b933b4b760c91b6044820152606401610cfd565b600e548210156113d95760405162461bcd60e51b815260206004820152600c60248201526b216d696e4c6576657261676560a01b6044820152606401610cfd565b6000818152601e602052604090205460ff166114215760405162461bcd60e51b81526020600482015260076024820152662161637469766560c81b6044820152606401610cfd565b6000818152601e60205260409020600101548211156114715760405162461bcd60e51b815260206004820152600c60248201526b216d61784c6576657261676560a01b6044820152606401610cfd565b505050565b6001546001600160a01b031633146114c85760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6001600160a01b038216600081815260266020908152604091829020805460ff191685151590811790915591519182527fca139a0ba60fe6426dd1d713a05ec0c645224f72d7a9912d64163974672dd41091015b60405180910390a25050565b60026000540361157a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000556115893382614419565b506001600055565b6001546001600160a01b031633146115e35760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b601c805461ffff19166101011790556040514281527faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab7906020015b60405180910390a1565b6001546001600160a01b0316331461167a5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6001600160a01b038216600081815260256020908152604091829020805460ff191685151590811790915591519182527f8c0d56805c3b43d441481229dc64bee168253ffe4305f37ab7cfe63b1c4268c6910161151c565b3360009081526026602052604090205460ff166117315760405162461bcd60e51b815260206004820152600960248201527f21677561726469616e00000000000000000000000000000000000000000000006044820152606401610cfd565b601c805461ffff191690556040514281527f587f3b25da67017c0da715067ea23a00ce02a7692dde05787d04b933a06881989060200161161e565b606080600084116117aa5760405162461bcd60e51b8152602060048201526008602482015267085cdd185c9d125960c21b6044820152606401610cfd565b600a548311156117ba57600a5492505b6117c48484615aeb565b6117cf906001615ad8565b6117da906002615afe565b67ffffffffffffffff8111156117f2576117f2615b47565b60405190808252806020026020018201604052801561181b578160200160208202803683370190505b5091506118288484615aeb565b611833906001615ad8565b61183e906002615afe565b67ffffffffffffffff81111561185657611856615b47565b60405190808252806020026020018201604052801561187f578160200160208202803683370190505b509050835b8381116119055761189481612a64565b836118a0600184615aeb565b815181106118b0576118b0615b5d565b6020908102919091018101919091526000828152601f9091526040902054826118da600184615aeb565b815181106118ea576118ea615b5d565b60209081029190910101526118fe81615b73565b9050611884565b509250929050565b6000612710600b54601254846027600101546119299190615afe565b6119339190615afe565b61193d9190615b33565b6119479190615b33565b92915050565b6001546001600160a01b0316331461199f5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b600280546001600160a01b038a81166001600160a01b03199283168117909355600380548b83169084168117909155600480548b84169085168117909155600580548b85169086168117909155600680548b86169087168117909155600780548b87169088168117909155600880548b8816908916811790915560098054978b16979098168717909755604080519889526020890195909552938701929092526060860152608085015260a084015260c083019190915260e08201527fded06d7bb35efa21cebe10555e7a0aad5a54d7c953203147308cf4fa431aac4d906101000160405180910390a15050505050505050565b600260005403611ae55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000556115893382614747565b6000611b07620186a06305f5e100615afe565b6000838152601e6020526040902060020154611b238587615afe565b611b2d9190615afe565b611b379190615b33565b949350505050565b600754601a546000916001600160a01b031690338214611ba15760405162461bcd60e51b815260206004820152601660248201527f217374616b696e675265776172645265636569766572000000000000000000006044820152606401610cfd565b8015611947576000601a55611be06001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168383614ad1565b6040518181527fcb85a20151ba0100ff8fdc798814296495ac8af2552b7fb99ce1da63e5d94be8906020015b60405180910390a192915050565b611c4e604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b506001600160a01b039081166000908152601d602090815260409182902082516080810184528154909416845260018101549184019190915260028101549183019190915260030154606082015290565b600260005403611cf15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000908155611d03338585610d91565b60008181526020805260408120600281015492935091611d24908590615ad8565b9050600082600301549050600082846002015483611d429190615afe565b611d4c9190615b33565b9050600e54811015611da05760405162461bcd60e51b815260206004820152600c60248201527f216d696e6c6576657261676500000000000000000000000000000000000000006044820152606401610cfd565b611e1033306305f5e100611dd47f00000000000000000000000000000000000000000000000000000000000000008b615afe565b611dde9190615b33565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016929190614b61565b6002840183905560038401819055604080518815158152602081018a9052908101879052606081018490526080810183905260a08101829052339086907ff91ad36a8598bc6a2da3411a0d0a8b41adffeb5a0d884fbef52e87248ec1c3019060c00160405180910390a350506001600055505050505050565b6001546001600160a01b03163314611edb5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6203f480811115611f2e5760405162461bcd60e51b815260206004820152600860248201527f216d696e54696d650000000000000000000000000000000000000000000000006044820152606401610cfd565b6027829055602b81905560408051838152602854602082015260295491810191909152602a546060820152608081018290527f7edc5e603c0e26d9ddf55b2e00957979b5a257cc6d16bcce68ba7c3918a78bf49060a001610d85565b611fbc6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b506040805160a0810182526027548152602854602082015260295491810191909152602a546060820152602b54608082015290565b601c54610100900460ff166120485760405162461bcd60e51b815260206004820152601960248201527f6f70656e20706f736974696f6e2069732064697361626c6564000000000000006044820152606401610cfd565b6004546001600160a01b031633148061206b57506005546001600160a01b031633145b6120a25760405162461bcd60e51b815260206004820152600860248201526710b6b0b730b3b2b960c11b6044820152606401610cfd565b600d5482101580156120bb575067ffffffffffffffff82105b6120f15760405162461bcd60e51b815260206004820152600760248201526610b6b0b933b4b760c91b6044820152606401610cfd565b600e548110156121325760405162461bcd60e51b815260206004820152600c60248201526b216d696e4c6576657261676560a01b6044820152606401610cfd565b6000848152601e6020908152604091829020825160e081018452815460ff1615158082526001830154938201939093526002820154938101939093526003810154606084015260048101546080840152600581015460a08401526006015460c08301526121cb5760405162461bcd60e51b81526020600482015260076024820152662161637469766560c81b6044820152606401610cfd565b806020015182111561220e5760405162461bcd60e51b815260206004820152600c60248201526b216d61784c6576657261676560a01b6044820152606401610cfd565b60006305f5e10061221f8486615afe565b6122299190615b33565b90506000620186a08360400151836122419190615afe565b61224b9190615b33565b905061228c33306305f5e1007f0000000000000000000000000000000000000000000000000000000000000000612282868b615ad8565b611dd49190615afe565b612297888284614b99565b60006122c088888660a001518760c001516122b5896060015161190d565b896080015189614d75565b90506122cf8884896001614f4c565b6000888152601f6020526040812054906122ea8b8b8b610d91565b6000818152602080805260409182902082516101008101845281546001600160a01b0381168252600160a01b900460ff1615159281019290925260018101549282019290925260028201546060820181905260038301546080830152600483015460a0830152600583015460c083015260069092015460e0820152919250156124b057612377888a615afe565b8160800151826060015161238b9190615afe565b6123959190615ad8565b846123a08a8c615afe565b6123aa9190615afe565b8260a00151836080015184606001516123c39190615afe565b6123cd9190615afe565b6123d79190615ad8565b6123e19190615b33565b93506123ed888a615afe565b816080015182606001516124019190615afe565b61240b9190615ad8565b836124168a8c615afe565b6124209190615b8c565b8260c00151836080015184606001516124399190615afe565b6124439190615b8c565b61244d9190615c2c565b6124579190615c54565b92508881606001516124699190615ad8565b612473898b615afe565b826080015183606001516124879190615afe565b6124919190615ad8565b61249b9190615b33565b97508881606001516124ad9190615ad8565b98505b6040518061010001604052808d6001600160a01b031681526020018b151581526020018c81526020018a8152602001898152602001858152602001848152602001428152506020600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160010155606082015181600201556080820151816003015560a0820151816004015560c0820151816005015560e082015181600601559050508b6001600160a01b0316827fcdbc2dc3244091bcbe6ae9efa60147af3ff947bc20a4ccb3f38f0c4b0d03a69e8c8e8d8d8a8c8b60405161260797969594939291909615158752602087019590955260408601939093526060850191909152608084015260a083015260c082015260e00190565b60405180910390a3505050505050505050505050565b60606000831161265a5760405162461bcd60e51b8152602060048201526008602482015267085cdd185c9d125960c21b6044820152606401610cfd565b600a5482111561266a57600a5491505b6126748383615aeb565b61267f906001615ad8565b61268a906002615afe565b67ffffffffffffffff8111156126a2576126a2615b47565b60405190808252806020026020018201604052801561272657816020015b61271360405180610100016040528060006001600160a01b031681526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816126c05790505b509050600080845b8481116128df5761274187826001610d91565b60008181526020805260409020549093506001600160a01b031615612802576000838152602080805260409182902082516101008101845281546001600160a01b0381168252600160a01b900460ff161515928101929092526001810154928201929092526002820154606082015260038201546080820152600482015460a0820152600582015460c082015260069091015460e082015284836127e481615b73565b9450815181106127f6576127f6615b5d565b60200260200101819052505b61280e87826000610d91565b60008181526020805260409020549093506001600160a01b0316156128cf576000838152602080805260409182902082516101008101845281546001600160a01b0381168252600160a01b900460ff161515928101929092526001810154928201929092526002820154606082015260038201546080820152600482015460a0820152600582015460c082015260069091015460e082015284836128b181615b73565b9450815181106128c3576128c3615b5d565b60200260200101819052505b6128d881615b73565b905061272e565b5050509392505050565b600084612929576000848152601f602052604090205464e8d4a51000906129109084615c82565b61291a9085615b8c565b6129249190615c54565b61295e565b6000848152601f602052604090205464e8d4a510009061294a908490615c82565b6129549085615b8c565b61295e9190615c54565b95945050505050565b600060206000612978868686610d91565b81526020019081526020016000206003015490509392505050565b600854601b546000916001600160a01b0316903382146129f55760405162461bcd60e51b815260206004820152601760248201527f21747265617375727952657761726452656365697665720000000000000000006044820152606401610cfd565b8015611947576000601b55612a346001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168383614ad1565b6040518181527f927cfccbec41ad4e05c94dc1d4b87d408e3642b8658ad3533bcd8e388ec9608690602001611c0c565b6000818152601e60205260408120600581015460068201546003909201549091908390612a909061190d565b6000868152601f602052604090206002015460155491925090838510612af25760008383612abe8789615aeb565b612ac89190615afe565b612ad29190615b33565b905081811015612ae757979650505050505050565b509695505050505050565b60008383612b008888615aeb565b612b0a9190615afe565b612b149190615b33565b905081811015612b3657612b2a81600019615b8c565b98975050505050505050565b612b2a82600019615b8c565b60008515612bd457848210612b90576305f5e10085612b618185615aeb565b612b6b8787615afe565b612b759190615afe565b612b7f9190615b33565b612b899190615b33565b905061295e565b6305f5e10085612ba08482615aeb565b612baa8787615afe565b612bb49190615afe565b612bbe9190615b33565b612bc89190615b33565b612b8990600019615b8c565b84821115612bec576305f5e10085612ba08185615aeb565b6305f5e10085612b618482615aeb565b6001546001600160a01b03163314612c4e5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b60008611612c9e5760405162461bcd60e51b815260206004820152601160248201527f696e76616c69642070726f6475637449640000000000000000000000000000006044820152606401610cfd565b6000868152601e602052604090206001810154612cfd5760405162461bcd60e51b815260206004820152601260248201527f70726f64756374206e6f742065786973747300000000000000000000000000006044820152606401610cfd565b612d0c6305f5e1006001615afe565b8510158015612d1d57506103e88411155b612d5b5760405162461bcd60e51b815260206004820152600f60248201526e1a5b9d985b1a59081c1c9bd91d58dd608a1b6044820152606401610cfd565b828160030154600b54612d6e9190615aeb565b612d789190615ad8565b600b55805460ff1916861515178155600181018590556002810184905560038101839055600481018290556040517f671b664bc17ffb1bd8deec8712115ea465623dc19db8f430db209ebf58447c2390612dd59089908490615ca9565b60405180910390a150505050505050565b600260005403612e385760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000908155338152602460209081526040808320546022909252822054612e619190615aeb565b905060008111612ea35760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b6044820152606401610cfd565b3360009081526024602052604081208054839290612ec2908490615ad8565b90915550612efc90506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383614ad1565b60405181815233907ffce929d82f3f52a0bb629ea34072d9edb26cda5dad81a678ebadaaebdcb0d787906020015b60405180910390a2506001600055565b612f7c6040518060e001604052806000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b506000908152601e6020908152604091829020825160e081018452815460ff16151581526001820154928101929092526002810154928201929092526003820154606082015260048201546080820152600582015460a082015260069091015460c082015290565b61303760405180610100016040528060006001600160a01b031681526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60206000613046868686610d91565b8152602080820192909252604090810160002081516101008101835281546001600160a01b0381168252600160a01b900460ff161515938101939093526001810154918301919091526002810154606083015260038101546080830152600481015460a0830152600581015460c08301526006015460e0820152949350505050565b3360009081526025602052604090205460ff166131275760405162461bcd60e51b815260206004820152600b60248201527f216c697175696461746f720000000000000000000000000000000000000000006044820152606401610cfd565b60005b81811015611471573063eaf7762c84848481811061314a5761314a615b5d565b905060200201356040518263ffffffff1660e01b815260040161316f91815260200190565b600060405180830381600087803b15801561318957600080fd5b505af192505050801561319a575060015b61324f576131a6615cfe565b806308c379a00361321b57506131ba615d55565b806131c5575061321d565b8383838181106131d7576131d7615b5d565b905060200201357ff8b325a0f68bd6a0d905e40b1937cbdd30c82d1334d58ef461a3f301f95d26408260405161320d9190615e03565b60405180910390a25061324f565b505b3d808015613247576040519150601f19603f3d011682016040523d82523d6000602084013e61324c565b606091505b50505b61325881615b73565b905061312a565b6001546001600160a01b031633146132b15760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b600085116133015760405162461bcd60e51b815260206004820152601160248201527f696e76616c69642070726f6475637449640000000000000000000000000000006044820152606401610cfd565b6000858152601e6020908152604091829020825160e081018452815460ff161515815260018201549281018390526002820154938101939093526003810154606084015260048101546080840152600581015460a08401526006015460c0830152156133af5760405162461bcd60e51b815260206004820152600e60248201527f70726f64756374206578697374730000000000000000000000000000000000006044820152606401610cfd565b6133be6305f5e1006001615afe565b85101580156133cf57506103e88411155b61340d5760405162461bcd60e51b815260206004820152600f60248201526e1a5b9d985b1a59081c1c9bd91d58dd608a1b6044820152606401610cfd565b6040518060e00160405280600115158152602001868152602001858152602001848152602001838152602001600081526020016000815250601e600088815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015590505082600b60008282546134c99190615ad8565b925050819055506001600a60008282546134e39190615ad8565b90915550506000868152601e60205260409081902090517f469ee7ec42e733d8a370e7ec08d7207f3c365b67384980c45e0592322a5e7a159161352891899190615ca9565b60405180910390a1505050505050565b60026000540361358a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000556006546001600160a01b031633146135e95760405162461bcd60e51b815260206004820152601460248201527f217661756c7452657761726452656365697665720000000000000000000000006044820152606401610cfd565b6135f38282614747565b50506001600055565b6001546001600160a01b0316331461364e5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f91a8c1cc2d4a3bb60738481947a00cbb9899c822916694cf8bb1d68172fdcd5490600090a250565b6002600054036136ea5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b600260009081553381526023602090815260408083205460219092528220546137139190615aeb565b9050600081116137555760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b6044820152606401610cfd565b3360009081526023602052604081208054839290613774908490615ad8565b909155506137ae90506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163383614ad1565b60405181815233907f4ff9eb307c447e363f7b7787fede06c88dd950603ca0516f7a066db07c267c2790602001612f2a565b33301461382f5760405162461bcd60e51b815260206004820152601260248201527f696e76616c6964206c697175696461746f7200000000000000000000000000006044820152606401610cfd565b6000818152602080805260409182902082516101008101845281546001600160a01b038116808352600160a01b90910460ff161515938201939093526001820154938101939093526002810154606084015260038101546080840152600481015460a0840152600581015460c08401526006015460e08301526138b0575050565b6040808201516000908152601e6020908152828220835160e081018552815460ff161515815260018201549281019290925260028101549382019390935260038301546060808301919091526004840154608080840191909152600585015460a084015260069094015460c0830152928401519284015190926305f5e100916139399190615afe565b6139439190615b33565b6002546040808601519051630e75722360e41b81529293506000926001600160a01b039092169163e7572230916139809160040190815260200190565b602060405180830381865afa15801561399d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139c19190615e36565b90506139d884604001518386602001516000614f4c565b60006139f285602001518660400151858860c001516128e9565b9050600081613a1487602001518860a0015189608001518a6060015188612b42565b613a1e9190615c82565b9050600081128015613a5957506127106014548760600151613a409190615afe565b613a4a9190615b33565b613a5682600019615b8c565b10155b613aa55760405162461bcd60e51b815260206004820152601c60248201527f706f736974696f6e206973206e6f74206c6971756964617461626c65000000006044820152606401610cfd565b6000620186a0866040015186613abb9190615afe565b613ac59190615b33565b9050613ad687600001518287614b99565b808760600151613ae69190615aeb565b60288054600090613af8908490615ad8565b9250508190555086600001516001600160a01b0316887f7c48994a8239b7b26e8de511662287f8456af2226eab8a3c71246311f2ac790660018a60400151888c60a001518d606001518e608001518f60600151600019613b589190615b8c565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e081018790526101000160405180910390a360055487516040808a015160208b01519151636599e85f60e11b81526001600160a01b0393841660048201526024810191909152901515604482015291169063cb33d0be90606401600060405180830381600087803b158015613bfc57600080fd5b505af1158015613c10573d6000803e3d6000fd5b5050506000988952505060208052505060408520805474ffffffffffffffffffffffffffffffffffffffffff1916815560018101869055600281018690556003810186905560048101869055600581018690556006019490945550505050565b613c9460405180606001604052806000815260200160008152602001600081525090565b506000908152601f6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6001546001600160a01b03163314613d1f5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6000828152601f602090815260409182902060020183905581518481529081018390527f4000829eec8ecb2dfc624cba376ec9b4cfe1167cf0613669d4d9559aafa7adad9101610d85565b6006546019546000916001600160a01b031690338214613dcc5760405162461bcd60e51b815260206004820152601460248201527f217661756c7452657761726452656365697665720000000000000000000000006044820152606401610cfd565b8015611947576000601955613e0b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168383614ad1565b6040518181527f97d3c68ccc07e002f029fb1d914cb534343b865ea8344f3543d3e9ea401ab08d90602001611c0c565b6004546001600160a01b0316331480613e5e57506005546001600160a01b031633145b613e955760405162461bcd60e51b815260206004820152600860248201526710b6b0b730b3b2b960c11b6044820152606401610cfd565b80600003613ea1575050565b6000828152602080526040902080546001600160a01b0316613ec257505050565b6001808201546000908152601e6020908152604091829020825160e081018452815460ff16151581529381015491840191909152600280820154928401929092526003810154606084015260048101546080840152600581015460a08401526006015460c0830152820154831115613f3c57816002015492505b60006305f5e100836003015485613f539190615afe565b613f5d9190615b33565b90506000613f9e84600101548560000160149054906101000a900460ff16158560a001518660c00151613f93886060015161190d565b886080015188614d75565b60018501548554919250613fbf918490600160a01b900460ff166000614f4c565b6000613fe68560000160149054906101000a900460ff1686600101548588600501546128e9565b90506000816140118760000160149054906101000a900460ff16886004015489600301548b88612b42565b61401b9190615c82565b9050600081121561409a57612710601454886140379190615afe565b6140419190615b33565b61404d82600019615b8c565b1061409a5760405162461bcd60e51b815260206004820152601d60248201527f706f736974696f6e2073686f756c64206265206c6971756964617465640000006044820152606401610cfd565b6000620186a08660400151866140b09190615afe565b6140ba9190615b33565b905060006140c88284615c82565b905060008112156141b05760006140e182600019615b8c565b90508981101561418f57885461416f906001600160a01b03166305f5e1007f000000000000000000000000000000000000000000000000000000000000000061412a858f615aeb565b6141349190615afe565b61413e9190615b33565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169190614ad1565b80602760010160008282546141849190615ad8565b909155506141aa9050565b89602760010160008282546141a49190615ad8565b90915550505b5061425f565b60285481908111156142045760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207661756c742062616c616e63650000000000006044820152606401610cfd565b8854614243906001600160a01b03166305f5e1007f000000000000000000000000000000000000000000000000000000000000000061412a858f615ad8565b80602760010160008282546142589190615aeb565b9091555050505b8754614275906001600160a01b03168388614b99565b816027600101600082825461428a9190615aeb565b90915550508754600189015460048a015460038b01546040805160008152602081019490945283018990526060830191909152608082018c905260a082015260c0810185905260e081018690526001600160a01b03909116908b907f7c48994a8239b7b26e8de511662287f8456af2226eab8a3c71246311f2ac7906906101000160405180910390a3876002015489036143f357600554885460018a0154604051636599e85f60e11b81526001600160a01b0380841660048301526024820192909252600160a01b90920460ff16151560448301529091169063cb33d0be90606401600060405180830381600087803b15801561438657600080fd5b505af115801561439a573d6000803e3d6000fd5b50505060008b81526020805260408120805474ffffffffffffffffffffffffffffffffffffffffff191681556001810182905560028101829055600381018290556004810182905560058101829055600601555061440d565b888860020160008282546144079190615aeb565b90915550505b50505050505050505050565b600081116144695760405162461bcd60e51b815260206004820152601560248201527f7368617265732063616e6e6f74206265207a65726f00000000000000000000006044820152606401610cfd565b6001600160a01b0382166000908152601d6020526040902060018101546144d25760405162461bcd60e51b815260206004820152601560248201527f75736572206e6f207374616b656420616d6f756e7400000000000000000000006044820152606401610cfd565b6003810154602b546144e49190615ad8565b42116145325760405162461bcd60e51b815260206004820152600e60248201527f217661756c742e6d696e54696d650000000000000000000000000000000000006044820152606401610cfd565b600954604051635fd6196560e01b81526001600160a01b03858116600483015290911690635fd6196590602401600060405180830381600087803b15801561457957600080fd5b505af115801561458d573d6000803e3d6000fd5b50505060028201548310801591506145a757816002015492505b602a54602854600091906145bb9086615afe565b6145c59190615b33565b9050600083600201548460010154866145de9190615afe565b6145e89190615b33565b905084602760030160008282546145ff9190615aeb565b909155505060288054839190600090614619908490615aeb565b909155505060298054829190600090614633908490615aeb565b9091555050821561467b576001600160a01b0386166000908152601d6020526040812080546001600160a01b03191681556001810182905560028101829055600301556146b0565b8484600201600082825461468f9190615aeb565b92505081905550808460010160008282546146aa9190615aeb565b90915550505b6146b8610de5565b6146eb866305f5e1006141347f000000000000000000000000000000000000000000000000000000000000000086615afe565b604080518281526020810187905290810183905283151560608201526001600160a01b038716907f0503cf9e0479b84300e6dc9e8027bf8ce5cadedc339caa4e666cb843b0e6c65a9060800160405180910390a2505050505050565b601c5460ff166147995760405162461bcd60e51b815260206004820152601360248201527f7374616b696e672069732064697361626c6564000000000000000000000000006044820152606401610cfd565b600081116147e95760405162461bcd60e51b815260206004820152601560248201527f616d6f756e742063616e6e6f74206265207a65726f00000000000000000000006044820152606401610cfd565b6027546029546147fa908390615ad8565b11156148485760405162461bcd60e51b815260206004820152601260248201527f7661756c742063617020657863656564656400000000000000000000000000006044820152606401610cfd565b6006546001600160a01b031633146148ba57600954604051635fd6196560e01b81526001600160a01b03848116600483015290911690635fd6196590602401600060405180830381600087803b1580156148a157600080fd5b505af11580156148b5573d6000803e3d6000fd5b505050505b6148ee33306305f5e100611dd47f000000000000000000000000000000000000000000000000000000000000000086615afe565b6029546000906148fe5781614918565b602854602a5461490e9084615afe565b6149189190615b33565b9050806027600301600082825461492f9190615ad8565b909155505060288054839190600090614949908490615ad8565b909155505060298054839190600090614963908490615ad8565b90915550506001600160a01b0383166000908152601d602052604081206001015490036149f657604080516080810182526001600160a01b03858116808352602080840187815284860187815242606087019081526000948552601d90935295909220935184546001600160a01b0319169316929092178355516001830155915160028201559051600390910155614a88565b6001600160a01b0383166000908152601d602052604081206002018054839290614a21908490615ad8565b90915550506001600160a01b0383166000908152601d602052604081206001018054849290614a51908490615ad8565b90915550506006546001600160a01b03163314614a88576001600160a01b0383166000908152601d60205260409020426003909101555b60408051838152602081018390526001600160a01b038516917fea356279e4ebe82254459146f5d632aabb6617adc0fa8e7f8af36e507e316228910160405180910390a2505050565b6040516001600160a01b03831660248201526044810182905261147190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152615254565b6040516001600160a01b03808516602483015283166044820152606481018290526112ec9085906323b872dd60e01b90608401614afd565b60035460405163e918032360e01b81526001600160a01b038581166004830152600092839283929091169063e918032390602401606060405180830381865afa158015614bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c0e9190615e4f565b9194509250905060006305f5e100614c467f000000000000000000000000000000000000000000000000000000000000000088615afe565b614c509190615b33565b90506001600160a01b03841615614d63576000612710614c708584615afe565b614c7a9190615b33565b90506000612710614c8b8585615afe565b614c959190615b33565b6001600160a01b038716600090815260216020526040812080549293508492909190614cc2908490615ad8565b90915550506001600160a01b03891660009081526022602052604081208054839290614cef908490615ad8565b9091555050604080516001600160a01b0380891682528b1660208201529081018890527f541a03e241caa2b572f251d27b9f3f00aa5d1f9b52c9b443accbecb5627b891e9060600160405180910390a1614d5c81614d4d8486615aeb565b614d579190615aeb565b615339565b5050614d6c565b614d6c81615339565b50505050505050565b600254604051632b82db0d60e11b815260048101899052871515602482015260009182916001600160a01b0390911690635705b61a90604401602060405180830381865afa158015614dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614def9190615e36565b90508315614f3e57600085600f54888a614e099190615c82565b614e139190615b8c565b614e1d9190615c54565b90508815614ecc576000846305f5e10087614e388382615aeb565b614e428a80615afe565b614e4c9190615b33565b614e569190615aeb565b614e609190615afe565b614e6a9190615b33565b90506000821215614e9d57601054614e8483600019615b8c565b614e8e9190615b33565b614e989082615aeb565b614ea7565b614ea78282615ad8565b90506305f5e100614eb88285615afe565b614ec29190615b33565b9350505050614f41565b6000846305f5e100614ede8289615ad8565b614ee88980615afe565b614ef29190615b33565b614efc9089615aeb565b614f069190615afe565b614f109190615b33565b90506000821215614f2757614e8e82600019615b8c565b601054614f349083615b33565b614ea79082615ad8565b90505b979650505050505050565b6000848152601f60205260409020600181015415614ff7576000614f6f86612a64565b90506301e13380826001015442614f869190615aeb565b614f909083615b8c565b614f9a9190615c54565b826000016000828254614fad9190615c2c565b9091555050815460408051888152602081019290925281018290527f65580b50c8ff7b1b8cb8565f5767831a76c4745e925cfe57e5024afbd5584c799060600160405180910390a1505b4260018201556000858152601e6020526040902082156151d25784600c60008282546150239190615ad8565b909155506150319050610de5565b6000615040826003015461190d565b9050612710816013546150539190615afe565b61505d9190615b33565b86836006015484600501546150729190615ad8565b61507c9190615ad8565b106150c95760405162461bcd60e51b815260206004820152601460248201527f2170726f647563744f70656e496e7465726573740000000000000000000000006044820152606401610cfd565b841561515057858260050160008282546150e39190615ad8565b909155505060068201546150f8908290615ad8565b8260050154111561514b5760405162461bcd60e51b815260206004820152601160248201527f216f70656e496e7465726573744c6f6e670000000000000000000000000000006044820152606401610cfd565b6151cc565b858260060160008282546151649190615ad8565b90915550506005820154615179908290615ad8565b826006015411156151cc5760405162461bcd60e51b815260206004820152601260248201527f216f70656e496e74657265737453686f727400000000000000000000000000006044820152606401610cfd565b5061524c565b84600c60008282546151e49190615aeb565b909155505083156152255784816005015410615219578481600501600082825461520e9190615aeb565b9091555061524c9050565b6000600582015561524c565b84816006015410615244578481600601600082825461520e9190615aeb565b600060068201555b505050505050565b60006152a9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166153d89092919063ffffffff16565b80519091501561147157808060200190518101906152c79190615e86565b6114715760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610cfd565b60006127106016548361534c9190615afe565b6153569190615b33565b905060006127106017548461536b9190615afe565b6153759190615b33565b905081601960008282546153899190615ad8565b9250508190555080601a60008282546153a29190615ad8565b909155508190506153b38385615aeb565b6153bd9190615aeb565b601b60008282546153ce9190615ad8565b9091555050505050565b6060611b378484600085856001600160a01b0385163b61543a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cfd565b600080866001600160a01b031685876040516154569190615ea3565b60006040518083038185875af1925050503d8060008114615493576040519150601f19603f3d011682016040523d82523d6000602084013e615498565b606091505b5091509150614f41828286606083156154b2575081610dde565b8251156154c25782518084602001fd5b8160405162461bcd60e51b8152600401610cfd9190615e03565b600080604083850312156154ef57600080fd5b50508035926020909101359150565b6001600160a01b038116811461551357600080fd5b50565b801515811461551357600080fd5b60008060006060848603121561553957600080fd5b8335615544816154fe565b925060208401359150604084013561555b81615516565b809150509250925092565b60006020828403121561557857600080fd5b8135610dde816154fe565b6000806000806080858703121561559957600080fd5b84356155a4816154fe565b93506020850135925060408501356155bb81615516565b9396929550929360600135925050565b6000806000606084860312156155e057600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561560a57600080fd5b8235615615816154fe565b9150602083013561562581615516565b809150509250929050565b60006020828403121561564257600080fd5b5035919050565b600081518084526020808501945080840160005b838110156156795781518752958201959082019060010161565d565b509495945050505050565b6040815260006156976040830185615649565b828103602084015261295e8185615649565b600080600080600080600080610100898b0312156156c657600080fd5b88356156d1816154fe565b975060208901356156e1816154fe565b965060408901356156f1816154fe565b95506060890135615701816154fe565b94506080890135615711816154fe565b935060a0890135615721816154fe565b925060c0890135615731816154fe565b915060e0890135615741816154fe565b809150509295985092959890939650565b60008060006060848603121561576757600080fd5b83359250602084013561577981615516565b929592945050506040919091013590565b600080600080600060a086880312156157a257600080fd5b85356157ad816154fe565b94506020860135935060408601356157c481615516565b94979396509394606081013594506080013592915050565b6000806000606084860312156157f157600080fd5b83356157fc816154fe565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b818110156158a8576158948385516001600160a01b03815116825260208101511515602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301525050565b92840192610100929092019160010161582d565b50909695505050505050565b600080600080608085870312156158ca57600080fd5b84356158d581615516565b966020860135965060408601359560600135945092505050565b600080600080600060a0868803121561590757600080fd5b853561591281615516565b97602087013597506040870135966060810135965060800135945092505050565b60008060008060008060c0878903121561594c57600080fd5b86359550602087013561595e81615516565b95989597505050506040840135936060810135936080820135935060a0909101359150565b610100810161194782846001600160a01b03815116825260208101511515602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301525050565b600080602083850312156159f957600080fd5b823567ffffffffffffffff80821115615a1157600080fd5b818501915085601f830112615a2557600080fd5b813581811115615a3457600080fd5b8660208260051b8501011115615a4957600080fd5b60209290920196919550909350505050565b600080600080600060a08688031215615a7357600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215615aa957600080fd5b8235615ab4816154fe565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561194757611947615ac2565b8181038181111561194757611947615ac2565b6000816000190483118215151615615b1857615b18615ac2565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615b4257615b42615b1d565b500490565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201615b8557615b85615ac2565b5060010190565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615bcd57615bcd615ac2565b600160ff1b6000871282811687830589121615615bec57615bec615ac2565b60008712925087820587128484161615615c0857615c08615ac2565b87850587128184161615615c1e57615c1e615ac2565b505050929093029392505050565b8082018281126000831280158216821582161715615c4c57615c4c615ac2565b505092915050565b600082615c6357615c63615b1d565b600160ff1b821460001984141615615c7d57615c7d615ac2565b500590565b8181036000831280158383131683831282161715615ca257615ca2615ac2565b5092915050565b828152815460ff1615156020820152600182015460408201526002820154606082015260038201546080820152600482015460a0820152600582015460c0820152600682015460e08201526101008101610dde565b600060033d1115615d175760046000803e5060005160e01c5b90565b601f8201601f1916810167ffffffffffffffff81118282101715615d4e57634e487b7160e01b600052604160045260246000fd5b6040525050565b600060443d1015615d635790565b6040516003193d81016004833e81513d67ffffffffffffffff8160248401118184111715615d9357505050505090565b8285019150815181811115615dab5750505050505090565b843d8701016020828501011115615dc55750505050505090565b615dd460208286010187615d1a565b509095945050505050565b60005b83811015615dfa578181015183820152602001615de2565b50506000910152565b6020815260008251806020840152615e22816040850160208701615ddf565b601f01601f19169190910160400192915050565b600060208284031215615e4857600080fd5b5051919050565b600080600060608486031215615e6457600080fd5b8351615e6f816154fe565b602085015160409095015190969495509392505050565b600060208284031215615e9857600080fd5b8151610dde81615516565b60008251615eb5818460208701615ddf565b919091019291505056fea2646970667358221220df0a6d01a1cec9e2fb6ac72f81218fefe80747741dbaf22bd0c66648e82f096364736f6c6343000810003300000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b0000000000000000000000000000000000000000000000000de0b6b3a7640000
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061057f5760003560e01c80638d928af8116102d7578063be10ad6711610186578063db16e989116100e3578063f90cdb3611610097578063fbb48bc11161007c578063fbb48bc114610c78578063fc0c546a14610c80578063fcea330214610ca757600080fd5b8063f90cdb3614610c42578063f9b6117f14610c6557600080fd5b8063ebed4bd4116100c8578063ebed4bd414610be8578063f41807bd14610c1d578063f71f02b414610c2f57600080fd5b8063db16e98914610bcc578063eaf7762c14610bd557600080fd5b8063cf499b9d1161013a578063d468e2a91161011f578063d468e2a914610bb2578063d593f3a214610bbb578063d5c73dab14610bc357600080fd5b8063cf499b9d14610b96578063cfad57a214610b9f57600080fd5b8063c5dc77af1161016b578063c5dc77af14610b63578063c9063d4614610b76578063cd643e1914610b8957600080fd5b8063be10ad6714610b3d578063c04c0f5814610b5057600080fd5b8063a0448fc511610234578063b4f3cdbe116101e8578063b9db15b4116101cd578063b9db15b414610aa9578063bc95baad14610b14578063bdced6d514610b3457600080fd5b8063b4f3cdbe14610a81578063b6b74a4714610a8957600080fd5b8063a9b7fe5e11610219578063a9b7fe5e14610a2f578063b1d4d09814610a5b578063b27cdeaf14610a6e57600080fd5b8063a0448fc514610a13578063a881167814610a1c57600080fd5b806396cebadf1161028b5780639bf00b26116102705780639bf00b26146109e55780639d7c85b8146109f85780639f52a26114610a0057600080fd5b806396cebadf146109c95780639b9d326d146109dc57600080fd5b806393324cc0116102bc57806393324cc01461098d5780639676a9bc146109ad57806396c82e57146109c057600080fd5b80638d928af8146109305780639267fbbd1461097a57600080fd5b80634031234c116104335780635d1183b7116103905780637a76646011610344578063841a4b5111610329578063841a4b5114610901578063898c4e291461090a5780638b60a3ee1461091d57600080fd5b80637a7664601461089f5780637dc0d1d0146108ee57600080fd5b80636519c9d5116103755780636519c9d514610871578063719181f114610884578063791b98bc1461088c57600080fd5b80635d1183b71461083e57806361814d041461085157600080fd5b806351858e27116103e75780635828a437116103cc5780635828a4371461080f5780635941dfbd146108225780635b3829891461083557600080fd5b806351858e27146107e65780635387b1b9146107ee57600080fd5b80634453a374116104185780634453a37414610717578063467405011461072a578063514ea4bf1461074a57600080fd5b80634031234c146106ee5780634353d7d4146106f757600080fd5b80632b8a1c5a116104e157806336b1b89f116104955780633b836ddc1161047a5780633b836ddc146106cb5780633ee19763146106de5780633f4ba83a146106e657600080fd5b806336b1b89f146106ba57806339c294be146106c257600080fd5b80632ccd9623116104c65780632ccd96231461068b578063314d794d1461069e5780633504c47b146106a757600080fd5b80632b8a1c5a1461066f5780632c35e7691461068257600080fd5b806312ee63f31161053857806314d8353f1161051d57806314d8353f1461064057806320f6f76f1461065357806321707f301461065c57600080fd5b806312ee63f314610625578063142d80d81461063857600080fd5b80630599a400116105695780630599a400146105bf5780630633b14a146105c757806312d43a51146105fa57600080fd5b80621b7934146105845780630298e27314610599575b600080fd5b6105976105923660046154dc565b610caf565b005b6105ac6105a7366004615524565b610d91565b6040519081526020015b60405180910390f35b610597610de5565b6105ea6105d5366004615566565b60266020526000908152604090205460ff1681565b60405190151581526020016105b6565b60015461060d906001600160a01b031681565b6040516001600160a01b0390911681526020016105b6565b6105976106333660046154dc565b610e55565b601b546105ac565b61059761064e366004615583565b6112d8565b6105ac600e5481565b61059761066a3660046155cb565b6112f2565b61059761067d3660046155f7565b611476565b6105ac60165481565b60035461060d906001600160a01b031681565b6105ac60175481565b60085461060d906001600160a01b031681565b601a546105ac565b6105ac600d5481565b6105976106d9366004615630565b611528565b6019546105ac565b610597611591565b6105ac60145481565b6105ac610705366004615566565b60216020526000908152604090205481565b6105976107253660046155f7565b611628565b6105ac610738366004615566565b60246020526000908152604090205481565b6107a1610758366004615630565b602080526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b03861696600160a01b90960460ff16959088565b604080516001600160a01b0390991689529615156020890152958701949094526060860192909252608085015260a084015260c083015260e0820152610100016105b6565b6105976116d2565b6108016107fc3660046154dc565b61176c565b6040516105b6929190615684565b6105ac61081d366004615630565b61190d565b6105976108303660046156a9565b61194d565b6105ac60115481565b61059761084c366004615630565b611a93565b6105ac61085f366004615566565b60236020526000908152604090205481565b6105ac61087f3660046155cb565b611af4565b6105ac611b3f565b60045461060d906001600160a01b031681565b6108b26108ad366004615566565b611c1a565b6040516105b6919081516001600160a01b0316815260208083015190820152604080830151908201526060918201519181019190915260800190565b60025461060d906001600160a01b031681565b6105ac60125481565b610597610918366004615752565b611c9f565b61059761092b3660046154dc565b611e89565b610938611f8a565b6040516105b69190600060a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015292915050565b61059761098836600461578a565b611ff1565b6109a061099b3660046157dc565b61261d565b6040516105b69190615811565b60075461060d906001600160a01b031681565b6105ac600b5481565b6105ac6109d73660046158b4565b6128e9565b6105ac600a5481565b6105ac6109f3366004615524565b612967565b6105ac612993565b6105ac610a0e366004615630565b612a64565b6105ac600f5481565b6105ac610a2a3660046158ef565b612b42565b6105ac610a3d366004615566565b6001600160a01b03166000908152601d602052604090206002015490565b610597610a69366004615933565b612bfc565b60065461060d906001600160a01b031681565b610597612de6565b6105ac610a97366004615566565b60226020526000908152604090205481565b610abc610ab7366004615630565b612f3a565b6040516105b69190600060e0820190508251151582526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015292915050565b610b27610b22366004615524565b612fe4565b6040516105b69190615983565b6105ac60105481565b60095461060d906001600160a01b031681565b610597610b5e3660046159e6565b6130c8565b610597610b71366004615a5b565b61325f565b610597610b84366004615a96565b613538565b601c546105ea9060ff1681565b6105ac60185481565b610597610bad366004615566565b6135fc565b6105ac600c5481565b610597613698565b6105ac60135481565b6105ac60155481565b610597610be3366004615630565b6137e0565b610bfb610bf6366004615630565b613c70565b60408051825181526020808401519082015291810151908201526060016105b6565b601c546105ea90610100900460ff1681565b610597610c3d3660046154dc565b613ccd565b6105ea610c50366004615566565b60256020526000908152604090205460ff1681565b60055461060d906001600160a01b031681565b6105ac613d6a565b61060d7f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b81565b602a546105ac565b6001546001600160a01b03163314610d065760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b60448201526064015b60405180910390fd5b612710610d138284615ad8565b1115610d1e57600080fd5b6016829055601781905580610d3583612710615aeb565b610d3f9190615aeb565b60188190556016546017546040805192835260208301919091528101919091527fda6a2f16e321508fdfc20dc87c11fd48f45b93b4367ca5346d783f894b3640a4906060015b60405180910390a15050565b6040516bffffffffffffffffffffffff19606085901b1660208201526034810183905281151560f81b60548201526000906055016040516020818303038152906040528051906020012090505b9392505050565b60115460285461271091610df891615afe565b610e029190615b33565b600c541115610e535760405162461bcd60e51b815260206004820152601560248201527f7661756c74206973206f7665727574696c697a656400000000000000000000006044820152606401610cfd565b565b6001546001600160a01b03163314610ea75760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b60018210158015610eb9575060098211155b610f055760405162461bcd60e51b815260206004820152601b60248201527f696e76616c696420696e64657820666f7220706172616d6574657200000000006044820152606401610cfd565b81600103610f7557610f1c6305f5e1006019615afe565b811015610f6b5760405162461bcd60e51b815260206004820152601160248201527f696e76616c6964206d696e4d617267696e0000000000000000000000000000006044820152606401610cfd565b600d8190556112a2565b81600203610fe557610f8c6305f5e1006001615afe565b811115610fdb5760405162461bcd60e51b815260206004820152601360248201527f696e76616c6964206d696e4c65766572616765000000000000000000000000006044820152606401610cfd565b600e8190556112a2565b8160030361104957620f4240811061103f5760405162461bcd60e51b815260206004820152601060248201527f696e76616c6964206d61785368696674000000000000000000000000000000006044820152606401610cfd565b600f8190556112a2565b816004036110ab57600081116110a15760405162461bcd60e51b815260206004820152601460248201527f696e76616c6964207368696674446976696465720000000000000000000000006044820152606401610cfd565b60108190556112a2565b8160050361110d57600081116111035760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964207574696c697a6174696f6e4d756c7469706c6965720000006044820152606401610cfd565b60118190556112a2565b8160060361116f57600081116111655760405162461bcd60e51b815260206004820152601a60248201527f696e76616c6964206578706f737572654d756c7469706c6965720000000000006044820152606401610cfd565b60128190556112a2565b816007036111d157600081116111c75760405162461bcd60e51b815260206004820152601d60248201527f696e76616c6964206d61784578706f737572654d756c7469706c6965720000006044820152606401610cfd565b60138190556112a2565b816008036112355761251c81101561122b5760405162461bcd60e51b815260206004820152601c60248201527f696e76616c6964206c69717569646174696f6e5468726573686f6c64000000006044820152606401610cfd565b60148190556112a2565b816009036112a25761124d64e8d4a51000600a615afe565b81111561129c5760405162461bcd60e51b815260206004820152601660248201527f696e76616c6964206d617846756e64696e6752617465000000000000000000006044820152606401610cfd565b60158190555b60408051838152602081018390527f7f10293466b199a9daa697555ec2f3510429f81493f7b208907e0f63f811cd9d9101610d85565b6112ec6112e6858585610d91565b82613e3b565b50505050565b601c54610100900460ff166113495760405162461bcd60e51b815260206004820152601960248201527f6f70656e20706f736974696f6e2069732064697361626c6564000000000000006044820152606401610cfd565b600d548310158015611362575067ffffffffffffffff83105b6113985760405162461bcd60e51b815260206004820152600760248201526610b6b0b933b4b760c91b6044820152606401610cfd565b600e548210156113d95760405162461bcd60e51b815260206004820152600c60248201526b216d696e4c6576657261676560a01b6044820152606401610cfd565b6000818152601e602052604090205460ff166114215760405162461bcd60e51b81526020600482015260076024820152662161637469766560c81b6044820152606401610cfd565b6000818152601e60205260409020600101548211156114715760405162461bcd60e51b815260206004820152600c60248201526b216d61784c6576657261676560a01b6044820152606401610cfd565b505050565b6001546001600160a01b031633146114c85760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6001600160a01b038216600081815260266020908152604091829020805460ff191685151590811790915591519182527fca139a0ba60fe6426dd1d713a05ec0c645224f72d7a9912d64163974672dd41091015b60405180910390a25050565b60026000540361157a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000556115893382614419565b506001600055565b6001546001600160a01b031633146115e35760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b601c805461ffff19166101011790556040514281527faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab7906020015b60405180910390a1565b6001546001600160a01b0316331461167a5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6001600160a01b038216600081815260256020908152604091829020805460ff191685151590811790915591519182527f8c0d56805c3b43d441481229dc64bee168253ffe4305f37ab7cfe63b1c4268c6910161151c565b3360009081526026602052604090205460ff166117315760405162461bcd60e51b815260206004820152600960248201527f21677561726469616e00000000000000000000000000000000000000000000006044820152606401610cfd565b601c805461ffff191690556040514281527f587f3b25da67017c0da715067ea23a00ce02a7692dde05787d04b933a06881989060200161161e565b606080600084116117aa5760405162461bcd60e51b8152602060048201526008602482015267085cdd185c9d125960c21b6044820152606401610cfd565b600a548311156117ba57600a5492505b6117c48484615aeb565b6117cf906001615ad8565b6117da906002615afe565b67ffffffffffffffff8111156117f2576117f2615b47565b60405190808252806020026020018201604052801561181b578160200160208202803683370190505b5091506118288484615aeb565b611833906001615ad8565b61183e906002615afe565b67ffffffffffffffff81111561185657611856615b47565b60405190808252806020026020018201604052801561187f578160200160208202803683370190505b509050835b8381116119055761189481612a64565b836118a0600184615aeb565b815181106118b0576118b0615b5d565b6020908102919091018101919091526000828152601f9091526040902054826118da600184615aeb565b815181106118ea576118ea615b5d565b60209081029190910101526118fe81615b73565b9050611884565b509250929050565b6000612710600b54601254846027600101546119299190615afe565b6119339190615afe565b61193d9190615b33565b6119479190615b33565b92915050565b6001546001600160a01b0316331461199f5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b600280546001600160a01b038a81166001600160a01b03199283168117909355600380548b83169084168117909155600480548b84169085168117909155600580548b85169086168117909155600680548b86169087168117909155600780548b87169088168117909155600880548b8816908916811790915560098054978b16979098168717909755604080519889526020890195909552938701929092526060860152608085015260a084015260c083019190915260e08201527fded06d7bb35efa21cebe10555e7a0aad5a54d7c953203147308cf4fa431aac4d906101000160405180910390a15050505050505050565b600260005403611ae55760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000556115893382614747565b6000611b07620186a06305f5e100615afe565b6000838152601e6020526040902060020154611b238587615afe565b611b2d9190615afe565b611b379190615b33565b949350505050565b600754601a546000916001600160a01b031690338214611ba15760405162461bcd60e51b815260206004820152601660248201527f217374616b696e675265776172645265636569766572000000000000000000006044820152606401610cfd565b8015611947576000601a55611be06001600160a01b037f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b168383614ad1565b6040518181527fcb85a20151ba0100ff8fdc798814296495ac8af2552b7fb99ce1da63e5d94be8906020015b60405180910390a192915050565b611c4e604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b506001600160a01b039081166000908152601d602090815260409182902082516080810184528154909416845260018101549184019190915260028101549183019190915260030154606082015290565b600260005403611cf15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000908155611d03338585610d91565b60008181526020805260408120600281015492935091611d24908590615ad8565b9050600082600301549050600082846002015483611d429190615afe565b611d4c9190615b33565b9050600e54811015611da05760405162461bcd60e51b815260206004820152600c60248201527f216d696e6c6576657261676500000000000000000000000000000000000000006044820152606401610cfd565b611e1033306305f5e100611dd47f0000000000000000000000000000000000000000000000000de0b6b3a76400008b615afe565b611dde9190615b33565b6001600160a01b037f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b16929190614b61565b6002840183905560038401819055604080518815158152602081018a9052908101879052606081018490526080810183905260a08101829052339086907ff91ad36a8598bc6a2da3411a0d0a8b41adffeb5a0d884fbef52e87248ec1c3019060c00160405180910390a350506001600055505050505050565b6001546001600160a01b03163314611edb5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6203f480811115611f2e5760405162461bcd60e51b815260206004820152600860248201527f216d696e54696d650000000000000000000000000000000000000000000000006044820152606401610cfd565b6027829055602b81905560408051838152602854602082015260295491810191909152602a546060820152608081018290527f7edc5e603c0e26d9ddf55b2e00957979b5a257cc6d16bcce68ba7c3918a78bf49060a001610d85565b611fbc6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b506040805160a0810182526027548152602854602082015260295491810191909152602a546060820152602b54608082015290565b601c54610100900460ff166120485760405162461bcd60e51b815260206004820152601960248201527f6f70656e20706f736974696f6e2069732064697361626c6564000000000000006044820152606401610cfd565b6004546001600160a01b031633148061206b57506005546001600160a01b031633145b6120a25760405162461bcd60e51b815260206004820152600860248201526710b6b0b730b3b2b960c11b6044820152606401610cfd565b600d5482101580156120bb575067ffffffffffffffff82105b6120f15760405162461bcd60e51b815260206004820152600760248201526610b6b0b933b4b760c91b6044820152606401610cfd565b600e548110156121325760405162461bcd60e51b815260206004820152600c60248201526b216d696e4c6576657261676560a01b6044820152606401610cfd565b6000848152601e6020908152604091829020825160e081018452815460ff1615158082526001830154938201939093526002820154938101939093526003810154606084015260048101546080840152600581015460a08401526006015460c08301526121cb5760405162461bcd60e51b81526020600482015260076024820152662161637469766560c81b6044820152606401610cfd565b806020015182111561220e5760405162461bcd60e51b815260206004820152600c60248201526b216d61784c6576657261676560a01b6044820152606401610cfd565b60006305f5e10061221f8486615afe565b6122299190615b33565b90506000620186a08360400151836122419190615afe565b61224b9190615b33565b905061228c33306305f5e1007f0000000000000000000000000000000000000000000000000de0b6b3a7640000612282868b615ad8565b611dd49190615afe565b612297888284614b99565b60006122c088888660a001518760c001516122b5896060015161190d565b896080015189614d75565b90506122cf8884896001614f4c565b6000888152601f6020526040812054906122ea8b8b8b610d91565b6000818152602080805260409182902082516101008101845281546001600160a01b0381168252600160a01b900460ff1615159281019290925260018101549282019290925260028201546060820181905260038301546080830152600483015460a0830152600583015460c083015260069092015460e0820152919250156124b057612377888a615afe565b8160800151826060015161238b9190615afe565b6123959190615ad8565b846123a08a8c615afe565b6123aa9190615afe565b8260a00151836080015184606001516123c39190615afe565b6123cd9190615afe565b6123d79190615ad8565b6123e19190615b33565b93506123ed888a615afe565b816080015182606001516124019190615afe565b61240b9190615ad8565b836124168a8c615afe565b6124209190615b8c565b8260c00151836080015184606001516124399190615afe565b6124439190615b8c565b61244d9190615c2c565b6124579190615c54565b92508881606001516124699190615ad8565b612473898b615afe565b826080015183606001516124879190615afe565b6124919190615ad8565b61249b9190615b33565b97508881606001516124ad9190615ad8565b98505b6040518061010001604052808d6001600160a01b031681526020018b151581526020018c81526020018a8152602001898152602001858152602001848152602001428152506020600084815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160010155606082015181600201556080820151816003015560a0820151816004015560c0820151816005015560e082015181600601559050508b6001600160a01b0316827fcdbc2dc3244091bcbe6ae9efa60147af3ff947bc20a4ccb3f38f0c4b0d03a69e8c8e8d8d8a8c8b60405161260797969594939291909615158752602087019590955260408601939093526060850191909152608084015260a083015260c082015260e00190565b60405180910390a3505050505050505050505050565b60606000831161265a5760405162461bcd60e51b8152602060048201526008602482015267085cdd185c9d125960c21b6044820152606401610cfd565b600a5482111561266a57600a5491505b6126748383615aeb565b61267f906001615ad8565b61268a906002615afe565b67ffffffffffffffff8111156126a2576126a2615b47565b60405190808252806020026020018201604052801561272657816020015b61271360405180610100016040528060006001600160a01b031681526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816126c05790505b509050600080845b8481116128df5761274187826001610d91565b60008181526020805260409020549093506001600160a01b031615612802576000838152602080805260409182902082516101008101845281546001600160a01b0381168252600160a01b900460ff161515928101929092526001810154928201929092526002820154606082015260038201546080820152600482015460a0820152600582015460c082015260069091015460e082015284836127e481615b73565b9450815181106127f6576127f6615b5d565b60200260200101819052505b61280e87826000610d91565b60008181526020805260409020549093506001600160a01b0316156128cf576000838152602080805260409182902082516101008101845281546001600160a01b0381168252600160a01b900460ff161515928101929092526001810154928201929092526002820154606082015260038201546080820152600482015460a0820152600582015460c082015260069091015460e082015284836128b181615b73565b9450815181106128c3576128c3615b5d565b60200260200101819052505b6128d881615b73565b905061272e565b5050509392505050565b600084612929576000848152601f602052604090205464e8d4a51000906129109084615c82565b61291a9085615b8c565b6129249190615c54565b61295e565b6000848152601f602052604090205464e8d4a510009061294a908490615c82565b6129549085615b8c565b61295e9190615c54565b95945050505050565b600060206000612978868686610d91565b81526020019081526020016000206003015490509392505050565b600854601b546000916001600160a01b0316903382146129f55760405162461bcd60e51b815260206004820152601760248201527f21747265617375727952657761726452656365697665720000000000000000006044820152606401610cfd565b8015611947576000601b55612a346001600160a01b037f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b168383614ad1565b6040518181527f927cfccbec41ad4e05c94dc1d4b87d408e3642b8658ad3533bcd8e388ec9608690602001611c0c565b6000818152601e60205260408120600581015460068201546003909201549091908390612a909061190d565b6000868152601f602052604090206002015460155491925090838510612af25760008383612abe8789615aeb565b612ac89190615afe565b612ad29190615b33565b905081811015612ae757979650505050505050565b509695505050505050565b60008383612b008888615aeb565b612b0a9190615afe565b612b149190615b33565b905081811015612b3657612b2a81600019615b8c565b98975050505050505050565b612b2a82600019615b8c565b60008515612bd457848210612b90576305f5e10085612b618185615aeb565b612b6b8787615afe565b612b759190615afe565b612b7f9190615b33565b612b899190615b33565b905061295e565b6305f5e10085612ba08482615aeb565b612baa8787615afe565b612bb49190615afe565b612bbe9190615b33565b612bc89190615b33565b612b8990600019615b8c565b84821115612bec576305f5e10085612ba08185615aeb565b6305f5e10085612b618482615aeb565b6001546001600160a01b03163314612c4e5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b60008611612c9e5760405162461bcd60e51b815260206004820152601160248201527f696e76616c69642070726f6475637449640000000000000000000000000000006044820152606401610cfd565b6000868152601e602052604090206001810154612cfd5760405162461bcd60e51b815260206004820152601260248201527f70726f64756374206e6f742065786973747300000000000000000000000000006044820152606401610cfd565b612d0c6305f5e1006001615afe565b8510158015612d1d57506103e88411155b612d5b5760405162461bcd60e51b815260206004820152600f60248201526e1a5b9d985b1a59081c1c9bd91d58dd608a1b6044820152606401610cfd565b828160030154600b54612d6e9190615aeb565b612d789190615ad8565b600b55805460ff1916861515178155600181018590556002810184905560038101839055600481018290556040517f671b664bc17ffb1bd8deec8712115ea465623dc19db8f430db209ebf58447c2390612dd59089908490615ca9565b60405180910390a150505050505050565b600260005403612e385760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000908155338152602460209081526040808320546022909252822054612e619190615aeb565b905060008111612ea35760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b6044820152606401610cfd565b3360009081526024602052604081208054839290612ec2908490615ad8565b90915550612efc90506001600160a01b037f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b163383614ad1565b60405181815233907ffce929d82f3f52a0bb629ea34072d9edb26cda5dad81a678ebadaaebdcb0d787906020015b60405180910390a2506001600055565b612f7c6040518060e001604052806000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b506000908152601e6020908152604091829020825160e081018452815460ff16151581526001820154928101929092526002810154928201929092526003820154606082015260048201546080820152600582015460a082015260069091015460c082015290565b61303760405180610100016040528060006001600160a01b031681526020016000151581526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60206000613046868686610d91565b8152602080820192909252604090810160002081516101008101835281546001600160a01b0381168252600160a01b900460ff161515938101939093526001810154918301919091526002810154606083015260038101546080830152600481015460a0830152600581015460c08301526006015460e0820152949350505050565b3360009081526025602052604090205460ff166131275760405162461bcd60e51b815260206004820152600b60248201527f216c697175696461746f720000000000000000000000000000000000000000006044820152606401610cfd565b60005b81811015611471573063eaf7762c84848481811061314a5761314a615b5d565b905060200201356040518263ffffffff1660e01b815260040161316f91815260200190565b600060405180830381600087803b15801561318957600080fd5b505af192505050801561319a575060015b61324f576131a6615cfe565b806308c379a00361321b57506131ba615d55565b806131c5575061321d565b8383838181106131d7576131d7615b5d565b905060200201357ff8b325a0f68bd6a0d905e40b1937cbdd30c82d1334d58ef461a3f301f95d26408260405161320d9190615e03565b60405180910390a25061324f565b505b3d808015613247576040519150601f19603f3d011682016040523d82523d6000602084013e61324c565b606091505b50505b61325881615b73565b905061312a565b6001546001600160a01b031633146132b15760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b600085116133015760405162461bcd60e51b815260206004820152601160248201527f696e76616c69642070726f6475637449640000000000000000000000000000006044820152606401610cfd565b6000858152601e6020908152604091829020825160e081018452815460ff161515815260018201549281018390526002820154938101939093526003810154606084015260048101546080840152600581015460a08401526006015460c0830152156133af5760405162461bcd60e51b815260206004820152600e60248201527f70726f64756374206578697374730000000000000000000000000000000000006044820152606401610cfd565b6133be6305f5e1006001615afe565b85101580156133cf57506103e88411155b61340d5760405162461bcd60e51b815260206004820152600f60248201526e1a5b9d985b1a59081c1c9bd91d58dd608a1b6044820152606401610cfd565b6040518060e00160405280600115158152602001868152602001858152602001848152602001838152602001600081526020016000815250601e600088815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015590505082600b60008282546134c99190615ad8565b925050819055506001600a60008282546134e39190615ad8565b90915550506000868152601e60205260409081902090517f469ee7ec42e733d8a370e7ec08d7207f3c365b67384980c45e0592322a5e7a159161352891899190615ca9565b60405180910390a1505050505050565b60026000540361358a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b60026000556006546001600160a01b031633146135e95760405162461bcd60e51b815260206004820152601460248201527f217661756c7452657761726452656365697665720000000000000000000000006044820152606401610cfd565b6135f38282614747565b50506001600055565b6001546001600160a01b0316331461364e5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f91a8c1cc2d4a3bb60738481947a00cbb9899c822916694cf8bb1d68172fdcd5490600090a250565b6002600054036136ea5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cfd565b600260009081553381526023602090815260408083205460219092528220546137139190615aeb565b9050600081116137555760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b6044820152606401610cfd565b3360009081526023602052604081208054839290613774908490615ad8565b909155506137ae90506001600160a01b037f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b163383614ad1565b60405181815233907f4ff9eb307c447e363f7b7787fede06c88dd950603ca0516f7a066db07c267c2790602001612f2a565b33301461382f5760405162461bcd60e51b815260206004820152601260248201527f696e76616c6964206c697175696461746f7200000000000000000000000000006044820152606401610cfd565b6000818152602080805260409182902082516101008101845281546001600160a01b038116808352600160a01b90910460ff161515938201939093526001820154938101939093526002810154606084015260038101546080840152600481015460a0840152600581015460c08401526006015460e08301526138b0575050565b6040808201516000908152601e6020908152828220835160e081018552815460ff161515815260018201549281019290925260028101549382019390935260038301546060808301919091526004840154608080840191909152600585015460a084015260069094015460c0830152928401519284015190926305f5e100916139399190615afe565b6139439190615b33565b6002546040808601519051630e75722360e41b81529293506000926001600160a01b039092169163e7572230916139809160040190815260200190565b602060405180830381865afa15801561399d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139c19190615e36565b90506139d884604001518386602001516000614f4c565b60006139f285602001518660400151858860c001516128e9565b9050600081613a1487602001518860a0015189608001518a6060015188612b42565b613a1e9190615c82565b9050600081128015613a5957506127106014548760600151613a409190615afe565b613a4a9190615b33565b613a5682600019615b8c565b10155b613aa55760405162461bcd60e51b815260206004820152601c60248201527f706f736974696f6e206973206e6f74206c6971756964617461626c65000000006044820152606401610cfd565b6000620186a0866040015186613abb9190615afe565b613ac59190615b33565b9050613ad687600001518287614b99565b808760600151613ae69190615aeb565b60288054600090613af8908490615ad8565b9250508190555086600001516001600160a01b0316887f7c48994a8239b7b26e8de511662287f8456af2226eab8a3c71246311f2ac790660018a60400151888c60a001518d606001518e608001518f60600151600019613b589190615b8c565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e081018790526101000160405180910390a360055487516040808a015160208b01519151636599e85f60e11b81526001600160a01b0393841660048201526024810191909152901515604482015291169063cb33d0be90606401600060405180830381600087803b158015613bfc57600080fd5b505af1158015613c10573d6000803e3d6000fd5b5050506000988952505060208052505060408520805474ffffffffffffffffffffffffffffffffffffffffff1916815560018101869055600281018690556003810186905560048101869055600581018690556006019490945550505050565b613c9460405180606001604052806000815260200160008152602001600081525090565b506000908152601f6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6001546001600160a01b03163314613d1f5760405162461bcd60e51b815260206004820152601560248201527423b7bb32b93730b136329d103337b93134b23232b760591b6044820152606401610cfd565b6000828152601f602090815260409182902060020183905581518481529081018390527f4000829eec8ecb2dfc624cba376ec9b4cfe1167cf0613669d4d9559aafa7adad9101610d85565b6006546019546000916001600160a01b031690338214613dcc5760405162461bcd60e51b815260206004820152601460248201527f217661756c7452657761726452656365697665720000000000000000000000006044820152606401610cfd565b8015611947576000601955613e0b6001600160a01b037f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b168383614ad1565b6040518181527f97d3c68ccc07e002f029fb1d914cb534343b865ea8344f3543d3e9ea401ab08d90602001611c0c565b6004546001600160a01b0316331480613e5e57506005546001600160a01b031633145b613e955760405162461bcd60e51b815260206004820152600860248201526710b6b0b730b3b2b960c11b6044820152606401610cfd565b80600003613ea1575050565b6000828152602080526040902080546001600160a01b0316613ec257505050565b6001808201546000908152601e6020908152604091829020825160e081018452815460ff16151581529381015491840191909152600280820154928401929092526003810154606084015260048101546080840152600581015460a08401526006015460c0830152820154831115613f3c57816002015492505b60006305f5e100836003015485613f539190615afe565b613f5d9190615b33565b90506000613f9e84600101548560000160149054906101000a900460ff16158560a001518660c00151613f93886060015161190d565b886080015188614d75565b60018501548554919250613fbf918490600160a01b900460ff166000614f4c565b6000613fe68560000160149054906101000a900460ff1686600101548588600501546128e9565b90506000816140118760000160149054906101000a900460ff16886004015489600301548b88612b42565b61401b9190615c82565b9050600081121561409a57612710601454886140379190615afe565b6140419190615b33565b61404d82600019615b8c565b1061409a5760405162461bcd60e51b815260206004820152601d60248201527f706f736974696f6e2073686f756c64206265206c6971756964617465640000006044820152606401610cfd565b6000620186a08660400151866140b09190615afe565b6140ba9190615b33565b905060006140c88284615c82565b905060008112156141b05760006140e182600019615b8c565b90508981101561418f57885461416f906001600160a01b03166305f5e1007f0000000000000000000000000000000000000000000000000de0b6b3a764000061412a858f615aeb565b6141349190615afe565b61413e9190615b33565b6001600160a01b037f00000000000000000000000087680b0a24aa4b079c6ba106e999eb061ff9136b169190614ad1565b80602760010160008282546141849190615ad8565b909155506141aa9050565b89602760010160008282546141a49190615ad8565b90915550505b5061425f565b60285481908111156142045760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e74207661756c742062616c616e63650000000000006044820152606401610cfd565b8854614243906001600160a01b03166305f5e1007f0000000000000000000000000000000000000000000000000de0b6b3a764000061412a858f615ad8565b80602760010160008282546142589190615aeb565b9091555050505b8754614275906001600160a01b03168388614b99565b816027600101600082825461428a9190615aeb565b90915550508754600189015460048a015460038b01546040805160008152602081019490945283018990526060830191909152608082018c905260a082015260c0810185905260e081018690526001600160a01b03909116908b907f7c48994a8239b7b26e8de511662287f8456af2226eab8a3c71246311f2ac7906906101000160405180910390a3876002015489036143f357600554885460018a0154604051636599e85f60e11b81526001600160a01b0380841660048301526024820192909252600160a01b90920460ff16151560448301529091169063cb33d0be90606401600060405180830381600087803b15801561438657600080fd5b505af115801561439a573d6000803e3d6000fd5b50505060008b81526020805260408120805474ffffffffffffffffffffffffffffffffffffffffff191681556001810182905560028101829055600381018290556004810182905560058101829055600601555061440d565b888860020160008282546144079190615aeb565b90915550505b50505050505050505050565b600081116144695760405162461bcd60e51b815260206004820152601560248201527f7368617265732063616e6e6f74206265207a65726f00000000000000000000006044820152606401610cfd565b6001600160a01b0382166000908152601d6020526040902060018101546144d25760405162461bcd60e51b815260206004820152601560248201527f75736572206e6f207374616b656420616d6f756e7400000000000000000000006044820152606401610cfd565b6003810154602b546144e49190615ad8565b42116145325760405162461bcd60e51b815260206004820152600e60248201527f217661756c742e6d696e54696d650000000000000000000000000000000000006044820152606401610cfd565b600954604051635fd6196560e01b81526001600160a01b03858116600483015290911690635fd6196590602401600060405180830381600087803b15801561457957600080fd5b505af115801561458d573d6000803e3d6000fd5b50505060028201548310801591506145a757816002015492505b602a54602854600091906145bb9086615afe565b6145c59190615b33565b9050600083600201548460010154866145de9190615afe565b6145e89190615b33565b905084602760030160008282546145ff9190615aeb565b909155505060288054839190600090614619908490615aeb565b909155505060298054829190600090614633908490615aeb565b9091555050821561467b576001600160a01b0386166000908152601d6020526040812080546001600160a01b03191681556001810182905560028101829055600301556146b0565b8484600201600082825461468f9190615aeb565b92505081905550808460010160008282546146aa9190615aeb565b90915550505b6146b8610de5565b6146eb866305f5e1006141347f0000000000000000000000000000000000000000000000000de0b6b3a764000086615afe565b604080518281526020810187905290810183905283151560608201526001600160a01b038716907f0503cf9e0479b84300e6dc9e8027bf8ce5cadedc339caa4e666cb843b0e6c65a9060800160405180910390a2505050505050565b601c5460ff166147995760405162461bcd60e51b815260206004820152601360248201527f7374616b696e672069732064697361626c6564000000000000000000000000006044820152606401610cfd565b600081116147e95760405162461bcd60e51b815260206004820152601560248201527f616d6f756e742063616e6e6f74206265207a65726f00000000000000000000006044820152606401610cfd565b6027546029546147fa908390615ad8565b11156148485760405162461bcd60e51b815260206004820152601260248201527f7661756c742063617020657863656564656400000000000000000000000000006044820152606401610cfd565b6006546001600160a01b031633146148ba57600954604051635fd6196560e01b81526001600160a01b03848116600483015290911690635fd6196590602401600060405180830381600087803b1580156148a157600080fd5b505af11580156148b5573d6000803e3d6000fd5b505050505b6148ee33306305f5e100611dd47f0000000000000000000000000000000000000000000000000de0b6b3a764000086615afe565b6029546000906148fe5781614918565b602854602a5461490e9084615afe565b6149189190615b33565b9050806027600301600082825461492f9190615ad8565b909155505060288054839190600090614949908490615ad8565b909155505060298054839190600090614963908490615ad8565b90915550506001600160a01b0383166000908152601d602052604081206001015490036149f657604080516080810182526001600160a01b03858116808352602080840187815284860187815242606087019081526000948552601d90935295909220935184546001600160a01b0319169316929092178355516001830155915160028201559051600390910155614a88565b6001600160a01b0383166000908152601d602052604081206002018054839290614a21908490615ad8565b90915550506001600160a01b0383166000908152601d602052604081206001018054849290614a51908490615ad8565b90915550506006546001600160a01b03163314614a88576001600160a01b0383166000908152601d60205260409020426003909101555b60408051838152602081018390526001600160a01b038516917fea356279e4ebe82254459146f5d632aabb6617adc0fa8e7f8af36e507e316228910160405180910390a2505050565b6040516001600160a01b03831660248201526044810182905261147190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152615254565b6040516001600160a01b03808516602483015283166044820152606481018290526112ec9085906323b872dd60e01b90608401614afd565b60035460405163e918032360e01b81526001600160a01b038581166004830152600092839283929091169063e918032390602401606060405180830381865afa158015614bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c0e9190615e4f565b9194509250905060006305f5e100614c467f0000000000000000000000000000000000000000000000000de0b6b3a764000088615afe565b614c509190615b33565b90506001600160a01b03841615614d63576000612710614c708584615afe565b614c7a9190615b33565b90506000612710614c8b8585615afe565b614c959190615b33565b6001600160a01b038716600090815260216020526040812080549293508492909190614cc2908490615ad8565b90915550506001600160a01b03891660009081526022602052604081208054839290614cef908490615ad8565b9091555050604080516001600160a01b0380891682528b1660208201529081018890527f541a03e241caa2b572f251d27b9f3f00aa5d1f9b52c9b443accbecb5627b891e9060600160405180910390a1614d5c81614d4d8486615aeb565b614d579190615aeb565b615339565b5050614d6c565b614d6c81615339565b50505050505050565b600254604051632b82db0d60e11b815260048101899052871515602482015260009182916001600160a01b0390911690635705b61a90604401602060405180830381865afa158015614dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614def9190615e36565b90508315614f3e57600085600f54888a614e099190615c82565b614e139190615b8c565b614e1d9190615c54565b90508815614ecc576000846305f5e10087614e388382615aeb565b614e428a80615afe565b614e4c9190615b33565b614e569190615aeb565b614e609190615afe565b614e6a9190615b33565b90506000821215614e9d57601054614e8483600019615b8c565b614e8e9190615b33565b614e989082615aeb565b614ea7565b614ea78282615ad8565b90506305f5e100614eb88285615afe565b614ec29190615b33565b9350505050614f41565b6000846305f5e100614ede8289615ad8565b614ee88980615afe565b614ef29190615b33565b614efc9089615aeb565b614f069190615afe565b614f109190615b33565b90506000821215614f2757614e8e82600019615b8c565b601054614f349083615b33565b614ea79082615ad8565b90505b979650505050505050565b6000848152601f60205260409020600181015415614ff7576000614f6f86612a64565b90506301e13380826001015442614f869190615aeb565b614f909083615b8c565b614f9a9190615c54565b826000016000828254614fad9190615c2c565b9091555050815460408051888152602081019290925281018290527f65580b50c8ff7b1b8cb8565f5767831a76c4745e925cfe57e5024afbd5584c799060600160405180910390a1505b4260018201556000858152601e6020526040902082156151d25784600c60008282546150239190615ad8565b909155506150319050610de5565b6000615040826003015461190d565b9050612710816013546150539190615afe565b61505d9190615b33565b86836006015484600501546150729190615ad8565b61507c9190615ad8565b106150c95760405162461bcd60e51b815260206004820152601460248201527f2170726f647563744f70656e496e7465726573740000000000000000000000006044820152606401610cfd565b841561515057858260050160008282546150e39190615ad8565b909155505060068201546150f8908290615ad8565b8260050154111561514b5760405162461bcd60e51b815260206004820152601160248201527f216f70656e496e7465726573744c6f6e670000000000000000000000000000006044820152606401610cfd565b6151cc565b858260060160008282546151649190615ad8565b90915550506005820154615179908290615ad8565b826006015411156151cc5760405162461bcd60e51b815260206004820152601260248201527f216f70656e496e74657265737453686f727400000000000000000000000000006044820152606401610cfd565b5061524c565b84600c60008282546151e49190615aeb565b909155505083156152255784816005015410615219578481600501600082825461520e9190615aeb565b9091555061524c9050565b6000600582015561524c565b84816006015410615244578481600601600082825461520e9190615aeb565b600060068201555b505050505050565b60006152a9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166153d89092919063ffffffff16565b80519091501561147157808060200190518101906152c79190615e86565b6114715760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610cfd565b60006127106016548361534c9190615afe565b6153569190615b33565b905060006127106017548461536b9190615afe565b6153759190615b33565b905081601960008282546153899190615ad8565b9250508190555080601a60008282546153a29190615ad8565b909155508190506153b38385615aeb565b6153bd9190615aeb565b601b60008282546153ce9190615ad8565b9091555050505050565b6060611b378484600085856001600160a01b0385163b61543a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cfd565b600080866001600160a01b031685876040516154569190615ea3565b60006040518083038185875af1925050503d8060008114615493576040519150601f19603f3d011682016040523d82523d6000602084013e615498565b606091505b5091509150614f41828286606083156154b2575081610dde565b8251156154c25782518084602001fd5b8160405162461bcd60e51b8152600401610cfd9190615e03565b600080604083850312156154ef57600080fd5b50508035926020909101359150565b6001600160a01b038116811461551357600080fd5b50565b801515811461551357600080fd5b60008060006060848603121561553957600080fd5b8335615544816154fe565b925060208401359150604084013561555b81615516565b809150509250925092565b60006020828403121561557857600080fd5b8135610dde816154fe565b6000806000806080858703121561559957600080fd5b84356155a4816154fe565b93506020850135925060408501356155bb81615516565b9396929550929360600135925050565b6000806000606084860312156155e057600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561560a57600080fd5b8235615615816154fe565b9150602083013561562581615516565b809150509250929050565b60006020828403121561564257600080fd5b5035919050565b600081518084526020808501945080840160005b838110156156795781518752958201959082019060010161565d565b509495945050505050565b6040815260006156976040830185615649565b828103602084015261295e8185615649565b600080600080600080600080610100898b0312156156c657600080fd5b88356156d1816154fe565b975060208901356156e1816154fe565b965060408901356156f1816154fe565b95506060890135615701816154fe565b94506080890135615711816154fe565b935060a0890135615721816154fe565b925060c0890135615731816154fe565b915060e0890135615741816154fe565b809150509295985092959890939650565b60008060006060848603121561576757600080fd5b83359250602084013561577981615516565b929592945050506040919091013590565b600080600080600060a086880312156157a257600080fd5b85356157ad816154fe565b94506020860135935060408601356157c481615516565b94979396509394606081013594506080013592915050565b6000806000606084860312156157f157600080fd5b83356157fc816154fe565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b818110156158a8576158948385516001600160a01b03815116825260208101511515602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301525050565b92840192610100929092019160010161582d565b50909695505050505050565b600080600080608085870312156158ca57600080fd5b84356158d581615516565b966020860135965060408601359560600135945092505050565b600080600080600060a0868803121561590757600080fd5b853561591281615516565b97602087013597506040870135966060810135965060800135945092505050565b60008060008060008060c0878903121561594c57600080fd5b86359550602087013561595e81615516565b95989597505050506040840135936060810135936080820135935060a0909101359150565b610100810161194782846001600160a01b03815116825260208101511515602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301525050565b600080602083850312156159f957600080fd5b823567ffffffffffffffff80821115615a1157600080fd5b818501915085601f830112615a2557600080fd5b813581811115615a3457600080fd5b8660208260051b8501011115615a4957600080fd5b60209290920196919550909350505050565b600080600080600060a08688031215615a7357600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060408385031215615aa957600080fd5b8235615ab4816154fe565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561194757611947615ac2565b8181038181111561194757611947615ac2565b6000816000190483118215151615615b1857615b18615ac2565b500290565b634e487b7160e01b600052601260045260246000fd5b600082615b4257615b42615b1d565b500490565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201615b8557615b85615ac2565b5060010190565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600084136000841385830485118282161615615bcd57615bcd615ac2565b600160ff1b6000871282811687830589121615615bec57615bec615ac2565b60008712925087820587128484161615615c0857615c08615ac2565b87850587128184161615615c1e57615c1e615ac2565b505050929093029392505050565b8082018281126000831280158216821582161715615c4c57615c4c615ac2565b505092915050565b600082615c6357615c63615b1d565b600160ff1b821460001984141615615c7d57615c7d615ac2565b500590565b8181036000831280158383131683831282161715615ca257615ca2615ac2565b5092915050565b828152815460ff1615156020820152600182015460408201526002820154606082015260038201546080820152600482015460a0820152600582015460c0820152600682015460e08201526101008101610dde565b600060033d1115615d175760046000803e5060005160e01c5b90565b601f8201601f1916810167ffffffffffffffff81118282101715615d4e57634e487b7160e01b600052604160045260246000fd5b6040525050565b600060443d1015615d635790565b6040516003193d81016004833e81513d67ffffffffffffffff8160248401118184111715615d9357505050505090565b8285019150815181811115615dab5750505050505090565b843d8701016020828501011115615dc55750505050505090565b615dd460208286010187615d1a565b509095945050505050565b60005b83811015615dfa578181015183820152602001615de2565b50506000910152565b6020815260008251806020840152615e22816040850160208701615ddf565b601f01601f19169190910160400192915050565b600060208284031215615e4857600080fd5b5051919050565b600080600060608486031215615e6457600080fd5b8351615e6f816154fe565b602085015160409095015190969495509392505050565b600060208284031215615e9857600080fd5b8151610dde81615516565b60008251615eb5818460208701615ddf565b919091019291505056fea2646970667358221220df0a6d01a1cec9e2fb6ac72f81218fefe80747741dbaf22bd0c66648e82f096364736f6c63430008100033