Contract 0x2FaE8C7Edd26213cA1A88fC57B65352dbe353698 12
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
PikaPerpV2
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/math/SignedSafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "../oracle/IOracle.sol"; import '../lib/UniERC20.sol'; import './IPikaPerp.sol'; import "../staking/IVaultReward.sol"; contract PikaPerpV2 is ReentrancyGuard { using SafeMath for uint256; using SignedSafeMath for int256; using SafeERC20 for IERC20; using UniERC20 for IERC20; // All amounts are stored with 8 decimals // Structs struct Vault { // 32 bytes uint96 cap; // Maximum capacity. 12 bytes uint96 balance; // 12 bytes uint64 staked; // Total staked by users. 8 bytes uint64 shares; // Total ownership shares. 8 bytes // 32 bytes uint32 stakingPeriod; // Time required to lock stake (seconds). 4 bytes } struct Stake { // 32 bytes address owner; // 20 bytes uint64 amount; // 8 bytes uint64 shares; // 8 bytes uint32 timestamp; // 4 bytes } struct Product { // 32 bytes address feed; // Chainlink feed. 20 bytes uint72 maxLeverage; // 9 bytes uint16 fee; // In bps. 0.5% = 50. 2 bytes bool isActive; // 1 byte // 32 bytes uint64 openInterestLong; // 6 bytes uint64 openInterestShort; // 6 bytes uint16 interest; // For 360 days, in bps. 10% = 1000. 2 bytes uint16 liquidationThreshold; // In bps. 8000 = 80%. 2 bytes uint16 liquidationBounty; // In bps. 500 = 5%. 2 bytes uint16 minPriceChange; // 1.5%, the minimum oracle price up change for trader to close trade with profit uint16 weight; // share of the max exposure uint64 reserve; // Virtual reserve in USDC. Used to calculate slippage } struct Position { // 32 bytes uint64 productId; // 8 bytes uint64 leverage; // 8 bytes uint64 price; // 8 bytes uint64 oraclePrice; // 8 bytes uint64 margin; // 8 bytes // 32 bytes address owner; // 20 bytes uint80 timestamp; // 10 bytes bool isLong; // 1 byte } // Variables address public owner; // Contract owner address public liquidator; address public token; uint256 public tokenDecimal; uint256 public tokenBase; address public oracle; uint256 public minMargin; uint256 public protocolRewardRatio = 2000; // 20% uint256 public pikaRewardRatio = 3000; // 30% uint256 public maxShift = 0.003e8; // max shift (shift is used adjust the price to balance the longs and shorts) uint256 public minProfitTime = 12 hours; // the time window where minProfit is effective uint256 public maxPositionMargin; // for guarded launch uint256 public totalWeight; // total exposure weights of all product uint256 public exposureMultiplier = 10000; // exposure multiplier uint256 public utilizationMultiplier = 10000; // exposure multiplier uint256 public pendingProtocolReward; // protocol reward collected uint256 public pendingPikaReward; // pika reward collected uint256 public pendingVaultReward; // vault reward collected address public protocolRewardDistributor; address public pikaRewardDistributor; address public vaultRewardDistributor; address public vaultTokenReward; uint256 public totalOpenInterest; uint256 public constant BASE_DECIMALS = 8; uint256 public constant BASE = 10**BASE_DECIMALS; bool canUserStake = false; bool allowPublicLiquidator = false; Vault private vault; mapping(uint256 => Product) private products; mapping(address => Stake) private stakes; mapping(uint256 => Position) private positions; // Events event Staked( address indexed user, uint256 amount, uint256 shares ); event Redeemed( address indexed user, uint256 amount, uint256 shares, uint256 shareBalance, bool isFullRedeem ); event NewPosition( uint256 indexed positionId, address indexed user, uint256 indexed productId, bool isLong, uint256 price, uint256 oraclePrice, uint256 margin, uint256 leverage, uint256 fee ); event AddMargin( uint256 indexed positionId, address indexed user, uint256 margin, uint256 newMargin, uint256 newLeverage ); event ClosePosition( uint256 indexed positionId, address indexed user, uint256 indexed productId, uint256 price, uint256 entryPrice, uint256 margin, uint256 leverage, uint256 fee, int256 pnl, bool wasLiquidated ); event PositionLiquidated( uint256 indexed positionId, address indexed liquidator, uint256 liquidatorReward, uint256 remainingReward ); event ProtocolRewardDistributed( address to, uint256 amount ); event PikaRewardDistributed( address to, uint256 amount ); event VaultRewardDistributed( address to, uint256 amount ); event VaultUpdated( Vault vault ); event ProductAdded( uint256 productId, Product product ); event ProductUpdated( uint256 productId, Product product ); event RewardRatioUpdated( uint256 protocolRewardRatio, uint256 pikaRewardRatio ); event OracleUpdated( address newOracle ); event OwnerUpdated( address newOwner ); // Constructor constructor(address _token, uint256 _tokenDecimal, address _oracle, uint256 _minMargin) { owner = msg.sender; liquidator = msg.sender; token = _token; tokenDecimal = _tokenDecimal; tokenBase = 10**_tokenDecimal; oracle = _oracle; minMargin = _minMargin; vault = Vault({ cap: 0, balance: 0, staked: 0, shares: 0, stakingPeriod: uint32(24 * 3600) }); } // Methods // Stakes amount of usdc in the vault for user function stakeForUser(uint256 amount, address user) public payable nonReentrant { require(canUserStake || msg.sender == owner, "!stake"); IVaultReward(vaultRewardDistributor).updateReward(user); IVaultReward(vaultTokenReward).updateReward(user); IERC20(token).uniTransferFromSenderToThis(amount.mul(tokenBase).div(BASE)); require(uint256(vault.staked) + amount <= uint256(vault.cap), "!cap"); uint256 shares = vault.staked > 0 ? amount.mul(uint256(vault.shares)).div(uint256(vault.balance)) : amount; vault.balance += uint96(amount); vault.staked += uint64(amount); vault.shares += uint64(shares); if (stakes[user].amount == 0) { stakes[user] = Stake({ owner: user, amount: uint64(amount), shares: uint64(shares), timestamp: uint32(block.timestamp) }); } else { stakes[user].amount += uint64(amount); stakes[user].shares += uint64(shares); stakes[user].timestamp = uint32(block.timestamp); } emit Staked( user, amount, shares ); } function stake(uint256 amount) external payable { stakeForUser(amount, msg.sender); } // Redeems amount from Stake with id = stakeId function redeem( uint256 shares ) external { require(shares <= uint256(vault.shares), "!staked"); address user = msg.sender; IVaultReward(vaultRewardDistributor).updateReward(user); IVaultReward(vaultTokenReward).updateReward(user); Stake storage _stake = stakes[user]; bool isFullRedeem = shares >= uint256(_stake.shares); if (isFullRedeem) { shares = uint256(_stake.shares); } if (user != owner) { uint256 timeDiff = block.timestamp.sub(uint256(_stake.timestamp)); require(timeDiff > uint256(vault.stakingPeriod), "!period"); } uint256 shareBalance = shares.mul(uint256(vault.balance)).div(uint256(vault.shares)); uint256 amount = shares.mul(_stake.amount).div(uint256(_stake.shares)); _stake.amount -= uint64(amount); _stake.shares -= uint64(shares); vault.staked -= uint64(amount); vault.shares -= uint64(shares); vault.balance -= uint96(shareBalance); require(totalOpenInterest <= uint256(vault.balance).mul(utilizationMultiplier).div(10**4), "!utilized"); if (isFullRedeem) { delete stakes[user]; } IERC20(token).uniTransfer(user, shareBalance.mul(tokenBase).div(BASE)); emit Redeemed( user, amount, shares, shareBalance, isFullRedeem ); } function openPosition( uint256 productId, uint256 margin, bool isLong, uint256 leverage ) external payable returns(uint256) { return openPositionForUser(msg.sender, productId, margin, isLong, leverage); } function openPositionForUser( address user, uint256 productId, uint256 margin, bool isLong, uint256 leverage ) public payable nonReentrant returns(uint256 positionId) { // Check params require(margin >= minMargin, "!margin"); require(leverage >= 1 * BASE, "!leverage"); // Check product Product storage product = products[productId]; require(product.isActive, "!product-active"); require(leverage <= uint256(product.maxLeverage), "!max-leverage"); // Transfer margin plus fee uint256 tradeFee = _getTradeFee(margin, leverage, uint256(product.fee)); IERC20(token).uniTransferFromSenderToThis((margin.add(tradeFee)).mul(tokenBase).div(BASE)); pendingProtocolReward = pendingProtocolReward.add(tradeFee.mul(protocolRewardRatio).div(10**4)); pendingPikaReward = pendingPikaReward.add(tradeFee.mul(pikaRewardRatio).div(10**4)); pendingVaultReward = pendingVaultReward.add(tradeFee.mul(10**4 - protocolRewardRatio - pikaRewardRatio).div(10**4)); uint256 amount = margin.mul(leverage).div(BASE); uint256 price = _calculatePrice(product.feed, isLong, product.openInterestLong, product.openInterestShort, uint256(vault.balance).mul(uint256(product.weight)).mul(exposureMultiplier).div(uint256(totalWeight)).div(10**4), uint256(product.reserve), amount); _updateOpenInterest(productId, amount, isLong, true); positionId = getPositionId(user, productId, isLong); Position storage position = positions[positionId]; if (position.margin > 0) { price = (uint256(position.margin).mul(position.leverage).mul(uint256(position.price)).add(margin.mul(leverage).mul(price))).div( uint256(position.margin).mul(position.leverage).add(margin.mul(leverage))); leverage = (uint256(position.margin).mul(uint256(position.leverage)).add(margin.mul(leverage))).div(uint256(position.margin).add(margin)); margin = uint256(position.margin).add(margin); } require(margin < maxPositionMargin, "!max margin"); positions[positionId] = Position({ owner: user, productId: uint64(productId), margin: uint64(margin), leverage: uint64(leverage), price: uint64(price), oraclePrice: uint64(IOracle(oracle).getPrice(product.feed)), timestamp: uint80(block.timestamp), isLong: isLong }); emit NewPosition( positionId, user, productId, isLong, price, IOracle(oracle).getPrice(product.feed), margin, leverage, tradeFee ); } // Add margin to Position with positionId function addMargin(uint256 positionId, uint256 margin) external payable nonReentrant { IERC20(token).uniTransferFromSenderToThis(margin.mul(tokenBase).div(BASE)); // Check params require(margin >= minMargin, "!margin"); // Check position Position storage position = positions[positionId]; require(msg.sender == position.owner, "!owner"); // New position params uint256 newMargin = uint256(position.margin).add(margin); uint256 newLeverage = uint256(position.leverage).mul(uint256(position.margin)).div(newMargin); require(newLeverage >= 1 * BASE, "!low-leverage"); position.margin = uint64(newMargin); position.leverage = uint64(newLeverage); emit AddMargin( positionId, position.owner, margin, newMargin, newLeverage ); } // Closes margin from Position with productId and direction function closePosition( uint256 productId, uint256 margin, bool isLong ) external { return closePositionWithId(getPositionId(msg.sender, productId, isLong), margin); } // Closes position from Position with id = positionId function closePositionWithId( uint256 positionId, uint256 margin ) public nonReentrant { // Check params require(margin >= minMargin, "!margin"); // Check position Position storage position = positions[positionId]; require(msg.sender == position.owner, "!owner"); // Check product Product storage product = products[uint256(position.productId)]; bool isFullClose; if (margin >= uint256(position.margin)) { margin = uint256(position.margin); isFullClose = true; } uint256 maxExposure = uint256(vault.balance).mul(uint256(product.weight)).mul(exposureMultiplier).div(uint256(totalWeight)).div(10**4); uint256 price = _calculatePrice(product.feed, !position.isLong, product.openInterestLong, product.openInterestShort, maxExposure, uint256(product.reserve), margin * position.leverage / BASE); bool isLiquidatable; int256 pnl = _getPnl(position, margin, price); if (pnl < 0 && uint256(-1 * pnl) >= margin.mul(uint256(product.liquidationThreshold)).div(10**4)) { margin = uint256(position.margin); pnl = -1 * int256(uint256(position.margin)); isLiquidatable = true; } else { // front running protection: if oracle price up change is smaller than threshold and minProfitTime has not passed, the pnl is be set to 0 if (pnl > 0 && !_canTakeProfit(position, IOracle(oracle).getPrice(product.feed), product.minPriceChange)) { pnl = 0; } } uint256 totalFee = _updateVaultAndGetFee(pnl, position, margin, uint256(product.fee), uint256(product.interest)); _updateOpenInterest(uint256(position.productId), margin.mul(uint256(position.leverage)).div(BASE), position.isLong, false); emit ClosePosition( positionId, position.owner, uint256(position.productId), price, uint256(position.price), margin, uint256(position.leverage), totalFee, pnl, isLiquidatable ); if (isFullClose) { delete positions[positionId]; } else { position.margin -= uint64(margin); } } function _updateVaultAndGetFee( int256 pnl, Position memory position, uint256 margin, uint256 fee, uint256 interest ) internal returns(uint256) { (int256 pnlAfterFee, uint256 totalFee) = _getPnlWithFee(pnl, position, margin, fee, interest); // Update vault if (pnlAfterFee < 0) { uint256 _pnlAfterFee = uint256(-1 * pnlAfterFee); if (_pnlAfterFee < margin) { IERC20(token).uniTransfer(position.owner, (margin.sub(_pnlAfterFee)).mul(tokenBase).div(BASE)); vault.balance += uint96(_pnlAfterFee); } else { vault.balance += uint96(margin); return totalFee; } } else { uint256 _pnlAfterFee = uint256(pnlAfterFee); // Check vault require(uint256(vault.balance) >= _pnlAfterFee, "!vault-insufficient"); vault.balance -= uint96(_pnlAfterFee); IERC20(token).uniTransfer(position.owner, (margin.add(_pnlAfterFee)).mul(tokenBase).div(BASE)); } pendingProtocolReward = pendingProtocolReward.add(totalFee.mul(protocolRewardRatio).div(10**4)); pendingPikaReward = pendingPikaReward.add(totalFee.mul(pikaRewardRatio).div(10**4)); pendingVaultReward = pendingVaultReward.add(totalFee.mul(10**4 - protocolRewardRatio - pikaRewardRatio).div(10**4)); vault.balance -= uint96(totalFee); return totalFee; } function releaseMargin(uint256 positionId) external onlyOwner { Position storage position = positions[positionId]; require(position.margin > 0, "!position"); uint256 margin = position.margin; address positionOwner = position.owner; uint256 amount = margin.mul(uint256(position.leverage)).div(BASE); _updateOpenInterest(uint256(position.productId), amount, position.isLong, false); emit ClosePosition( positionId, positionOwner, position.productId, position.price, position.price, margin, position.leverage, 0, 0, false ); delete positions[positionId]; IERC20(token).uniTransfer(positionOwner, margin.mul(tokenBase).div(BASE)); } // Liquidate positionIds function liquidatePositions(uint256[] calldata positionIds) external { require(msg.sender == liquidator || allowPublicLiquidator, "!liquidator"); uint256 totalLiquidatorReward; for (uint256 i = 0; i < positionIds.length; i++) { uint256 positionId = positionIds[i]; uint256 liquidatorReward = liquidatePosition(positionId); totalLiquidatorReward = totalLiquidatorReward.add(liquidatorReward); } if (totalLiquidatorReward > 0) { IERC20(token).uniTransfer(msg.sender, totalLiquidatorReward.mul(tokenBase).div(BASE)); } } function liquidatePosition( uint256 positionId ) internal returns(uint256 liquidatorReward) { Position storage position = positions[positionId]; if (position.productId == 0) { return 0; } Product storage product = products[uint256(position.productId)]; uint256 price = IOracle(oracle).getPrice(product.feed); // use oracle price for liquidation uint256 remainingReward; if (_checkLiquidation(position, price, uint256(product.liquidationThreshold))) { int256 pnl = _getPnl(position, position.margin, price); if (pnl < 0 && uint256(position.margin) > uint256(-1*pnl)) { uint256 _pnl = uint256(-1*pnl); liquidatorReward = (uint256(position.margin).sub(_pnl)).mul(uint256(product.liquidationBounty)).div(10**4); remainingReward = (uint256(position.margin).sub(_pnl).sub(liquidatorReward)); pendingProtocolReward = pendingProtocolReward.add(remainingReward.mul(protocolRewardRatio).div(10**4)); pendingPikaReward = pendingPikaReward.add(remainingReward.mul(pikaRewardRatio).div(10**4)); pendingVaultReward = pendingVaultReward.add(remainingReward.mul(10**4 - protocolRewardRatio - pikaRewardRatio).div(10**4)); vault.balance += uint96(_pnl); } else { vault.balance += uint96(position.margin); } uint256 amount = uint256(position.margin).mul(uint256(position.leverage)).div(BASE); _updateOpenInterest(uint256(position.productId), amount, position.isLong, false); emit ClosePosition( positionId, position.owner, uint256(position.productId), price, uint256(position.price), uint256(position.margin), uint256(position.leverage), 0, int256(uint256(position.margin)), true ); delete positions[positionId]; emit PositionLiquidated( positionId, msg.sender, liquidatorReward, remainingReward ); } return liquidatorReward; } function _updateOpenInterest(uint256 productId, uint256 amount, bool isLong, bool isIncrease) internal { Product storage product = products[productId]; if (isIncrease) { totalOpenInterest = totalOpenInterest.add(amount); require(totalOpenInterest <= uint256(vault.balance).mul(utilizationMultiplier).div(10**4), "!maxOpenInterest"); uint256 maxExposure = uint256(vault.balance).mul(uint256(product.weight)).mul(exposureMultiplier).div(uint256(totalWeight)).div(10**4); if (isLong) { product.openInterestLong += uint64(amount); require(uint256(product.openInterestLong) <= uint256(maxExposure).add(uint256(product.openInterestShort)), "!exposure-long"); } else { product.openInterestShort += uint64(amount); require(uint256(product.openInterestShort) <= uint256(maxExposure).add(uint256(product.openInterestLong)), "!exposure-short"); } } else { totalOpenInterest = totalOpenInterest.sub(amount); if (isLong) { if (uint256(product.openInterestLong) >= amount) { product.openInterestLong -= uint64(amount); } else { product.openInterestLong = 0; } } else { if (uint256(product.openInterestShort) >= amount) { product.openInterestShort -= uint64(amount); } else { product.openInterestShort = 0; } } } } function distributeProtocolReward() external returns(uint256) { require(msg.sender == protocolRewardDistributor, "!distributor"); uint256 _pendingProtocolReward = pendingProtocolReward.mul(tokenBase).div(BASE); if (pendingProtocolReward > 0) { pendingProtocolReward = 0; IERC20(token).uniTransfer(protocolRewardDistributor, _pendingProtocolReward); emit ProtocolRewardDistributed(protocolRewardDistributor, _pendingProtocolReward); } return _pendingProtocolReward; } function distributePikaReward() external returns(uint256) { require(msg.sender == pikaRewardDistributor, "!distributor"); uint256 _pendingPikaReward = pendingPikaReward.mul(tokenBase).div(BASE); if (pendingPikaReward > 0) { pendingPikaReward = 0; IERC20(token).uniTransfer(pikaRewardDistributor, _pendingPikaReward); emit PikaRewardDistributed(pikaRewardDistributor, _pendingPikaReward); } return _pendingPikaReward; } function distributeVaultReward() external returns(uint256) { require(msg.sender == vaultRewardDistributor, "!distributor"); uint256 _pendingVaultReward = pendingVaultReward.mul(tokenBase).div(BASE); if (pendingVaultReward > 0) { pendingVaultReward = 0; IERC20(token).uniTransfer(vaultRewardDistributor, _pendingVaultReward); emit VaultRewardDistributed(vaultRewardDistributor, _pendingVaultReward); } return _pendingVaultReward; } // Getters function getPendingPikaReward() external view returns(uint256) { return pendingPikaReward.mul(tokenBase).div(BASE); } function getPendingProtocolReward() external view returns(uint256) { return pendingProtocolReward.mul(tokenBase).div(BASE); } function getPendingVaultReward() external view returns(uint256) { return pendingVaultReward.mul(tokenBase).div(BASE); } function getVault() external view returns(Vault memory) { return vault; } function getProduct(uint256 productId) external view returns(Product memory) { return products[productId]; } function getPositionId( address account, uint256 productId, bool isLong ) public pure returns (uint256) { return uint256(keccak256(abi.encodePacked(account, productId, isLong))); } function getPosition( address account, uint256 productId, bool isLong ) external view returns(Position memory position) { position = positions[getPositionId(account, productId, isLong)]; } function getPositions(uint256[] calldata positionIds) external view returns(Position[] memory _positions) { uint256 length = positionIds.length; _positions = new Position[](length); for (uint256 i=0; i < length; i++) { _positions[i] = positions[positionIds[i]]; } } function getTotalShare() external view returns(uint256) { return uint256(vault.shares); } function getShare(address stakeOwner) external view returns(uint256) { return uint256(stakes[stakeOwner].shares); } function getShareBalance(address stakeOwner) external view returns(uint256) { if (vault.shares == 0) { return 0; } return (uint256(stakes[stakeOwner].shares)).mul(uint256(vault.balance)).div(uint256(vault.shares)); } function getStake(address stakeOwner) external view returns(Stake memory) { return stakes[stakeOwner]; } function canLiquidate( uint256 positionId ) external view returns(bool) { Position memory position = positions[positionId]; Product storage product = products[uint256(position.productId)]; uint256 price = IOracle(oracle).getPrice(product.feed); return _checkLiquidation(position, price, product.liquidationThreshold); } // Internal methods function _canTakeProfit( Position memory position, uint256 oraclePrice, uint256 minPriceChange ) internal view returns(bool) { if (block.timestamp > uint256(position.timestamp).add(minProfitTime)) { return true; } else if (position.isLong && oraclePrice > uint256(position.oraclePrice).mul(uint256(1e4).add(minPriceChange)).div(1e4)) { return true; } else if (!position.isLong && oraclePrice < uint256(position.oraclePrice).mul(uint256(1e4).sub(minPriceChange)).div(1e4)) { return true; } return false; } function _calculatePrice( address feed, bool isLong, uint256 openInterestLong, uint256 openInterestShort, uint256 maxExposure, uint256 reserve, uint256 amount ) internal view returns(uint256) { uint256 oraclePrice = IOracle(oracle).getPrice(feed); int256 shift = (int256(openInterestLong) - int256(openInterestShort)) * int256(maxShift) / int256(maxExposure); if (isLong) { uint256 slippage = (reserve.mul(reserve).div(reserve.sub(amount)).sub(reserve)).mul(BASE).div(amount); slippage = shift >= 0 ? slippage.add(uint256(shift)) : slippage.sub(uint256(-1 * shift).div(2)); return oraclePrice.mul(slippage).div(BASE); } else { uint256 slippage = (reserve.sub(reserve.mul(reserve).div(reserve.add(amount)))).mul(BASE).div(amount); slippage = shift >= 0 ? slippage.add(uint256(shift).div(2)) : slippage.sub(uint256(-1 * shift)); return oraclePrice.mul(slippage).div(BASE); } } function _getInterest( Position memory position, uint256 margin, uint256 interest ) internal view returns(uint256) { return margin.mul(uint256(position.leverage)).mul(interest) .mul(block.timestamp.sub(uint256(position.timestamp))).div(uint256(10**12).mul(365 days)); } function _getPnl( Position memory position, uint256 margin, uint256 price ) internal view returns(int256 _pnl) { bool pnlIsNegative; uint256 pnl; if (position.isLong) { if (price >= uint256(position.price)) { pnl = margin.mul(uint256(position.leverage)).mul(price.sub(uint256(position.price))).div(uint256(position.price)).div(BASE); } else { pnl = margin.mul(uint256(position.leverage)).mul(uint256(position.price).sub(price)).div(uint256(position.price)).div(BASE); pnlIsNegative = true; } } else { if (price > uint256(position.price)) { pnl = margin.mul(uint256(position.leverage)).mul(price - uint256(position.price)).div(uint256(position.price)).div(BASE); pnlIsNegative = true; } else { pnl = margin.mul(uint256(position.leverage)).mul(uint256(position.price).sub(price)).div(uint256(position.price)).div(BASE); } } if (pnlIsNegative) { _pnl = -1 * int256(pnl); } else { _pnl = int256(pnl); } return _pnl; } function _getPnlWithFee( int256 pnl, Position memory position, uint256 margin, uint256 fee, uint256 interest ) internal view returns(int256 pnlAfterFee, uint256 totalFee) { // Subtract trade fee from P/L uint256 tradeFee = _getTradeFee(margin, uint256(position.leverage), fee); pnlAfterFee = pnl.sub(int256(tradeFee)); // Subtract interest from P/L uint256 interestFee = _getInterest(position, margin, interest); pnlAfterFee = pnlAfterFee.sub(int256(interestFee)); totalFee = tradeFee.add(interestFee); } function _getTradeFee( uint256 margin, uint256 leverage, uint256 fee ) internal pure returns(uint256) { return margin.mul(leverage).div(BASE).mul(fee).div(10**4); } function _checkLiquidation( Position memory position, uint256 price, uint256 liquidationThreshold ) internal pure returns (bool) { uint256 liquidationPrice; if (position.isLong) { liquidationPrice = position.price - position.price * liquidationThreshold * 10**4 / uint256(position.leverage); } else { liquidationPrice = position.price + position.price * liquidationThreshold * 10**4 / uint256(position.leverage); } if (position.isLong && price <= liquidationPrice || !position.isLong && price >= liquidationPrice) { return true; } else { return false; } } // Owner methods function updateVault(Vault memory _vault) external onlyOwner { require(_vault.cap > 0, "!cap"); require(_vault.stakingPeriod > 0 && _vault.stakingPeriod < 30 days, "!stakingPeriod"); vault.cap = _vault.cap; vault.stakingPeriod = _vault.stakingPeriod; emit VaultUpdated(vault); } function addProduct(uint256 productId, Product memory _product) external onlyOwner { require(productId > 0, "!productId"); Product memory product = products[productId]; require(product.maxLeverage == 0, "!product-exists"); require(_product.maxLeverage > 1 * BASE, "!max-leverage"); require(_product.feed != address(0), "!feed"); require(_product.liquidationThreshold > 0, "!liquidationThreshold"); products[productId] = Product({ feed: _product.feed, maxLeverage: _product.maxLeverage, fee: _product.fee, isActive: true, openInterestLong: 0, openInterestShort: 0, interest: _product.interest, liquidationThreshold: _product.liquidationThreshold, liquidationBounty: _product.liquidationBounty, minPriceChange: _product.minPriceChange, weight: _product.weight, reserve: _product.reserve }); totalWeight += _product.weight; emit ProductAdded(productId, products[productId]); } function updateProduct(uint256 productId, Product memory _product) external onlyOwner { require(productId > 0, "!productId"); Product storage product = products[productId]; require(product.maxLeverage > 0, "!product-exists"); require(_product.maxLeverage >= 1 * BASE, "!max-leverage"); require(_product.feed != address(0), "!feed"); require(_product.liquidationThreshold > 0, "!liquidationThreshold"); product.feed = _product.feed; product.maxLeverage = _product.maxLeverage; product.fee = _product.fee; product.isActive = _product.isActive; product.interest = _product.interest; product.liquidationThreshold = _product.liquidationThreshold; product.liquidationBounty = _product.liquidationBounty; totalWeight = totalWeight - product.weight + _product.weight; product.weight = _product.weight; emit ProductUpdated(productId, product); } function setDistributors( address _protocolRewardDistributor, address _pikaRewardDistributor, address _vaultRewardDistributor, address _vaultTokenReward ) external onlyOwner { protocolRewardDistributor = _protocolRewardDistributor; pikaRewardDistributor = _pikaRewardDistributor; vaultRewardDistributor = _vaultRewardDistributor; vaultTokenReward = _vaultTokenReward; } function setRewardRatio(uint256 _protocolRewardRatio, uint256 _pikaRewardRatio) external onlyOwner { require(_protocolRewardRatio + _pikaRewardRatio <= 10000, "!too-much"); protocolRewardRatio = _protocolRewardRatio; pikaRewardRatio = _pikaRewardRatio; emit RewardRatioUpdated(protocolRewardRatio, pikaRewardRatio); } function setMargin(uint256 _minMargin, uint256 _maxPositionMargin) external onlyOwner { minMargin = _minMargin; maxPositionMargin = _maxPositionMargin; } function setMaxShiftAndMinProfitTime(uint256 _maxShift, uint256 _minProfitTime) external onlyOwner { require(_maxShift >= 0 && _maxShift <= 0.01e8 && _minProfitTime >= 0 && _minProfitTime <= 24 hours); maxShift = _maxShift; minProfitTime = _minProfitTime; } function setCanUserStakeAndAllowPublicLiquidator(bool _canUserStake, bool _allowPublicLiquidator) external onlyOwner { canUserStake = _canUserStake; allowPublicLiquidator = _allowPublicLiquidator; } function setExposureMultiplier(uint256 _exposureMultiplier) external onlyOwner { exposureMultiplier = _exposureMultiplier; } function setOracle(address _oracle) external onlyOwner { oracle = _oracle; emit OracleUpdated(_oracle); } function setLiquidator(address _liquidator) external onlyOwner { liquidator = _liquidator; } function setOwner(address _owner) external onlyOwner { owner = _owner; emit OwnerUpdated(_owner); } modifier onlyOwner() { require(msg.sender == owner, "!owner"); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SignedSafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SignedSafeMath { /** * @dev Returns the multiplication of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { return a * b; } /** * @dev Returns the integer division of two signed integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(int256 a, int256 b) internal pure returns (int256) { return a / b; } /** * @dev Returns the subtraction of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { return a - b; } /** * @dev Returns the addition of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { return a + b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.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)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT 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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
pragma solidity ^0.8.0; interface IOracle { function getPrice(address feed) external view returns (uint256); }
// SPDX-License-Identifier: MIT // Originally: https://github.com/CryptoManiacsZone/mooniswap/blob/master/contracts/libraries/UniERC20.sol pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; library UniERC20 { using SafeMath for uint256; using SafeERC20 for IERC20; function isETH(IERC20 token) internal pure returns (bool) { return (address(token) == address(0)); } function uniBalanceOf(IERC20 token, address account) internal view returns (uint256) { if (isETH(token)) { return account.balance; } else { return token.balanceOf(account); } } function uniTransfer( IERC20 token, address to, uint256 amount ) internal { if (amount > 0) { if (isETH(token)) { (bool success, ) = payable(to).call{value: amount}(""); require(success, "Transfer failed"); } else { token.safeTransfer(to, amount); } } } function uniTransferFromSenderToThis(IERC20 token, uint256 amount) internal { if (amount > 0) { if (isETH(token)) { require(msg.value >= amount, "UniERC20: not enough value"); if (msg.value > amount) { // Return remainder if exist uint256 refundAmount = msg.value.sub(amount); (bool success, ) = msg.sender.call{value: refundAmount}(""); require(success, "Transfer failed"); } } else { token.safeTransferFrom(msg.sender, address(this), amount); } } } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IPikaPerp { function getTotalShare() external view returns(uint256); function getShare(address stakeOwner) external view returns(uint256); function distributeProtocolReward() external returns(uint256); function distributePikaReward() external returns(uint256); function distributeVaultReward() external returns(uint256); function getPendingPikaReward() external view returns(uint256); function getPendingProtocolReward() external view returns(uint256); function getPendingVaultReward() external view returns(uint256); function stake(uint256 amount) external; function stakeForUser(uint256 amount, address user) external; function redeem(uint256 shares) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IVaultReward { function updateReward(address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenDecimal","type":"uint256"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"uint256","name":"_minMargin","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"margin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMargin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLeverage","type":"uint256"}],"name":"AddMargin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"productId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"entryPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"margin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leverage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"int256","name":"pnl","type":"int256"},{"indexed":false,"internalType":"bool","name":"wasLiquidated","type":"bool"}],"name":"ClosePosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"productId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oraclePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"margin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leverage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"NewPosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOracle","type":"address"}],"name":"OracleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PikaRewardDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidatorReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingReward","type":"uint256"}],"name":"PositionLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"productId","type":"uint256"},{"components":[{"internalType":"address","name":"feed","type":"address"},{"internalType":"uint72","name":"maxLeverage","type":"uint72"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"uint64","name":"openInterestLong","type":"uint64"},{"internalType":"uint64","name":"openInterestShort","type":"uint64"},{"internalType":"uint16","name":"interest","type":"uint16"},{"internalType":"uint16","name":"liquidationThreshold","type":"uint16"},{"internalType":"uint16","name":"liquidationBounty","type":"uint16"},{"internalType":"uint16","name":"minPriceChange","type":"uint16"},{"internalType":"uint16","name":"weight","type":"uint16"},{"internalType":"uint64","name":"reserve","type":"uint64"}],"indexed":false,"internalType":"struct PikaPerpV2.Product","name":"product","type":"tuple"}],"name":"ProductAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"productId","type":"uint256"},{"components":[{"internalType":"address","name":"feed","type":"address"},{"internalType":"uint72","name":"maxLeverage","type":"uint72"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"uint64","name":"openInterestLong","type":"uint64"},{"internalType":"uint64","name":"openInterestShort","type":"uint64"},{"internalType":"uint16","name":"interest","type":"uint16"},{"internalType":"uint16","name":"liquidationThreshold","type":"uint16"},{"internalType":"uint16","name":"liquidationBounty","type":"uint16"},{"internalType":"uint16","name":"minPriceChange","type":"uint16"},{"internalType":"uint16","name":"weight","type":"uint16"},{"internalType":"uint64","name":"reserve","type":"uint64"}],"indexed":false,"internalType":"struct PikaPerpV2.Product","name":"product","type":"tuple"}],"name":"ProductUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProtocolRewardDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shareBalance","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isFullRedeem","type":"bool"}],"name":"Redeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"protocolRewardRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pikaRewardRatio","type":"uint256"}],"name":"RewardRatioUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"VaultRewardDistributed","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint96","name":"cap","type":"uint96"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint64","name":"staked","type":"uint64"},{"internalType":"uint64","name":"shares","type":"uint64"},{"internalType":"uint32","name":"stakingPeriod","type":"uint32"}],"indexed":false,"internalType":"struct PikaPerpV2.Vault","name":"vault","type":"tuple"}],"name":"VaultUpdated","type":"event"},{"inputs":[],"name":"BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"}],"name":"addMargin","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"productId","type":"uint256"},{"components":[{"internalType":"address","name":"feed","type":"address"},{"internalType":"uint72","name":"maxLeverage","type":"uint72"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"uint64","name":"openInterestLong","type":"uint64"},{"internalType":"uint64","name":"openInterestShort","type":"uint64"},{"internalType":"uint16","name":"interest","type":"uint16"},{"internalType":"uint16","name":"liquidationThreshold","type":"uint16"},{"internalType":"uint16","name":"liquidationBounty","type":"uint16"},{"internalType":"uint16","name":"minPriceChange","type":"uint16"},{"internalType":"uint16","name":"weight","type":"uint16"},{"internalType":"uint64","name":"reserve","type":"uint64"}],"internalType":"struct PikaPerpV2.Product","name":"_product","type":"tuple"}],"name":"addProduct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"positionId","type":"uint256"}],"name":"canLiquidate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"}],"name":"closePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"}],"name":"closePositionWithId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributePikaReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributeProtocolReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributeVaultReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exposureMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingPikaReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingProtocolReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingVaultReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"}],"name":"getPosition","outputs":[{"components":[{"internalType":"uint64","name":"productId","type":"uint64"},{"internalType":"uint64","name":"leverage","type":"uint64"},{"internalType":"uint64","name":"price","type":"uint64"},{"internalType":"uint64","name":"oraclePrice","type":"uint64"},{"internalType":"uint64","name":"margin","type":"uint64"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint80","name":"timestamp","type":"uint80"},{"internalType":"bool","name":"isLong","type":"bool"}],"internalType":"struct PikaPerpV2.Position","name":"position","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"}],"name":"getPositionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"positionIds","type":"uint256[]"}],"name":"getPositions","outputs":[{"components":[{"internalType":"uint64","name":"productId","type":"uint64"},{"internalType":"uint64","name":"leverage","type":"uint64"},{"internalType":"uint64","name":"price","type":"uint64"},{"internalType":"uint64","name":"oraclePrice","type":"uint64"},{"internalType":"uint64","name":"margin","type":"uint64"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint80","name":"timestamp","type":"uint80"},{"internalType":"bool","name":"isLong","type":"bool"}],"internalType":"struct PikaPerpV2.Position[]","name":"_positions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"productId","type":"uint256"}],"name":"getProduct","outputs":[{"components":[{"internalType":"address","name":"feed","type":"address"},{"internalType":"uint72","name":"maxLeverage","type":"uint72"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"uint64","name":"openInterestLong","type":"uint64"},{"internalType":"uint64","name":"openInterestShort","type":"uint64"},{"internalType":"uint16","name":"interest","type":"uint16"},{"internalType":"uint16","name":"liquidationThreshold","type":"uint16"},{"internalType":"uint16","name":"liquidationBounty","type":"uint16"},{"internalType":"uint16","name":"minPriceChange","type":"uint16"},{"internalType":"uint16","name":"weight","type":"uint16"},{"internalType":"uint64","name":"reserve","type":"uint64"}],"internalType":"struct PikaPerpV2.Product","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakeOwner","type":"address"}],"name":"getShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakeOwner","type":"address"}],"name":"getShareBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakeOwner","type":"address"}],"name":"getStake","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint64","name":"amount","type":"uint64"},{"internalType":"uint64","name":"shares","type":"uint64"},{"internalType":"uint32","name":"timestamp","type":"uint32"}],"internalType":"struct PikaPerpV2.Stake","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVault","outputs":[{"components":[{"internalType":"uint96","name":"cap","type":"uint96"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint64","name":"staked","type":"uint64"},{"internalType":"uint64","name":"shares","type":"uint64"},{"internalType":"uint32","name":"stakingPeriod","type":"uint32"}],"internalType":"struct PikaPerpV2.Vault","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"positionIds","type":"uint256[]"}],"name":"liquidatePositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquidator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPositionMargin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxShift","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minMargin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minProfitTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"},{"internalType":"uint256","name":"leverage","type":"uint256"}],"name":"openPosition","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"uint256","name":"margin","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"},{"internalType":"uint256","name":"leverage","type":"uint256"}],"name":"openPositionForUser","outputs":[{"internalType":"uint256","name":"positionId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingPikaReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingProtocolReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingVaultReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pikaRewardDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pikaRewardRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolRewardDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolRewardRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"positionId","type":"uint256"}],"name":"releaseMargin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_canUserStake","type":"bool"},{"internalType":"bool","name":"_allowPublicLiquidator","type":"bool"}],"name":"setCanUserStakeAndAllowPublicLiquidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_protocolRewardDistributor","type":"address"},{"internalType":"address","name":"_pikaRewardDistributor","type":"address"},{"internalType":"address","name":"_vaultRewardDistributor","type":"address"},{"internalType":"address","name":"_vaultTokenReward","type":"address"}],"name":"setDistributors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_exposureMultiplier","type":"uint256"}],"name":"setExposureMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_liquidator","type":"address"}],"name":"setLiquidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minMargin","type":"uint256"},{"internalType":"uint256","name":"_maxPositionMargin","type":"uint256"}],"name":"setMargin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxShift","type":"uint256"},{"internalType":"uint256","name":"_minProfitTime","type":"uint256"}],"name":"setMaxShiftAndMinProfitTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolRewardRatio","type":"uint256"},{"internalType":"uint256","name":"_pikaRewardRatio","type":"uint256"}],"name":"setRewardRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"stakeForUser","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDecimal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalOpenInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"productId","type":"uint256"},{"components":[{"internalType":"address","name":"feed","type":"address"},{"internalType":"uint72","name":"maxLeverage","type":"uint72"},{"internalType":"uint16","name":"fee","type":"uint16"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"uint64","name":"openInterestLong","type":"uint64"},{"internalType":"uint64","name":"openInterestShort","type":"uint64"},{"internalType":"uint16","name":"interest","type":"uint16"},{"internalType":"uint16","name":"liquidationThreshold","type":"uint16"},{"internalType":"uint16","name":"liquidationBounty","type":"uint16"},{"internalType":"uint16","name":"minPriceChange","type":"uint16"},{"internalType":"uint16","name":"weight","type":"uint16"},{"internalType":"uint64","name":"reserve","type":"uint64"}],"internalType":"struct PikaPerpV2.Product","name":"_product","type":"tuple"}],"name":"updateProduct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint96","name":"cap","type":"uint96"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"uint64","name":"staked","type":"uint64"},{"internalType":"uint64","name":"shares","type":"uint64"},{"internalType":"uint32","name":"stakingPeriod","type":"uint32"}],"internalType":"struct PikaPerpV2.Vault","name":"_vault","type":"tuple"}],"name":"updateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"utilizationMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultRewardDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultTokenReward","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040526107d0600855610bb8600955620493e0600a5561a8c0600b55612710600e819055600f556018805461ffff191690553480156200004057600080fd5b50604051620062b7380380620062b7833981016040819052620000639162000149565b600160008190558054336001600160a01b03199182168117909255600280548216909217909155600380549091166001600160a01b0386161790556004839055620000b083600a620001db565b600555600680546001600160a01b0319166001600160a01b03939093169290921790915560075550506040805160a0810182526000808252602082018190529181018290526060810182905262015180608090910152601955601a80546001600160601b0319166a0151800000000000000000179055620002bc565b80516001600160a01b03811681146200014457600080fd5b919050565b600080600080608085870312156200016057600080fd5b6200016b856200012c565b93506020850151925062000182604086016200012c565b6060959095015193969295505050565b600181815b80851115620001d3578160001904821115620001b757620001b7620002a6565b80851615620001c557918102915b93841c939080029062000197565b509250929050565b6000620001e98383620001f0565b9392505050565b6000826200020157506001620002a0565b816200021057506000620002a0565b8160018114620002295760028114620002345762000254565b6001915050620002a0565b60ff841115620002485762000248620002a6565b50506001821b620002a0565b5060208310610133831016604e8410600b841016171562000279575081810a620002a0565b62000285838362000192565b80600019048211156200029c576200029c620002a6565b0290505b92915050565b634e487b7160e01b600052601160045260246000fd5b615feb80620002cc6000396000f3fe6080604052600436106103b55760003560e01c806381a3daca116101f2578063b9db15b41161010d578063d65fe355116100a0578063ec342ad01161006f578063ec342ad014610d79578063f4b1559514610d8e578063fbb48bc114610dae578063fc0c546a14610dc357600080fd5b8063d65fe35514610d0d578063d9ac422514610d2d578063db006a7514610d43578063e19a60e114610d6357600080fd5b8063d32bb3e9116100dc578063d32bb3e914610ca4578063d41194b814610cc4578063d468e2a914610cd7578063d48788b914610ced57600080fd5b8063b9db15b414610ad0578063bc95baad14610c37578063bed5755414610c64578063cd84db0914610c8457600080fd5b806396c82e5711610185578063a576d8ad11610154578063a576d8ad14610a67578063a694fc3a14610a87578063b26d97e914610a9a578063b61daaee14610aba57600080fd5b806396c82e57146109eb5780639df411ee14610a01578063a0448fc514610a31578063a082cdd214610a4757600080fd5b80638d928af8116101c15780638d928af8146108945780638da5cb5b146109955780638ea8f7fc146109b5578063904a53b6146109cb57600080fd5b806381a3daca14610834578063841a4b51146108545780638b09578d1461086a5780638c10ad1b1461087f57600080fd5b80633ee19763116102e25780635f3b21801161027557806378d7fb7f1161024457806378d7fb7f146106e85780637a766460146106fb5780637adbf973146107f45780637dc0d1d01461081457600080fd5b80635f3b21801461068a57806367d3ef9a146106a05780636e20c3b4146106c057806370607f5d146106d557600080fd5b80634c723c28116102b15780634c723c28146106115780634d452ec01461063e5780635b3829891461065e5780635caed0291461067457600080fd5b80633ee197631461057c5780633f06cd66146105915780634046ebae146105af5780634b3ab9c5146105cf57600080fd5b80631ba938441161035a5780632dc9265e116103295780632dc9265e1461051d57806333af0efa1461053d57806339c294be146105535780633dc8f1441461056957600080fd5b80631ba93844146104a55780631ea8c3a7146104dd5780631fbeef4e146104f2578063228f524e1461050757600080fd5b806301c76f811161039657806301c76f81146104255780630904c2db14610445578063114379411461046557806313af40351461048557600080fd5b80620b15a3146103ba5780621b7934146103dc578062eb5b62146103fc575b600080fd5b3480156103c657600080fd5b506103da6103d5366004615672565b610de3565b005b3480156103e857600080fd5b506103da6103f7366004615783565b6110e6565b34801561040857600080fd5b5061041260125481565b6040519081526020015b60405180910390f35b34801561043157600080fd5b506103da6104403660046153a5565b61119e565b34801561045157600080fd5b506103da610460366004615614565b6111ea565b34801561047157600080fd5b506104126104803660046153a5565b611219565b34801561049157600080fd5b506103da6104a03660046153a5565b611290565b3480156104b157600080fd5b506015546104c5906001600160a01b031681565b6040516001600160a01b03909116815260200161041c565b3480156104e957600080fd5b5061041261130f565b3480156104fe57600080fd5b506104126113d6565b34801561051357600080fd5b50610412600c5481565b34801561052957600080fd5b506103da610538366004615783565b611493565b34801561054957600080fd5b5061041260115481565b34801561055f57600080fd5b5061041260075481565b6104126105773660046157d3565b6114c8565b34801561058857600080fd5b506104126114e0565b34801561059d57600080fd5b50601a546001600160401b0316610412565b3480156105bb57600080fd5b506002546104c5906001600160a01b031681565b3480156105db57600080fd5b506104126105ea3660046153a5565b6001600160a01b03166000908152601c60205260409020600101546001600160401b031690565b34801561061d57600080fd5b5061063161062c3660046154a4565b611505565b60405161041c9190615990565b34801561064a57600080fd5b506103da6106593660046154a4565b61165d565b34801561066a57600080fd5b50610412600f5481565b34801561068057600080fd5b5061041260045481565b34801561069657600080fd5b5061041260085481565b3480156106ac57600080fd5b506103da6106bb3660046157a5565b61174e565b3480156106cc57600080fd5b50610412611762565b6103da6106e3366004615646565b611773565b6104126106f6366004615454565b611c59565b34801561070757600080fd5b506107a46107163660046153a5565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b039081166000908152601c6020908152604091829020825160808101845281549485168152600160a01b9094046001600160401b03908116928501929092526001015490811691830191909152600160401b900463ffffffff16606082015290565b6040805182516001600160a01b031681526020808401516001600160401b039081169183019190915283830151169181019190915260609182015163ffffffff169181019190915260800161041c565b34801561080057600080fd5b506103da61080f3660046153a5565b6123ef565b34801561082057600080fd5b506006546104c5906001600160a01b031681565b34801561084057600080fd5b506014546104c5906001600160a01b031681565b34801561086057600080fd5b50610412600e5481565b34801561087657600080fd5b50610412600881565b34801561088b57600080fd5b50610412612467565b3480156108a057600080fd5b506109316040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526019546001600160601b038082168352600160601b8204166020830152600160c01b90046001600160401b0390811692820192909252601a549182166060820152600160401b90910463ffffffff16608082015290565b60405161041c9190600060a0820190506001600160601b038084511683528060208501511660208401525060408301516001600160401b038082166040850152806060860151166060850152505063ffffffff608084015116608083015292915050565b3480156109a157600080fd5b506001546104c5906001600160a01b031681565b3480156109c157600080fd5b5061041260105481565b3480156109d757600080fd5b506103da6109e6366004615783565b612478565b3480156109f757600080fd5b50610412600d5481565b348015610a0d57600080fd5b50610a21610a1c366004615614565b6124d6565b604051901515815260200161041c565b348015610a3d57600080fd5b50610412600a5481565b348015610a5357600080fd5b506103da610a623660046153c0565b612615565b348015610a7357600080fd5b506103da610a82366004615614565b61268f565b6103da610a95366004615614565b61286d565b348015610aa657600080fd5b506103da610ab5366004615672565b61287a565b348015610ac657600080fd5b5061041260055481565b348015610adc57600080fd5b50610c2a610aeb366004615614565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810191909152506000908152601b602090815260409182902082516101808101845281546001600160a01b0381168252600160a01b8082046001600160481b031694830194909452600160e81b810461ffff90811695830195909552600160f81b900460ff161515606082015260018201546001600160401b038082166080840152600160401b8204811660a0840152600160801b8204861660c0840152600160901b8204861660e08401529381048516610100830152600160b01b81048516610120830152600160c01b9004909316610140840152600201541661016082015290565b60405161041c9190615ae6565b348015610c4357600080fd5b50610c57610c52366004615414565b612de0565b60405161041c9190615ad7565b348015610c7057600080fd5b506013546104c5906001600160a01b031681565b348015610c9057600080fd5b506103da610c9f366004615783565b612e9c565b348015610cb057600080fd5b506103da610cbf36600461556e565b613495565b6103da610cd2366004615783565b613616565b348015610ce357600080fd5b5061041260175481565b348015610cf957600080fd5b506016546104c5906001600160a01b031681565b348015610d1957600080fd5b50610412610d28366004615414565b613800565b348015610d3957600080fd5b50610412600b5481565b348015610d4f57600080fd5b506103da610d5e366004615614565b613852565b348015610d6f57600080fd5b5061041260095481565b348015610d8557600080fd5b50610412613d28565b348015610d9a57600080fd5b506103da610da9366004615535565b613d37565b348015610dba57600080fd5b50610412613d85565b348015610dcf57600080fd5b506003546104c5906001600160a01b031681565b6001546001600160a01b03163314610e165760405162461bcd60e51b8152600401610e0d90615ab7565b60405180910390fd5b60008211610e535760405162461bcd60e51b815260206004820152600a602482015269085c1c9bd91d58dd125960b21b6044820152606401610e0d565b6000828152601b602052604090208054600160a01b90046001600160481b0316610eb15760405162461bcd60e51b815260206004820152600f60248201526e2170726f647563742d65786973747360881b6044820152606401610e0d565b610ebd6008600a615d1e565b610ec8906001615e4b565b82602001516001600160481b03161015610ef45760405162461bcd60e51b8152600401610e0d90615a59565b81516001600160a01b0316610f335760405162461bcd60e51b8152602060048201526005602482015264085999595960da1b6044820152606401610e0d565b60008260e0015161ffff1611610f835760405162461bcd60e51b8152602060048201526015602482015274085b1a5c5d5a59185d1a5bdb951a1c995cda1bdb19605a1b6044820152606401610e0d565b815181546020840151604085015160608601516001600160a01b039094166001600160e81b031990931692909217600160a01b6001600160481b039092168202176001600160e81b0316600160e81b61ffff938416026001600160f81b031617600160f81b9315159390930292909217835560c084015160018401805460e087015161010088015163ffffffff60801b19909216600160801b9486169490940261ffff60901b191693909317600160901b938516939093029290921761ffff60a01b19169183169093021791829055610140840151600d549082169261107292600160c01b9091041690615ea9565b61107c9190615c34565b600d5561014082015160018201805461ffff909216600160c01b0261ffff60c01b199092169190911790556040517ff67c96d097a316014b351edfed880cf93784164f445f0bbb26cde56fb89fa2fc906110d99085908490615be8565b60405180910390a1505050565b6001546001600160a01b031633146111105760405162461bcd60e51b8152600401610e0d90615ab7565b61271061111d8284615c34565b11156111575760405162461bcd60e51b8152602060048201526009602482015268042e8dede5adaeac6d60bb1b6044820152606401610e0d565b6008829055600981905560408051838152602081018390527f2cda5f90308a6ed0aad400f6ddc7575e31b5f1428c50c054ae54e1939ff164b8910160405180910390a15050565b6001546001600160a01b031633146111c85760405162461bcd60e51b8152600401610e0d90615ab7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146112145760405162461bcd60e51b8152600401610e0d90615ab7565b600e55565b601a546000906001600160401b031661123457506000919050565b601a546019546001600160a01b0384166000908152601c602052604090206001015461128a926001600160401b039081169261128492909116906001600160601b03600160601b90910416613e33565b90613e3f565b92915050565b6001546001600160a01b031633146112ba5760405162461bcd60e51b8152600401610e0d90615ab7565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b906020015b60405180910390a150565b6014546000906001600160a01b0316331461133c5760405162461bcd60e51b8152600401610e0d90615a12565b600061135c61134d6008600a615d1e565b60055460115461128491613e33565b601154909150156113d1576000601155601454600354611389916001600160a01b03918216911683613e4b565b601454604080516001600160a01b039092168252602082018390527f304116b7df0fff49d35547e731489e0e2f288bf99c5293f5fb4697671108280d91015b60405180910390a15b919050565b6013546000906001600160a01b031633146114035760405162461bcd60e51b8152600401610e0d90615a12565b60006114236114146008600a615d1e565b60055460105461128491613e33565b601054909150156113d1576000601055601354600354611450916001600160a01b03918216911683613e4b565b601354604080516001600160a01b039092168252602082018390527ffbbb21b60e499f2366d8f9dbdb1884e047dcf008673ee2c189b6153bfacc06e891016113c8565b6001546001600160a01b031633146114bd5760405162461bcd60e51b8152600401610e0d90615ab7565b600791909155600c55565b60006114d73386868686611c59565b95945050505050565b60006115006114f16008600a615d1e565b60055460125461128491613e33565b905090565b606081806001600160401b0381111561152057611520615f91565b60405190808252806020026020018201604052801561155957816020015b6115466152e8565b81526020019060019003908161153e5790505b50915060005b8181101561165557601d600086868481811061157d5761157d615f7b565b6020908102929092013583525081810192909252604090810160002081516101008101835281546001600160401b038082168352600160401b808304821696840196909652600160801b8204811694830194909452600160c01b90048316606082015260018201549283166080820152929091046001600160a01b031660a0830152600201546001600160501b03811660c0830152600160501b900460ff16151560e0820152835184908390811061163757611637615f7b565b6020026020010181905250808061164d90615f34565b91505061155f565b505092915050565b6002546001600160a01b031633148061167d5750601854610100900460ff165b6116b75760405162461bcd60e51b815260206004820152600b60248201526a10b634b8bab4b230ba37b960a91b6044820152606401610e0d565b6000805b8281101561170e5760008484838181106116d7576116d7615f7b565b90506020020135905060006116eb82613f0e565b90506116f7848261444d565b93505050808061170690615f34565b9150506116bb565b50801561174957611749336117366117286008600a615d1e565b600554611284908690613e33565b6003546001600160a01b03169190613e4b565b505050565b61174961175c338584613800565b83612e9c565b600061150061134d6008600a615d1e565b600260005414156117965760405162461bcd60e51b8152600401610e0d90615a80565b600260005560185460ff16806117b657506001546001600160a01b031633145b6117eb5760405162461bcd60e51b8152602060048201526006602482015265217374616b6560d01b6044820152606401610e0d565b60155460405163632447c960e01b81526001600160a01b0383811660048301529091169063632447c990602401600060405180830381600087803b15801561183257600080fd5b505af1158015611846573d6000803e3d6000fd5b505060165460405163632447c960e01b81526001600160a01b038581166004830152909116925063632447c99150602401600060405180830381600087803b15801561189157600080fd5b505af11580156118a5573d6000803e3d6000fd5b505050506118cf6118bd6008600a6117289190615d1e565b6003546001600160a01b031690614459565b6019546001600160601b038116906118f8908490600160c01b90046001600160401b0316615c34565b111561192f5760405162461bcd60e51b8152600401610e0d906020808252600490820152630216361760e41b604082015260600190565b601954600090600160c01b90046001600160401b031661194f578261197e565b601954601a5461197e91600160601b90046001600160601b0316906112849086906001600160401b0316613e33565b601980549192508491600c906119a5908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082601960000160188282829054906101000a90046001600160401b03166119f09190615c4c565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555080601960010160008282829054906101000a90046001600160401b0316611a3b9190615c4c565b82546101009290920a6001600160401b038181021990931691831602179091556001600160a01b0384166000908152601c6020526040902054600160a01b90041615159050611b2657604080516080810182526001600160a01b038085168083526001600160401b03808816602080860191825287831686880190815263ffffffff428116606089019081526000968752601c909352979094209551865492518416600160a01b026001600160e01b03199093169516949094171784559051600190930180549251909416600160401b026001600160601b0319909216921691909117179055611c0b565b6001600160a01b0382166000908152601c602052604090208054849190601490611b61908490600160a01b90046001600160401b0316615c4c565b82546101009290920a6001600160401b038181021990931691831602179091556001600160a01b0384166000908152601c6020526040812060010180548594509092611baf91859116615c4c565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001600160a01b0382166000908152601c60205260409020600101805463ffffffff60401b1916600160401b4263ffffffff16021790555b60408051848152602081018390526001600160a01b038416917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910160405180910390a25050600160005550565b600060026000541415611c7e5760405162461bcd60e51b8152600401610e0d90615a80565b6002600055600754841015611ca55760405162461bcd60e51b8152600401610e0d90615a38565b611cb16008600a615d1e565b611cbc906001615e4b565b821015611cf75760405162461bcd60e51b8152602060048201526009602482015268216c6576657261676560b81b6044820152606401610e0d565b6000858152601b602052604090208054600160f81b900460ff16611d4f5760405162461bcd60e51b815260206004820152600f60248201526e2170726f647563742d61637469766560881b6044820152606401610e0d565b8054600160a01b90046001600160481b0316831115611d805760405162461bcd60e51b8152600401610e0d90615a59565b8054600090611d9d9087908690600160e81b900461ffff1661452f565b9050611dc86118bd611db16008600a615d1e565b60055461128490611dc28b8761444d565b90613e33565b611def611de661271061128460085485613e3390919063ffffffff16565b6010549061444d565b601055600954611e1590611e0c9061271090611284908590613e33565b6011549061444d565b601181905550611e54611e4b612710611284600954600854612710611e3a9190615ea9565b611e449190615ea9565b8590613e33565b6012549061444d565b6012556000611e72611e686008600a615d1e565b6112848988613e33565b83546001850154600d54600e54601954949550600094611ef8946001600160a01b0316938c936001600160401b0380831694600160401b840490911693611ee493612710936112849390928492611dc291600160601b90046001600160601b031690600160c01b900461ffff16613e33565b60028a01546001600160401b03168861455c565b9050611f078983896001614707565b611f128a8a89613800565b6000818152601d602052604090206001810154919650906001600160401b03161561202557611fb6611f72611f478b8a613e33565b83546001850154611f6c916001600160401b0391821691600160401b90910416613e33565b9061444d565b611284611f8385611dc28e8d613e33565b84546001860154611f6c916001600160401b03600160801b8204811692611dc29290821691600160401b90910416613e33565b600182015490925061200790611fd5906001600160401b03168b61444d565b611284611fe28c8b613e33565b84546001860154611f6c916001600160401b0391821691600160401b90910416613e33565b6001820154909750612022906001600160401b03168a61444d565b98505b600c5489106120645760405162461bcd60e51b815260206004820152600b60248201526a10b6b0bc1036b0b933b4b760a91b6044820152606401610e0d565b60408051610100810182526001600160401b038c811682528981166020830152841681830152600654875492516341976e0960e01b81526001600160a01b039384166004820152919260608401929116906341976e099060240160206040518083038186803b1580156120d657600080fd5b505afa1580156120ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210e919061562d565b6001600160401b031681526020018a6001600160401b031681526020018c6001600160a01b03168152602001426001600160501b03168152602001891515815250601d600088815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a8154816001600160401b0302191690836001600160401b0316021790555060408201518160000160106101000a8154816001600160401b0302191690836001600160401b0316021790555060608201518160000160186101000a8154816001600160401b0302191690836001600160401b0316021790555060808201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060a08201518160010160086101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160020160006101000a8154816001600160501b0302191690836001600160501b0316021790555060e082015181600201600a6101000a81548160ff021916908315150217905550905050898b6001600160a01b0316877f340ad004f2cc7f2adb2ebb38a9900cbc5888c8c67aeab767e74b16dbe1c87a4a8b86600660009054906101000a90046001600160a01b03166001600160a01b03166341976e098c60000160009054906101000a90046001600160a01b03166040518263ffffffff1660e01b815260040161235691906001600160a01b0391909116815260200190565b60206040518083038186803b15801561236e57600080fd5b505afa158015612382573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a6919061562d565b604080519315158452602084019290925290820152606081018e9052608081018c905260a0810189905260c00160405180910390a4505060016000555091979650505050505050565b6001546001600160a01b031633146124195760405162461bcd60e51b8152600401610e0d90615ab7565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527f3df77beb5db05fcdd70a30fc8adf3f83f9501b68579455adbd100b818094039490602001611304565b60006115006114146008600a615d1e565b6001546001600160a01b031633146124a25760405162461bcd60e51b8152600401610e0d90615ab7565b620f424082111580156124b3575060015b80156124c25750620151808111155b6124cb57600080fd5b600a91909155600b55565b6000818152601d6020908152604080832081516101008101835281546001600160401b03808216808452600160401b808404831685890152600160801b8404831685880152600160c01b90930482166060850152600185015491821660808501529190046001600160a01b0390811660a08401526002909301546001600160501b03811660c0840152600160501b900460ff16151560e08301528552601b909352818420600654815493516341976e0960e01b815293831660048501529092859291909116906341976e099060240160206040518083038186803b1580156125bd57600080fd5b505afa1580156125d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f5919061562d565b60018301549091506114d79084908390600160901b900461ffff16614a48565b6001546001600160a01b0316331461263f5760405162461bcd60e51b8152600401610e0d90615ab7565b601380546001600160a01b039586166001600160a01b0319918216179091556014805494861694821694909417909355601580549285169284169290921790915560168054919093169116179055565b6001546001600160a01b031633146126b95760405162461bcd60e51b8152600401610e0d90615ab7565b6000818152601d6020526040902060018101546001600160401b031661270d5760405162461bcd60e51b815260206004820152600960248201526810b837b9b4ba34b7b760b91b6044820152606401610e0d565b60018101546001600160401b03811690600160401b90046001600160a01b0316600061275b61273e6008600a615d1e565b8554611284908690600160401b90046001600160401b0316613e33565b84546002860154919250612788916001600160401b03909116908390600160501b900460ff166000614707565b8354604080516001600160401b03600160801b840481168083526020830152918101869052600160401b83048216606082015260006080820181905260a0820181905260c08201529116906001600160a01b0384169087907f36b11e691447eee9c5d7286d5c0db51ec49fde6c88b2e4931328a15b554312be9060e00160405180910390a46000858152601d602052604081209081556001810180546001600160e01b031916905560020180546affffffffffffffffffffff19169055612866826117366128586008600a615d1e565b600554611284908890613e33565b5050505050565b6128778133611773565b50565b6001546001600160a01b031633146128a45760405162461bcd60e51b8152600401610e0d90615ab7565b600082116128e15760405162461bcd60e51b815260206004820152600a602482015269085c1c9bd91d58dd125960b21b6044820152606401610e0d565b6000828152601b602090815260409182902082516101808101845281546001600160a01b0381168252600160a01b8082046001600160481b0316948301859052600160e81b820461ffff90811696840196909652600160f81b90910460ff161515606083015260018301546001600160401b038082166080850152600160401b8204811660a0850152600160801b8204871660c0850152600160901b8204871660e08501529181048616610100840152600160b01b81048616610120840152600160c01b9004909416610140820152600290910154909216610160830152156129fe5760405162461bcd60e51b815260206004820152600f60248201526e2170726f647563742d65786973747360881b6044820152606401610e0d565b612a0a6008600a615d1e565b612a15906001615e4b565b82602001516001600160481b031611612a405760405162461bcd60e51b8152600401610e0d90615a59565b81516001600160a01b0316612a7f5760405162461bcd60e51b8152602060048201526005602482015264085999595960da1b6044820152606401610e0d565b60008260e0015161ffff1611612acf5760405162461bcd60e51b8152602060048201526015602482015274085b1a5c5d5a59185d1a5bdb951a1c995cda1bdb19605a1b6044820152606401610e0d565b60405180610180016040528083600001516001600160a01b0316815260200183602001516001600160481b03168152602001836040015161ffff16815260200160011515815260200160006001600160401b0316815260200160006001600160401b031681526020018360c0015161ffff1681526020018360e0015161ffff16815260200183610100015161ffff16815260200183610120015161ffff16815260200183610140015161ffff1681526020018361016001516001600160401b0316815250601b600085815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a8154816001600160481b0302191690836001600160481b03160217905550604082015181600001601d6101000a81548161ffff021916908361ffff160217905550606082015181600001601f6101000a81548160ff02191690831515021790555060808201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060a08201518160010160086101000a8154816001600160401b0302191690836001600160401b0316021790555060c08201518160010160106101000a81548161ffff021916908361ffff16021790555060e08201518160010160126101000a81548161ffff021916908361ffff1602179055506101008201518160010160146101000a81548161ffff021916908361ffff1602179055506101208201518160010160166101000a81548161ffff021916908361ffff1602179055506101408201518160010160186101000a81548161ffff021916908361ffff1602179055506101608201518160020160006101000a8154816001600160401b0302191690836001600160401b0316021790555090505081610140015161ffff16600d6000828254612d9b9190615c34565b90915550506000838152601b60205260409081902090517fe1bc4dae2db817ece6daf52cd2b267924bd2427a16d157ada9d40383ce6a16e8916110d991869190615be8565b612de86152e8565b601d6000612df7868686613800565b8152602080820192909252604090810160002081516101008101835281546001600160401b038082168352600160401b808304821696840196909652600160801b8204811694830194909452600160c01b90048316606082015260018201549283166080820152929091046001600160a01b031660a0830152600201546001600160501b03811660c0830152600160501b900460ff16151560e0820152949350505050565b60026000541415612ebf5760405162461bcd60e51b8152600401610e0d90615a80565b6002600055600754811015612ee65760405162461bcd60e51b8152600401610e0d90615a38565b6000828152601d602052604090206001810154600160401b90046001600160a01b03163314612f275760405162461bcd60e51b8152600401610e0d90615ab7565b80546001600160401b039081166000908152601b6020526040812060018401549092168410612f6357506001808301546001600160401b031693505b600d54600e546001840154601954600093612fa8936127109361128493849291611dc291600160601b90046001600160601b031690600160c01b900461ffff16613e33565b835460028681015460018701549187015493945060009361302b936001600160a01b031692600160501b90920460ff1615916001600160401b0380821692600160401b9092048116918891166130006008600a615d1e565b8c5461301c90600160401b90046001600160401b03168f615e4b565b6130269190615cc7565b61455c565b604080516101008101825287546001600160401b038082168352600160401b80830482166020850152600160801b8304821694840194909452600160c01b9091048116606083015260018901549081166080830152919091046001600160a01b031660a082015260028701546001600160501b03811660c0830152600160501b900460ff16151560e082015290915060009081906130ca908985614b4b565b9050600081128015613109575060018601546130fa9061271090611284908b90600160901b900461ffff16613e33565b61310682600019615dc6565b10155b156131355760018701546001600160401b0316975061312a88600019615dc6565b905060019150613261565b6000811380156132585750604080516101008101825288546001600160401b038082168352600160401b80830482166020850152600160801b8304821684860152600160c01b9092048116606084015260018b01549081166080840152046001600160a01b0390811660a083015260028a01546001600160501b03811660c0840152600160501b900460ff16151560e0830152600654895493516341976e0960e01b81529382166004850152613256939116906341976e099060240160206040518083038186803b15801561320957600080fd5b505afa15801561321d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613241919061562d565b6001890154600160b01b900461ffff16614c6a565b155b15613261575060005b604080516101008101825288546001600160401b038082168352600160401b80830482166020850152600160801b808404831695850195909552600160c01b909204811660608401526001808c015491821660808501529190046001600160a01b031660a083015260028a01546001600160501b03811660c0840152600160501b900460ff16151560e083015288549089015460009361331993869390928e92600160e81b90920461ffff9081169290910416614d1a565b885490915061336d906001600160401b031661335761333a6008600a615d1e565b8b54611284908e90600160401b90046001600160401b0316613e33565b60028b0154600160501b900460ff166000614707565b87546001890154604080518781526001600160401b03600160801b8504811660208301529181018d9052600160401b808504831660608301526080820186905260a0820187905287151560c0830152919093169291046001600160a01b0316908c907f36b11e691447eee9c5d7286d5c0db51ec49fde6c88b2e4931328a15b554312be9060e00160405180910390a4851561343f5760008a8152601d602052604081209081556001810180546001600160e01b031916905560020180546affffffffffffffffffffff19169055613484565b6001880180548a919060009061345f9084906001600160401b0316615ec0565b92506101000a8154816001600160401b0302191690836001600160401b031602179055505b505060016000555050505050505050565b6001546001600160a01b031633146134bf5760405162461bcd60e51b8152600401610e0d90615ab7565b80516001600160601b03166134ff5760405162461bcd60e51b8152600401610e0d906020808252600490820152630216361760e41b604082015260600190565b6000816080015163ffffffff16118015613525575062278d00816080015163ffffffff16105b6135625760405162461bcd60e51b815260206004820152600e60248201526d085cdd185ada5b99d4195c9a5bd960921b6044820152606401610e0d565b8051601980546001600160601b0319166001600160601b0392831690811791829055608080850151601a805463ffffffff60401b198116600160401b63ffffffff948516029081179283905560408051968752606088811c909916602088015260c09790971c868801526001600160401b03908116911617958401959095529390921c909216908201527fe065d479bcd6a90bffb826e7a706adf8190a71be3596fc227088af379a93510b9060a001611304565b600260005414156136395760405162461bcd60e51b8152600401610e0d90615a80565b600260005561365e6118bd6136506008600a615d1e565b600554611284908590613e33565b6007548110156136805760405162461bcd60e51b8152600401610e0d90615a38565b6000828152601d602052604090206001810154600160401b90046001600160a01b031633146136c15760405162461bcd60e51b8152600401610e0d90615ab7565b60018101546000906136dc906001600160401b03168461444d565b6001830154835491925060009161370c918491611284916001600160401b03600160401b90920482169116613e33565b905061371a6008600a615d1e565b613725906001615e4b565b8110156137645760405162461bcd60e51b815260206004820152600d60248201526c216c6f772d6c6576657261676560981b6044820152606401610e0d565b60018301805467ffffffffffffffff19166001600160401b038481169190911791829055845467ffffffffffffffff60401b1916600160401b9184168202178555604080518781526020810186905290810184905291046001600160a01b03169086907f8bd26f20a052ff42ee3d1f3e02f0d7c447371c96dfc7d3a14b6fa5c89df272179060600160405180910390a350506001600055505050565b6040516001600160601b0319606085901b1660208201526034810183905281151560f81b60548201526000906055016040516020818303038152906040528051906020012060001c90505b9392505050565b601a546001600160401b03168111156138975760405162461bcd60e51b8152602060048201526007602482015266085cdd185ad95960ca1b6044820152606401610e0d565b60155460405163632447c960e01b81523360048201819052916001600160a01b03169063632447c990602401600060405180830381600087803b1580156138dd57600080fd5b505af11580156138f1573d6000803e3d6000fd5b505060165460405163632447c960e01b81526001600160a01b038581166004830152909116925063632447c99150602401600060405180830381600087803b15801561393c57600080fd5b505af1158015613950573d6000803e3d6000fd5b505050506001600160a01b0381166000908152601c6020526040902060018101546001600160401b031683108015906139945760018201546001600160401b031693505b6001546001600160a01b03848116911614613a1a5760018201546000906139cd90429063ffffffff600160401b909104811690614fab16565b601a54909150600160401b900463ffffffff168111613a185760405162461bcd60e51b8152602060048201526007602482015266085c195c9a5bd960ca1b6044820152606401610e0d565b505b601a54601954600091613a4e916001600160401b0390911690611284908890600160601b90046001600160601b0316613e33565b60018401548454919250600091613a7e916001600160401b0390811691611284918a91600160a01b900416613e33565b845490915081908590601490613aa5908490600160a01b90046001600160401b0316615ec0565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550858460010160008282829054906101000a90046001600160401b0316613aef9190615ec0565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555080601960000160188282829054906101000a90046001600160401b0316613b3a9190615ec0565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555085601960010160008282829054906101000a90046001600160401b0316613b859190615ec0565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550816019600001600c8282829054906101000a90046001600160601b0316613bd09190615ee8565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550613c30612710611284600f546019600001600c9054906101000a90046001600160601b03166001600160601b0316613e3390919063ffffffff16565b6017541115613c6d5760405162461bcd60e51b8152602060048201526009602482015268085d5d1a5b1a5e995960ba1b6044820152606401610e0d565b8215613cab576001600160a01b0385166000908152601c6020526040902080546001600160e01b031916815560010180546001600160601b03191690555b613ccc85611736613cbe6008600a615d1e565b600554611284908790613e33565b604080518281526020810188905290810183905283151560608201526001600160a01b038616907f81ff784935ffa11d6a1785237495788f94842be763045286ed403b1f2e619d189060800160405180910390a2505050505050565b613d346008600a615d1e565b81565b6001546001600160a01b03163314613d615760405162461bcd60e51b8152600401610e0d90615ab7565b6018805461ffff191692151561ff0019169290921761010091151591909102179055565b6015546000906001600160a01b03163314613db25760405162461bcd60e51b8152600401610e0d90615a12565b6000613dc36114f16008600a615d1e565b601254909150156113d1576000601255601554600354613df0916001600160a01b03918216911683613e4b565b601554604080516001600160a01b039092168252602082018390527f19ffdf6391d49bb1730b3f4d19c279b1275dddf2a4e981af93b1099c111369e691016113c8565b600061384b8284615e4b565b600061384b8284615cc7565b8015611749576001600160a01b038316613efa576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613eac576040519150601f19603f3d011682016040523d82523d6000602084013e613eb1565b606091505b5050905080613ef45760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610e0d565b50505050565b6117496001600160a01b0384168383614fb7565b6000818152601d6020526040812080546001600160401b0316613f345750600092915050565b80546001600160401b03166000908152601b6020526040808220600654815492516341976e0960e01b81526001600160a01b03938416600482015291939216906341976e099060240160206040518083038186803b158015613f9557600080fd5b505afa158015613fa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fcd919061562d565b604080516101008101825285546001600160401b038082168352600160401b80830482166020850152600160801b8304821694840194909452600160c01b9091048116606083015260018088015491821660808401529290046001600160a01b031660a082015260028601546001600160501b03811660c0830152600160501b900460ff16151560e08201529084015491925060009161407a91908490600160901b900461ffff16614a48565b1561444457604080516101008101825285546001600160401b038082168352600160401b80830482166020850152600160801b8304821694840194909452600160c01b909104811660608301526001870154908116608083018190529290046001600160a01b031660a082015260028601546001600160501b03811660c0830152600160501b900460ff16151560e082015260009161411a919085614b4b565b9050600081128015614143575061413381600019615dc6565b60018601546001600160401b0316115b1561427b57600061415682600019615dc6565b6001868101549088015491925061418f916127109161128491600160a01b90910461ffff1690611dc2906001600160401b031686614fab565b60018701549097506141b69088906141b0906001600160401b031684614fab565b90614fab565b92506141d6611de661271061128460085487613e3390919063ffffffff16565b6010556009546141f390611e0c9061271090611284908790613e33565b601181905550614229611e4b6127106112846009546008546127106142189190615ea9565b6142229190615ea9565b8790613e33565b60125560198054829190600c90614251908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550506142d3565b6001850154601980546001600160401b0390921691600c906142ae908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b60006143096142e46008600a615d1e565b87546001890154611284916001600160401b0391821691600160401b90910416613e33565b86546002880154919250614336916001600160401b03909116908390600160501b900460ff166000614707565b8554600180880154604080518881526001600160401b03600160801b860481166020830152808416928201839052600160401b808704821660608401526000608084015260a083019390935260c082019490945292909316926001600160a01b03910416908a907f36b11e691447eee9c5d7286d5c0db51ec49fde6c88b2e4931328a15b554312be9060e00160405180910390a46000888152601d602090815260408083209283556001830180546001600160e01b0319169055600290920180546affffffffffffffffffffff19169055815189815290810185905233918a917f6f7734c2b603545392ede46279193d0b944bffb5d4c822bb78cd37eb6c2aadc9910160405180910390a350505b50505050919050565b600061384b8284615c34565b8015614516576001600160a01b03821661451a57803410156144bd5760405162461bcd60e51b815260206004820152601a60248201527f556e6945524332303a206e6f7420656e6f7567682076616c75650000000000006044820152606401610e0d565b803411156145165760006144d13483614fab565b604051909150600090339083908381818185875af1925050503d8060008114613eac576040519150601f19603f3d011682016040523d82523d6000602084013e613eb1565b5050565b6145166001600160a01b03831633308461501a565b600061455461271061128484611dc261454a6008600a615d1e565b6112848a8a613e33565b949350505050565b6006546040516341976e0960e01b81526001600160a01b03898116600483015260009283929116906341976e099060240160206040518083038186803b1580156145a557600080fd5b505afa1580156145b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145dd919061562d565b9050600085600a54888a6145f19190615e6a565b6145fb9190615dc6565b6146059190615c99565b9050881561469757600061463d856112846146226008600a615d1e565b611dc28a6141b0614633828d614fab565b6112848e80613e33565b905060008212156146685761466361465c600261128485600019615dc6565b8290614fab565b614672565b614672818361444d565b905061468d6146836008600a615d1e565b6112848584613e33565b93505050506146fc565b60006146cd856112846146ac6008600a615d1e565b611dc26146c66146bc8c8c61444d565b6112848d80613e33565b8b90614fab565b905060008212156146e75761466361465c83600019615dc6565b6146726146f5836002613e3f565b829061444d565b979650505050505050565b6000848152601b60205260409020811561496157601754614728908561444d565b601755600f54601954614754916127109161128491600160601b9091046001600160601b031690613e33565b60175411156147985760405162461bcd60e51b815260206004820152601060248201526f085b585e13dc195b925b9d195c995cdd60821b6044820152606401610e0d565b600d54600e5460018301546019546000936147dd936127109361128493849291611dc291600160601b90046001600160601b031690600160c01b900461ffff16613e33565b905083156148ae576001820180548691906000906148059084906001600160401b0316615c4c565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555061485c8260010160089054906101000a90046001600160401b03166001600160401b03168261444d90919063ffffffff16565b60018301546001600160401b031611156148a95760405162461bcd60e51b815260206004820152600e60248201526d216578706f737572652d6c6f6e6760901b6044820152606401610e0d565b61495b565b848260010160088282829054906101000a90046001600160401b03166148d49190615c4c565b82546101009290920a6001600160401b038181021990931691831602179091556001840154614906925083911661444d565b6001830154600160401b90046001600160401b0316111561495b5760405162461bcd60e51b815260206004820152600f60248201526e08595e1c1bdcdd5c994b5cda1bdc9d608a1b6044820152606401610e0d565b50612866565b60175461496e9085614fab565b60175582156149ec5760018101546001600160401b031684116149d4576001810180548591906000906149ab9084906001600160401b0316615ec0565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550612866565b60018101805467ffffffffffffffff19169055612866565b6001810154600160401b90046001600160401b03168411614a2d57838160010160088282829054906101000a90046001600160401b03166149ab9190615ec0565b600101805467ffffffffffffffff60401b1916905550505050565b6000808460e0015115614ab15784602001516001600160401b03168386604001516001600160401b0316614a7c9190615e4b565b614a8890612710615e4b565b614a929190615cc7565b85604001516001600160401b0316614aaa9190615ea9565b9050614b09565b84602001516001600160401b03168386604001516001600160401b0316614ad89190615e4b565b614ae490612710615e4b565b614aee9190615cc7565b85604001516001600160401b0316614b069190615c34565b90505b8460e001518015614b1a5750808411155b80614b3257508460e00151158015614b325750808410155b15614b4157600191505061384b565b600091505061384b565b60008060008560e0015115614bf15785604001516001600160401b03168410614bba57614bb3614b7d6008600a615d1e565b6040880151611284906001600160401b031681614b9a8983614fab565b60208c0151611dc2908c906001600160401b0316613e33565b9050614c44565b614be6614bc96008600a615d1e565b6040880151611284906001600160401b031681614b9a828a614fab565b905060019150614c44565b85604001516001600160401b0316841115614c3257614be6614c156008600a615d1e565b6040880151611284906001600160401b031681614b9a828a615ea9565b614c41614bc96008600a615d1e565b90505b8115614c5d57614c5681600019615dc6565b9250614c61565b8092505b50509392505050565b6000614c8e600b548560c001516001600160501b031661444d90919063ffffffff16565b421115614c9d5750600161384b565b8360e001518015614cd35750614cd0612710611284614cbc828661444d565b60608801516001600160401b031690613e33565b83115b15614ce05750600161384b565b8360e00151158015614d035750614d00612710611284614cbc8286614fab565b83105b15614d105750600161384b565b5060009392505050565b6000806000614d2c8888888888615052565b915091506000821215614e22576000614d4783600019615dc6565b905086811015614dc85760a0880151614d7a90611736614d696008600a615d1e565b60055461128490611dc28d88614fab565b60198054829190600c90614d9f908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550614e1c565b60198054889190600c90614ded908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508193505050506114d7565b50614ef1565b6019548290600160601b90046001600160601b0316811115614e7c5760405162461bcd60e51b8152602060048201526013602482015272085d985d5b1d0b5a5b9cdd59999a58da595b9d606a1b6044820152606401610e0d565b60198054829190600c90614ea1908490600160601b90046001600160601b0316615ee8565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550614eef8860a001516117366008600a614ede9190615d1e565b60055461128490611dc28d8861444d565b505b614f0f611de661271061128460085485613e3390919063ffffffff16565b601055600954614f2c90611e0c9061271090611284908590613e33565b601181905550614f51611e4b612710611284600954600854612710611e3a9190615ea9565b60125560198054829190600c90614f79908490600160601b90046001600160601b0316615ee8565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550809250505095945050505050565b600061384b8284615ea9565b6040516001600160a01b03831660248201526044810182905261174990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526150b0565b6040516001600160a01b0380851660248301528316604482015260648101829052613ef49085906323b872dd60e01b90608401614fe3565b600080600061506f8688602001516001600160401b03168761452f565b905061507b8882615182565b9250600061508a88888761518e565b90506150968482615182565b93506150a2828261444d565b925050509550959350505050565b6000615105826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166151ed9092919063ffffffff16565b80519091501561174957808060200190518101906151239190615518565b6117495760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610e0d565b600061384b8284615e6a565b60006145546151a664e8d4a510006301e13380613e33565b6112846151c98760c001516001600160501b031642614fab90919063ffffffff16565b611dc286611dc28a602001516001600160401b03168a613e3390919063ffffffff16565b6060614554848460008585843b6152465760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e0d565b600080866001600160a01b031685876040516152629190615974565b60006040518083038185875af1925050503d806000811461529f576040519150601f19603f3d011682016040523d82523d6000602084013e6152a4565b606091505b50915091506146fc828286606083156152be57508161384b565b8251156152ce5782518084602001fd5b8160405162461bcd60e51b8152600401610e0d91906159df565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b80356001600160a01b03811681146113d157600080fd5b80356113d181615fa7565b803561ffff811681146113d157600080fd5b80356001600160401b03811681146113d157600080fd5b80356001600160481b03811681146113d157600080fd5b80356001600160601b03811681146113d157600080fd5b6000602082840312156153b757600080fd5b61384b8261532c565b600080600080608085870312156153d657600080fd5b6153df8561532c565b93506153ed6020860161532c565b92506153fb6040860161532c565b91506154096060860161532c565b905092959194509250565b60008060006060848603121561542957600080fd5b6154328461532c565b925060208401359150604084013561544981615fa7565b809150509250925092565b600080600080600060a0868803121561546c57600080fd5b6154758661532c565b94506020860135935060408601359250606086013561549381615fa7565b949793965091946080013592915050565b600080602083850312156154b757600080fd5b82356001600160401b03808211156154ce57600080fd5b818501915085601f8301126154e257600080fd5b8135818111156154f157600080fd5b8660208260051b850101111561550657600080fd5b60209290920196919550909350505050565b60006020828403121561552a57600080fd5b815161384b81615fa7565b6000806040838503121561554857600080fd5b823561555381615fa7565b9150602083013561556381615fa7565b809150509250929050565b600060a0828403121561558057600080fd5b60405160a081018181106001600160401b03821117156155b057634e487b7160e01b600052604160045260246000fd5b6040526155bc8361538e565b81526155ca6020840161538e565b60208201526155db60408401615360565b60408201526155ec60608401615360565b6060820152608083013563ffffffff8116811461560857600080fd5b60808201529392505050565b60006020828403121561562657600080fd5b5035919050565b60006020828403121561563f57600080fd5b5051919050565b6000806040838503121561565957600080fd5b823591506156696020840161532c565b90509250929050565b6000808284036101a081121561568757600080fd5b8335925061018080601f198301121561569f57600080fd5b6156a7615bfd565b91506156b56020860161532c565b82526156c360408601615377565b60208301526156d46060860161534e565b60408301526156e560808601615343565b60608301526156f660a08601615360565b608083015261570760c08601615360565b60a083015261571860e0860161534e565b60c083015261010061572b81870161534e565b60e084015261012061573e81880161534e565b82850152610140915061575282880161534e565b9084015261016061576487820161534e565b82850152615773838801615360565b9084015250929590945092505050565b6000806040838503121561579657600080fd5b50508035926020909101359150565b6000806000606084860312156157ba57600080fd5b8335925060208401359150604084013561544981615fa7565b600080600080608085870312156157e957600080fd5b8435935060208501359250604085013561580281615fa7565b9396929550929360600135925050565b6001600160401b038082511683528060208301511660208401528060408301511660408401528060608301511660608401528060808301511660808401525060018060a01b0360a08201511660a08301526001600160501b0360c08201511660c083015260e081015161174960e084018215159052565b80546001600160a01b038116835260a081901c6001600160481b0316602084015261ffff60e882901c811660408501526158ca606085018360f81c15159052565b60018301546001600160401b038082166080870152604082901c811660a08701529092505061590460c08501828460801c1661ffff169052565b61591960e08501828460901c1661ffff169052565b61592f6101008501828460a01c1661ffff169052565b6159456101208501828460b01c1661ffff169052565b61595b6101408501828460c01c1661ffff169052565b5050600201546001600160401b03166101609190910152565b60008251615986818460208701615f08565b9190910192915050565b6020808252825182820181905260009190848201906040850190845b818110156159d3576159bf838551615812565b9284019261010092909201916001016159ac565b50909695505050505050565b60208152600082518060208401526159fe816040850160208701615f08565b601f01601f19169190910160400192915050565b6020808252600c908201526b10b234b9ba3934b13aba37b960a11b604082015260600190565b60208082526007908201526610b6b0b933b4b760c91b604082015260600190565b6020808252600d908201526c216d61782d6c6576657261676560981b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526006908201526510b7bbb732b960d11b604082015260600190565b610100810161128a8284615812565b81516001600160a01b0316815261018081016020830151615b1260208401826001600160481b03169052565b506040830151615b28604084018261ffff169052565b506060830151615b3c606084018215159052565b506080830151615b5760808401826001600160401b03169052565b5060a0830151615b7260a08401826001600160401b03169052565b5060c0830151615b8860c084018261ffff169052565b5060e0830151615b9e60e084018261ffff169052565b506101008381015161ffff90811691840191909152610120808501518216908401526101408085015190911690830152610160808401516001600160401b03811682850152611655565b8281526101a0810161384b6020830184615889565b60405161018081016001600160401b0381118282101715615c2e57634e487b7160e01b600052604160045260246000fd5b60405290565b60008219821115615c4757615c47615f4f565b500190565b60006001600160401b03808316818516808303821115615c6e57615c6e615f4f565b01949350505050565b60006001600160601b03808316818516808303821115615c6e57615c6e615f4f565b600082615ca857615ca8615f65565b600160ff1b821460001984141615615cc257615cc2615f4f565b500590565b600082615cd657615cd6615f65565b500490565b600181815b80851115615d16578160001904821115615cfc57615cfc615f4f565b80851615615d0957918102915b93841c9390800290615ce0565b509250929050565b600061384b8383600082615d345750600161128a565b81615d415750600061128a565b8160018114615d575760028114615d6157615d7d565b600191505061128a565b60ff841115615d7257615d72615f4f565b50506001821b61128a565b5060208310610133831016604e8410600b8410161715615da0575081810a61128a565b615daa8383615cdb565b8060001904821115615dbe57615dbe615f4f565b029392505050565b60006001600160ff1b0381841382841380821686840486111615615dec57615dec615f4f565b600160ff1b6000871282811687830589121615615e0b57615e0b615f4f565b60008712925087820587128484161615615e2757615e27615f4f565b87850587128184161615615e3d57615e3d615f4f565b505050929093029392505050565b6000816000190483118215151615615e6557615e65615f4f565b500290565b60008083128015600160ff1b850184121615615e8857615e88615f4f565b6001600160ff1b0384018313811615615ea357615ea3615f4f565b50500390565b600082821015615ebb57615ebb615f4f565b500390565b60006001600160401b0383811690831681811015615ee057615ee0615f4f565b039392505050565b60006001600160601b0383811690831681811015615ee057615ee0615f4f565b60005b83811015615f23578181015183820152602001615f0b565b83811115613ef45750506000910152565b6000600019821415615f4857615f48615f4f565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461287757600080fdfea2646970667358221220ca2a3eafb2b2cff0d911a5d3992ecd445edb765a2c24592c3593752f3d43459d64736f6c634300080700330000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000000000000000000000000000000000000000000006000000000000000000000000250e7ab9b5ea0e95bf68f9fbe2f4f9dc5c8af74600000000000000000000000000000000000000000000000000000002540be400
Deployed Bytecode
0x6080604052600436106103b55760003560e01c806381a3daca116101f2578063b9db15b41161010d578063d65fe355116100a0578063ec342ad01161006f578063ec342ad014610d79578063f4b1559514610d8e578063fbb48bc114610dae578063fc0c546a14610dc357600080fd5b8063d65fe35514610d0d578063d9ac422514610d2d578063db006a7514610d43578063e19a60e114610d6357600080fd5b8063d32bb3e9116100dc578063d32bb3e914610ca4578063d41194b814610cc4578063d468e2a914610cd7578063d48788b914610ced57600080fd5b8063b9db15b414610ad0578063bc95baad14610c37578063bed5755414610c64578063cd84db0914610c8457600080fd5b806396c82e5711610185578063a576d8ad11610154578063a576d8ad14610a67578063a694fc3a14610a87578063b26d97e914610a9a578063b61daaee14610aba57600080fd5b806396c82e57146109eb5780639df411ee14610a01578063a0448fc514610a31578063a082cdd214610a4757600080fd5b80638d928af8116101c15780638d928af8146108945780638da5cb5b146109955780638ea8f7fc146109b5578063904a53b6146109cb57600080fd5b806381a3daca14610834578063841a4b51146108545780638b09578d1461086a5780638c10ad1b1461087f57600080fd5b80633ee19763116102e25780635f3b21801161027557806378d7fb7f1161024457806378d7fb7f146106e85780637a766460146106fb5780637adbf973146107f45780637dc0d1d01461081457600080fd5b80635f3b21801461068a57806367d3ef9a146106a05780636e20c3b4146106c057806370607f5d146106d557600080fd5b80634c723c28116102b15780634c723c28146106115780634d452ec01461063e5780635b3829891461065e5780635caed0291461067457600080fd5b80633ee197631461057c5780633f06cd66146105915780634046ebae146105af5780634b3ab9c5146105cf57600080fd5b80631ba938441161035a5780632dc9265e116103295780632dc9265e1461051d57806333af0efa1461053d57806339c294be146105535780633dc8f1441461056957600080fd5b80631ba93844146104a55780631ea8c3a7146104dd5780631fbeef4e146104f2578063228f524e1461050757600080fd5b806301c76f811161039657806301c76f81146104255780630904c2db14610445578063114379411461046557806313af40351461048557600080fd5b80620b15a3146103ba5780621b7934146103dc578062eb5b62146103fc575b600080fd5b3480156103c657600080fd5b506103da6103d5366004615672565b610de3565b005b3480156103e857600080fd5b506103da6103f7366004615783565b6110e6565b34801561040857600080fd5b5061041260125481565b6040519081526020015b60405180910390f35b34801561043157600080fd5b506103da6104403660046153a5565b61119e565b34801561045157600080fd5b506103da610460366004615614565b6111ea565b34801561047157600080fd5b506104126104803660046153a5565b611219565b34801561049157600080fd5b506103da6104a03660046153a5565b611290565b3480156104b157600080fd5b506015546104c5906001600160a01b031681565b6040516001600160a01b03909116815260200161041c565b3480156104e957600080fd5b5061041261130f565b3480156104fe57600080fd5b506104126113d6565b34801561051357600080fd5b50610412600c5481565b34801561052957600080fd5b506103da610538366004615783565b611493565b34801561054957600080fd5b5061041260115481565b34801561055f57600080fd5b5061041260075481565b6104126105773660046157d3565b6114c8565b34801561058857600080fd5b506104126114e0565b34801561059d57600080fd5b50601a546001600160401b0316610412565b3480156105bb57600080fd5b506002546104c5906001600160a01b031681565b3480156105db57600080fd5b506104126105ea3660046153a5565b6001600160a01b03166000908152601c60205260409020600101546001600160401b031690565b34801561061d57600080fd5b5061063161062c3660046154a4565b611505565b60405161041c9190615990565b34801561064a57600080fd5b506103da6106593660046154a4565b61165d565b34801561066a57600080fd5b50610412600f5481565b34801561068057600080fd5b5061041260045481565b34801561069657600080fd5b5061041260085481565b3480156106ac57600080fd5b506103da6106bb3660046157a5565b61174e565b3480156106cc57600080fd5b50610412611762565b6103da6106e3366004615646565b611773565b6104126106f6366004615454565b611c59565b34801561070757600080fd5b506107a46107163660046153a5565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b039081166000908152601c6020908152604091829020825160808101845281549485168152600160a01b9094046001600160401b03908116928501929092526001015490811691830191909152600160401b900463ffffffff16606082015290565b6040805182516001600160a01b031681526020808401516001600160401b039081169183019190915283830151169181019190915260609182015163ffffffff169181019190915260800161041c565b34801561080057600080fd5b506103da61080f3660046153a5565b6123ef565b34801561082057600080fd5b506006546104c5906001600160a01b031681565b34801561084057600080fd5b506014546104c5906001600160a01b031681565b34801561086057600080fd5b50610412600e5481565b34801561087657600080fd5b50610412600881565b34801561088b57600080fd5b50610412612467565b3480156108a057600080fd5b506109316040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a0810182526019546001600160601b038082168352600160601b8204166020830152600160c01b90046001600160401b0390811692820192909252601a549182166060820152600160401b90910463ffffffff16608082015290565b60405161041c9190600060a0820190506001600160601b038084511683528060208501511660208401525060408301516001600160401b038082166040850152806060860151166060850152505063ffffffff608084015116608083015292915050565b3480156109a157600080fd5b506001546104c5906001600160a01b031681565b3480156109c157600080fd5b5061041260105481565b3480156109d757600080fd5b506103da6109e6366004615783565b612478565b3480156109f757600080fd5b50610412600d5481565b348015610a0d57600080fd5b50610a21610a1c366004615614565b6124d6565b604051901515815260200161041c565b348015610a3d57600080fd5b50610412600a5481565b348015610a5357600080fd5b506103da610a623660046153c0565b612615565b348015610a7357600080fd5b506103da610a82366004615614565b61268f565b6103da610a95366004615614565b61286d565b348015610aa657600080fd5b506103da610ab5366004615672565b61287a565b348015610ac657600080fd5b5061041260055481565b348015610adc57600080fd5b50610c2a610aeb366004615614565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810191909152506000908152601b602090815260409182902082516101808101845281546001600160a01b0381168252600160a01b8082046001600160481b031694830194909452600160e81b810461ffff90811695830195909552600160f81b900460ff161515606082015260018201546001600160401b038082166080840152600160401b8204811660a0840152600160801b8204861660c0840152600160901b8204861660e08401529381048516610100830152600160b01b81048516610120830152600160c01b9004909316610140840152600201541661016082015290565b60405161041c9190615ae6565b348015610c4357600080fd5b50610c57610c52366004615414565b612de0565b60405161041c9190615ad7565b348015610c7057600080fd5b506013546104c5906001600160a01b031681565b348015610c9057600080fd5b506103da610c9f366004615783565b612e9c565b348015610cb057600080fd5b506103da610cbf36600461556e565b613495565b6103da610cd2366004615783565b613616565b348015610ce357600080fd5b5061041260175481565b348015610cf957600080fd5b506016546104c5906001600160a01b031681565b348015610d1957600080fd5b50610412610d28366004615414565b613800565b348015610d3957600080fd5b50610412600b5481565b348015610d4f57600080fd5b506103da610d5e366004615614565b613852565b348015610d6f57600080fd5b5061041260095481565b348015610d8557600080fd5b50610412613d28565b348015610d9a57600080fd5b506103da610da9366004615535565b613d37565b348015610dba57600080fd5b50610412613d85565b348015610dcf57600080fd5b506003546104c5906001600160a01b031681565b6001546001600160a01b03163314610e165760405162461bcd60e51b8152600401610e0d90615ab7565b60405180910390fd5b60008211610e535760405162461bcd60e51b815260206004820152600a602482015269085c1c9bd91d58dd125960b21b6044820152606401610e0d565b6000828152601b602052604090208054600160a01b90046001600160481b0316610eb15760405162461bcd60e51b815260206004820152600f60248201526e2170726f647563742d65786973747360881b6044820152606401610e0d565b610ebd6008600a615d1e565b610ec8906001615e4b565b82602001516001600160481b03161015610ef45760405162461bcd60e51b8152600401610e0d90615a59565b81516001600160a01b0316610f335760405162461bcd60e51b8152602060048201526005602482015264085999595960da1b6044820152606401610e0d565b60008260e0015161ffff1611610f835760405162461bcd60e51b8152602060048201526015602482015274085b1a5c5d5a59185d1a5bdb951a1c995cda1bdb19605a1b6044820152606401610e0d565b815181546020840151604085015160608601516001600160a01b039094166001600160e81b031990931692909217600160a01b6001600160481b039092168202176001600160e81b0316600160e81b61ffff938416026001600160f81b031617600160f81b9315159390930292909217835560c084015160018401805460e087015161010088015163ffffffff60801b19909216600160801b9486169490940261ffff60901b191693909317600160901b938516939093029290921761ffff60a01b19169183169093021791829055610140840151600d549082169261107292600160c01b9091041690615ea9565b61107c9190615c34565b600d5561014082015160018201805461ffff909216600160c01b0261ffff60c01b199092169190911790556040517ff67c96d097a316014b351edfed880cf93784164f445f0bbb26cde56fb89fa2fc906110d99085908490615be8565b60405180910390a1505050565b6001546001600160a01b031633146111105760405162461bcd60e51b8152600401610e0d90615ab7565b61271061111d8284615c34565b11156111575760405162461bcd60e51b8152602060048201526009602482015268042e8dede5adaeac6d60bb1b6044820152606401610e0d565b6008829055600981905560408051838152602081018390527f2cda5f90308a6ed0aad400f6ddc7575e31b5f1428c50c054ae54e1939ff164b8910160405180910390a15050565b6001546001600160a01b031633146111c85760405162461bcd60e51b8152600401610e0d90615ab7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146112145760405162461bcd60e51b8152600401610e0d90615ab7565b600e55565b601a546000906001600160401b031661123457506000919050565b601a546019546001600160a01b0384166000908152601c602052604090206001015461128a926001600160401b039081169261128492909116906001600160601b03600160601b90910416613e33565b90613e3f565b92915050565b6001546001600160a01b031633146112ba5760405162461bcd60e51b8152600401610e0d90615ab7565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b906020015b60405180910390a150565b6014546000906001600160a01b0316331461133c5760405162461bcd60e51b8152600401610e0d90615a12565b600061135c61134d6008600a615d1e565b60055460115461128491613e33565b601154909150156113d1576000601155601454600354611389916001600160a01b03918216911683613e4b565b601454604080516001600160a01b039092168252602082018390527f304116b7df0fff49d35547e731489e0e2f288bf99c5293f5fb4697671108280d91015b60405180910390a15b919050565b6013546000906001600160a01b031633146114035760405162461bcd60e51b8152600401610e0d90615a12565b60006114236114146008600a615d1e565b60055460105461128491613e33565b601054909150156113d1576000601055601354600354611450916001600160a01b03918216911683613e4b565b601354604080516001600160a01b039092168252602082018390527ffbbb21b60e499f2366d8f9dbdb1884e047dcf008673ee2c189b6153bfacc06e891016113c8565b6001546001600160a01b031633146114bd5760405162461bcd60e51b8152600401610e0d90615ab7565b600791909155600c55565b60006114d73386868686611c59565b95945050505050565b60006115006114f16008600a615d1e565b60055460125461128491613e33565b905090565b606081806001600160401b0381111561152057611520615f91565b60405190808252806020026020018201604052801561155957816020015b6115466152e8565b81526020019060019003908161153e5790505b50915060005b8181101561165557601d600086868481811061157d5761157d615f7b565b6020908102929092013583525081810192909252604090810160002081516101008101835281546001600160401b038082168352600160401b808304821696840196909652600160801b8204811694830194909452600160c01b90048316606082015260018201549283166080820152929091046001600160a01b031660a0830152600201546001600160501b03811660c0830152600160501b900460ff16151560e0820152835184908390811061163757611637615f7b565b6020026020010181905250808061164d90615f34565b91505061155f565b505092915050565b6002546001600160a01b031633148061167d5750601854610100900460ff165b6116b75760405162461bcd60e51b815260206004820152600b60248201526a10b634b8bab4b230ba37b960a91b6044820152606401610e0d565b6000805b8281101561170e5760008484838181106116d7576116d7615f7b565b90506020020135905060006116eb82613f0e565b90506116f7848261444d565b93505050808061170690615f34565b9150506116bb565b50801561174957611749336117366117286008600a615d1e565b600554611284908690613e33565b6003546001600160a01b03169190613e4b565b505050565b61174961175c338584613800565b83612e9c565b600061150061134d6008600a615d1e565b600260005414156117965760405162461bcd60e51b8152600401610e0d90615a80565b600260005560185460ff16806117b657506001546001600160a01b031633145b6117eb5760405162461bcd60e51b8152602060048201526006602482015265217374616b6560d01b6044820152606401610e0d565b60155460405163632447c960e01b81526001600160a01b0383811660048301529091169063632447c990602401600060405180830381600087803b15801561183257600080fd5b505af1158015611846573d6000803e3d6000fd5b505060165460405163632447c960e01b81526001600160a01b038581166004830152909116925063632447c99150602401600060405180830381600087803b15801561189157600080fd5b505af11580156118a5573d6000803e3d6000fd5b505050506118cf6118bd6008600a6117289190615d1e565b6003546001600160a01b031690614459565b6019546001600160601b038116906118f8908490600160c01b90046001600160401b0316615c34565b111561192f5760405162461bcd60e51b8152600401610e0d906020808252600490820152630216361760e41b604082015260600190565b601954600090600160c01b90046001600160401b031661194f578261197e565b601954601a5461197e91600160601b90046001600160601b0316906112849086906001600160401b0316613e33565b601980549192508491600c906119a5908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082601960000160188282829054906101000a90046001600160401b03166119f09190615c4c565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555080601960010160008282829054906101000a90046001600160401b0316611a3b9190615c4c565b82546101009290920a6001600160401b038181021990931691831602179091556001600160a01b0384166000908152601c6020526040902054600160a01b90041615159050611b2657604080516080810182526001600160a01b038085168083526001600160401b03808816602080860191825287831686880190815263ffffffff428116606089019081526000968752601c909352979094209551865492518416600160a01b026001600160e01b03199093169516949094171784559051600190930180549251909416600160401b026001600160601b0319909216921691909117179055611c0b565b6001600160a01b0382166000908152601c602052604090208054849190601490611b61908490600160a01b90046001600160401b0316615c4c565b82546101009290920a6001600160401b038181021990931691831602179091556001600160a01b0384166000908152601c6020526040812060010180548594509092611baf91859116615c4c565b82546101009290920a6001600160401b03818102199093169190921691909102179055506001600160a01b0382166000908152601c60205260409020600101805463ffffffff60401b1916600160401b4263ffffffff16021790555b60408051848152602081018390526001600160a01b038416917f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee90910160405180910390a25050600160005550565b600060026000541415611c7e5760405162461bcd60e51b8152600401610e0d90615a80565b6002600055600754841015611ca55760405162461bcd60e51b8152600401610e0d90615a38565b611cb16008600a615d1e565b611cbc906001615e4b565b821015611cf75760405162461bcd60e51b8152602060048201526009602482015268216c6576657261676560b81b6044820152606401610e0d565b6000858152601b602052604090208054600160f81b900460ff16611d4f5760405162461bcd60e51b815260206004820152600f60248201526e2170726f647563742d61637469766560881b6044820152606401610e0d565b8054600160a01b90046001600160481b0316831115611d805760405162461bcd60e51b8152600401610e0d90615a59565b8054600090611d9d9087908690600160e81b900461ffff1661452f565b9050611dc86118bd611db16008600a615d1e565b60055461128490611dc28b8761444d565b90613e33565b611def611de661271061128460085485613e3390919063ffffffff16565b6010549061444d565b601055600954611e1590611e0c9061271090611284908590613e33565b6011549061444d565b601181905550611e54611e4b612710611284600954600854612710611e3a9190615ea9565b611e449190615ea9565b8590613e33565b6012549061444d565b6012556000611e72611e686008600a615d1e565b6112848988613e33565b83546001850154600d54600e54601954949550600094611ef8946001600160a01b0316938c936001600160401b0380831694600160401b840490911693611ee493612710936112849390928492611dc291600160601b90046001600160601b031690600160c01b900461ffff16613e33565b60028a01546001600160401b03168861455c565b9050611f078983896001614707565b611f128a8a89613800565b6000818152601d602052604090206001810154919650906001600160401b03161561202557611fb6611f72611f478b8a613e33565b83546001850154611f6c916001600160401b0391821691600160401b90910416613e33565b9061444d565b611284611f8385611dc28e8d613e33565b84546001860154611f6c916001600160401b03600160801b8204811692611dc29290821691600160401b90910416613e33565b600182015490925061200790611fd5906001600160401b03168b61444d565b611284611fe28c8b613e33565b84546001860154611f6c916001600160401b0391821691600160401b90910416613e33565b6001820154909750612022906001600160401b03168a61444d565b98505b600c5489106120645760405162461bcd60e51b815260206004820152600b60248201526a10b6b0bc1036b0b933b4b760a91b6044820152606401610e0d565b60408051610100810182526001600160401b038c811682528981166020830152841681830152600654875492516341976e0960e01b81526001600160a01b039384166004820152919260608401929116906341976e099060240160206040518083038186803b1580156120d657600080fd5b505afa1580156120ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061210e919061562d565b6001600160401b031681526020018a6001600160401b031681526020018c6001600160a01b03168152602001426001600160501b03168152602001891515815250601d600088815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a8154816001600160401b0302191690836001600160401b0316021790555060408201518160000160106101000a8154816001600160401b0302191690836001600160401b0316021790555060608201518160000160186101000a8154816001600160401b0302191690836001600160401b0316021790555060808201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060a08201518160010160086101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160020160006101000a8154816001600160501b0302191690836001600160501b0316021790555060e082015181600201600a6101000a81548160ff021916908315150217905550905050898b6001600160a01b0316877f340ad004f2cc7f2adb2ebb38a9900cbc5888c8c67aeab767e74b16dbe1c87a4a8b86600660009054906101000a90046001600160a01b03166001600160a01b03166341976e098c60000160009054906101000a90046001600160a01b03166040518263ffffffff1660e01b815260040161235691906001600160a01b0391909116815260200190565b60206040518083038186803b15801561236e57600080fd5b505afa158015612382573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a6919061562d565b604080519315158452602084019290925290820152606081018e9052608081018c905260a0810189905260c00160405180910390a4505060016000555091979650505050505050565b6001546001600160a01b031633146124195760405162461bcd60e51b8152600401610e0d90615ab7565b600680546001600160a01b0319166001600160a01b0383169081179091556040519081527f3df77beb5db05fcdd70a30fc8adf3f83f9501b68579455adbd100b818094039490602001611304565b60006115006114146008600a615d1e565b6001546001600160a01b031633146124a25760405162461bcd60e51b8152600401610e0d90615ab7565b620f424082111580156124b3575060015b80156124c25750620151808111155b6124cb57600080fd5b600a91909155600b55565b6000818152601d6020908152604080832081516101008101835281546001600160401b03808216808452600160401b808404831685890152600160801b8404831685880152600160c01b90930482166060850152600185015491821660808501529190046001600160a01b0390811660a08401526002909301546001600160501b03811660c0840152600160501b900460ff16151560e08301528552601b909352818420600654815493516341976e0960e01b815293831660048501529092859291909116906341976e099060240160206040518083038186803b1580156125bd57600080fd5b505afa1580156125d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f5919061562d565b60018301549091506114d79084908390600160901b900461ffff16614a48565b6001546001600160a01b0316331461263f5760405162461bcd60e51b8152600401610e0d90615ab7565b601380546001600160a01b039586166001600160a01b0319918216179091556014805494861694821694909417909355601580549285169284169290921790915560168054919093169116179055565b6001546001600160a01b031633146126b95760405162461bcd60e51b8152600401610e0d90615ab7565b6000818152601d6020526040902060018101546001600160401b031661270d5760405162461bcd60e51b815260206004820152600960248201526810b837b9b4ba34b7b760b91b6044820152606401610e0d565b60018101546001600160401b03811690600160401b90046001600160a01b0316600061275b61273e6008600a615d1e565b8554611284908690600160401b90046001600160401b0316613e33565b84546002860154919250612788916001600160401b03909116908390600160501b900460ff166000614707565b8354604080516001600160401b03600160801b840481168083526020830152918101869052600160401b83048216606082015260006080820181905260a0820181905260c08201529116906001600160a01b0384169087907f36b11e691447eee9c5d7286d5c0db51ec49fde6c88b2e4931328a15b554312be9060e00160405180910390a46000858152601d602052604081209081556001810180546001600160e01b031916905560020180546affffffffffffffffffffff19169055612866826117366128586008600a615d1e565b600554611284908890613e33565b5050505050565b6128778133611773565b50565b6001546001600160a01b031633146128a45760405162461bcd60e51b8152600401610e0d90615ab7565b600082116128e15760405162461bcd60e51b815260206004820152600a602482015269085c1c9bd91d58dd125960b21b6044820152606401610e0d565b6000828152601b602090815260409182902082516101808101845281546001600160a01b0381168252600160a01b8082046001600160481b0316948301859052600160e81b820461ffff90811696840196909652600160f81b90910460ff161515606083015260018301546001600160401b038082166080850152600160401b8204811660a0850152600160801b8204871660c0850152600160901b8204871660e08501529181048616610100840152600160b01b81048616610120840152600160c01b9004909416610140820152600290910154909216610160830152156129fe5760405162461bcd60e51b815260206004820152600f60248201526e2170726f647563742d65786973747360881b6044820152606401610e0d565b612a0a6008600a615d1e565b612a15906001615e4b565b82602001516001600160481b031611612a405760405162461bcd60e51b8152600401610e0d90615a59565b81516001600160a01b0316612a7f5760405162461bcd60e51b8152602060048201526005602482015264085999595960da1b6044820152606401610e0d565b60008260e0015161ffff1611612acf5760405162461bcd60e51b8152602060048201526015602482015274085b1a5c5d5a59185d1a5bdb951a1c995cda1bdb19605a1b6044820152606401610e0d565b60405180610180016040528083600001516001600160a01b0316815260200183602001516001600160481b03168152602001836040015161ffff16815260200160011515815260200160006001600160401b0316815260200160006001600160401b031681526020018360c0015161ffff1681526020018360e0015161ffff16815260200183610100015161ffff16815260200183610120015161ffff16815260200183610140015161ffff1681526020018361016001516001600160401b0316815250601b600085815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a8154816001600160481b0302191690836001600160481b03160217905550604082015181600001601d6101000a81548161ffff021916908361ffff160217905550606082015181600001601f6101000a81548160ff02191690831515021790555060808201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060a08201518160010160086101000a8154816001600160401b0302191690836001600160401b0316021790555060c08201518160010160106101000a81548161ffff021916908361ffff16021790555060e08201518160010160126101000a81548161ffff021916908361ffff1602179055506101008201518160010160146101000a81548161ffff021916908361ffff1602179055506101208201518160010160166101000a81548161ffff021916908361ffff1602179055506101408201518160010160186101000a81548161ffff021916908361ffff1602179055506101608201518160020160006101000a8154816001600160401b0302191690836001600160401b0316021790555090505081610140015161ffff16600d6000828254612d9b9190615c34565b90915550506000838152601b60205260409081902090517fe1bc4dae2db817ece6daf52cd2b267924bd2427a16d157ada9d40383ce6a16e8916110d991869190615be8565b612de86152e8565b601d6000612df7868686613800565b8152602080820192909252604090810160002081516101008101835281546001600160401b038082168352600160401b808304821696840196909652600160801b8204811694830194909452600160c01b90048316606082015260018201549283166080820152929091046001600160a01b031660a0830152600201546001600160501b03811660c0830152600160501b900460ff16151560e0820152949350505050565b60026000541415612ebf5760405162461bcd60e51b8152600401610e0d90615a80565b6002600055600754811015612ee65760405162461bcd60e51b8152600401610e0d90615a38565b6000828152601d602052604090206001810154600160401b90046001600160a01b03163314612f275760405162461bcd60e51b8152600401610e0d90615ab7565b80546001600160401b039081166000908152601b6020526040812060018401549092168410612f6357506001808301546001600160401b031693505b600d54600e546001840154601954600093612fa8936127109361128493849291611dc291600160601b90046001600160601b031690600160c01b900461ffff16613e33565b835460028681015460018701549187015493945060009361302b936001600160a01b031692600160501b90920460ff1615916001600160401b0380821692600160401b9092048116918891166130006008600a615d1e565b8c5461301c90600160401b90046001600160401b03168f615e4b565b6130269190615cc7565b61455c565b604080516101008101825287546001600160401b038082168352600160401b80830482166020850152600160801b8304821694840194909452600160c01b9091048116606083015260018901549081166080830152919091046001600160a01b031660a082015260028701546001600160501b03811660c0830152600160501b900460ff16151560e082015290915060009081906130ca908985614b4b565b9050600081128015613109575060018601546130fa9061271090611284908b90600160901b900461ffff16613e33565b61310682600019615dc6565b10155b156131355760018701546001600160401b0316975061312a88600019615dc6565b905060019150613261565b6000811380156132585750604080516101008101825288546001600160401b038082168352600160401b80830482166020850152600160801b8304821684860152600160c01b9092048116606084015260018b01549081166080840152046001600160a01b0390811660a083015260028a01546001600160501b03811660c0840152600160501b900460ff16151560e0830152600654895493516341976e0960e01b81529382166004850152613256939116906341976e099060240160206040518083038186803b15801561320957600080fd5b505afa15801561321d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613241919061562d565b6001890154600160b01b900461ffff16614c6a565b155b15613261575060005b604080516101008101825288546001600160401b038082168352600160401b80830482166020850152600160801b808404831695850195909552600160c01b909204811660608401526001808c015491821660808501529190046001600160a01b031660a083015260028a01546001600160501b03811660c0840152600160501b900460ff16151560e083015288549089015460009361331993869390928e92600160e81b90920461ffff9081169290910416614d1a565b885490915061336d906001600160401b031661335761333a6008600a615d1e565b8b54611284908e90600160401b90046001600160401b0316613e33565b60028b0154600160501b900460ff166000614707565b87546001890154604080518781526001600160401b03600160801b8504811660208301529181018d9052600160401b808504831660608301526080820186905260a0820187905287151560c0830152919093169291046001600160a01b0316908c907f36b11e691447eee9c5d7286d5c0db51ec49fde6c88b2e4931328a15b554312be9060e00160405180910390a4851561343f5760008a8152601d602052604081209081556001810180546001600160e01b031916905560020180546affffffffffffffffffffff19169055613484565b6001880180548a919060009061345f9084906001600160401b0316615ec0565b92506101000a8154816001600160401b0302191690836001600160401b031602179055505b505060016000555050505050505050565b6001546001600160a01b031633146134bf5760405162461bcd60e51b8152600401610e0d90615ab7565b80516001600160601b03166134ff5760405162461bcd60e51b8152600401610e0d906020808252600490820152630216361760e41b604082015260600190565b6000816080015163ffffffff16118015613525575062278d00816080015163ffffffff16105b6135625760405162461bcd60e51b815260206004820152600e60248201526d085cdd185ada5b99d4195c9a5bd960921b6044820152606401610e0d565b8051601980546001600160601b0319166001600160601b0392831690811791829055608080850151601a805463ffffffff60401b198116600160401b63ffffffff948516029081179283905560408051968752606088811c909916602088015260c09790971c868801526001600160401b03908116911617958401959095529390921c909216908201527fe065d479bcd6a90bffb826e7a706adf8190a71be3596fc227088af379a93510b9060a001611304565b600260005414156136395760405162461bcd60e51b8152600401610e0d90615a80565b600260005561365e6118bd6136506008600a615d1e565b600554611284908590613e33565b6007548110156136805760405162461bcd60e51b8152600401610e0d90615a38565b6000828152601d602052604090206001810154600160401b90046001600160a01b031633146136c15760405162461bcd60e51b8152600401610e0d90615ab7565b60018101546000906136dc906001600160401b03168461444d565b6001830154835491925060009161370c918491611284916001600160401b03600160401b90920482169116613e33565b905061371a6008600a615d1e565b613725906001615e4b565b8110156137645760405162461bcd60e51b815260206004820152600d60248201526c216c6f772d6c6576657261676560981b6044820152606401610e0d565b60018301805467ffffffffffffffff19166001600160401b038481169190911791829055845467ffffffffffffffff60401b1916600160401b9184168202178555604080518781526020810186905290810184905291046001600160a01b03169086907f8bd26f20a052ff42ee3d1f3e02f0d7c447371c96dfc7d3a14b6fa5c89df272179060600160405180910390a350506001600055505050565b6040516001600160601b0319606085901b1660208201526034810183905281151560f81b60548201526000906055016040516020818303038152906040528051906020012060001c90505b9392505050565b601a546001600160401b03168111156138975760405162461bcd60e51b8152602060048201526007602482015266085cdd185ad95960ca1b6044820152606401610e0d565b60155460405163632447c960e01b81523360048201819052916001600160a01b03169063632447c990602401600060405180830381600087803b1580156138dd57600080fd5b505af11580156138f1573d6000803e3d6000fd5b505060165460405163632447c960e01b81526001600160a01b038581166004830152909116925063632447c99150602401600060405180830381600087803b15801561393c57600080fd5b505af1158015613950573d6000803e3d6000fd5b505050506001600160a01b0381166000908152601c6020526040902060018101546001600160401b031683108015906139945760018201546001600160401b031693505b6001546001600160a01b03848116911614613a1a5760018201546000906139cd90429063ffffffff600160401b909104811690614fab16565b601a54909150600160401b900463ffffffff168111613a185760405162461bcd60e51b8152602060048201526007602482015266085c195c9a5bd960ca1b6044820152606401610e0d565b505b601a54601954600091613a4e916001600160401b0390911690611284908890600160601b90046001600160601b0316613e33565b60018401548454919250600091613a7e916001600160401b0390811691611284918a91600160a01b900416613e33565b845490915081908590601490613aa5908490600160a01b90046001600160401b0316615ec0565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550858460010160008282829054906101000a90046001600160401b0316613aef9190615ec0565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555080601960000160188282829054906101000a90046001600160401b0316613b3a9190615ec0565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555085601960010160008282829054906101000a90046001600160401b0316613b859190615ec0565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550816019600001600c8282829054906101000a90046001600160601b0316613bd09190615ee8565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550613c30612710611284600f546019600001600c9054906101000a90046001600160601b03166001600160601b0316613e3390919063ffffffff16565b6017541115613c6d5760405162461bcd60e51b8152602060048201526009602482015268085d5d1a5b1a5e995960ba1b6044820152606401610e0d565b8215613cab576001600160a01b0385166000908152601c6020526040902080546001600160e01b031916815560010180546001600160601b03191690555b613ccc85611736613cbe6008600a615d1e565b600554611284908790613e33565b604080518281526020810188905290810183905283151560608201526001600160a01b038616907f81ff784935ffa11d6a1785237495788f94842be763045286ed403b1f2e619d189060800160405180910390a2505050505050565b613d346008600a615d1e565b81565b6001546001600160a01b03163314613d615760405162461bcd60e51b8152600401610e0d90615ab7565b6018805461ffff191692151561ff0019169290921761010091151591909102179055565b6015546000906001600160a01b03163314613db25760405162461bcd60e51b8152600401610e0d90615a12565b6000613dc36114f16008600a615d1e565b601254909150156113d1576000601255601554600354613df0916001600160a01b03918216911683613e4b565b601554604080516001600160a01b039092168252602082018390527f19ffdf6391d49bb1730b3f4d19c279b1275dddf2a4e981af93b1099c111369e691016113c8565b600061384b8284615e4b565b600061384b8284615cc7565b8015611749576001600160a01b038316613efa576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613eac576040519150601f19603f3d011682016040523d82523d6000602084013e613eb1565b606091505b5050905080613ef45760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610e0d565b50505050565b6117496001600160a01b0384168383614fb7565b6000818152601d6020526040812080546001600160401b0316613f345750600092915050565b80546001600160401b03166000908152601b6020526040808220600654815492516341976e0960e01b81526001600160a01b03938416600482015291939216906341976e099060240160206040518083038186803b158015613f9557600080fd5b505afa158015613fa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fcd919061562d565b604080516101008101825285546001600160401b038082168352600160401b80830482166020850152600160801b8304821694840194909452600160c01b9091048116606083015260018088015491821660808401529290046001600160a01b031660a082015260028601546001600160501b03811660c0830152600160501b900460ff16151560e08201529084015491925060009161407a91908490600160901b900461ffff16614a48565b1561444457604080516101008101825285546001600160401b038082168352600160401b80830482166020850152600160801b8304821694840194909452600160c01b909104811660608301526001870154908116608083018190529290046001600160a01b031660a082015260028601546001600160501b03811660c0830152600160501b900460ff16151560e082015260009161411a919085614b4b565b9050600081128015614143575061413381600019615dc6565b60018601546001600160401b0316115b1561427b57600061415682600019615dc6565b6001868101549088015491925061418f916127109161128491600160a01b90910461ffff1690611dc2906001600160401b031686614fab565b60018701549097506141b69088906141b0906001600160401b031684614fab565b90614fab565b92506141d6611de661271061128460085487613e3390919063ffffffff16565b6010556009546141f390611e0c9061271090611284908790613e33565b601181905550614229611e4b6127106112846009546008546127106142189190615ea9565b6142229190615ea9565b8790613e33565b60125560198054829190600c90614251908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550506142d3565b6001850154601980546001600160401b0390921691600c906142ae908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b60006143096142e46008600a615d1e565b87546001890154611284916001600160401b0391821691600160401b90910416613e33565b86546002880154919250614336916001600160401b03909116908390600160501b900460ff166000614707565b8554600180880154604080518881526001600160401b03600160801b860481166020830152808416928201839052600160401b808704821660608401526000608084015260a083019390935260c082019490945292909316926001600160a01b03910416908a907f36b11e691447eee9c5d7286d5c0db51ec49fde6c88b2e4931328a15b554312be9060e00160405180910390a46000888152601d602090815260408083209283556001830180546001600160e01b0319169055600290920180546affffffffffffffffffffff19169055815189815290810185905233918a917f6f7734c2b603545392ede46279193d0b944bffb5d4c822bb78cd37eb6c2aadc9910160405180910390a350505b50505050919050565b600061384b8284615c34565b8015614516576001600160a01b03821661451a57803410156144bd5760405162461bcd60e51b815260206004820152601a60248201527f556e6945524332303a206e6f7420656e6f7567682076616c75650000000000006044820152606401610e0d565b803411156145165760006144d13483614fab565b604051909150600090339083908381818185875af1925050503d8060008114613eac576040519150601f19603f3d011682016040523d82523d6000602084013e613eb1565b5050565b6145166001600160a01b03831633308461501a565b600061455461271061128484611dc261454a6008600a615d1e565b6112848a8a613e33565b949350505050565b6006546040516341976e0960e01b81526001600160a01b03898116600483015260009283929116906341976e099060240160206040518083038186803b1580156145a557600080fd5b505afa1580156145b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145dd919061562d565b9050600085600a54888a6145f19190615e6a565b6145fb9190615dc6565b6146059190615c99565b9050881561469757600061463d856112846146226008600a615d1e565b611dc28a6141b0614633828d614fab565b6112848e80613e33565b905060008212156146685761466361465c600261128485600019615dc6565b8290614fab565b614672565b614672818361444d565b905061468d6146836008600a615d1e565b6112848584613e33565b93505050506146fc565b60006146cd856112846146ac6008600a615d1e565b611dc26146c66146bc8c8c61444d565b6112848d80613e33565b8b90614fab565b905060008212156146e75761466361465c83600019615dc6565b6146726146f5836002613e3f565b829061444d565b979650505050505050565b6000848152601b60205260409020811561496157601754614728908561444d565b601755600f54601954614754916127109161128491600160601b9091046001600160601b031690613e33565b60175411156147985760405162461bcd60e51b815260206004820152601060248201526f085b585e13dc195b925b9d195c995cdd60821b6044820152606401610e0d565b600d54600e5460018301546019546000936147dd936127109361128493849291611dc291600160601b90046001600160601b031690600160c01b900461ffff16613e33565b905083156148ae576001820180548691906000906148059084906001600160401b0316615c4c565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555061485c8260010160089054906101000a90046001600160401b03166001600160401b03168261444d90919063ffffffff16565b60018301546001600160401b031611156148a95760405162461bcd60e51b815260206004820152600e60248201526d216578706f737572652d6c6f6e6760901b6044820152606401610e0d565b61495b565b848260010160088282829054906101000a90046001600160401b03166148d49190615c4c565b82546101009290920a6001600160401b038181021990931691831602179091556001840154614906925083911661444d565b6001830154600160401b90046001600160401b0316111561495b5760405162461bcd60e51b815260206004820152600f60248201526e08595e1c1bdcdd5c994b5cda1bdc9d608a1b6044820152606401610e0d565b50612866565b60175461496e9085614fab565b60175582156149ec5760018101546001600160401b031684116149d4576001810180548591906000906149ab9084906001600160401b0316615ec0565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550612866565b60018101805467ffffffffffffffff19169055612866565b6001810154600160401b90046001600160401b03168411614a2d57838160010160088282829054906101000a90046001600160401b03166149ab9190615ec0565b600101805467ffffffffffffffff60401b1916905550505050565b6000808460e0015115614ab15784602001516001600160401b03168386604001516001600160401b0316614a7c9190615e4b565b614a8890612710615e4b565b614a929190615cc7565b85604001516001600160401b0316614aaa9190615ea9565b9050614b09565b84602001516001600160401b03168386604001516001600160401b0316614ad89190615e4b565b614ae490612710615e4b565b614aee9190615cc7565b85604001516001600160401b0316614b069190615c34565b90505b8460e001518015614b1a5750808411155b80614b3257508460e00151158015614b325750808410155b15614b4157600191505061384b565b600091505061384b565b60008060008560e0015115614bf15785604001516001600160401b03168410614bba57614bb3614b7d6008600a615d1e565b6040880151611284906001600160401b031681614b9a8983614fab565b60208c0151611dc2908c906001600160401b0316613e33565b9050614c44565b614be6614bc96008600a615d1e565b6040880151611284906001600160401b031681614b9a828a614fab565b905060019150614c44565b85604001516001600160401b0316841115614c3257614be6614c156008600a615d1e565b6040880151611284906001600160401b031681614b9a828a615ea9565b614c41614bc96008600a615d1e565b90505b8115614c5d57614c5681600019615dc6565b9250614c61565b8092505b50509392505050565b6000614c8e600b548560c001516001600160501b031661444d90919063ffffffff16565b421115614c9d5750600161384b565b8360e001518015614cd35750614cd0612710611284614cbc828661444d565b60608801516001600160401b031690613e33565b83115b15614ce05750600161384b565b8360e00151158015614d035750614d00612710611284614cbc8286614fab565b83105b15614d105750600161384b565b5060009392505050565b6000806000614d2c8888888888615052565b915091506000821215614e22576000614d4783600019615dc6565b905086811015614dc85760a0880151614d7a90611736614d696008600a615d1e565b60055461128490611dc28d88614fab565b60198054829190600c90614d9f908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550614e1c565b60198054889190600c90614ded908490600160601b90046001600160601b0316615c77565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508193505050506114d7565b50614ef1565b6019548290600160601b90046001600160601b0316811115614e7c5760405162461bcd60e51b8152602060048201526013602482015272085d985d5b1d0b5a5b9cdd59999a58da595b9d606a1b6044820152606401610e0d565b60198054829190600c90614ea1908490600160601b90046001600160601b0316615ee8565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550614eef8860a001516117366008600a614ede9190615d1e565b60055461128490611dc28d8861444d565b505b614f0f611de661271061128460085485613e3390919063ffffffff16565b601055600954614f2c90611e0c9061271090611284908590613e33565b601181905550614f51611e4b612710611284600954600854612710611e3a9190615ea9565b60125560198054829190600c90614f79908490600160601b90046001600160601b0316615ee8565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550809250505095945050505050565b600061384b8284615ea9565b6040516001600160a01b03831660248201526044810182905261174990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526150b0565b6040516001600160a01b0380851660248301528316604482015260648101829052613ef49085906323b872dd60e01b90608401614fe3565b600080600061506f8688602001516001600160401b03168761452f565b905061507b8882615182565b9250600061508a88888761518e565b90506150968482615182565b93506150a2828261444d565b925050509550959350505050565b6000615105826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166151ed9092919063ffffffff16565b80519091501561174957808060200190518101906151239190615518565b6117495760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610e0d565b600061384b8284615e6a565b60006145546151a664e8d4a510006301e13380613e33565b6112846151c98760c001516001600160501b031642614fab90919063ffffffff16565b611dc286611dc28a602001516001600160401b03168a613e3390919063ffffffff16565b6060614554848460008585843b6152465760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e0d565b600080866001600160a01b031685876040516152629190615974565b60006040518083038185875af1925050503d806000811461529f576040519150601f19603f3d011682016040523d82523d6000602084013e6152a4565b606091505b50915091506146fc828286606083156152be57508161384b565b8251156152ce5782518084602001fd5b8160405162461bcd60e51b8152600401610e0d91906159df565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b80356001600160a01b03811681146113d157600080fd5b80356113d181615fa7565b803561ffff811681146113d157600080fd5b80356001600160401b03811681146113d157600080fd5b80356001600160481b03811681146113d157600080fd5b80356001600160601b03811681146113d157600080fd5b6000602082840312156153b757600080fd5b61384b8261532c565b600080600080608085870312156153d657600080fd5b6153df8561532c565b93506153ed6020860161532c565b92506153fb6040860161532c565b91506154096060860161532c565b905092959194509250565b60008060006060848603121561542957600080fd5b6154328461532c565b925060208401359150604084013561544981615fa7565b809150509250925092565b600080600080600060a0868803121561546c57600080fd5b6154758661532c565b94506020860135935060408601359250606086013561549381615fa7565b949793965091946080013592915050565b600080602083850312156154b757600080fd5b82356001600160401b03808211156154ce57600080fd5b818501915085601f8301126154e257600080fd5b8135818111156154f157600080fd5b8660208260051b850101111561550657600080fd5b60209290920196919550909350505050565b60006020828403121561552a57600080fd5b815161384b81615fa7565b6000806040838503121561554857600080fd5b823561555381615fa7565b9150602083013561556381615fa7565b809150509250929050565b600060a0828403121561558057600080fd5b60405160a081018181106001600160401b03821117156155b057634e487b7160e01b600052604160045260246000fd5b6040526155bc8361538e565b81526155ca6020840161538e565b60208201526155db60408401615360565b60408201526155ec60608401615360565b6060820152608083013563ffffffff8116811461560857600080fd5b60808201529392505050565b60006020828403121561562657600080fd5b5035919050565b60006020828403121561563f57600080fd5b5051919050565b6000806040838503121561565957600080fd5b823591506156696020840161532c565b90509250929050565b6000808284036101a081121561568757600080fd5b8335925061018080601f198301121561569f57600080fd5b6156a7615bfd565b91506156b56020860161532c565b82526156c360408601615377565b60208301526156d46060860161534e565b60408301526156e560808601615343565b60608301526156f660a08601615360565b608083015261570760c08601615360565b60a083015261571860e0860161534e565b60c083015261010061572b81870161534e565b60e084015261012061573e81880161534e565b82850152610140915061575282880161534e565b9084015261016061576487820161534e565b82850152615773838801615360565b9084015250929590945092505050565b6000806040838503121561579657600080fd5b50508035926020909101359150565b6000806000606084860312156157ba57600080fd5b8335925060208401359150604084013561544981615fa7565b600080600080608085870312156157e957600080fd5b8435935060208501359250604085013561580281615fa7565b9396929550929360600135925050565b6001600160401b038082511683528060208301511660208401528060408301511660408401528060608301511660608401528060808301511660808401525060018060a01b0360a08201511660a08301526001600160501b0360c08201511660c083015260e081015161174960e084018215159052565b80546001600160a01b038116835260a081901c6001600160481b0316602084015261ffff60e882901c811660408501526158ca606085018360f81c15159052565b60018301546001600160401b038082166080870152604082901c811660a08701529092505061590460c08501828460801c1661ffff169052565b61591960e08501828460901c1661ffff169052565b61592f6101008501828460a01c1661ffff169052565b6159456101208501828460b01c1661ffff169052565b61595b6101408501828460c01c1661ffff169052565b5050600201546001600160401b03166101609190910152565b60008251615986818460208701615f08565b9190910192915050565b6020808252825182820181905260009190848201906040850190845b818110156159d3576159bf838551615812565b9284019261010092909201916001016159ac565b50909695505050505050565b60208152600082518060208401526159fe816040850160208701615f08565b601f01601f19169190910160400192915050565b6020808252600c908201526b10b234b9ba3934b13aba37b960a11b604082015260600190565b60208082526007908201526610b6b0b933b4b760c91b604082015260600190565b6020808252600d908201526c216d61782d6c6576657261676560981b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526006908201526510b7bbb732b960d11b604082015260600190565b610100810161128a8284615812565b81516001600160a01b0316815261018081016020830151615b1260208401826001600160481b03169052565b506040830151615b28604084018261ffff169052565b506060830151615b3c606084018215159052565b506080830151615b5760808401826001600160401b03169052565b5060a0830151615b7260a08401826001600160401b03169052565b5060c0830151615b8860c084018261ffff169052565b5060e0830151615b9e60e084018261ffff169052565b506101008381015161ffff90811691840191909152610120808501518216908401526101408085015190911690830152610160808401516001600160401b03811682850152611655565b8281526101a0810161384b6020830184615889565b60405161018081016001600160401b0381118282101715615c2e57634e487b7160e01b600052604160045260246000fd5b60405290565b60008219821115615c4757615c47615f4f565b500190565b60006001600160401b03808316818516808303821115615c6e57615c6e615f4f565b01949350505050565b60006001600160601b03808316818516808303821115615c6e57615c6e615f4f565b600082615ca857615ca8615f65565b600160ff1b821460001984141615615cc257615cc2615f4f565b500590565b600082615cd657615cd6615f65565b500490565b600181815b80851115615d16578160001904821115615cfc57615cfc615f4f565b80851615615d0957918102915b93841c9390800290615ce0565b509250929050565b600061384b8383600082615d345750600161128a565b81615d415750600061128a565b8160018114615d575760028114615d6157615d7d565b600191505061128a565b60ff841115615d7257615d72615f4f565b50506001821b61128a565b5060208310610133831016604e8410600b8410161715615da0575081810a61128a565b615daa8383615cdb565b8060001904821115615dbe57615dbe615f4f565b029392505050565b60006001600160ff1b0381841382841380821686840486111615615dec57615dec615f4f565b600160ff1b6000871282811687830589121615615e0b57615e0b615f4f565b60008712925087820587128484161615615e2757615e27615f4f565b87850587128184161615615e3d57615e3d615f4f565b505050929093029392505050565b6000816000190483118215151615615e6557615e65615f4f565b500290565b60008083128015600160ff1b850184121615615e8857615e88615f4f565b6001600160ff1b0384018313811615615ea357615ea3615f4f565b50500390565b600082821015615ebb57615ebb615f4f565b500390565b60006001600160401b0383811690831681811015615ee057615ee0615f4f565b039392505050565b60006001600160601b0383811690831681811015615ee057615ee0615f4f565b60005b83811015615f23578181015183820152602001615f0b565b83811115613ef45750506000910152565b6000600019821415615f4857615f48615f4f565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461287757600080fdfea2646970667358221220ca2a3eafb2b2cff0d911a5d3992ecd445edb765a2c24592c3593752f3d43459d64736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c316070000000000000000000000000000000000000000000000000000000000000006000000000000000000000000250e7ab9b5ea0e95bf68f9fbe2f4f9dc5c8af74600000000000000000000000000000000000000000000000000000002540be400
-----Decoded View---------------
Arg [0] : _token (address): 0x7F5c764cBc14f9669B88837ca1490cCa17c31607
Arg [1] : _tokenDecimal (uint256): 6
Arg [2] : _oracle (address): 0x250e7AB9b5EA0e95bF68F9Fbe2f4F9DC5C8af746
Arg [3] : _minMargin (uint256): 10000000000
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [2] : 000000000000000000000000250e7ab9b5ea0e95bf68f9fbe2f4f9dc5c8af746
Arg [3] : 00000000000000000000000000000000000000000000000000000002540be400
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.