Source Code
Overview
MATIC Balance
0 MATIC
More Info
ContractCreator:
Multichain Info
N/A
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 18868844 | 927 days ago | IN | Create: LongShort | 0 MATIC | 0.01310283 |
Loading...
Loading
Contract Name:
LongShort
Compiler Version
v0.8.3+commit.8d00100c
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "./interfaces/ITokenFactory.sol"; import "./interfaces/ISyntheticToken.sol"; import "./interfaces/IStaker.sol"; import "./interfaces/ILongShort.sol"; import "./interfaces/IYieldManager.sol"; import "./interfaces/IOracleManager.sol"; import "./abstract/AccessControlledAndUpgradeable.sol"; import "./GEMS.sol"; import "hardhat/console.sol"; /** **** visit https://float.capital ***** */ /// @title Core logic of Float Protocal markets /// @author float.capital /// @notice visit https://float.capital for more info /// @dev All functions in this file are currently `virtual`. This is NOT to encourage inheritance. /// It is merely for convenince when unit testing. /// @custom:auditors This contract balances long and short sides. contract LongShort is ILongShort, AccessControlledAndUpgradeable { //Using Open Zeppelin safe transfer library for token transfers using SafeERC20 for IERC20; /*╔═════════════════════════════╗ ║ VARIABLES ║ ╚═════════════════════════════╝*/ /* ══════ Fixed-precision constants ══════ */ /// @notice this is the address that permanently locked initial liquidity for markets is held by. /// These tokens will never move so market can never have zero liquidity on a side. /// @dev f10a7 spells float in hex - for fun - important part is that the private key for this address in not known. address public constant PERMANENT_INITIAL_LIQUIDITY_HOLDER = 0xf10A7_F10A7_f10A7_F10a7_F10A7_f10a7_F10A7_f10a7; /// @dev an empty allocation of storage for use in future upgrades - inspiration from OZ: /// https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/10f0f1a95b1b0fd5520351886bae7a03490f1056/contracts/token/ERC20/ERC20Upgradeable.sol#L361 uint256[45] private __constantsGap; /* ══════ Global state ══════ */ uint32 public latestMarket; address public staker; address public tokenFactory; address public gems; uint256[45] private __globalStateGap; /* ══════ Market specific ══════ */ mapping(uint32 => bool) public marketExists; mapping(uint32 => int256) public assetPrice; mapping(uint32 => uint256) public override marketUpdateIndex; mapping(uint32 => uint256) public marketTreasurySplitGradient_e18; mapping(uint32 => uint256) public marketLeverage_e18; mapping(uint32 => address) public paymentTokens; mapping(uint32 => address) public yieldManagers; mapping(uint32 => address) public oracleManagers; uint256[45] private __marketStateGap; /* ══════ Market + position (long/short) specific ══════ */ mapping(uint32 => mapping(bool => address)) public override syntheticTokens; mapping(uint32 => mapping(bool => uint256)) public override marketSideValueInPaymentToken; /// @notice synthetic token prices of a given market of a (long/short) at every previous price update mapping(uint32 => mapping(bool => mapping(uint256 => uint256))) public override syntheticToken_priceSnapshot; mapping(uint32 => mapping(bool => uint256)) public batched_amountPaymentToken_deposit; mapping(uint32 => mapping(bool => uint256)) public batched_amountSyntheticToken_redeem; mapping(uint32 => mapping(bool => uint256)) public batched_amountSyntheticToken_toShiftAwayFrom_marketSide; uint256[45] private __marketPositonStateGap; /* ══════ User specific ══════ */ mapping(uint32 => mapping(address => uint256)) public userNextPrice_currentUpdateIndex; mapping(uint32 => mapping(bool => mapping(address => uint256))) public userNextPrice_paymentToken_depositAmount; mapping(uint32 => mapping(bool => mapping(address => uint256))) public userNextPrice_syntheticToken_redeemAmount; mapping(uint32 => mapping(bool => mapping(address => uint256))) public userNextPrice_syntheticToken_toShiftAwayFrom_marketSide; /*╔═════════════════════════════╗ ║ MODIFIERS ║ ╚═════════════════════════════╝*/ function adminOnlyModifierLogic() internal virtual { _checkRole(ADMIN_ROLE, msg.sender); } modifier adminOnly() { adminOnlyModifierLogic(); _; } function requireMarketExistsModifierLogic(uint32 marketIndex) internal view virtual { require(marketExists[marketIndex], "market doesn't exist"); } modifier requireMarketExists(uint32 marketIndex) { requireMarketExistsModifierLogic(marketIndex); _; } modifier updateSystemStateMarketAndExecuteOutstandingNextPriceSettlements( address user, uint32 marketIndex ) { _updateSystemStateInternal(marketIndex); _executeOutstandingNextPriceSettlements(user, marketIndex); _; } function gemCollectingModifierLogic() internal virtual { if (msg.sender != staker) { GEMS(gems).gm(msg.sender); } } modifier gemCollecting() { gemCollectingModifierLogic(); _; } /*╔═════════════════════════════╗ ║ CONTRACT SET-UP ║ ╚═════════════════════════════╝*/ /// @notice Initializes the contract. /// @dev Calls OpenZeppelin's initializer modifier. /// @param _admin Address of the admin role. /// @param _tokenFactory Address of the contract which creates synthetic asset tokens. /// @param _staker Address of the contract which handles synthetic asset stakes. function initialize( address _admin, address _tokenFactory, address _staker, address _gems ) external virtual initializer { require( _admin != address(0) && _tokenFactory != address(0) && _staker != address(0) && _gems != address(0) ); _AccessControlledAndUpgradeable_init(_admin); tokenFactory = _tokenFactory; staker = _staker; gems = _gems; emit LongShortV1(_admin, _tokenFactory, _staker); } /*╔═══════════════════╗ ║ ADMIN ║ ╚═══════════════════╝*/ /// @notice Update oracle for a market /// @dev Can only be called by the current admin. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param _newOracleManager Address of the replacement oracle manager. function updateMarketOracle(uint32 marketIndex, address _newOracleManager) external adminOnly { // If not a oracle contract this would break things.. Test's arn't validating this // Ie require isOracle interface - ERC165 address previousOracleManager = oracleManagers[marketIndex]; oracleManagers[marketIndex] = _newOracleManager; emit OracleUpdated(marketIndex, previousOracleManager, _newOracleManager); } /// @notice changes the gradient of the line for determining the yield split between market and treasury. function changeMarketTreasurySplitGradient( uint32 marketIndex, uint256 _marketTreasurySplitGradient_e18 ) external adminOnly { marketTreasurySplitGradient_e18[marketIndex] = _marketTreasurySplitGradient_e18; } /*╔═════════════════════════════╗ ║ MARKET CREATION ║ ╚═════════════════════════════╝*/ /// @notice Creates an entirely new long/short market tracking an underlying oracle price. /// Make sure the synthetic names/symbols are unique. /// @dev This does not make the market active. /// The `initializeMarket` function was split out separately to this function to reduce costs. /// @param syntheticName Name of the synthetic asset /// @param syntheticSymbol Symbol for the synthetic asset /// @param _paymentToken The address of the erc20 token used to buy this synthetic asset /// this will likely always be DAI /// @param _oracleManager The address of the oracle manager that provides the price feed for this market /// @param _yieldManager The contract that manages depositing the paymentToken into a yield bearing protocol function createNewSyntheticMarket( string calldata syntheticName, string calldata syntheticSymbol, address _paymentToken, address _oracleManager, address _yieldManager ) external adminOnly { require( _paymentToken != address(0) && _oracleManager != address(0) && _yieldManager != address(0) ); uint32 marketIndex = ++latestMarket; address _staker = staker; // Ensure new markets don't use the same yield manager IYieldManager(_yieldManager).initializeForMarket(); // Create new synthetic long token. syntheticTokens[marketIndex][true] = ITokenFactory(tokenFactory).createSyntheticToken( string(abi.encodePacked("Float Long ", syntheticName)), string(abi.encodePacked("fl", syntheticSymbol)), _staker, marketIndex, true ); // Create new synthetic short token. syntheticTokens[marketIndex][false] = ITokenFactory(tokenFactory).createSyntheticToken( string(abi.encodePacked("Float Short ", syntheticName)), string(abi.encodePacked("fs", syntheticSymbol)), _staker, marketIndex, false ); // Initial market state. paymentTokens[marketIndex] = _paymentToken; yieldManagers[marketIndex] = _yieldManager; oracleManagers[marketIndex] = _oracleManager; assetPrice[marketIndex] = IOracleManager(oracleManagers[marketIndex]).updatePrice(); emit SyntheticMarketCreated( marketIndex, syntheticTokens[marketIndex][true], syntheticTokens[marketIndex][false], _paymentToken, assetPrice[marketIndex], syntheticName, syntheticSymbol, _oracleManager, _yieldManager ); } /// @notice Creates an entirely new long/short market tracking an underlying oracle price. /// Uses already created synthetic tokens. /// @dev This does not make the market active. /// The `initializeMarket` function was split out separately to this function to reduce costs. /// @param syntheticName Name of the synthetic asset /// @param syntheticSymbol Symbol for the synthetic asset /// @param _longToken Address for the long token. /// @param _shortToken Address for the short token. /// @param _paymentToken The address of the erc20 token used to buy this synthetic asset /// this will likely always be DAI /// @param _oracleManager The address of the oracle manager that provides the price feed for this market /// @param _yieldManager The contract that manages depositing the paymentToken into a yield bearing protocol function createNewSyntheticMarketExternalSyntheticTokens( string calldata syntheticName, string calldata syntheticSymbol, address _longToken, address _shortToken, address _paymentToken, address _oracleManager, address _yieldManager ) external adminOnly { uint32 marketIndex = ++latestMarket; // Ensure new markets don't use the same yield manager IYieldManager(_yieldManager).initializeForMarket(); // Assign new synthetic long token. syntheticTokens[marketIndex][true] = _longToken; // Assign new synthetic short token. syntheticTokens[marketIndex][false] = _shortToken; // Initial market state. paymentTokens[marketIndex] = _paymentToken; yieldManagers[marketIndex] = _yieldManager; oracleManagers[marketIndex] = _oracleManager; assetPrice[marketIndex] = IOracleManager(oracleManagers[marketIndex]).updatePrice(); emit SyntheticMarketCreated( marketIndex, _longToken, _shortToken, _paymentToken, assetPrice[marketIndex], syntheticName, syntheticSymbol, _oracleManager, _yieldManager ); } /// @notice Seeds a new market with initial capital. /// @dev Only called when initializing a market. /// @param initialMarketSeedForEachMarketSide Amount in wei for which to seed both sides of the market. /// @param marketIndex An uint32 which uniquely identifies a market. function _seedMarketInitially(uint256 initialMarketSeedForEachMarketSide, uint32 marketIndex) internal virtual { require( // You require at least 1e18 (1 payment token with 18 decimal places) of the underlying payment token to seed the market. initialMarketSeedForEachMarketSide >= 1e18, "Insufficient market seed" ); uint256 amountToLockInYieldManager = initialMarketSeedForEachMarketSide * 2; _transferPaymentTokensFromUserToYieldManager(marketIndex, amountToLockInYieldManager); IYieldManager(yieldManagers[marketIndex]).depositPaymentToken(amountToLockInYieldManager); ISyntheticToken(syntheticTokens[marketIndex][true]).mint( PERMANENT_INITIAL_LIQUIDITY_HOLDER, initialMarketSeedForEachMarketSide ); ISyntheticToken(syntheticTokens[marketIndex][false]).mint( PERMANENT_INITIAL_LIQUIDITY_HOLDER, initialMarketSeedForEachMarketSide ); marketSideValueInPaymentToken[marketIndex][true] = initialMarketSeedForEachMarketSide; marketSideValueInPaymentToken[marketIndex][false] = initialMarketSeedForEachMarketSide; } /// @notice Sets a market as active once it has already been setup by createNewSyntheticMarket. /// @dev Seperated from createNewSyntheticMarket due to gas considerations. /// @param marketIndex An int32 which uniquely identifies the market. /// @param kInitialMultiplier Linearly decreasing multiplier for Float token issuance for the market when staking synths. /// @param kPeriod Time which kInitialMultiplier will last /// @param unstakeFee_e18 Base 1e18 percentage fee levied when unstaking for the market. /// @param balanceIncentiveCurve_exponent Sets the degree to which Float token issuance differs /// for market sides in unbalanced markets. See Staker.sol /// @param balanceIncentiveCurve_equilibriumOffset An offset to account for naturally imbalanced markets /// when Float token issuance should differ for market sides. See Staker.sol /// @param initialMarketSeedForEachMarketSide Amount of payment token that will be deposited in each market side to seed the market. function initializeMarket( uint32 marketIndex, uint256 kInitialMultiplier, uint256 kPeriod, uint256 unstakeFee_e18, uint256 initialMarketSeedForEachMarketSide, uint256 balanceIncentiveCurve_exponent, int256 balanceIncentiveCurve_equilibriumOffset, uint256 _marketTreasurySplitGradient_e18, uint256 marketLeverage ) external adminOnly { require( kInitialMultiplier != 0 && unstakeFee_e18 != 0 && initialMarketSeedForEachMarketSide != 0 && balanceIncentiveCurve_exponent != 0 && _marketTreasurySplitGradient_e18 != 0 ); require(!marketExists[marketIndex], "already initialized"); require(marketIndex <= latestMarket, "index too high"); marketExists[marketIndex] = true; marketTreasurySplitGradient_e18[marketIndex] = _marketTreasurySplitGradient_e18; // Set this value to one initially - 0 is a null value and thus potentially bug prone. marketUpdateIndex[marketIndex] = 1; _seedMarketInitially(initialMarketSeedForEachMarketSide, marketIndex); marketLeverage_e18[marketIndex] = marketLeverage; // Add new staker funds with fresh synthetic tokens. IStaker(staker).addNewStakingFund( marketIndex, syntheticTokens[marketIndex][true], syntheticTokens[marketIndex][false], kInitialMultiplier, kPeriod, unstakeFee_e18, balanceIncentiveCurve_exponent, balanceIncentiveCurve_equilibriumOffset ); IStaker(staker).pushUpdatedMarketPricesToUpdateFloatIssuanceCalculations( marketIndex, 1, 1e18, 1e18, initialMarketSeedForEachMarketSide, initialMarketSeedForEachMarketSide ); emit NewMarketLaunchedAndSeeded( marketIndex, initialMarketSeedForEachMarketSide, marketLeverage ); } /*╔══════════════════════════════╗ ║ GETTER FUNCTIONS ║ ╚══════════════════════════════╝*/ /// @notice Calculates the conversion rate from synthetic tokens to payment tokens. /// @dev Synth tokens have a fixed 18 decimals. /// @param amountPaymentTokenBackingSynth Amount of payment tokens in that token's lowest denomination. /// @param amountSyntheticToken Amount of synth token in wei. /// @return syntheticTokenPrice The calculated conversion rate in base 1e18. function _getSyntheticTokenPrice( uint256 amountPaymentTokenBackingSynth, uint256 amountSyntheticToken ) internal pure virtual returns (uint256 syntheticTokenPrice) { return (amountPaymentTokenBackingSynth * 1e18) / amountSyntheticToken; } /// @notice Converts synth token amounts to payment token amounts at a synth token price. /// @dev Price assumed base 1e18. /// @param amountSyntheticToken Amount of synth token in wei. /// @param syntheticTokenPriceInPaymentTokens The conversion rate from synth to payment tokens in base 1e18. /// @return amountPaymentToken The calculated amount of payment tokens in token's lowest denomination. function _getAmountPaymentToken( uint256 amountSyntheticToken, uint256 syntheticTokenPriceInPaymentTokens ) internal pure virtual returns (uint256 amountPaymentToken) { return (amountSyntheticToken * syntheticTokenPriceInPaymentTokens) / 1e18; } /// @notice Converts payment token amounts to synth token amounts at a synth token price. /// @dev Price assumed base 1e18. /// @param amountPaymentTokenBackingSynth Amount of payment tokens in that token's lowest denomination. /// @param syntheticTokenPriceInPaymentTokens The conversion rate from synth to payment tokens in base 1e18. /// @return amountSyntheticToken The calculated amount of synthetic token in wei. function _getAmountSyntheticToken( uint256 amountPaymentTokenBackingSynth, uint256 syntheticTokenPriceInPaymentTokens ) internal pure virtual returns (uint256 amountSyntheticToken) { return (amountPaymentTokenBackingSynth * 1e18) / syntheticTokenPriceInPaymentTokens; } /** @notice Calculate the amount of target side synthetic tokens that are worth the same amount of payment tokens as X many synthetic tokens on origin side. The resulting equation comes from simplifying this function _getAmountSyntheticToken( _getAmountPaymentToken( amountOriginSynth, priceOriginSynth ), priceTargetSynth) Unpacking the function we get: ((amountOriginSynth * priceOriginSynth) / 1e18) * 1e18 / priceTargetSynth And simplifying this we get: (amountOriginSynth * priceOriginSynth) / priceTargetSynth @param amountSyntheticTokens_originSide Amount of synthetic tokens on origin side @param syntheticTokenPrice_originSide Price of origin side's synthetic token @param syntheticTokenPrice_targetSide Price of target side's synthetic token @return equivalentAmountSyntheticTokensOnTargetSide Amount of synthetic token on target side */ function _getEquivalentAmountSyntheticTokensOnTargetSide( uint256 amountSyntheticTokens_originSide, uint256 syntheticTokenPrice_originSide, uint256 syntheticTokenPrice_targetSide ) internal pure virtual returns (uint256 equivalentAmountSyntheticTokensOnTargetSide) { equivalentAmountSyntheticTokensOnTargetSide = (amountSyntheticTokens_originSide * syntheticTokenPrice_originSide) / syntheticTokenPrice_targetSide; } /// @notice Given an executed next price shift from tokens on one market side to the other, /// determines how many other side tokens the shift was worth. /// @dev Intended for use primarily by Staker.sol /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amountSyntheticToken_redeemOnOriginSide Amount of synth token in wei. /// @param isShiftFromLong Whether the token shift is from long to short (true), or short to long (false). /// @param priceSnapshotIndex Index which identifies which synth prices to use. /// @return amountSyntheticTokensToMintOnTargetSide The amount in wei of tokens for the other side that the shift was worth. function getAmountSyntheticTokenToMintOnTargetSide( uint32 marketIndex, uint256 amountSyntheticToken_redeemOnOriginSide, bool isShiftFromLong, uint256 priceSnapshotIndex ) public view virtual override returns (uint256 amountSyntheticTokensToMintOnTargetSide) { uint256 syntheticTokenPriceOnOriginSide = syntheticToken_priceSnapshot[marketIndex][ isShiftFromLong ][priceSnapshotIndex]; uint256 syntheticTokenPriceOnTargetSide = syntheticToken_priceSnapshot[marketIndex][ !isShiftFromLong ][priceSnapshotIndex]; amountSyntheticTokensToMintOnTargetSide = _getEquivalentAmountSyntheticTokensOnTargetSide( amountSyntheticToken_redeemOnOriginSide, syntheticTokenPriceOnOriginSide, syntheticTokenPriceOnTargetSide ); } /** @notice The amount of a synth token a user is owed following a batch execution. 4 possible states for next price actions: - "Pending" - means the next price update hasn't happened or been enacted on by the updateSystemState function. - "Confirmed" - means the next price has been updated by the updateSystemState function. There is still - outstanding (lazy) computation that needs to be executed per user in the batch. - "Settled" - there is no more computation left for the user. - "Non-existent" - user has no next price actions. This function returns a calculated value only in the case of 'confirmed' next price actions. It should return zero for all other types of next price actions. @dev Used in SyntheticToken.sol balanceOf to allow for automatic reflection of next price actions. @param user The address of the user for whom to execute the function for. @param marketIndex An uint32 which uniquely identifies a market. @param isLong Whether it is for the long synthetic asset or the short synthetic asset. @return confirmedButNotSettledBalance The amount in wei of tokens that the user is owed. */ function getUsersConfirmedButNotSettledSynthBalance( address user, uint32 marketIndex, bool isLong ) external view virtual override requireMarketExists(marketIndex) returns (uint256 confirmedButNotSettledBalance) { uint256 currentMarketUpdateIndex = marketUpdateIndex[marketIndex]; uint256 userNextPrice_currentUpdateIndex_forMarket = userNextPrice_currentUpdateIndex[ marketIndex ][user]; if ( userNextPrice_currentUpdateIndex_forMarket != 0 && userNextPrice_currentUpdateIndex_forMarket <= currentMarketUpdateIndex ) { uint256 amountPaymentTokenDeposited = userNextPrice_paymentToken_depositAmount[marketIndex][ isLong ][user]; if (amountPaymentTokenDeposited > 0) { uint256 syntheticTokenPrice = syntheticToken_priceSnapshot[marketIndex][isLong][ userNextPrice_currentUpdateIndex_forMarket ]; confirmedButNotSettledBalance = _getAmountSyntheticToken( amountPaymentTokenDeposited, syntheticTokenPrice ); } uint256 amountSyntheticTokensToBeShiftedAwayFromOriginSide = userNextPrice_syntheticToken_toShiftAwayFrom_marketSide[ marketIndex ][!isLong][user]; if (amountSyntheticTokensToBeShiftedAwayFromOriginSide > 0) { uint256 syntheticTokenPriceOnOriginSide = syntheticToken_priceSnapshot[marketIndex][ !isLong ][userNextPrice_currentUpdateIndex_forMarket]; uint256 syntheticTokenPriceOnTargetSide = syntheticToken_priceSnapshot[marketIndex][isLong][ userNextPrice_currentUpdateIndex_forMarket ]; confirmedButNotSettledBalance += _getEquivalentAmountSyntheticTokensOnTargetSide( amountSyntheticTokensToBeShiftedAwayFromOriginSide, syntheticTokenPriceOnOriginSide, syntheticTokenPriceOnTargetSide ); } } } /** @notice Calculates the percentage in base 1e18 of how much of the accrued yield for a market should be allocated to treasury. @dev For gas considerations also returns whether the long side is imbalanced. @dev For gas considerations totalValueLockedInMarket is passed as a parameter as the function calling this function has pre calculated the value @param longValue The current total payment token value of the long side of the market. @param shortValue The current total payment token value of the short side of the market. @param totalValueLockedInMarket Total payment token value of both sides of the market. @return isLongSideUnderbalanced Whether the long side initially had less value than the short side. @return treasuryYieldPercent_e18 The percentage in base 1e18 of how much of the accrued yield for a market should be allocated to treasury. */ function _getYieldSplit( uint32 marketIndex, uint256 longValue, uint256 shortValue, uint256 totalValueLockedInMarket ) internal view virtual returns (bool isLongSideUnderbalanced, uint256 treasuryYieldPercent_e18) { isLongSideUnderbalanced = longValue < shortValue; uint256 imbalance; unchecked { if (isLongSideUnderbalanced) { imbalance = shortValue - longValue; } else { imbalance = longValue - shortValue; } } // marketTreasurySplitGradient_e18 may be adjusted to ensure yield is given // to the market at a desired rate e.g. if a market tends to become imbalanced // frequently then the gradient can be increased to funnel yield to the market // quicker. // See this equation in latex: https://ipfs.io/ipfs/QmXsW4cHtxpJ5BFwRcMSUw7s5G11Qkte13NTEfPLTKEx4x // Interact with this equation: https://www.desmos.com/calculator/pnl43tfv5b uint256 marketPercentCalculated_e18 = (imbalance * marketTreasurySplitGradient_e18[marketIndex]) / totalValueLockedInMarket; uint256 marketPercent_e18 = Math.min(marketPercentCalculated_e18, 1e18); unchecked { treasuryYieldPercent_e18 = 1e18 - marketPercent_e18; } } /*╔══════════════════════════════╗ ║ HELPER FUNCTIONS ║ ╚══════════════════════════════╝*/ /// @notice First gets yield from the yield manager and allocates it to market and treasury. /// It then allocates the full market yield portion to the underbalanced side of the market. /// NB this function also adjusts the value of the long and short side based on the latest /// price of the underlying asset received from the oracle. This function should ideally be /// called everytime there is an price update from the oracle. We have built a bot that does this. /// The system is still perectly safe if not called every price update, the synthetic will just /// less closely track the underlying asset. /// @dev In one function as yield should be allocated before rebalancing. /// This prevents an attack whereby the user imbalances a side to capture all accrued yield. /// @param marketIndex The market for which to execute the function for. /// @param newAssetPrice The new asset price. /// @return longValue The value of the long side after rebalancing. /// @return shortValue The value of the short side after rebalancing. function _claimAndDistributeYieldThenRebalanceMarket(uint32 marketIndex, int256 newAssetPrice) internal virtual returns (uint256 longValue, uint256 shortValue) { int256 oldAssetPrice = assetPrice[marketIndex]; // Claiming and distributing the yield longValue = marketSideValueInPaymentToken[marketIndex][true]; shortValue = marketSideValueInPaymentToken[marketIndex][false]; uint256 totalValueLockedInMarket = longValue + shortValue; (bool isLongSideUnderbalanced, uint256 treasuryYieldPercent_e18) = _getYieldSplit( marketIndex, longValue, shortValue, totalValueLockedInMarket ); uint256 marketAmount = IYieldManager(yieldManagers[marketIndex]) .distributeYieldForTreasuryAndReturnMarketAllocation( totalValueLockedInMarket, treasuryYieldPercent_e18 ); if (marketAmount > 0) { if (isLongSideUnderbalanced) { longValue += marketAmount; } else { shortValue += marketAmount; } } // Adjusting value of long and short pool based on price movement // The side/position with less liquidity has 100% percent exposure to the price movement. // The side/position with more liquidity will have exposure < 100% to the price movement. // I.e. Imagine $100 in longValue and $50 shortValue // long side would have $50/$100 = 50% exposure to price movements based on the liquidity imbalance. // min(longValue, shortValue) = $50 , therefore if the price change was -10% then // $50 * 10% = $5 gained for short side and conversely $5 lost for long side. int256 underbalancedSideValue = int256(Math.min(longValue, shortValue)); // See this equation in latex: https://ipfs.io/ipfs/QmPeJ3SZdn1GfxqCD4GDYyWTJGPMSHkjPJaxrzk2qTTPSE // Interact with this equation: https://www.desmos.com/calculator/t8gr6j5vsq int256 valueChange = ((newAssetPrice - oldAssetPrice) * underbalancedSideValue * int256(marketLeverage_e18[marketIndex])) / (oldAssetPrice * 1e18); if (valueChange < 0) { valueChange = -valueChange; // make value change positive // handle 'impossible' edge case where underlying price feed changes more than 100% downwards gracefully. if (uint256(valueChange) > longValue) { valueChange = (int256(longValue) * 99999) / 100000; } longValue -= uint256(valueChange); shortValue += uint256(valueChange); } else { // handle 'impossible' edge case where underlying price feed changes more than 100% upwards gracefully. if (uint256(valueChange) > shortValue) { valueChange = (int256(shortValue) * 99999) / 100000; } longValue += uint256(valueChange); shortValue -= uint256(valueChange); } } /*╔═══════════════════════════════╗ ║ UPDATING SYSTEM STATE ║ ╚═══════════════════════════════╝*/ /// @notice Updates the value of the long and short sides to account for latest oracle price updates /// and batches all next price actions. /// @dev To prevent front-running only executes on price change from an oracle. /// We assume the function will be called for each market at least once per price update. /// Note Even if not called on every price update, this won't affect security, it will only affect how closely /// the synthetic asset actually tracks the underlying asset. /// @param marketIndex The market index for which to update. function _updateSystemStateInternal(uint32 marketIndex) internal virtual requireMarketExists(marketIndex) { // If a negative int is return this should fail. int256 newAssetPrice = IOracleManager(oracleManagers[marketIndex]).updatePrice(); uint256 currentMarketIndex = marketUpdateIndex[marketIndex]; bool assetPriceHasChanged = assetPrice[marketIndex] != newAssetPrice; if (assetPriceHasChanged) { uint256 syntheticTokenPrice_inPaymentTokens_long = syntheticToken_priceSnapshot[marketIndex][ true ][currentMarketIndex]; uint256 syntheticTokenPrice_inPaymentTokens_short = syntheticToken_priceSnapshot[marketIndex][ false ][currentMarketIndex]; // if there is a price change and the 'staker' contract has pending updates, push the stakers price snapshot index to the staker // (so the staker can handle its internal accounting) ( uint256 newLongPoolValue, uint256 newShortPoolValue ) = _claimAndDistributeYieldThenRebalanceMarket(marketIndex, newAssetPrice); syntheticTokenPrice_inPaymentTokens_long = _getSyntheticTokenPrice( newLongPoolValue, ISyntheticToken(syntheticTokens[marketIndex][true]).totalSupply() ); syntheticTokenPrice_inPaymentTokens_short = _getSyntheticTokenPrice( newShortPoolValue, ISyntheticToken(syntheticTokens[marketIndex][false]).totalSupply() ); assetPrice[marketIndex] = newAssetPrice; currentMarketIndex++; marketUpdateIndex[marketIndex] = currentMarketIndex; syntheticToken_priceSnapshot[marketIndex][true][ currentMarketIndex ] = syntheticTokenPrice_inPaymentTokens_long; syntheticToken_priceSnapshot[marketIndex][false][ currentMarketIndex ] = syntheticTokenPrice_inPaymentTokens_short; ( int256 long_changeInMarketValue_inPaymentToken, int256 short_changeInMarketValue_inPaymentToken ) = _batchConfirmOutstandingPendingActions( marketIndex, syntheticTokenPrice_inPaymentTokens_long, syntheticTokenPrice_inPaymentTokens_short ); newLongPoolValue = uint256( int256(newLongPoolValue) + long_changeInMarketValue_inPaymentToken ); newShortPoolValue = uint256( int256(newShortPoolValue) + short_changeInMarketValue_inPaymentToken ); marketSideValueInPaymentToken[marketIndex][true] = newLongPoolValue; marketSideValueInPaymentToken[marketIndex][false] = newShortPoolValue; IStaker(staker).pushUpdatedMarketPricesToUpdateFloatIssuanceCalculations( marketIndex, currentMarketIndex, syntheticTokenPrice_inPaymentTokens_long, syntheticTokenPrice_inPaymentTokens_short, newLongPoolValue, newShortPoolValue ); emit SystemStateUpdated( marketIndex, currentMarketIndex, newAssetPrice, newLongPoolValue, newShortPoolValue, syntheticTokenPrice_inPaymentTokens_long, syntheticTokenPrice_inPaymentTokens_short ); } } /// @notice Updates the state of a market to account for the latest oracle price update. /// @param marketIndex An uint32 which uniquely identifies a market. function updateSystemState(uint32 marketIndex) external override { _updateSystemStateInternal(marketIndex); } /// @notice Updates the state of multiples markets to account for their latest oracle price updates. /// @param marketIndexes An array of int32s which uniquely identify markets. function updateSystemStateMulti(uint32[] calldata marketIndexes) external override { uint256 length = marketIndexes.length; for (uint256 i = 0; i < length; i++) { _updateSystemStateInternal(marketIndexes[i]); } } /*╔═══════════════════════════╗ ║ DEPOSIT ║ ╚═══════════════════════════╝*/ /// @notice Transfers payment tokens for a market from msg.sender to this contract. /// @dev Tokens are transferred directly to this contract to be deposited by the yield manager in the batch to earn yield. /// Since we check the return value of the transferFrom method, all payment tokens we use must conform to the ERC20 standard. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amount Amount of payment tokens in that token's lowest denominationto deposit. function _transferPaymentTokensFromUserToYieldManager(uint32 marketIndex, uint256 amount) internal virtual { IERC20(paymentTokens[marketIndex]).safeTransferFrom( msg.sender, yieldManagers[marketIndex], amount ); } /*╔═══════════════════════════╗ ║ MINT POSITION ║ ╚═══════════════════════════╝*/ /// @notice Allows users to mint synthetic assets for a market. To prevent front-running these mints are executed on the next price update from the oracle. /// @dev Called by external functions to mint either long or short. If a user mints multiple times before a price update, these are treated as a single mint. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amount Amount of payment tokens in that token's lowest denominationfor which to mint synthetic assets at next price. /// @param isLong Whether the mint is for a long or short synth. function _mintNextPrice( uint32 marketIndex, uint256 amount, bool isLong ) internal virtual updateSystemStateMarketAndExecuteOutstandingNextPriceSettlements(msg.sender, marketIndex) gemCollecting { _transferPaymentTokensFromUserToYieldManager(marketIndex, amount); batched_amountPaymentToken_deposit[marketIndex][isLong] += amount; userNextPrice_paymentToken_depositAmount[marketIndex][isLong][msg.sender] += amount; uint256 nextUpdateIndex = marketUpdateIndex[marketIndex] + 1; userNextPrice_currentUpdateIndex[marketIndex][msg.sender] = nextUpdateIndex; emit NextPriceDeposit(marketIndex, isLong, amount, msg.sender, nextUpdateIndex); } /// @notice Allows users to mint long synthetic assets for a market. To prevent front-running these mints are executed on the next price update from the oracle. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amount Amount of payment tokens in that token's lowest denominationfor which to mint synthetic assets at next price. function mintLongNextPrice(uint32 marketIndex, uint256 amount) external override { _mintNextPrice(marketIndex, amount, true); } /// @notice Allows users to mint short synthetic assets for a market. To prevent front-running these mints are executed on the next price update from the oracle. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amount Amount of payment tokens in that token's lowest denominationfor which to mint synthetic assets at next price. function mintShortNextPrice(uint32 marketIndex, uint256 amount) external override { _mintNextPrice(marketIndex, amount, false); } /*╔═══════════════════════════╗ ║ REDEEM POSITION ║ ╚═══════════════════════════╝*/ /// @notice Allows users to redeem their synthetic tokens for payment tokens. To prevent front-running these redeems are executed on the next price update from the oracle. /// @dev Called by external functions to redeem either long or short. Payment tokens are actually transferred to the user when executeOutstandingNextPriceSettlements is called from a function call by the user. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param tokens_redeem Amount in wei of synth tokens to redeem. /// @param isLong Whether this redeem is for a long or short synth. function _redeemNextPrice( uint32 marketIndex, uint256 tokens_redeem, bool isLong ) internal virtual updateSystemStateMarketAndExecuteOutstandingNextPriceSettlements(msg.sender, marketIndex) gemCollecting { ISyntheticToken(syntheticTokens[marketIndex][isLong]).transferFrom( msg.sender, address(this), tokens_redeem ); userNextPrice_syntheticToken_redeemAmount[marketIndex][isLong][msg.sender] += tokens_redeem; uint256 nextUpdateIndex = marketUpdateIndex[marketIndex] + 1; userNextPrice_currentUpdateIndex[marketIndex][msg.sender] = nextUpdateIndex; batched_amountSyntheticToken_redeem[marketIndex][isLong] += tokens_redeem; emit NextPriceRedeem(marketIndex, isLong, tokens_redeem, msg.sender, nextUpdateIndex); } /// @notice Allows users to redeem long synthetic assets for a market. To prevent front-running these redeems are executed on the next price update from the oracle. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param tokens_redeem Amount in wei of synth tokens to redeem at the next oracle price. function redeemLongNextPrice(uint32 marketIndex, uint256 tokens_redeem) external override { _redeemNextPrice(marketIndex, tokens_redeem, true); } /// @notice Allows users to redeem short synthetic assets for a market. To prevent front-running these redeems are executed on the next price update from the oracle. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param tokens_redeem Amount in wei of synth tokens to redeem at the next oracle price. function redeemShortNextPrice(uint32 marketIndex, uint256 tokens_redeem) external override { _redeemNextPrice(marketIndex, tokens_redeem, false); } /*╔═══════════════════════════╗ ║ SHIFT POSITION ║ ╚═══════════════════════════╝*/ /// @notice Allows users to shift their position from one side of the market to the other in a single transaction. To prevent front-running these shifts are executed on the next price update from the oracle. /// @dev Called by external functions to shift either way. Intended for primary use by Staker.sol /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amountSyntheticTokensToShift Amount in wei of synthetic tokens to shift from the one side to the other at the next oracle price update. /// @param isShiftFromLong Whether the token shift is from long to short (true), or short to long (false). function shiftPositionNextPrice( uint32 marketIndex, uint256 amountSyntheticTokensToShift, bool isShiftFromLong ) public virtual override updateSystemStateMarketAndExecuteOutstandingNextPriceSettlements(msg.sender, marketIndex) gemCollecting { require( ISyntheticToken(syntheticTokens[marketIndex][isShiftFromLong]).transferFrom( msg.sender, address(this), amountSyntheticTokensToShift ) ); userNextPrice_syntheticToken_toShiftAwayFrom_marketSide[marketIndex][isShiftFromLong][ msg.sender ] += amountSyntheticTokensToShift; uint256 nextUpdateIndex = marketUpdateIndex[marketIndex] + 1; userNextPrice_currentUpdateIndex[marketIndex][msg.sender] = nextUpdateIndex; batched_amountSyntheticToken_toShiftAwayFrom_marketSide[marketIndex][ isShiftFromLong ] += amountSyntheticTokensToShift; emit NextPriceSyntheticPositionShift( marketIndex, isShiftFromLong, amountSyntheticTokensToShift, msg.sender, nextUpdateIndex ); } /// @notice Allows users to shift their position from long to short in a single transaction. To prevent front-running these shifts are executed on the next price update from the oracle. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amountSyntheticTokensToShift Amount in wei of synthetic tokens to shift from long to short the next oracle price update. function shiftPositionFromLongNextPrice(uint32 marketIndex, uint256 amountSyntheticTokensToShift) external override { shiftPositionNextPrice(marketIndex, amountSyntheticTokensToShift, true); } /// @notice Allows users to shift their position from short to long in a single transaction. To prevent front-running these shifts are executed on the next price update from the oracle. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param amountSyntheticTokensToShift Amount in wei of synthetic tokens to shift from the short to long at the next oracle price update. function shiftPositionFromShortNextPrice(uint32 marketIndex, uint256 amountSyntheticTokensToShift) external override { shiftPositionNextPrice(marketIndex, amountSyntheticTokensToShift, false); } /*╔════════════════════════════════╗ ║ NEXT PRICE SETTLEMENTS ║ ╚════════════════════════════════╝*/ /// @notice Transfers outstanding synth tokens from a next price mint to the user. /// @dev The outstanding synths should already be reflected for the user due to balanceOf in SyntheticToken.sol, this just does the accounting. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param user The address of the user for whom to execute the function for. /// @param isLong Whether this is for the long or short synth for the market. function _executeOutstandingNextPriceMints( uint32 marketIndex, address user, bool isLong ) internal virtual { uint256 currentPaymentTokenDepositAmount = userNextPrice_paymentToken_depositAmount[ marketIndex ][isLong][user]; if (currentPaymentTokenDepositAmount > 0) { userNextPrice_paymentToken_depositAmount[marketIndex][isLong][user] = 0; uint256 amountSyntheticTokensToTransferToUser = _getAmountSyntheticToken( currentPaymentTokenDepositAmount, syntheticToken_priceSnapshot[marketIndex][isLong][ userNextPrice_currentUpdateIndex[marketIndex][user] ] ); ISyntheticToken(syntheticTokens[marketIndex][isLong]).transfer( user, amountSyntheticTokensToTransferToUser ); } } /// @notice Transfers outstanding payment tokens from a next price redemption to the user. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param user The address of the user for whom to execute the function for. /// @param isLong Whether this is for the long or short synth for the market. function _executeOutstandingNextPriceRedeems( uint32 marketIndex, address user, bool isLong ) internal virtual { uint256 currentSyntheticTokenRedemptions = userNextPrice_syntheticToken_redeemAmount[ marketIndex ][isLong][user]; if (currentSyntheticTokenRedemptions > 0) { userNextPrice_syntheticToken_redeemAmount[marketIndex][isLong][user] = 0; uint256 amountPaymentToken_toRedeem = _getAmountPaymentToken( currentSyntheticTokenRedemptions, syntheticToken_priceSnapshot[marketIndex][isLong][ userNextPrice_currentUpdateIndex[marketIndex][user] ] ); IYieldManager(yieldManagers[marketIndex]).transferPaymentTokensToUser( user, amountPaymentToken_toRedeem ); } } /// @notice Transfers outstanding synth tokens from a next price position shift to the user. /// @dev The outstanding synths should already be reflected for the user due to balanceOf in SyntheticToken.sol, this just does the accounting. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param user The address of the user for whom to execute the function for. /// @param isShiftFromLong Whether the token shift was from long to short (true), or short to long (false). function _executeOutstandingNextPriceTokenShifts( uint32 marketIndex, address user, bool isShiftFromLong ) internal virtual { uint256 syntheticToken_toShiftAwayFrom_marketSide = userNextPrice_syntheticToken_toShiftAwayFrom_marketSide[ marketIndex ][isShiftFromLong][user]; if (syntheticToken_toShiftAwayFrom_marketSide > 0) { uint256 syntheticToken_toShiftTowardsTargetSide = getAmountSyntheticTokenToMintOnTargetSide( marketIndex, syntheticToken_toShiftAwayFrom_marketSide, isShiftFromLong, userNextPrice_currentUpdateIndex[marketIndex][user] ); userNextPrice_syntheticToken_toShiftAwayFrom_marketSide[marketIndex][isShiftFromLong][ user ] = 0; require( ISyntheticToken(syntheticTokens[marketIndex][!isShiftFromLong]).transfer( user, syntheticToken_toShiftTowardsTargetSide ) ); } } /// @notice After markets have been batched updated on a new oracle price, transfers any owed tokens to a user from their next price actions for that update to that user. /// @dev Once the market has updated for the next price, should be guaranteed (through modifiers) to execute for a user before user initiation of new next price actions. /// @param user The address of the user for whom to execute the function. /// @param marketIndex An uint32 which uniquely identifies a market. function _executeOutstandingNextPriceSettlements(address user, uint32 marketIndex) internal virtual { uint256 userCurrentUpdateIndex = userNextPrice_currentUpdateIndex[marketIndex][user]; if (userCurrentUpdateIndex != 0 && userCurrentUpdateIndex <= marketUpdateIndex[marketIndex]) { _executeOutstandingNextPriceMints(marketIndex, user, true); _executeOutstandingNextPriceMints(marketIndex, user, false); _executeOutstandingNextPriceRedeems(marketIndex, user, true); _executeOutstandingNextPriceRedeems(marketIndex, user, false); _executeOutstandingNextPriceTokenShifts(marketIndex, user, true); _executeOutstandingNextPriceTokenShifts(marketIndex, user, false); userNextPrice_currentUpdateIndex[marketIndex][user] = 0; emit ExecuteNextPriceSettlementsUser(user, marketIndex); } } /// @notice After markets have been batched updated on a new oracle price, transfers any owed tokens to a user from their next price actions for that update to that user. /// @param user The address of the user for whom to execute the function. /// @param marketIndex An uint32 which uniquely identifies a market. function executeOutstandingNextPriceSettlementsUser(address user, uint32 marketIndex) external override { _executeOutstandingNextPriceSettlements(user, marketIndex); } /// @notice Executes outstanding next price settlements for a user for multiple markets. /// @param user The address of the user for whom to execute the function. /// @param marketIndexes An array of int32s which each uniquely identify a market. function executeOutstandingNextPriceSettlementsUserMulti( address user, uint32[] memory marketIndexes ) external { uint256 length = marketIndexes.length; for (uint256 i = 0; i < length; i++) { _executeOutstandingNextPriceSettlements(user, marketIndexes[i]); } } /*╔═══════════════════════════════════════════╗ ║ BATCHED NEXT PRICE SETTLEMENT ACTIONS ║ ╚═══════════════════════════════════════════╝*/ /// @notice Either transfers funds from the yield manager to this contract if redeems > deposits, /// and vice versa. The yield manager handles depositing and withdrawing the funds from a yield market. /// @dev When all batched next price actions are handled the total value in the market can either increase or decrease based on the value of mints and redeems. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param totalPaymentTokenValueChangeForMarket An int256 which indicates the magnitude and direction of the change in market value. function _handleTotalPaymentTokenValueChangeForMarketWithYieldManager( uint32 marketIndex, int256 totalPaymentTokenValueChangeForMarket ) internal virtual { if (totalPaymentTokenValueChangeForMarket > 0) { IYieldManager(yieldManagers[marketIndex]).depositPaymentToken( uint256(totalPaymentTokenValueChangeForMarket) ); } else if (totalPaymentTokenValueChangeForMarket < 0) { // NB there will be issues here if not enough liquidity exists to withdraw // Boolean should be returned from yield manager and think how to appropriately handle this IYieldManager(yieldManagers[marketIndex]).removePaymentTokenFromMarket( uint256(-totalPaymentTokenValueChangeForMarket) ); } } /// @notice Given a desired change in synth token supply, either mints or burns tokens to achieve that desired change. /// @dev When all batched next price actions are executed total supply for a synth can either increase or decrease. /// @param marketIndex An uint32 which uniquely identifies a market. /// @param isLong Whether this function should execute for the long or short synth for the market. /// @param changeInSyntheticTokensTotalSupply The amount in wei by which synth token supply should change. function _handleChangeInSyntheticTokensTotalSupply( uint32 marketIndex, bool isLong, int256 changeInSyntheticTokensTotalSupply ) internal virtual { if (changeInSyntheticTokensTotalSupply > 0) { ISyntheticToken(syntheticTokens[marketIndex][isLong]).mint( address(this), uint256(changeInSyntheticTokensTotalSupply) ); } else if (changeInSyntheticTokensTotalSupply < 0) { ISyntheticToken(syntheticTokens[marketIndex][isLong]).burn( uint256(-changeInSyntheticTokensTotalSupply) ); } } /** @notice Performs all batched next price actions on an oracle price update. @dev Mints or burns all synthetic tokens for this contract. After this function is executed all user actions in that batch are confirmed and can be settled individually by calling _executeOutstandingNexPriceSettlements for a given user. The maths here is safe from rounding errors since it always over estimates on the batch with division. (as an example (5/3) + (5/3) = 2 but (5+5)/3 = 10/3 = 3, so the batched action would mint one more) @param marketIndex An uint32 which uniquely identifies a market. @param syntheticTokenPrice_inPaymentTokens_long The long synthetic token price for this oracle price update. @param syntheticTokenPrice_inPaymentTokens_short The short synthetic token price for this oracle price update. @return long_changeInMarketValue_inPaymentToken The total value change for the long side after all batched actions are executed. @return short_changeInMarketValue_inPaymentToken The total value change for the short side after all batched actions are executed. */ function _batchConfirmOutstandingPendingActions( uint32 marketIndex, uint256 syntheticTokenPrice_inPaymentTokens_long, uint256 syntheticTokenPrice_inPaymentTokens_short ) internal virtual returns ( int256 long_changeInMarketValue_inPaymentToken, int256 short_changeInMarketValue_inPaymentToken ) { int256 changeInSupply_syntheticToken_long; int256 changeInSupply_syntheticToken_short; // NOTE: the only reason we are reusing amountForCurrentAction_workingVariable for all actions (redeemLong, redeemShort, mintLong, mintShort, shiftFromLong, shiftFromShort) is to reduce stack usage uint256 amountForCurrentAction_workingVariable = batched_amountPaymentToken_deposit[ marketIndex ][true]; // Handle batched deposits LONG if (amountForCurrentAction_workingVariable > 0) { long_changeInMarketValue_inPaymentToken = int256(amountForCurrentAction_workingVariable); batched_amountPaymentToken_deposit[marketIndex][true] = 0; changeInSupply_syntheticToken_long = int256( _getAmountSyntheticToken( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_long ) ); } // Handle batched deposits SHORT amountForCurrentAction_workingVariable = batched_amountPaymentToken_deposit[marketIndex][false]; if (amountForCurrentAction_workingVariable > 0) { short_changeInMarketValue_inPaymentToken = int256(amountForCurrentAction_workingVariable); batched_amountPaymentToken_deposit[marketIndex][false] = 0; changeInSupply_syntheticToken_short = int256( _getAmountSyntheticToken( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_short ) ); } // Handle shift tokens from LONG to SHORT amountForCurrentAction_workingVariable = batched_amountSyntheticToken_toShiftAwayFrom_marketSide[ marketIndex ][true]; if (amountForCurrentAction_workingVariable > 0) { int256 paymentTokenValueChangeForShiftToShort = int256( _getAmountPaymentToken( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_long ) ); long_changeInMarketValue_inPaymentToken -= paymentTokenValueChangeForShiftToShort; short_changeInMarketValue_inPaymentToken += paymentTokenValueChangeForShiftToShort; changeInSupply_syntheticToken_long -= int256(amountForCurrentAction_workingVariable); changeInSupply_syntheticToken_short += int256( _getEquivalentAmountSyntheticTokensOnTargetSide( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_long, syntheticTokenPrice_inPaymentTokens_short ) ); batched_amountSyntheticToken_toShiftAwayFrom_marketSide[marketIndex][true] = 0; } // Handle shift tokens from SHORT to LONG amountForCurrentAction_workingVariable = batched_amountSyntheticToken_toShiftAwayFrom_marketSide[ marketIndex ][false]; if (amountForCurrentAction_workingVariable > 0) { int256 paymentTokenValueChangeForShiftToLong = int256( _getAmountPaymentToken( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_short ) ); short_changeInMarketValue_inPaymentToken -= paymentTokenValueChangeForShiftToLong; long_changeInMarketValue_inPaymentToken += paymentTokenValueChangeForShiftToLong; changeInSupply_syntheticToken_short -= int256(amountForCurrentAction_workingVariable); changeInSupply_syntheticToken_long += int256( _getEquivalentAmountSyntheticTokensOnTargetSide( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_short, syntheticTokenPrice_inPaymentTokens_long ) ); batched_amountSyntheticToken_toShiftAwayFrom_marketSide[marketIndex][false] = 0; } // Handle batched redeems LONG amountForCurrentAction_workingVariable = batched_amountSyntheticToken_redeem[marketIndex][true]; if (amountForCurrentAction_workingVariable > 0) { long_changeInMarketValue_inPaymentToken -= int256( _getAmountPaymentToken( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_long ) ); changeInSupply_syntheticToken_long -= int256(amountForCurrentAction_workingVariable); batched_amountSyntheticToken_redeem[marketIndex][true] = 0; } // Handle batched redeems SHORT amountForCurrentAction_workingVariable = batched_amountSyntheticToken_redeem[marketIndex][ false ]; if (amountForCurrentAction_workingVariable > 0) { short_changeInMarketValue_inPaymentToken -= int256( _getAmountPaymentToken( amountForCurrentAction_workingVariable, syntheticTokenPrice_inPaymentTokens_short ) ); changeInSupply_syntheticToken_short -= int256(amountForCurrentAction_workingVariable); batched_amountSyntheticToken_redeem[marketIndex][false] = 0; } // Batch settle payment tokens _handleTotalPaymentTokenValueChangeForMarketWithYieldManager( marketIndex, long_changeInMarketValue_inPaymentToken + short_changeInMarketValue_inPaymentToken ); // Batch settle synthetic tokens _handleChangeInSyntheticTokensTotalSupply( marketIndex, true, changeInSupply_syntheticToken_long ); _handleChangeInSyntheticTokensTotalSupply( marketIndex, false, changeInSupply_syntheticToken_short ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(uint160(account), 20), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } function _grantRole(bytes32 role, address account) private { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal initializer { __ERC1967Upgrade_init_unchained(); } function __ERC1967Upgrade_init_unchained() internal initializer { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallSecure( address newImplementation, bytes memory data, bool forceCall ) internal { address oldImplementation = _getImplementation(); // Initial upgrade and setup call _setImplementation(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } // Perform rollback test if not already in progress StorageSlotUpgradeable.BooleanSlot storage rollbackTesting = StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT); if (!rollbackTesting.value) { // Trigger rollback using upgradeTo from the new implementation rollbackTesting.value = true; _functionDelegateCall( newImplementation, abi.encodeWithSignature("upgradeTo(address)", oldImplementation) ); rollbackTesting.value = false; // Check rollback was effective require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades"); // Finally reset to the new implementation and log the upgrade _upgradeTo(newImplementation); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @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) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal initializer { __ERC1967Upgrade_init_unchained(); __UUPSUpgradeable_init_unchained(); } function __UUPSUpgradeable_init_unchained() internal initializer { } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual { _authorizeUpgrade(newImplementation); _upgradeToAndCallSecure(newImplementation, bytes(""), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual { _authorizeUpgrade(newImplementation); _upgradeToAndCallSecure(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ 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 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); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal initializer { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal initializer { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// 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 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); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; import "./abstract/AccessControlledAndUpgradeable.sol"; /** Contract giving user GEMS*/ // Inspired by https://github.com/andrecronje/rarity/blob/main/rarity.sol /** @title GEMS */ contract GEMS is AccessControlledAndUpgradeable { bytes32 public constant GEM_ROLE = keccak256("GEM_ROLE"); uint256 constant gems_per_day = 250e18; uint256 constant DAY = 1 days; mapping(address => uint256) public gems; mapping(address => uint256) public streak; mapping(address => uint256) public lastAction; event GemsCollected(address user, uint256 gems, uint256 streak); function initialize( address _admin, address _longShort, address _staker ) external initializer { _AccessControlledAndUpgradeable_init(_admin); _setupRole(GEM_ROLE, _longShort); _setupRole(GEM_ROLE, _staker); } // Say gm and get gems by performing an action in LongShort or Staker function gm(address user) external { if (hasRole(GEM_ROLE, msg.sender)) { uint256 usersLastAction = lastAction[user]; uint256 blocktimestamp = block.timestamp; if (blocktimestamp - usersLastAction >= DAY) { // Award gems gems[user] += gems_per_day; // Increment streak if (blocktimestamp - usersLastAction < 2 * DAY) { streak[user] += 1; } else { streak[user] = 1; // reset streak to 1 } lastAction[user] = blocktimestamp; } emit GemsCollected(user, gems[user], streak[user]); } } }
// SPDX-License-Identifier: BUSL-1.1 import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; abstract contract AccessControlledAndUpgradeable is Initializable, AccessControlUpgradeable, UUPSUpgradeable { bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE"); bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); /// @notice Initializes the contract when called by parent initializers. /// @param initialAdmin The initial admin who will hold all roles. function _AccessControlledAndUpgradeable_init(address initialAdmin) internal initializer { __AccessControl_init(); __UUPSUpgradeable_init(); _AccessControlledAndUpgradeable_init_unchained(initialAdmin); } /// @notice Initializes the contract for contracts that already call both __AccessControl_init /// and _UUPSUpgradeable_init when initializing. /// @param initialAdmin The initial admin who will hold all roles. function _AccessControlledAndUpgradeable_init_unchained(address initialAdmin) internal initializer { require(initialAdmin != address(0)); _setupRole(DEFAULT_ADMIN_ROLE, initialAdmin); _setupRole(ADMIN_ROLE, initialAdmin); _setupRole(UPGRADER_ROLE, initialAdmin); } /// @notice Authorizes an upgrade to a new address. /// @dev Can only be called by addresses wih UPGRADER_ROLE function _authorizeUpgrade(address) internal override onlyRole(UPGRADER_ROLE) {} }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; interface ILongShort { /*╔════════════════════════════╗ ║ EVENTS ║ ╚════════════════════════════╝*/ event LongShortV1(address admin, address tokenFactory, address staker); event SystemStateUpdated( uint32 marketIndex, uint256 updateIndex, int256 underlyingAssetPrice, uint256 longValue, uint256 shortValue, uint256 longPrice, uint256 shortPrice ); event SyntheticMarketCreated( uint32 marketIndex, address longTokenAddress, address shortTokenAddress, address paymentToken, int256 initialAssetPrice, string name, string symbol, address oracleAddress, address yieldManagerAddress ); event NextPriceRedeem( uint32 marketIndex, bool isLong, uint256 synthRedeemed, address user, uint256 oracleUpdateIndex ); event NextPriceSyntheticPositionShift( uint32 marketIndex, bool isShiftFromLong, uint256 synthShifted, address user, uint256 oracleUpdateIndex ); event NextPriceDeposit( uint32 marketIndex, bool isLong, uint256 depositAdded, address user, uint256 oracleUpdateIndex ); event OracleUpdated(uint32 marketIndex, address oldOracleAddress, address newOracleAddress); event NewMarketLaunchedAndSeeded(uint32 marketIndex, uint256 initialSeed, uint256 marketLeverage); event ExecuteNextPriceSettlementsUser(address user, uint32 marketIndex); function syntheticTokens(uint32, bool) external view returns (address); function marketUpdateIndex(uint32) external view returns (uint256); function syntheticToken_priceSnapshot( uint32, bool, uint256 ) external view returns (uint256); function marketSideValueInPaymentToken(uint32 marketIndex, bool isLong) external view returns (uint256 marketSideValueInPaymentToken); function updateSystemState(uint32 marketIndex) external; function updateSystemStateMulti(uint32[] calldata marketIndex) external; function getUsersConfirmedButNotSettledSynthBalance( address user, uint32 marketIndex, bool isLong ) external view returns (uint256 confirmedButNotSettledBalance); function executeOutstandingNextPriceSettlementsUser(address user, uint32 marketIndex) external; function shiftPositionNextPrice( uint32 marketIndex, uint256 amountSyntheticTokensToShift, bool isShiftFromLong ) external; function shiftPositionFromLongNextPrice(uint32 marketIndex, uint256 amountSyntheticTokensToShift) external; function shiftPositionFromShortNextPrice(uint32 marketIndex, uint256 amountSyntheticTokensToShift) external; function getAmountSyntheticTokenToMintOnTargetSide( uint32 marketIndex, uint256 amountSyntheticTokenShiftedFromOneSide, bool isShiftFromLong, uint256 priceSnapshotIndex ) external view returns (uint256 amountSynthShiftedToOtherSide); function mintLongNextPrice(uint32 marketIndex, uint256 amount) external; function mintShortNextPrice(uint32 marketIndex, uint256 amount) external; function redeemLongNextPrice(uint32 marketIndex, uint256 amount) external; function redeemShortNextPrice(uint32 marketIndex, uint256 amount) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; /* * Manages price feeds from different oracle implementations. */ interface IOracleManager { function updatePrice() external returns (int256); /* *Returns the latest price from the oracle feed. */ function getLatestPrice() external view returns (int256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; interface IStaker { /*╔════════════════════════════╗ ║ EVENTS ║ ╚════════════════════════════╝*/ event StakerV1( address admin, address floatTreasury, address floatCapital, address floatToken, uint256 floatPercentage ); event MarketAddedToStaker( uint32 marketIndex, uint256 exitFee_e18, uint256 period, uint256 multiplier, uint256 balanceIncentiveExponent, int256 balanceIncentiveEquilibriumOffset, uint256 safeExponentBitShifting ); event AccumulativeIssuancePerStakedSynthSnapshotCreated( uint32 marketIndex, uint256 accumulativeFloatIssuanceSnapshotIndex, uint256 accumulativeLong, uint256 accumulativeShort ); event StakeAdded(address user, address token, uint256 amount, uint256 lastMintIndex); event StakeWithdrawn(address user, address token, uint256 amount); // Note: the `amountFloatMinted` isn't strictly needed by the graph, but it is good to add it to validate calculations are accurate. event FloatMinted(address user, uint32 marketIndex, uint256 amountFloatMinted); event MarketLaunchIncentiveParametersChanges( uint32 marketIndex, uint256 period, uint256 multiplier ); event StakeWithdrawalFeeUpdated(uint32 marketIndex, uint256 stakeWithdralFee); event BalanceIncentiveParamsUpdated( uint32 marketIndex, uint256 balanceIncentiveExponent, int256 balanceIncentiveCurve_equilibriumOffset, uint256 safeExponentBitShifting ); event FloatPercentageUpdated(uint256 floatPercentage); event NextPriceStakeShift( address user, uint32 marketIndex, uint256 amount, bool isShiftFromLong, uint256 userShiftIndex ); // only for graph validation event StakeShifted( address user, uint32 marketIndex, uint256 newAmountStakedLong, uint256 newAmountStakedShort ); function userAmountStaked(address, address) external view returns (uint256); function addNewStakingFund( uint32 marketIndex, address longTokenAddress, address shortTokenAddress, uint256 kInitialMultiplier, uint256 kPeriod, uint256 unstakeFee_e18, uint256 _balanceIncentiveCurve_exponent, int256 _balanceIncentiveCurve_equilibriumOffset ) external; function pushUpdatedMarketPricesToUpdateFloatIssuanceCalculations( uint32 marketIndex, uint256 marketUpdateIndex, uint256 longTokenPrice, uint256 shortTokenPrice, uint256 longValue, uint256 shortValue ) external; function stakeFromUser(address from, uint256 amount) external; function shiftTokens( uint256 amountSyntheticTokensToShift, uint32 marketIndex, bool isShiftFromLong ) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; /** @title SyntheticToken @notice An ERC20 token that tracks or inversely tracks the price of an underlying asset with floating exposure. */ interface ISyntheticToken { // function MINTER_ROLE() external returns (bytes32); /// @notice Allows users to stake their synthetic tokens to earn Float. function stake(uint256) external; function mint(address, uint256) external; function totalSupply() external returns (uint256); function transferFrom( address, address, uint256 ) external returns (bool); function transfer(address, uint256) external returns (bool); function burn(uint256 amount) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; interface ITokenFactory { function createSyntheticToken( string calldata syntheticName, string calldata syntheticSymbol, address staker, uint32 marketIndex, bool isLong ) external returns (address); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.3; /// @notice Manages yield accumulation for the LongShort contract. Each market is deployed with its own yield manager to simplify the bookkeeping, as different markets may share a payment token and yield pool. abstract contract IYieldManager { event ClaimAaveRewardTokenToTreasury(uint256 amount); event YieldDistributed(uint256 unrealizedYield, uint256 treasuryYieldPercent_e18); /// @dev This is purely saving some gas, but the subgraph will know how much is due for the treasury at all times - no need to include in event. event WithdrawTreasuryFunds(); /// @notice distributed yield not yet transferred to the treasury function totalReservedForTreasury() external virtual returns (uint256); /// @notice Deposits the given amount of payment tokens into this yield manager. /// @param amount Amount of payment token to deposit function depositPaymentToken(uint256 amount) external virtual; /// @notice Allows the LongShort pay out a user from tokens already withdrawn from Aave /// @param user User to recieve the payout /// @param amount Amount of payment token to pay to user function transferPaymentTokensToUser(address user, uint256 amount) external virtual; /// @notice Withdraws the given amount of tokens from this yield manager. /// @param amount Amount of payment token to withdraw function removePaymentTokenFromMarket(uint256 amount) external virtual; /** @notice Calculates and updates the yield allocation to the treasury and the market @dev treasuryPercent = 1 - marketPercent @param totalValueRealizedForMarket total value of long and short side of the market @param treasuryYieldPercent_e18 Percentage of yield in base 1e18 that is allocated to the treasury @return amountForMarketIncentives The market allocation of the yield */ function distributeYieldForTreasuryAndReturnMarketAllocation( uint256 totalValueRealizedForMarket, uint256 treasuryYieldPercent_e18 ) external virtual returns (uint256 amountForMarketIncentives); /// @notice Withdraw treasury allocated accrued yield from the lending pool to the treasury contract function withdrawTreasuryFunds() external virtual; /// @notice Initializes a specific yield manager to a given market function initializeForMarket() external virtual; }
// SPDX-License-Identifier: MIT pragma solidity >= 0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); } function logUint(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); } function log(uint p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); } function log(uint p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); } function log(uint p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); } function log(string memory p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); } function log(uint p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); } function log(uint p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); } function log(uint p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); } function log(uint p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); } function log(uint p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); } function log(uint p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); } function log(uint p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); } function log(uint p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); } function log(uint p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); } function log(uint p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); } function log(uint p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); } function log(uint p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); } function log(uint p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); } function log(uint p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); } function log(uint p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); } function log(string memory p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); } function log(string memory p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); } function log(string memory p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); } function log(string memory p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); } function log(bool p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); } function log(bool p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); } function log(bool p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); } function log(address p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); } function log(address p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); } function log(address p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"}],"name":"ExecuteNextPriceSettlementsUser","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"address","name":"tokenFactory","type":"address"},{"indexed":false,"internalType":"address","name":"staker","type":"address"}],"name":"LongShortV1","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"initialSeed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"marketLeverage","type":"uint256"}],"name":"NewMarketLaunchedAndSeeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"depositAdded","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oracleUpdateIndex","type":"uint256"}],"name":"NextPriceDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"},{"indexed":false,"internalType":"bool","name":"isLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"synthRedeemed","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oracleUpdateIndex","type":"uint256"}],"name":"NextPriceRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"},{"indexed":false,"internalType":"bool","name":"isShiftFromLong","type":"bool"},{"indexed":false,"internalType":"uint256","name":"synthShifted","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oracleUpdateIndex","type":"uint256"}],"name":"NextPriceSyntheticPositionShift","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"},{"indexed":false,"internalType":"address","name":"oldOracleAddress","type":"address"},{"indexed":false,"internalType":"address","name":"newOracleAddress","type":"address"}],"name":"OracleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"},{"indexed":false,"internalType":"address","name":"longTokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"shortTokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"paymentToken","type":"address"},{"indexed":false,"internalType":"int256","name":"initialAssetPrice","type":"int256"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"address","name":"oracleAddress","type":"address"},{"indexed":false,"internalType":"address","name":"yieldManagerAddress","type":"address"}],"name":"SyntheticMarketCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"marketIndex","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"updateIndex","type":"uint256"},{"indexed":false,"internalType":"int256","name":"underlyingAssetPrice","type":"int256"},{"indexed":false,"internalType":"uint256","name":"longValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shortValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"longPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shortPrice","type":"uint256"}],"name":"SystemStateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMANENT_INITIAL_LIQUIDITY_HOLDER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"assetPrice","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"}],"name":"batched_amountPaymentToken_deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"}],"name":"batched_amountSyntheticToken_redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"}],"name":"batched_amountSyntheticToken_toShiftAwayFrom_marketSide","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"_marketTreasurySplitGradient_e18","type":"uint256"}],"name":"changeMarketTreasurySplitGradient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"syntheticName","type":"string"},{"internalType":"string","name":"syntheticSymbol","type":"string"},{"internalType":"address","name":"_paymentToken","type":"address"},{"internalType":"address","name":"_oracleManager","type":"address"},{"internalType":"address","name":"_yieldManager","type":"address"}],"name":"createNewSyntheticMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"syntheticName","type":"string"},{"internalType":"string","name":"syntheticSymbol","type":"string"},{"internalType":"address","name":"_longToken","type":"address"},{"internalType":"address","name":"_shortToken","type":"address"},{"internalType":"address","name":"_paymentToken","type":"address"},{"internalType":"address","name":"_oracleManager","type":"address"},{"internalType":"address","name":"_yieldManager","type":"address"}],"name":"createNewSyntheticMarketExternalSyntheticTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"marketIndex","type":"uint32"}],"name":"executeOutstandingNextPriceSettlementsUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32[]","name":"marketIndexes","type":"uint32[]"}],"name":"executeOutstandingNextPriceSettlementsUserMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gems","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"amountSyntheticToken_redeemOnOriginSide","type":"uint256"},{"internalType":"bool","name":"isShiftFromLong","type":"bool"},{"internalType":"uint256","name":"priceSnapshotIndex","type":"uint256"}],"name":"getAmountSyntheticTokenToMintOnTargetSide","outputs":[{"internalType":"uint256","name":"amountSyntheticTokensToMintOnTargetSide","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"bool","name":"isLong","type":"bool"}],"name":"getUsersConfirmedButNotSettledSynthBalance","outputs":[{"internalType":"uint256","name":"confirmedButNotSettledBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_tokenFactory","type":"address"},{"internalType":"address","name":"_staker","type":"address"},{"internalType":"address","name":"_gems","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"kInitialMultiplier","type":"uint256"},{"internalType":"uint256","name":"kPeriod","type":"uint256"},{"internalType":"uint256","name":"unstakeFee_e18","type":"uint256"},{"internalType":"uint256","name":"initialMarketSeedForEachMarketSide","type":"uint256"},{"internalType":"uint256","name":"balanceIncentiveCurve_exponent","type":"uint256"},{"internalType":"int256","name":"balanceIncentiveCurve_equilibriumOffset","type":"int256"},{"internalType":"uint256","name":"_marketTreasurySplitGradient_e18","type":"uint256"},{"internalType":"uint256","name":"marketLeverage","type":"uint256"}],"name":"initializeMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"latestMarket","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"marketExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"marketLeverage_e18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"}],"name":"marketSideValueInPaymentToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"marketTreasurySplitGradient_e18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"marketUpdateIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintLongNextPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintShortNextPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"oracleManagers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"paymentTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"tokens_redeem","type":"uint256"}],"name":"redeemLongNextPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"tokens_redeem","type":"uint256"}],"name":"redeemShortNextPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"amountSyntheticTokensToShift","type":"uint256"}],"name":"shiftPositionFromLongNextPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"amountSyntheticTokensToShift","type":"uint256"}],"name":"shiftPositionFromShortNextPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"uint256","name":"amountSyntheticTokensToShift","type":"uint256"},{"internalType":"bool","name":"isShiftFromLong","type":"bool"}],"name":"shiftPositionNextPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"staker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"syntheticToken_priceSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"}],"name":"syntheticTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"},{"internalType":"address","name":"_newOracleManager","type":"address"}],"name":"updateMarketOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"marketIndex","type":"uint32"}],"name":"updateSystemState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"marketIndexes","type":"uint32[]"}],"name":"updateSystemStateMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address","name":"","type":"address"}],"name":"userNextPrice_currentUpdateIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"address","name":"","type":"address"}],"name":"userNextPrice_paymentToken_depositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"address","name":"","type":"address"}],"name":"userNextPrice_syntheticToken_redeemAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"address","name":"","type":"address"}],"name":"userNextPrice_syntheticToken_toShiftAwayFrom_marketSide","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"yieldManagers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50614e0f806100206000396000f3fe60806040526004361061031a5760003560e01c8063867dfc6d116101ab578063c2b80072116100f7578063eeb0235211610095578063f72c0d8b1161006f578063f72c0d8b14610b3e578063f7cbb68714610b72578063f80c9b9214610b92578063f8c8765e14610bcb5761031a565b8063eeb0235214610ac7578063f41cb19514610ae7578063f68a327f14610b1e5761031a565b8063d88905c9116100d1578063d88905c914610a46578063da04ce1414610a66578063e6b604e014610a86578063e77772fe14610aa65761031a565b8063c2b80072146109c7578063c2e1247114610a06578063d547741f14610a265761031a565b80639c5b0ee311610164578063b054c4a11161013e578063b054c4a1146108f3578063b36f537414610935578063b3c7e21814610966578063bb0a45291461099f5761031a565b80639c5b0ee31461086e5780639dc39e0f146108a5578063a217fddf146108de5761031a565b8063867dfc6d146107a05780638900bdfa146107c0578063897a0786146107ee57806391a9fa611461080e57806391d148541461082e57806392f6fe801461084e5761031a565b80634f1ef2861161026a578063682ad286116102235780636f486c5b116101fd5780636f486c5b146106ed57806371fd96231461072c57806375b238fc1461074c5780637a0e94f0146107805761031a565b8063682ad2861461068c5780636c305055146106ac5780636c8d2b97146106cd5761031a565b80634f1ef286146105965780635ebaf1db146105a9578063602aabab146105d2578063636190c81461060057806364d16f531461063357806364e4a81d146106535761031a565b8063248a9ca3116102d757806334daaa25116102b157806334daaa25146104fd57806336568abe146105365780633659cfe6146105565780633d6a2b3f146105765761031a565b8063248a9ca31461046e5780632f2ff15d1461049e57806334898684146104be5761031a565b806301ffc9a71461031f57806305c8146f146103545780630e5140dc1461037657806314c88ffa146103c35780631badf5c0146103f157806321658e4814610440575b600080fd5b34801561032b57600080fd5b5061033f61033a36600461446c565b610beb565b60405190151581526020015b60405180910390f35b34801561036057600080fd5b5061037461036f36600461461c565b610c24565b005b34801561038257600080fd5b506103b561039136600461468c565b6101c360209081526000938452604080852082529284528284209052825290205481565b60405190815260200161034b565b3480156103cf57600080fd5b506103b56103de36600461461c565b61015a6020526000908152604090205481565b3480156103fd57600080fd5b5061042861040c36600461461c565b61015f602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161034b565b34801561044c57600080fd5b506103b561045b36600461461c565b61015b6020526000908152604090205481565b34801561047a57600080fd5b506103b5610489366004614425565b60009081526065602052604090206001015490565b3480156104aa57600080fd5b506103746104b936600461443d565b610c30565b3480156104ca57600080fd5b506103b56104d936600461468c565b6101c260209081526000938452604080852082529284528284209052825290205481565b34801561050957600080fd5b506103b5610518366004614661565b61019160209081526000928352604080842090915290825290205481565b34801561054257600080fd5b5061037461055136600461443d565b610c5c565b34801561056257600080fd5b50610374610571366004614124565b610cdf565b34801561058257600080fd5b50610374610591366004614552565b610d03565b6103746105a436600461427b565b610f2a565b3480156105b557600080fd5b50610128546104289064010000000090046001600160a01b031681565b3480156105de57600080fd5b506103b56105ed36600461461c565b61015c6020526000908152604090205481565b34801561060c57600080fd5b506101285461061e9063ffffffff1681565b60405163ffffffff909116815260200161034b565b34801561063f57600080fd5b5061037461064e366004614636565b610f3f565b34801561065f57600080fd5b506103b561066e366004614661565b61019060209081526000928352604080842090915290825290205481565b34801561069857600080fd5b506103746106a7366004614707565b610fc5565b3480156106b857600080fd5b5061012a54610428906001600160a01b031681565b3480156106d957600080fd5b506103746106e8366004614399565b610fd1565b3480156106f957600080fd5b506103b56107083660046146c9565b61018f60209081526000938452604080852082529284528284209052825290205481565b34801561073857600080fd5b50610374610747366004614730565b611032565b34801561075857600080fd5b506103b57fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b34801561078c57600080fd5b5061037461079b3660046141b7565b611201565b3480156107ac57600080fd5b506103746107bb366004614707565b611251565b3480156107cc57600080fd5b506103b56107db36600461461c565b6101596020526000908152604090205481565b3480156107fa57600080fd5b5061037461080936600461431d565b61125d565b34801561081a57600080fd5b50610374610829366004614707565b611267565b34801561083a57600080fd5b5061033f61084936600461443d565b611273565b34801561085a57600080fd5b506103b5610869366004614764565b61129e565b34801561087a57600080fd5b5061042861088936600461461c565b61015e602052600090815260409020546001600160a01b031681565b3480156108b157600080fd5b506103b56108c0366004614636565b6101c060209081526000928352604080842090915290825290205481565b3480156108ea57600080fd5b506103b5600081565b3480156108ff57600080fd5b5061042861090e366004614661565b61018d6020908152600092835260408084209091529082529020546001600160a01b031681565b34801561094157600080fd5b5061033f61095036600461461c565b6101586020526000908152604090205460ff1681565b34801561097257600080fd5b506103b5610981366004614661565b61018e60209081526000928352604080842090915290825290205481565b3480156109ab57600080fd5b5061042873f10a7f10a7f10a7f10a7f10a7f10a7f10a7f10a781565b3480156109d357600080fd5b506103b56109e236600461468c565b6101c160209081526000938452604080852082529284528284209052825290205481565b348015610a1257600080fd5b50610374610a21366004614707565b6112f4565b348015610a3257600080fd5b50610374610a4136600461443d565b611300565b348015610a5257600080fd5b50610374610a613660046144ac565b611326565b348015610a7257600080fd5b50610374610a81366004614707565b6117f4565b348015610a9257600080fd5b50610374610aa1366004614707565b611816565b348015610ab257600080fd5b5061012954610428906001600160a01b031681565b348015610ad357600080fd5b50610374610ae2366004614707565b611822565b348015610af357600080fd5b50610428610b0236600461461c565b61015d602052600090815260409020546001600160a01b031681565b348015610b2a57600080fd5b506103b5610b39366004614351565b61182e565b348015610b4a57600080fd5b506103b57f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b348015610b7e57600080fd5b50610374610b8d3660046147a9565b61199a565b348015610b9e57600080fd5b506103b5610bad366004614661565b61019260209081526000928352604080842090915290825290205481565b348015610bd757600080fd5b50610374610be636600461415c565b611c74565b60006001600160e01b03198216637965db0b60e01b1480610c1c57506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b610c2d81611dd6565b50565b600082815260656020526040902060010154610c4d81335b6121c9565b610c57838361222d565b505050565b6001600160a01b0381163314610cd15760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b610cdb82826122b3565b5050565b610ce88161231a565b610c2d81604051806020016040528060008152506000612345565b610d0b6124c6565b6101288054600091908290610d259063ffffffff16614d0f565b91906101000a81548163ffffffff021916908363ffffffff16021790559050816001600160a01b031663edf565cc6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d7f57600080fd5b505af1158015610d93573d6000803e3d6000fd5b5050505063ffffffff8116600081815261018d6020908152604080832060018452825280832080546001600160a01b03199081166001600160a01b038d811691909117909255848052828520805482168c841617905594845261015d8352818420805486168a831617905561015e83528184208054861688831617905561015f835281842080549095169088169081179094558051630ce74fc560e31b8152905163673a7e2893600480840194938390030190829087803b158015610e5757600080fd5b505af1158015610e6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8f9190614494565b61015960008363ffffffff1663ffffffff168152602001908152602001600020819055507f901e73890694712ca72bdc627d356f05f11be45e7ccf490a8d4924c393bcb5658187878761015960008763ffffffff1663ffffffff168152602001908152602001600020548f8f8f8f8c8c604051610f169b9a99989796959493929190614a35565b60405180910390a150505050505050505050565b610f338261231a565b610cdb82826001612345565b610f476124c6565b63ffffffff8216600081815261015f602090815260409182902080546001600160a01b038681166001600160a01b03198316811790935584519586521691840182905291830191909152907ffc4d69f373858d480cfc3f12e7cc7f9b12201291753ffc3babef0e7a8041979f906060015b60405180910390a1505050565b610cdb82826000611032565b8060005b8181101561102c5761101a84848381811061100057634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611015919061461c565b611dd6565b8061102481614cf4565b915050610fd5565b50505050565b338361103d81611dd6565b61104782826124f2565b61104f6125f3565b63ffffffff8516600090815261018d602090815260408083208615158452909152908190205490516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156110c357600080fd5b505af11580156110d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fb9190614409565b61110457600080fd5b63ffffffff851660009081526101c360209081526040808320861515845282528083203384529091528120805486929061113f908490614b5f565b909155505063ffffffff8516600090815261015a6020526040812054611166906001614b5f565b63ffffffff871660008181526101c0602090815260408083203384528252808320859055928252610192815282822088151583529052908120805492935087929091906111b4908490614b5f565b90915550506040517fd850f5d8405edb0730cd72e6bb9e228043c91fd591562543ea553efda14970b6906111f19088908790899033908790614ab9565b60405180910390a1505050505050565b805160005b8181101561102c5761123f8484838151811061123257634e487b7160e01b600052603260045260246000fd5b60200260200101516124f2565b8061124981614cf4565b915050611206565b610cdb82826001612668565b610cdb82826124f2565b610cdb82826000612668565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b63ffffffff8416600090815261018f602090815260408083208515801585528184528285208686528452828520549085529083528184208585529092528220546112e9868383612787565b979650505050505050565b610cdb828260016127a6565b60008281526065602052604090206001015461131c8133610c48565b610c5783836122b3565b61132e6124c6565b6001600160a01b0383161580159061134e57506001600160a01b03821615155b801561136257506001600160a01b03811615155b61136b57600080fd5b61012880546000919082906113859063ffffffff16614d0f565b91906101000a81548163ffffffff021916908363ffffffff16021790559050600061012860049054906101000a90046001600160a01b03169050826001600160a01b031663edf565cc6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156113fa57600080fd5b505af115801561140e573d6000803e3d6000fd5b5050610129546040516001600160a01b03909116925063e6d30467915061143b908c908c90602001614959565b604051602081830303815290604052898960405160200161145d9291906148c6565b604051602081830303815290604052848660016040518663ffffffff1660e01b8152600401611490959493929190614993565b602060405180830381600087803b1580156114aa57600080fd5b505af11580156114be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e29190614140565b63ffffffff8316600090815261018d602090815260408083206001845282529182902080546001600160a01b0319166001600160a01b03948516179055610129549151919092169163e6d304679161153e918d918d910161489e565b6040516020818303038152906040528989604051602001611560929190614880565b604051602081830303815290604052848660006040518663ffffffff1660e01b8152600401611593959493929190614993565b602060405180830381600087803b1580156115ad57600080fd5b505af11580156115c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e59190614140565b63ffffffff8316600081815261018d60209081526040808320838052825280832080546001600160a01b03199081166001600160a01b039788161790915593835261015d8252808320805485168b871617905561015e82528083208054851689871617905561015f825280832080549094169489169485179093558251630ce74fc560e31b8152925163673a7e2893600480820194918390030190829087803b15801561169157600080fd5b505af11580156116a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c99190614494565b61015960008463ffffffff1663ffffffff168152602001908152602001600020819055507f901e73890694712ca72bdc627d356f05f11be45e7ccf490a8d4924c393bcb5658261018d60008563ffffffff1663ffffffff1681526020019081526020016000206000600115151515815260200190815260200160002060009054906101000a90046001600160a01b031661018d60008663ffffffff1663ffffffff16815260200190815260200160002060008015151515815260200190815260200160002060009054906101000a90046001600160a01b03168861015960008863ffffffff1663ffffffff168152602001908152602001600020548e8e8e8e8d8d6040516117e19b9a99989796959493929190614a35565b60405180910390a1505050505050505050565b6117fc6124c6565b63ffffffff909116600090815261015b6020526040902055565b610cdb828260006127a6565b610cdb82826001611032565b60008261183a8161295d565b63ffffffff8416600090815261015a60209081526040808320546101c083528184206001600160a01b038a16855290925290912054801580159061187e5750818111155b156119905763ffffffff861660009081526101c160209081526040808320881515845282528083206001600160a01b038b16845290915290205480156118f85763ffffffff8716600090815261018f60209081526040808320891515845282528083208584529091529020546118f482826129ba565b9550505b63ffffffff871660009081526101c3602090815260408083208915845282528083206001600160a01b038c168452909152902054801561198d5763ffffffff8816600090815261018f602090815260408083208a15808552818452828520888652845282852054901585529083528184208785529092529091205461197e838383612787565b6119889089614b5f565b975050505b50505b5050509392505050565b6119a26124c6565b87158015906119b057508515155b80156119bb57508415155b80156119c657508315155b80156119d157508115155b6119da57600080fd5b63ffffffff89166000908152610158602052604090205460ff1615611a375760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610cc8565b6101285463ffffffff908116908a161115611a855760405162461bcd60e51b815260206004820152600e60248201526d0d2dcc8caf040e8dede40d0d2ced60931b6044820152606401610cc8565b63ffffffff8916600090815261015860209081526040808320805460ff1916600190811790915561015b835281842086905561015a90925290912055611acb858a6129e0565b63ffffffff8916600081815261015c602090815260408083208590556101285461018d835281842060018552909252808320548380529281902054905163b0956b5f60e01b815260048101949094526001600160a01b03928316602485015282166044840152606483018b9052608483018a905260a4830189905260c4830187905260e483018690526401000000009004169063b0956b5f9061010401600060405180830381600087803b158015611b8257600080fd5b505af1158015611b96573d6000803e3d6000fd5b5050610128546040516317b4d3fb60e31b815263ffffffff8d16600482015260016024820152670de0b6b3a76400006044820181905260648201526084810189905260a481018990526401000000009091046001600160a01b0316925063bda69fd8915060c401600060405180830381600087803b158015611c1757600080fd5b505af1158015611c2b573d6000803e3d6000fd5b50506040805163ffffffff8d168152602081018990529081018490527f95eeb1c33a758f56bd880588063c2f122e39c8885929e5fbbbd57418b97e58d0925060600190506117e1565b600054610100900460ff1680611c8d575060005460ff16155b611ca95760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015611ccb576000805461ffff19166101011790555b6001600160a01b03851615801590611ceb57506001600160a01b03841615155b8015611cff57506001600160a01b03831615155b8015611d1357506001600160a01b03821615155b611d1c57600080fd5b611d2585612c29565b61012980546001600160a01b03199081166001600160a01b038781169182179093556101288054640100000000600160c01b0319166401000000008886169081029190911790915561012a80549093168685161790925560408051938916845260208401919091528201527f48aa6e6153c5dedbe00925ab3c8e28c6ce0c1a80652b3369f176065e797b45079060600160405180910390a18015611dcf576000805461ff00191690555b5050505050565b80611de08161295d565b63ffffffff8216600090815261015f60209081526040808320548151630ce74fc560e31b815291516001600160a01b039091169263673a7e28926004808201939182900301818787803b158015611e3657600080fd5b505af1158015611e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6e9190614494565b63ffffffff8416600090815261015a602090815260408083205461015990925290912054919250908214801590611dcf5763ffffffff8516600090815261018f6020908152604080832060018452808352818420868552835281842054848052908352818420868552909252822054909180611eea8988612cae565b63ffffffff8b16600090815261018d602090815260408083206001845282528083205481516318160ddd60e01b81529151959750939550611f949487946001600160a01b0316936318160ddd93600480850194919392918390030190829087803b158015611f5757600080fd5b505af1158015611f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8f9190614494565b6129ba565b63ffffffff8a16600090815261018d6020908152604080832083805282528083205481516318160ddd60e01b81529151949850611fff9486946001600160a01b03909216936318160ddd93600480820194929392918390030190829087803b158015611f5757600080fd5b63ffffffff8a1660009081526101596020526040902088905592508561202481614cf4565b63ffffffff8b16600090815261015a6020908152604080832084905561018f82528083206001845280835281842085855283528184208a9055838052825280832084845290915281208690559097509050806120818b8787612ed5565b90925090506120908285614b1e565b935061209c8184614b1e565b63ffffffff8c16600081815261018e6020908152604080832060018452909152808220889055818052908190208390556101285490516317b4d3fb60e31b81526004810192909252602482018b905260448201899052606482018890526084820187905260a482018390529194506401000000009091046001600160a01b03169063bda69fd89060c401600060405180830381600087803b15801561214057600080fd5b505af1158015612154573d6000803e3d6000fd5b50506040805163ffffffff8f168152602081018c90529081018c9052606081018790526080810186905260a0810189905260c081018890527f69e662f95898affac086a5bc1177755bdaf7f4a40a3880364c48012170ee57fe925060e001905060405180910390a15050505050505050505050565b6121d38282611273565b610cdb576121eb816001600160a01b031660146131d4565b6121f68360206131d4565b6040516020016122079291906148e4565b60408051601f198184030181529082905262461bcd60e51b8252610cc891600401614980565b6122378282611273565b610cdb5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561226f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6122bd8282611273565b15610cdb5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3610cdb8133610c48565b60006123787f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b9050612383846133b6565b6000835111806123905750815b156123a15761239f848461345b565b505b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143805460ff16611dcf57805460ff191660011781556040516001600160a01b038316602482015261242090869060440160408051601f198184030181529190526020810180516001600160e01b0316631b2ce7f360e11b17905261345b565b50805460ff191681557f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b038381169116146124bd5760405162461bcd60e51b815260206004820152602f60248201527f45524331393637557067726164653a207570677261646520627265616b73206660448201526e75727468657220757067726164657360881b6064820152608401610cc8565b611dcf85613546565b6124f07fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775336121c9565b565b63ffffffff811660009081526101c0602090815260408083206001600160a01b03861684529091529020548015801590612542575063ffffffff8216600090815261015a60205260409020548111155b15610c575761255382846001613586565b61255f82846000613586565b61256b828460016136ea565b612577828460006136ea565b61258382846001613820565b61258f82846000613820565b63ffffffff821660008181526101c0602090815260408083206001600160a01b038816808552908352818420939093558051928352908201929092527fe03aa867e2345cc967d98e4c81f6b0707b5ef082d9d20bac3dcf95540acdeae49101610fb8565b6101285464010000000090046001600160a01b031633146124f05761012a546040516324b4085360e21b81523360048201526001600160a01b03909116906392d0214c90602401600060405180830381600087803b15801561265457600080fd5b505af115801561102c573d6000803e3d6000fd5b338361267381611dd6565b61267d82826124f2565b6126856125f3565b61268f858561396a565b63ffffffff85166000908152610190602090815260408083208615158452909152812080548692906126c2908490614b5f565b909155505063ffffffff851660009081526101c1602090815260408083208615158452825280832033845290915281208054869290612702908490614b5f565b909155505063ffffffff8516600090815261015a6020526040812054612729906001614b5f565b63ffffffff871660009081526101c0602090815260408083203380855292529182902083905590519192507f50b8727b538cf16daeb79894e8bde5c1e975985071be8a8d7620675a5dddfc6b916111f191899188918a918790614ab9565b6000816127948486614c3c565b61279e9190614ba5565b949350505050565b33836127b181611dd6565b6127bb82826124f2565b6127c36125f3565b63ffffffff8516600090815261018d602090815260408083208615158452909152908190205490516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561283757600080fd5b505af115801561284b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286f9190614409565b5063ffffffff851660009081526101c26020908152604080832086151584528252808320338452909152812080548692906128ab908490614b5f565b909155505063ffffffff8516600090815261015a60205260408120546128d2906001614b5f565b63ffffffff871660008181526101c060209081526040808320338452825280832085905592825261019181528282208815158352905290812080549293508792909190612920908490614b5f565b90915550506040517f191d5f0d51691cdc223884e5321013c9663c6b337a07d550c538d9dcbbd66203906111f19088908790899033908790614ab9565b63ffffffff81166000908152610158602052604090205460ff16610c2d5760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d08191bd95cdb89dd08195e1a5cdd60621b6044820152606401610cc8565b6000816129cf84670de0b6b3a7640000614c3c565b6129d99190614ba5565b9392505050565b670de0b6b3a7640000821015612a385760405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e74206d61726b6574207365656400000000000000006044820152606401610cc8565b6000612a45836002614c3c565b9050612a51828261396a565b63ffffffff8216600090815261015e6020526040908190205490516304831f7160e51b8152600481018390526001600160a01b0390911690639063ee2090602401600060405180830381600087803b158015612aac57600080fd5b505af1158015612ac0573d6000803e3d6000fd5b5050505063ffffffff8216600090815261018d6020908152604080832060018452909152908190205490516340c10f1960e01b815273f10a7f10a7f10a7f10a7f10a7f10a7f10a7f10a76004820152602481018590526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015612b4557600080fd5b505af1158015612b59573d6000803e3d6000fd5b5050505063ffffffff8216600090815261018d60209081526040808320838052909152908190205490516340c10f1960e01b815273f10a7f10a7f10a7f10a7f10a7f10a7f10a7f10a76004820152602481018590526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015612bdd57600080fd5b505af1158015612bf1573d6000803e3d6000fd5b5050505063ffffffff91909116600090815261018e602090815260408083206001845290915280822084905581805290209190915550565b600054610100900460ff1680612c42575060005460ff16155b612c5e5760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015612c80576000805461ffff19166101011790555b612c886139ab565b612c90613a2e565b612c9982613a8c565b8015610cdb576000805461ff00191690555050565b63ffffffff82166000908152610159602090815260408083205461018e835281842060018552808452828520548580529352908320549192612cf08385614b5f565b9050600080612d0188878786613b55565b63ffffffff8a16600090815261015e602052604080822054905163452accd960e11b81526004810188905260248101849052939550919350916001600160a01b0390911690638a5599b290604401602060405180830381600087803b158015612d6957600080fd5b505af1158015612d7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da19190614494565b90508015612dcd578215612dc057612db98188614b5f565b9650612dcd565b612dca8187614b5f565b95505b6000612dd98888613bcd565b90506000612def87670de0b6b3a7640000614bb9565b63ffffffff8c16600090815261015c602052604090205483612e118a8e614c5b565b612e1b9190614bb9565b612e259190614bb9565b612e2f9190614b77565b90506000811215612e8857612e4381614d33565b905088811115612e6b57620186a0612e5e8a6201869f614bb9565b612e689190614b77565b90505b612e75818a614c9a565b9850612e818189614b5f565b9750612ec7565b87811115612eae57620186a0612ea1896201869f614bb9565b612eab9190614b77565b90505b612eb8818a614b5f565b9850612ec48189614c9a565b97505b505050505050509250929050565b63ffffffff8316600090815261019060209081526040808320600184529091528120548190819081908015612f375763ffffffff881660009081526101906020908152604080832060018452909152812055935083612f3481886129ba565b92505b5063ffffffff87166000908152610190602090815260408083208380529091529020548015612f925763ffffffff8816600090815261019060209081526040808320838052909152812055925082612f8f81876129ba565b91505b5063ffffffff871660009081526101926020908152604080832060018452909152902054801561302a576000612fc88289613be3565b9050612fd48187614c5b565b9550612fe08186614b1e565b9450612fec8285614c5b565b9350612ff9828989612787565b6130039084614b1e565b63ffffffff8a16600090815261019260209081526040808320600184529091528120559250505b5063ffffffff871660009081526101926020908152604080832083805290915290205480156130c057600061305f8288613be3565b905061306b8186614c5b565b94506130778187614b1e565b95506130838284614c5b565b925061309082888a612787565b61309a9085614b1e565b63ffffffff8a166000908152610192602090815260408083208380529091528120559350505b5063ffffffff8716600090815261019160209081526040808320600184529091529020548015613130576130f48188613be3565b6130fe9086614c5b565b945061310a8184614c5b565b63ffffffff89166000908152610191602090815260408083206001845290915281205592505b5063ffffffff8716600090815261019160209081526040808320838052909152902054801561319e576131638187613be3565b61316d9085614c5b565b93506131798183614c5b565b63ffffffff891660009081526101916020908152604080832083805290915281205591505b6131b1886131ac8688614b1e565b613bf8565b6131bd88600185613cfc565b6131c988600084613cfc565b505050935093915050565b606060006131e3836002614c3c565b6131ee906002614b5f565b67ffffffffffffffff81111561321457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561323e576020820181803683370190505b509050600360fc1b8160008151811061326757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106132a457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006132c8846002614c3c565b6132d3906001614b5f565b90505b6001811115613367576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061331557634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061333957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361336081614cdd565b90506132d6565b5083156129d95760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610cc8565b803b61341a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610cc8565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6060823b6134ba5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610cc8565b600080846001600160a01b0316846040516134d59190614864565b600060405180830381855af49150503d8060008114613510576040519150601f19603f3d011682016040523d82523d6000602084013e613515565b606091505b509150915061353d8282604051806060016040528060278152602001614db360279139613e29565b95945050505050565b61354f816133b6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b63ffffffff831660009081526101c160209081526040808320841515845282528083206001600160a01b0386168452909152902054801561102c5763ffffffff841660008181526101c1602090815260408083208615158085529083528184206001600160a01b03891680865290845282852085905585855261018f84528285209185529083528184209484526101c083528184209084528252808320548352929052908120546136389083906129ba565b63ffffffff8616600090815261018d6020908152604080832087151584529091529081902054905163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b1580156136aa57600080fd5b505af11580156136be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e29190614409565b505050505050565b63ffffffff831660009081526101c260209081526040808320841515845282528083206001600160a01b0386168452909152902054801561102c5763ffffffff841660008181526101c2602090815260408083208615158085529083528184206001600160a01b03891680865290845282852085905585855261018f84528285209185529083528184209484526101c0835281842090845282528083205483529290529081205461379c908390613be3565b63ffffffff8616600090815261015e6020526040908190205490516375b5ffd160e11b81526001600160a01b0387811660048301526024820184905292935091169063eb6bffa290604401600060405180830381600087803b15801561380157600080fd5b505af1158015613815573d6000803e3d6000fd5b505050505050505050565b63ffffffff831660009081526101c360209081526040808320841515845282528083206001600160a01b0386168452909152902054801561102c5763ffffffff841660009081526101c0602090815260408083206001600160a01b03871684529091528120546138959086908490869061129e565b63ffffffff861660008181526101c3602090815260408083208815801585529083528184206001600160a01b038b811680875291855283862086905595855261018d845282852091855292529182902054915163a9059cbb60e01b8152600481019190915260248101849052929350169063a9059cbb90604401602060405180830381600087803b15801561392957600080fd5b505af115801561393d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139619190614409565b611dcf57600080fd5b63ffffffff808316600090815261015e602090815260408083205461015d90925290912054610cdb926001600160a01b0391821692339216908590613e6216565b600054610100900460ff16806139c4575060005460ff16155b6139e05760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613a02576000805461ffff19166101011790555b613a0a613ebc565b613a12613ebc565b613a1a613ebc565b8015610c2d576000805461ff001916905550565b600054610100900460ff1680613a47575060005460ff16155b613a635760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613a0a576000805461ffff1916610101179055613a12613ebc565b600054610100900460ff1680613aa5575060005460ff16155b613ac15760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613ae3576000805461ffff19166101011790555b6001600160a01b038216613af657600080fd5b613b01600083613f26565b613b2b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177583613f26565b612c997f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e383613f26565b8183106000808215613b6a5750848403613b6f565b508385035b63ffffffff8716600090815261015b60205260408120548590613b929084614c3c565b613b9c9190614ba5565b90506000613bb282670de0b6b3a7640000613bcd565b905080670de0b6b3a764000003935050505094509492505050565b6000818310613bdc57816129d9565b5090919050565b6000670de0b6b3a76400006129cf8385614c3c565b6000811315613c795763ffffffff8216600090815261015e6020526040908190205490516304831f7160e51b8152600481018390526001600160a01b0390911690639063ee2090602401600060405180830381600087803b158015613c5c57600080fd5b505af1158015613c70573d6000803e3d6000fd5b50505050610cdb565b6000811215610cdb5763ffffffff8216600090815261015e60205260409020546001600160a01b0316631c499b55613cb083614d33565b6040518263ffffffff1660e01b8152600401613cce91815260200190565b600060405180830381600087803b158015613ce857600080fd5b505af11580156136e2573d6000803e3d6000fd5b6000811315613d905763ffffffff8316600090815261018d602090815260408083208515158452909152908190205490516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015613d7357600080fd5b505af1158015613d87573d6000803e3d6000fd5b50505050610c57565b6000811215610c575763ffffffff8316600090815261018d6020908152604080832085151584529091529020546001600160a01b03166342966c68613dd483614d33565b6040518263ffffffff1660e01b8152600401613df291815260200190565b600060405180830381600087803b158015613e0c57600080fd5b505af1158015613e20573d6000803e3d6000fd5b50505050505050565b60608315613e385750816129d9565b825115613e485782518084602001fd5b8160405162461bcd60e51b8152600401610cc89190614980565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261102c908590613f30565b600054610100900460ff1680613ed5575060005460ff16155b613ef15760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613a1a576000805461ffff19166101011790558015610c2d576000805461ff001916905550565b610cdb828261222d565b6000613f85826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140029092919063ffffffff16565b805190915015610c575780806020019051810190613fa39190614409565b610c575760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cc8565b606061279e848460008585843b61405b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cc8565b600080866001600160a01b031685876040516140779190614864565b60006040518083038185875af1925050503d80600081146140b4576040519150601f19603f3d011682016040523d82523d6000602084013e6140b9565b606091505b50915091506112e9828286613e29565b60008083601f8401126140da578182fd5b50813567ffffffffffffffff8111156140f1578182fd5b60208301915083602082850101111561410957600080fd5b9250929050565b803563ffffffff81168114610c1f57600080fd5b600060208284031215614135578081fd5b81356129d981614d8f565b600060208284031215614151578081fd5b81516129d981614d8f565b60008060008060808587031215614171578283fd5b843561417c81614d8f565b9350602085013561418c81614d8f565b9250604085013561419c81614d8f565b915060608501356141ac81614d8f565b939692955090935050565b600080604083850312156141c9578182fd5b82356141d481614d8f565b915060208381013567ffffffffffffffff808211156141f1578384fd5b818601915086601f830112614204578384fd5b81358181111561421657614216614d79565b8060051b9150614227848301614aed565b8181528481019084860184860187018b1015614241578788fd5b8795505b8386101561426a5761425681614110565b835260019590950194918601918601614245565b508096505050505050509250929050565b6000806040838503121561428d578182fd5b823561429881614d8f565b915060208381013567ffffffffffffffff808211156142b5578384fd5b818601915086601f8301126142c8578384fd5b8135818111156142da576142da614d79565b6142ec601f8201601f19168501614aed565b91508082528784828501011115614301578485fd5b8084840185840137810190920192909252919491935090915050565b6000806040838503121561432f578182fd5b823561433a81614d8f565b915061434860208401614110565b90509250929050565b600080600060608486031215614365578283fd5b833561437081614d8f565b925061437e60208501614110565b9150604084013561438e81614da4565b809150509250925092565b600080602083850312156143ab578182fd5b823567ffffffffffffffff808211156143c2578384fd5b818501915085601f8301126143d5578384fd5b8135818111156143e3578485fd5b8660208260051b85010111156143f7578485fd5b60209290920196919550909350505050565b60006020828403121561441a578081fd5b81516129d981614da4565b600060208284031215614436578081fd5b5035919050565b6000806040838503121561444f578182fd5b82359150602083013561446181614d8f565b809150509250929050565b60006020828403121561447d578081fd5b81356001600160e01b0319811681146129d9578182fd5b6000602082840312156144a5578081fd5b5051919050565b600080600080600080600060a0888a0312156144c6578485fd5b873567ffffffffffffffff808211156144dd578687fd5b6144e98b838c016140c9565b909950975060208a0135915080821115614501578687fd5b5061450e8a828b016140c9565b909650945050604088013561452281614d8f565b9250606088013561453281614d8f565b9150608088013561454281614d8f565b8091505092959891949750929550565b600080600080600080600080600060e08a8c03121561456f578283fd5b893567ffffffffffffffff80821115614586578485fd5b6145928d838e016140c9565b909b50995060208c01359150808211156145aa578485fd5b506145b78c828d016140c9565b90985096505060408a01356145cb81614d8f565b945060608a01356145db81614d8f565b935060808a01356145eb81614d8f565b925060a08a01356145fb81614d8f565b915060c08a013561460b81614d8f565b809150509295985092959850929598565b60006020828403121561462d578081fd5b6129d982614110565b60008060408385031215614648578182fd5b61465183614110565b9150602083013561446181614d8f565b60008060408385031215614673578182fd5b61467c83614110565b9150602083013561446181614da4565b6000806000606084860312156146a0578081fd5b6146a984614110565b925060208401356146b981614da4565b9150604084013561438e81614d8f565b6000806000606084860312156146dd578081fd5b6146e684614110565b925060208401356146f681614da4565b929592945050506040919091013590565b60008060408385031215614719578182fd5b61472283614110565b946020939093013593505050565b600080600060608486031215614744578081fd5b61474d84614110565b925060208401359150604084013561438e81614da4565b60008060008060808587031215614779578182fd5b61478285614110565b935060208501359250604085013561479981614da4565b9396929550929360600135925050565b60008060008060008060008060006101208a8c0312156147c7578283fd5b6147d08a614110565b9b60208b01359b5060408b01359a60608101359a506080810135995060a0810135985060c0810135975060e081013596506101000135945092505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614850816020860160208601614cb1565b601f01601f19169290920160200192915050565b60008251614876818460208701614cb1565b9190910192915050565b600061667360f01b8252828460028401379101600201908152919050565b60006b0233637b0ba1029b437b93a160a51b82528284600c8401379101600c01908152919050565b600061199b60f21b8252828460028401379101600201908152919050565b60007f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008252835161491c816017850160208801614cb1565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161494d816028840160208801614cb1565b01602801949350505050565b60006a0233637b0ba102637b733960ad1b82528284600b8401379101600b01908152919050565b6000602082526129d96020830184614838565b600060a082526149a660a0830188614838565b82810360208401526149b88188614838565b6001600160a01b03969096166040840152505063ffffffff929092166060830152151560809091015292915050565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b63ffffffff8c1681526001600160a01b038b811660208301528a8116604083015289811660608301526080820189905261012060a08301819052600091614a7f8483018a8c61480e565b915083820360c0850152614a9482888a61480e565b925080861660e085015280851661010085015250509c9b505050505050505050505050565b63ffffffff959095168552921515602085015260408401919091526001600160a01b03166060830152608082015260a00190565b604051601f8201601f1916810167ffffffffffffffff81118282101715614b1657614b16614d79565b604052919050565b600080821280156001600160ff1b0384900385131615614b4057614b40614d4d565b600160ff1b8390038412811615614b5957614b59614d4d565b50500190565b60008219821115614b7257614b72614d4d565b500190565b600082614b8657614b86614d63565b600160ff1b821460001984141615614ba057614ba0614d4d565b500590565b600082614bb457614bb4614d63565b500490565b60006001600160ff1b0381841382841380821686840486111615614bdf57614bdf614d4d565b600160ff1b84871282811687830589121615614bfd57614bfd614d4d565b858712925087820587128484161615614c1857614c18614d4d565b87850587128184161615614c2e57614c2e614d4d565b505050929093029392505050565b6000816000190483118215151615614c5657614c56614d4d565b500290565b60008083128015600160ff1b850184121615614c7957614c79614d4d565b6001600160ff1b0384018313811615614c9457614c94614d4d565b50500390565b600082821015614cac57614cac614d4d565b500390565b60005b83811015614ccc578181015183820152602001614cb4565b8381111561102c5750506000910152565b600081614cec57614cec614d4d565b506000190190565b6000600019821415614d0857614d08614d4d565b5060010190565b600063ffffffff80831681811415614d2957614d29614d4d565b6001019392505050565b6000600160ff1b821415614d4957614d49614d4d565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c2d57600080fd5b8015158114610c2d57600080fdfe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122019c08cac8a0f49b932356c300d2307de330f5556f8e594b13b296ff33c2c3ffd64736f6c63430008030033
Deployed Bytecode
0x60806040526004361061031a5760003560e01c8063867dfc6d116101ab578063c2b80072116100f7578063eeb0235211610095578063f72c0d8b1161006f578063f72c0d8b14610b3e578063f7cbb68714610b72578063f80c9b9214610b92578063f8c8765e14610bcb5761031a565b8063eeb0235214610ac7578063f41cb19514610ae7578063f68a327f14610b1e5761031a565b8063d88905c9116100d1578063d88905c914610a46578063da04ce1414610a66578063e6b604e014610a86578063e77772fe14610aa65761031a565b8063c2b80072146109c7578063c2e1247114610a06578063d547741f14610a265761031a565b80639c5b0ee311610164578063b054c4a11161013e578063b054c4a1146108f3578063b36f537414610935578063b3c7e21814610966578063bb0a45291461099f5761031a565b80639c5b0ee31461086e5780639dc39e0f146108a5578063a217fddf146108de5761031a565b8063867dfc6d146107a05780638900bdfa146107c0578063897a0786146107ee57806391a9fa611461080e57806391d148541461082e57806392f6fe801461084e5761031a565b80634f1ef2861161026a578063682ad286116102235780636f486c5b116101fd5780636f486c5b146106ed57806371fd96231461072c57806375b238fc1461074c5780637a0e94f0146107805761031a565b8063682ad2861461068c5780636c305055146106ac5780636c8d2b97146106cd5761031a565b80634f1ef286146105965780635ebaf1db146105a9578063602aabab146105d2578063636190c81461060057806364d16f531461063357806364e4a81d146106535761031a565b8063248a9ca3116102d757806334daaa25116102b157806334daaa25146104fd57806336568abe146105365780633659cfe6146105565780633d6a2b3f146105765761031a565b8063248a9ca31461046e5780632f2ff15d1461049e57806334898684146104be5761031a565b806301ffc9a71461031f57806305c8146f146103545780630e5140dc1461037657806314c88ffa146103c35780631badf5c0146103f157806321658e4814610440575b600080fd5b34801561032b57600080fd5b5061033f61033a36600461446c565b610beb565b60405190151581526020015b60405180910390f35b34801561036057600080fd5b5061037461036f36600461461c565b610c24565b005b34801561038257600080fd5b506103b561039136600461468c565b6101c360209081526000938452604080852082529284528284209052825290205481565b60405190815260200161034b565b3480156103cf57600080fd5b506103b56103de36600461461c565b61015a6020526000908152604090205481565b3480156103fd57600080fd5b5061042861040c36600461461c565b61015f602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161034b565b34801561044c57600080fd5b506103b561045b36600461461c565b61015b6020526000908152604090205481565b34801561047a57600080fd5b506103b5610489366004614425565b60009081526065602052604090206001015490565b3480156104aa57600080fd5b506103746104b936600461443d565b610c30565b3480156104ca57600080fd5b506103b56104d936600461468c565b6101c260209081526000938452604080852082529284528284209052825290205481565b34801561050957600080fd5b506103b5610518366004614661565b61019160209081526000928352604080842090915290825290205481565b34801561054257600080fd5b5061037461055136600461443d565b610c5c565b34801561056257600080fd5b50610374610571366004614124565b610cdf565b34801561058257600080fd5b50610374610591366004614552565b610d03565b6103746105a436600461427b565b610f2a565b3480156105b557600080fd5b50610128546104289064010000000090046001600160a01b031681565b3480156105de57600080fd5b506103b56105ed36600461461c565b61015c6020526000908152604090205481565b34801561060c57600080fd5b506101285461061e9063ffffffff1681565b60405163ffffffff909116815260200161034b565b34801561063f57600080fd5b5061037461064e366004614636565b610f3f565b34801561065f57600080fd5b506103b561066e366004614661565b61019060209081526000928352604080842090915290825290205481565b34801561069857600080fd5b506103746106a7366004614707565b610fc5565b3480156106b857600080fd5b5061012a54610428906001600160a01b031681565b3480156106d957600080fd5b506103746106e8366004614399565b610fd1565b3480156106f957600080fd5b506103b56107083660046146c9565b61018f60209081526000938452604080852082529284528284209052825290205481565b34801561073857600080fd5b50610374610747366004614730565b611032565b34801561075857600080fd5b506103b57fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b34801561078c57600080fd5b5061037461079b3660046141b7565b611201565b3480156107ac57600080fd5b506103746107bb366004614707565b611251565b3480156107cc57600080fd5b506103b56107db36600461461c565b6101596020526000908152604090205481565b3480156107fa57600080fd5b5061037461080936600461431d565b61125d565b34801561081a57600080fd5b50610374610829366004614707565b611267565b34801561083a57600080fd5b5061033f61084936600461443d565b611273565b34801561085a57600080fd5b506103b5610869366004614764565b61129e565b34801561087a57600080fd5b5061042861088936600461461c565b61015e602052600090815260409020546001600160a01b031681565b3480156108b157600080fd5b506103b56108c0366004614636565b6101c060209081526000928352604080842090915290825290205481565b3480156108ea57600080fd5b506103b5600081565b3480156108ff57600080fd5b5061042861090e366004614661565b61018d6020908152600092835260408084209091529082529020546001600160a01b031681565b34801561094157600080fd5b5061033f61095036600461461c565b6101586020526000908152604090205460ff1681565b34801561097257600080fd5b506103b5610981366004614661565b61018e60209081526000928352604080842090915290825290205481565b3480156109ab57600080fd5b5061042873f10a7f10a7f10a7f10a7f10a7f10a7f10a7f10a781565b3480156109d357600080fd5b506103b56109e236600461468c565b6101c160209081526000938452604080852082529284528284209052825290205481565b348015610a1257600080fd5b50610374610a21366004614707565b6112f4565b348015610a3257600080fd5b50610374610a4136600461443d565b611300565b348015610a5257600080fd5b50610374610a613660046144ac565b611326565b348015610a7257600080fd5b50610374610a81366004614707565b6117f4565b348015610a9257600080fd5b50610374610aa1366004614707565b611816565b348015610ab257600080fd5b5061012954610428906001600160a01b031681565b348015610ad357600080fd5b50610374610ae2366004614707565b611822565b348015610af357600080fd5b50610428610b0236600461461c565b61015d602052600090815260409020546001600160a01b031681565b348015610b2a57600080fd5b506103b5610b39366004614351565b61182e565b348015610b4a57600080fd5b506103b57f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e381565b348015610b7e57600080fd5b50610374610b8d3660046147a9565b61199a565b348015610b9e57600080fd5b506103b5610bad366004614661565b61019260209081526000928352604080842090915290825290205481565b348015610bd757600080fd5b50610374610be636600461415c565b611c74565b60006001600160e01b03198216637965db0b60e01b1480610c1c57506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b610c2d81611dd6565b50565b600082815260656020526040902060010154610c4d81335b6121c9565b610c57838361222d565b505050565b6001600160a01b0381163314610cd15760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b610cdb82826122b3565b5050565b610ce88161231a565b610c2d81604051806020016040528060008152506000612345565b610d0b6124c6565b6101288054600091908290610d259063ffffffff16614d0f565b91906101000a81548163ffffffff021916908363ffffffff16021790559050816001600160a01b031663edf565cc6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d7f57600080fd5b505af1158015610d93573d6000803e3d6000fd5b5050505063ffffffff8116600081815261018d6020908152604080832060018452825280832080546001600160a01b03199081166001600160a01b038d811691909117909255848052828520805482168c841617905594845261015d8352818420805486168a831617905561015e83528184208054861688831617905561015f835281842080549095169088169081179094558051630ce74fc560e31b8152905163673a7e2893600480840194938390030190829087803b158015610e5757600080fd5b505af1158015610e6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8f9190614494565b61015960008363ffffffff1663ffffffff168152602001908152602001600020819055507f901e73890694712ca72bdc627d356f05f11be45e7ccf490a8d4924c393bcb5658187878761015960008763ffffffff1663ffffffff168152602001908152602001600020548f8f8f8f8c8c604051610f169b9a99989796959493929190614a35565b60405180910390a150505050505050505050565b610f338261231a565b610cdb82826001612345565b610f476124c6565b63ffffffff8216600081815261015f602090815260409182902080546001600160a01b038681166001600160a01b03198316811790935584519586521691840182905291830191909152907ffc4d69f373858d480cfc3f12e7cc7f9b12201291753ffc3babef0e7a8041979f906060015b60405180910390a1505050565b610cdb82826000611032565b8060005b8181101561102c5761101a84848381811061100057634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611015919061461c565b611dd6565b8061102481614cf4565b915050610fd5565b50505050565b338361103d81611dd6565b61104782826124f2565b61104f6125f3565b63ffffffff8516600090815261018d602090815260408083208615158452909152908190205490516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156110c357600080fd5b505af11580156110d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fb9190614409565b61110457600080fd5b63ffffffff851660009081526101c360209081526040808320861515845282528083203384529091528120805486929061113f908490614b5f565b909155505063ffffffff8516600090815261015a6020526040812054611166906001614b5f565b63ffffffff871660008181526101c0602090815260408083203384528252808320859055928252610192815282822088151583529052908120805492935087929091906111b4908490614b5f565b90915550506040517fd850f5d8405edb0730cd72e6bb9e228043c91fd591562543ea553efda14970b6906111f19088908790899033908790614ab9565b60405180910390a1505050505050565b805160005b8181101561102c5761123f8484838151811061123257634e487b7160e01b600052603260045260246000fd5b60200260200101516124f2565b8061124981614cf4565b915050611206565b610cdb82826001612668565b610cdb82826124f2565b610cdb82826000612668565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b63ffffffff8416600090815261018f602090815260408083208515801585528184528285208686528452828520549085529083528184208585529092528220546112e9868383612787565b979650505050505050565b610cdb828260016127a6565b60008281526065602052604090206001015461131c8133610c48565b610c5783836122b3565b61132e6124c6565b6001600160a01b0383161580159061134e57506001600160a01b03821615155b801561136257506001600160a01b03811615155b61136b57600080fd5b61012880546000919082906113859063ffffffff16614d0f565b91906101000a81548163ffffffff021916908363ffffffff16021790559050600061012860049054906101000a90046001600160a01b03169050826001600160a01b031663edf565cc6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156113fa57600080fd5b505af115801561140e573d6000803e3d6000fd5b5050610129546040516001600160a01b03909116925063e6d30467915061143b908c908c90602001614959565b604051602081830303815290604052898960405160200161145d9291906148c6565b604051602081830303815290604052848660016040518663ffffffff1660e01b8152600401611490959493929190614993565b602060405180830381600087803b1580156114aa57600080fd5b505af11580156114be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e29190614140565b63ffffffff8316600090815261018d602090815260408083206001845282529182902080546001600160a01b0319166001600160a01b03948516179055610129549151919092169163e6d304679161153e918d918d910161489e565b6040516020818303038152906040528989604051602001611560929190614880565b604051602081830303815290604052848660006040518663ffffffff1660e01b8152600401611593959493929190614993565b602060405180830381600087803b1580156115ad57600080fd5b505af11580156115c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e59190614140565b63ffffffff8316600081815261018d60209081526040808320838052825280832080546001600160a01b03199081166001600160a01b039788161790915593835261015d8252808320805485168b871617905561015e82528083208054851689871617905561015f825280832080549094169489169485179093558251630ce74fc560e31b8152925163673a7e2893600480820194918390030190829087803b15801561169157600080fd5b505af11580156116a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c99190614494565b61015960008463ffffffff1663ffffffff168152602001908152602001600020819055507f901e73890694712ca72bdc627d356f05f11be45e7ccf490a8d4924c393bcb5658261018d60008563ffffffff1663ffffffff1681526020019081526020016000206000600115151515815260200190815260200160002060009054906101000a90046001600160a01b031661018d60008663ffffffff1663ffffffff16815260200190815260200160002060008015151515815260200190815260200160002060009054906101000a90046001600160a01b03168861015960008863ffffffff1663ffffffff168152602001908152602001600020548e8e8e8e8d8d6040516117e19b9a99989796959493929190614a35565b60405180910390a1505050505050505050565b6117fc6124c6565b63ffffffff909116600090815261015b6020526040902055565b610cdb828260006127a6565b610cdb82826001611032565b60008261183a8161295d565b63ffffffff8416600090815261015a60209081526040808320546101c083528184206001600160a01b038a16855290925290912054801580159061187e5750818111155b156119905763ffffffff861660009081526101c160209081526040808320881515845282528083206001600160a01b038b16845290915290205480156118f85763ffffffff8716600090815261018f60209081526040808320891515845282528083208584529091529020546118f482826129ba565b9550505b63ffffffff871660009081526101c3602090815260408083208915845282528083206001600160a01b038c168452909152902054801561198d5763ffffffff8816600090815261018f602090815260408083208a15808552818452828520888652845282852054901585529083528184208785529092529091205461197e838383612787565b6119889089614b5f565b975050505b50505b5050509392505050565b6119a26124c6565b87158015906119b057508515155b80156119bb57508415155b80156119c657508315155b80156119d157508115155b6119da57600080fd5b63ffffffff89166000908152610158602052604090205460ff1615611a375760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b6044820152606401610cc8565b6101285463ffffffff908116908a161115611a855760405162461bcd60e51b815260206004820152600e60248201526d0d2dcc8caf040e8dede40d0d2ced60931b6044820152606401610cc8565b63ffffffff8916600090815261015860209081526040808320805460ff1916600190811790915561015b835281842086905561015a90925290912055611acb858a6129e0565b63ffffffff8916600081815261015c602090815260408083208590556101285461018d835281842060018552909252808320548380529281902054905163b0956b5f60e01b815260048101949094526001600160a01b03928316602485015282166044840152606483018b9052608483018a905260a4830189905260c4830187905260e483018690526401000000009004169063b0956b5f9061010401600060405180830381600087803b158015611b8257600080fd5b505af1158015611b96573d6000803e3d6000fd5b5050610128546040516317b4d3fb60e31b815263ffffffff8d16600482015260016024820152670de0b6b3a76400006044820181905260648201526084810189905260a481018990526401000000009091046001600160a01b0316925063bda69fd8915060c401600060405180830381600087803b158015611c1757600080fd5b505af1158015611c2b573d6000803e3d6000fd5b50506040805163ffffffff8d168152602081018990529081018490527f95eeb1c33a758f56bd880588063c2f122e39c8885929e5fbbbd57418b97e58d0925060600190506117e1565b600054610100900460ff1680611c8d575060005460ff16155b611ca95760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015611ccb576000805461ffff19166101011790555b6001600160a01b03851615801590611ceb57506001600160a01b03841615155b8015611cff57506001600160a01b03831615155b8015611d1357506001600160a01b03821615155b611d1c57600080fd5b611d2585612c29565b61012980546001600160a01b03199081166001600160a01b038781169182179093556101288054640100000000600160c01b0319166401000000008886169081029190911790915561012a80549093168685161790925560408051938916845260208401919091528201527f48aa6e6153c5dedbe00925ab3c8e28c6ce0c1a80652b3369f176065e797b45079060600160405180910390a18015611dcf576000805461ff00191690555b5050505050565b80611de08161295d565b63ffffffff8216600090815261015f60209081526040808320548151630ce74fc560e31b815291516001600160a01b039091169263673a7e28926004808201939182900301818787803b158015611e3657600080fd5b505af1158015611e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6e9190614494565b63ffffffff8416600090815261015a602090815260408083205461015990925290912054919250908214801590611dcf5763ffffffff8516600090815261018f6020908152604080832060018452808352818420868552835281842054848052908352818420868552909252822054909180611eea8988612cae565b63ffffffff8b16600090815261018d602090815260408083206001845282528083205481516318160ddd60e01b81529151959750939550611f949487946001600160a01b0316936318160ddd93600480850194919392918390030190829087803b158015611f5757600080fd5b505af1158015611f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8f9190614494565b6129ba565b63ffffffff8a16600090815261018d6020908152604080832083805282528083205481516318160ddd60e01b81529151949850611fff9486946001600160a01b03909216936318160ddd93600480820194929392918390030190829087803b158015611f5757600080fd5b63ffffffff8a1660009081526101596020526040902088905592508561202481614cf4565b63ffffffff8b16600090815261015a6020908152604080832084905561018f82528083206001845280835281842085855283528184208a9055838052825280832084845290915281208690559097509050806120818b8787612ed5565b90925090506120908285614b1e565b935061209c8184614b1e565b63ffffffff8c16600081815261018e6020908152604080832060018452909152808220889055818052908190208390556101285490516317b4d3fb60e31b81526004810192909252602482018b905260448201899052606482018890526084820187905260a482018390529194506401000000009091046001600160a01b03169063bda69fd89060c401600060405180830381600087803b15801561214057600080fd5b505af1158015612154573d6000803e3d6000fd5b50506040805163ffffffff8f168152602081018c90529081018c9052606081018790526080810186905260a0810189905260c081018890527f69e662f95898affac086a5bc1177755bdaf7f4a40a3880364c48012170ee57fe925060e001905060405180910390a15050505050505050505050565b6121d38282611273565b610cdb576121eb816001600160a01b031660146131d4565b6121f68360206131d4565b6040516020016122079291906148e4565b60408051601f198184030181529082905262461bcd60e51b8252610cc891600401614980565b6122378282611273565b610cdb5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561226f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6122bd8282611273565b15610cdb5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b7f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e3610cdb8133610c48565b60006123787f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b9050612383846133b6565b6000835111806123905750815b156123a15761239f848461345b565b505b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143805460ff16611dcf57805460ff191660011781556040516001600160a01b038316602482015261242090869060440160408051601f198184030181529190526020810180516001600160e01b0316631b2ce7f360e11b17905261345b565b50805460ff191681557f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b038381169116146124bd5760405162461bcd60e51b815260206004820152602f60248201527f45524331393637557067726164653a207570677261646520627265616b73206660448201526e75727468657220757067726164657360881b6064820152608401610cc8565b611dcf85613546565b6124f07fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775336121c9565b565b63ffffffff811660009081526101c0602090815260408083206001600160a01b03861684529091529020548015801590612542575063ffffffff8216600090815261015a60205260409020548111155b15610c575761255382846001613586565b61255f82846000613586565b61256b828460016136ea565b612577828460006136ea565b61258382846001613820565b61258f82846000613820565b63ffffffff821660008181526101c0602090815260408083206001600160a01b038816808552908352818420939093558051928352908201929092527fe03aa867e2345cc967d98e4c81f6b0707b5ef082d9d20bac3dcf95540acdeae49101610fb8565b6101285464010000000090046001600160a01b031633146124f05761012a546040516324b4085360e21b81523360048201526001600160a01b03909116906392d0214c90602401600060405180830381600087803b15801561265457600080fd5b505af115801561102c573d6000803e3d6000fd5b338361267381611dd6565b61267d82826124f2565b6126856125f3565b61268f858561396a565b63ffffffff85166000908152610190602090815260408083208615158452909152812080548692906126c2908490614b5f565b909155505063ffffffff851660009081526101c1602090815260408083208615158452825280832033845290915281208054869290612702908490614b5f565b909155505063ffffffff8516600090815261015a6020526040812054612729906001614b5f565b63ffffffff871660009081526101c0602090815260408083203380855292529182902083905590519192507f50b8727b538cf16daeb79894e8bde5c1e975985071be8a8d7620675a5dddfc6b916111f191899188918a918790614ab9565b6000816127948486614c3c565b61279e9190614ba5565b949350505050565b33836127b181611dd6565b6127bb82826124f2565b6127c36125f3565b63ffffffff8516600090815261018d602090815260408083208615158452909152908190205490516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561283757600080fd5b505af115801561284b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286f9190614409565b5063ffffffff851660009081526101c26020908152604080832086151584528252808320338452909152812080548692906128ab908490614b5f565b909155505063ffffffff8516600090815261015a60205260408120546128d2906001614b5f565b63ffffffff871660008181526101c060209081526040808320338452825280832085905592825261019181528282208815158352905290812080549293508792909190612920908490614b5f565b90915550506040517f191d5f0d51691cdc223884e5321013c9663c6b337a07d550c538d9dcbbd66203906111f19088908790899033908790614ab9565b63ffffffff81166000908152610158602052604090205460ff16610c2d5760405162461bcd60e51b81526020600482015260146024820152731b585c9ad95d08191bd95cdb89dd08195e1a5cdd60621b6044820152606401610cc8565b6000816129cf84670de0b6b3a7640000614c3c565b6129d99190614ba5565b9392505050565b670de0b6b3a7640000821015612a385760405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e74206d61726b6574207365656400000000000000006044820152606401610cc8565b6000612a45836002614c3c565b9050612a51828261396a565b63ffffffff8216600090815261015e6020526040908190205490516304831f7160e51b8152600481018390526001600160a01b0390911690639063ee2090602401600060405180830381600087803b158015612aac57600080fd5b505af1158015612ac0573d6000803e3d6000fd5b5050505063ffffffff8216600090815261018d6020908152604080832060018452909152908190205490516340c10f1960e01b815273f10a7f10a7f10a7f10a7f10a7f10a7f10a7f10a76004820152602481018590526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015612b4557600080fd5b505af1158015612b59573d6000803e3d6000fd5b5050505063ffffffff8216600090815261018d60209081526040808320838052909152908190205490516340c10f1960e01b815273f10a7f10a7f10a7f10a7f10a7f10a7f10a7f10a76004820152602481018590526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015612bdd57600080fd5b505af1158015612bf1573d6000803e3d6000fd5b5050505063ffffffff91909116600090815261018e602090815260408083206001845290915280822084905581805290209190915550565b600054610100900460ff1680612c42575060005460ff16155b612c5e5760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015612c80576000805461ffff19166101011790555b612c886139ab565b612c90613a2e565b612c9982613a8c565b8015610cdb576000805461ff00191690555050565b63ffffffff82166000908152610159602090815260408083205461018e835281842060018552808452828520548580529352908320549192612cf08385614b5f565b9050600080612d0188878786613b55565b63ffffffff8a16600090815261015e602052604080822054905163452accd960e11b81526004810188905260248101849052939550919350916001600160a01b0390911690638a5599b290604401602060405180830381600087803b158015612d6957600080fd5b505af1158015612d7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da19190614494565b90508015612dcd578215612dc057612db98188614b5f565b9650612dcd565b612dca8187614b5f565b95505b6000612dd98888613bcd565b90506000612def87670de0b6b3a7640000614bb9565b63ffffffff8c16600090815261015c602052604090205483612e118a8e614c5b565b612e1b9190614bb9565b612e259190614bb9565b612e2f9190614b77565b90506000811215612e8857612e4381614d33565b905088811115612e6b57620186a0612e5e8a6201869f614bb9565b612e689190614b77565b90505b612e75818a614c9a565b9850612e818189614b5f565b9750612ec7565b87811115612eae57620186a0612ea1896201869f614bb9565b612eab9190614b77565b90505b612eb8818a614b5f565b9850612ec48189614c9a565b97505b505050505050509250929050565b63ffffffff8316600090815261019060209081526040808320600184529091528120548190819081908015612f375763ffffffff881660009081526101906020908152604080832060018452909152812055935083612f3481886129ba565b92505b5063ffffffff87166000908152610190602090815260408083208380529091529020548015612f925763ffffffff8816600090815261019060209081526040808320838052909152812055925082612f8f81876129ba565b91505b5063ffffffff871660009081526101926020908152604080832060018452909152902054801561302a576000612fc88289613be3565b9050612fd48187614c5b565b9550612fe08186614b1e565b9450612fec8285614c5b565b9350612ff9828989612787565b6130039084614b1e565b63ffffffff8a16600090815261019260209081526040808320600184529091528120559250505b5063ffffffff871660009081526101926020908152604080832083805290915290205480156130c057600061305f8288613be3565b905061306b8186614c5b565b94506130778187614b1e565b95506130838284614c5b565b925061309082888a612787565b61309a9085614b1e565b63ffffffff8a166000908152610192602090815260408083208380529091528120559350505b5063ffffffff8716600090815261019160209081526040808320600184529091529020548015613130576130f48188613be3565b6130fe9086614c5b565b945061310a8184614c5b565b63ffffffff89166000908152610191602090815260408083206001845290915281205592505b5063ffffffff8716600090815261019160209081526040808320838052909152902054801561319e576131638187613be3565b61316d9085614c5b565b93506131798183614c5b565b63ffffffff891660009081526101916020908152604080832083805290915281205591505b6131b1886131ac8688614b1e565b613bf8565b6131bd88600185613cfc565b6131c988600084613cfc565b505050935093915050565b606060006131e3836002614c3c565b6131ee906002614b5f565b67ffffffffffffffff81111561321457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561323e576020820181803683370190505b509050600360fc1b8160008151811061326757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106132a457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006132c8846002614c3c565b6132d3906001614b5f565b90505b6001811115613367576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061331557634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061333957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361336081614cdd565b90506132d6565b5083156129d95760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610cc8565b803b61341a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610cc8565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6060823b6134ba5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610cc8565b600080846001600160a01b0316846040516134d59190614864565b600060405180830381855af49150503d8060008114613510576040519150601f19603f3d011682016040523d82523d6000602084013e613515565b606091505b509150915061353d8282604051806060016040528060278152602001614db360279139613e29565b95945050505050565b61354f816133b6565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b63ffffffff831660009081526101c160209081526040808320841515845282528083206001600160a01b0386168452909152902054801561102c5763ffffffff841660008181526101c1602090815260408083208615158085529083528184206001600160a01b03891680865290845282852085905585855261018f84528285209185529083528184209484526101c083528184209084528252808320548352929052908120546136389083906129ba565b63ffffffff8616600090815261018d6020908152604080832087151584529091529081902054905163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b1580156136aa57600080fd5b505af11580156136be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136e29190614409565b505050505050565b63ffffffff831660009081526101c260209081526040808320841515845282528083206001600160a01b0386168452909152902054801561102c5763ffffffff841660008181526101c2602090815260408083208615158085529083528184206001600160a01b03891680865290845282852085905585855261018f84528285209185529083528184209484526101c0835281842090845282528083205483529290529081205461379c908390613be3565b63ffffffff8616600090815261015e6020526040908190205490516375b5ffd160e11b81526001600160a01b0387811660048301526024820184905292935091169063eb6bffa290604401600060405180830381600087803b15801561380157600080fd5b505af1158015613815573d6000803e3d6000fd5b505050505050505050565b63ffffffff831660009081526101c360209081526040808320841515845282528083206001600160a01b0386168452909152902054801561102c5763ffffffff841660009081526101c0602090815260408083206001600160a01b03871684529091528120546138959086908490869061129e565b63ffffffff861660008181526101c3602090815260408083208815801585529083528184206001600160a01b038b811680875291855283862086905595855261018d845282852091855292529182902054915163a9059cbb60e01b8152600481019190915260248101849052929350169063a9059cbb90604401602060405180830381600087803b15801561392957600080fd5b505af115801561393d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139619190614409565b611dcf57600080fd5b63ffffffff808316600090815261015e602090815260408083205461015d90925290912054610cdb926001600160a01b0391821692339216908590613e6216565b600054610100900460ff16806139c4575060005460ff16155b6139e05760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613a02576000805461ffff19166101011790555b613a0a613ebc565b613a12613ebc565b613a1a613ebc565b8015610c2d576000805461ff001916905550565b600054610100900460ff1680613a47575060005460ff16155b613a635760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613a0a576000805461ffff1916610101179055613a12613ebc565b600054610100900460ff1680613aa5575060005460ff16155b613ac15760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613ae3576000805461ffff19166101011790555b6001600160a01b038216613af657600080fd5b613b01600083613f26565b613b2b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177583613f26565b612c997f189ab7a9244df0848122154315af71fe140f3db0fe014031783b0946b8c9d2e383613f26565b8183106000808215613b6a5750848403613b6f565b508385035b63ffffffff8716600090815261015b60205260408120548590613b929084614c3c565b613b9c9190614ba5565b90506000613bb282670de0b6b3a7640000613bcd565b905080670de0b6b3a764000003935050505094509492505050565b6000818310613bdc57816129d9565b5090919050565b6000670de0b6b3a76400006129cf8385614c3c565b6000811315613c795763ffffffff8216600090815261015e6020526040908190205490516304831f7160e51b8152600481018390526001600160a01b0390911690639063ee2090602401600060405180830381600087803b158015613c5c57600080fd5b505af1158015613c70573d6000803e3d6000fd5b50505050610cdb565b6000811215610cdb5763ffffffff8216600090815261015e60205260409020546001600160a01b0316631c499b55613cb083614d33565b6040518263ffffffff1660e01b8152600401613cce91815260200190565b600060405180830381600087803b158015613ce857600080fd5b505af11580156136e2573d6000803e3d6000fd5b6000811315613d905763ffffffff8316600090815261018d602090815260408083208515158452909152908190205490516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401600060405180830381600087803b158015613d7357600080fd5b505af1158015613d87573d6000803e3d6000fd5b50505050610c57565b6000811215610c575763ffffffff8316600090815261018d6020908152604080832085151584529091529020546001600160a01b03166342966c68613dd483614d33565b6040518263ffffffff1660e01b8152600401613df291815260200190565b600060405180830381600087803b158015613e0c57600080fd5b505af1158015613e20573d6000803e3d6000fd5b50505050505050565b60608315613e385750816129d9565b825115613e485782518084602001fd5b8160405162461bcd60e51b8152600401610cc89190614980565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261102c908590613f30565b600054610100900460ff1680613ed5575060005460ff16155b613ef15760405162461bcd60e51b8152600401610cc8906149e7565b600054610100900460ff16158015613a1a576000805461ffff19166101011790558015610c2d576000805461ff001916905550565b610cdb828261222d565b6000613f85826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140029092919063ffffffff16565b805190915015610c575780806020019051810190613fa39190614409565b610c575760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cc8565b606061279e848460008585843b61405b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cc8565b600080866001600160a01b031685876040516140779190614864565b60006040518083038185875af1925050503d80600081146140b4576040519150601f19603f3d011682016040523d82523d6000602084013e6140b9565b606091505b50915091506112e9828286613e29565b60008083601f8401126140da578182fd5b50813567ffffffffffffffff8111156140f1578182fd5b60208301915083602082850101111561410957600080fd5b9250929050565b803563ffffffff81168114610c1f57600080fd5b600060208284031215614135578081fd5b81356129d981614d8f565b600060208284031215614151578081fd5b81516129d981614d8f565b60008060008060808587031215614171578283fd5b843561417c81614d8f565b9350602085013561418c81614d8f565b9250604085013561419c81614d8f565b915060608501356141ac81614d8f565b939692955090935050565b600080604083850312156141c9578182fd5b82356141d481614d8f565b915060208381013567ffffffffffffffff808211156141f1578384fd5b818601915086601f830112614204578384fd5b81358181111561421657614216614d79565b8060051b9150614227848301614aed565b8181528481019084860184860187018b1015614241578788fd5b8795505b8386101561426a5761425681614110565b835260019590950194918601918601614245565b508096505050505050509250929050565b6000806040838503121561428d578182fd5b823561429881614d8f565b915060208381013567ffffffffffffffff808211156142b5578384fd5b818601915086601f8301126142c8578384fd5b8135818111156142da576142da614d79565b6142ec601f8201601f19168501614aed565b91508082528784828501011115614301578485fd5b8084840185840137810190920192909252919491935090915050565b6000806040838503121561432f578182fd5b823561433a81614d8f565b915061434860208401614110565b90509250929050565b600080600060608486031215614365578283fd5b833561437081614d8f565b925061437e60208501614110565b9150604084013561438e81614da4565b809150509250925092565b600080602083850312156143ab578182fd5b823567ffffffffffffffff808211156143c2578384fd5b818501915085601f8301126143d5578384fd5b8135818111156143e3578485fd5b8660208260051b85010111156143f7578485fd5b60209290920196919550909350505050565b60006020828403121561441a578081fd5b81516129d981614da4565b600060208284031215614436578081fd5b5035919050565b6000806040838503121561444f578182fd5b82359150602083013561446181614d8f565b809150509250929050565b60006020828403121561447d578081fd5b81356001600160e01b0319811681146129d9578182fd5b6000602082840312156144a5578081fd5b5051919050565b600080600080600080600060a0888a0312156144c6578485fd5b873567ffffffffffffffff808211156144dd578687fd5b6144e98b838c016140c9565b909950975060208a0135915080821115614501578687fd5b5061450e8a828b016140c9565b909650945050604088013561452281614d8f565b9250606088013561453281614d8f565b9150608088013561454281614d8f565b8091505092959891949750929550565b600080600080600080600080600060e08a8c03121561456f578283fd5b893567ffffffffffffffff80821115614586578485fd5b6145928d838e016140c9565b909b50995060208c01359150808211156145aa578485fd5b506145b78c828d016140c9565b90985096505060408a01356145cb81614d8f565b945060608a01356145db81614d8f565b935060808a01356145eb81614d8f565b925060a08a01356145fb81614d8f565b915060c08a013561460b81614d8f565b809150509295985092959850929598565b60006020828403121561462d578081fd5b6129d982614110565b60008060408385031215614648578182fd5b61465183614110565b9150602083013561446181614d8f565b60008060408385031215614673578182fd5b61467c83614110565b9150602083013561446181614da4565b6000806000606084860312156146a0578081fd5b6146a984614110565b925060208401356146b981614da4565b9150604084013561438e81614d8f565b6000806000606084860312156146dd578081fd5b6146e684614110565b925060208401356146f681614da4565b929592945050506040919091013590565b60008060408385031215614719578182fd5b61472283614110565b946020939093013593505050565b600080600060608486031215614744578081fd5b61474d84614110565b925060208401359150604084013561438e81614da4565b60008060008060808587031215614779578182fd5b61478285614110565b935060208501359250604085013561479981614da4565b9396929550929360600135925050565b60008060008060008060008060006101208a8c0312156147c7578283fd5b6147d08a614110565b9b60208b01359b5060408b01359a60608101359a506080810135995060a0810135985060c0810135975060e081013596506101000135945092505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614850816020860160208601614cb1565b601f01601f19169290920160200192915050565b60008251614876818460208701614cb1565b9190910192915050565b600061667360f01b8252828460028401379101600201908152919050565b60006b0233637b0ba1029b437b93a160a51b82528284600c8401379101600c01908152919050565b600061199b60f21b8252828460028401379101600201908152919050565b60007f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008252835161491c816017850160208801614cb1565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161494d816028840160208801614cb1565b01602801949350505050565b60006a0233637b0ba102637b733960ad1b82528284600b8401379101600b01908152919050565b6000602082526129d96020830184614838565b600060a082526149a660a0830188614838565b82810360208401526149b88188614838565b6001600160a01b03969096166040840152505063ffffffff929092166060830152151560809091015292915050565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b63ffffffff8c1681526001600160a01b038b811660208301528a8116604083015289811660608301526080820189905261012060a08301819052600091614a7f8483018a8c61480e565b915083820360c0850152614a9482888a61480e565b925080861660e085015280851661010085015250509c9b505050505050505050505050565b63ffffffff959095168552921515602085015260408401919091526001600160a01b03166060830152608082015260a00190565b604051601f8201601f1916810167ffffffffffffffff81118282101715614b1657614b16614d79565b604052919050565b600080821280156001600160ff1b0384900385131615614b4057614b40614d4d565b600160ff1b8390038412811615614b5957614b59614d4d565b50500190565b60008219821115614b7257614b72614d4d565b500190565b600082614b8657614b86614d63565b600160ff1b821460001984141615614ba057614ba0614d4d565b500590565b600082614bb457614bb4614d63565b500490565b60006001600160ff1b0381841382841380821686840486111615614bdf57614bdf614d4d565b600160ff1b84871282811687830589121615614bfd57614bfd614d4d565b858712925087820587128484161615614c1857614c18614d4d565b87850587128184161615614c2e57614c2e614d4d565b505050929093029392505050565b6000816000190483118215151615614c5657614c56614d4d565b500290565b60008083128015600160ff1b850184121615614c7957614c79614d4d565b6001600160ff1b0384018313811615614c9457614c94614d4d565b50500390565b600082821015614cac57614cac614d4d565b500390565b60005b83811015614ccc578181015183820152602001614cb4565b8381111561102c5750506000910152565b600081614cec57614cec614d4d565b506000190190565b6000600019821415614d0857614d08614d4d565b5060010190565b600063ffffffff80831681811415614d2957614d29614d4d565b6001019392505050565b6000600160ff1b821415614d4957614d49614d4d565b0390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c2d57600080fd5b8015158114610c2d57600080fdfe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122019c08cac8a0f49b932356c300d2307de330f5556f8e594b13b296ff33c2c3ffd64736f6c63430008030033
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.