Overview
POL Balance
0 POL
POL Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 12 from a total of 12 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Owner | 53780053 | 287 days ago | IN | 0 POL | 0.00422667 | ||||
Set Owner | 53779850 | 287 days ago | IN | 0 POL | 0.00464097 | ||||
Create Pool | 53298454 | 299 days ago | IN | 0 POL | 0.20786156 | ||||
Create Pool | 52421605 | 322 days ago | IN | 0 POL | 0.22973569 | ||||
Create Pool | 48661709 | 418 days ago | IN | 0 POL | 1.65969292 | ||||
Create Pool | 48356637 | 426 days ago | IN | 0 POL | 0.46662361 | ||||
Create Pool | 46929410 | 462 days ago | IN | 0 POL | 0.00384874 | ||||
Set Vault Addres... | 34611573 | 775 days ago | IN | 0 POL | 0.00351134 | ||||
Set Vault Addres... | 34300909 | 783 days ago | IN | 0 POL | 0.00838959 | ||||
Set Owner | 33107789 | 811 days ago | IN | 0 POL | 0.00088572 | ||||
Create Pool | 32611263 | 823 days ago | IN | 0 POL | 0.20464699 | ||||
Set Farming Addr... | 32611216 | 823 days ago | IN | 0 POL | 0.00332577 |
Latest 25 internal transactions (View All)
Loading...
Loading
Contract Name:
AlgebraFactory
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 0 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.7.6; pragma abicoder v2; import './interfaces/IAlgebraFactory.sol'; import './interfaces/IAlgebraPoolDeployer.sol'; import './interfaces/IDataStorageOperator.sol'; import './libraries/AdaptiveFee.sol'; import './DataStorageOperator.sol'; /** * @title Algebra factory * @notice Is used to deploy pools and its dataStorages */ contract AlgebraFactory is IAlgebraFactory { /// @inheritdoc IAlgebraFactory address public override owner; /// @inheritdoc IAlgebraFactory address public immutable override poolDeployer; /// @inheritdoc IAlgebraFactory address public override farmingAddress; /// @inheritdoc IAlgebraFactory address public override vaultAddress; // values of constants for sigmoids in fee calculation formula AdaptiveFee.Configuration public baseFeeConfiguration = AdaptiveFee.Configuration( 3000 - Constants.BASE_FEE, // alpha1 15000 - 3000, // alpha2 360, // beta1 60000, // beta2 59, // gamma1 8500, // gamma2 0, // volumeBeta 10, // volumeGamma Constants.BASE_FEE // baseFee ); modifier onlyOwner() { require(msg.sender == owner); _; } /// @inheritdoc IAlgebraFactory mapping(address => mapping(address => address)) public override poolByPair; constructor(address _poolDeployer, address _vaultAddress) { owner = msg.sender; emit Owner(msg.sender); poolDeployer = _poolDeployer; vaultAddress = _vaultAddress; } /// @inheritdoc IAlgebraFactory function createPool(address tokenA, address tokenB) external override returns (address pool) { require(tokenA != tokenB); (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0)); require(poolByPair[token0][token1] == address(0)); IDataStorageOperator dataStorage = new DataStorageOperator(computeAddress(token0, token1)); dataStorage.changeFeeConfiguration(baseFeeConfiguration); pool = IAlgebraPoolDeployer(poolDeployer).deploy(address(dataStorage), address(this), token0, token1); poolByPair[token0][token1] = pool; // to avoid future addresses comparing we are populating the mapping twice poolByPair[token1][token0] = pool; emit Pool(token0, token1, pool); } /// @inheritdoc IAlgebraFactory function setOwner(address _owner) external override onlyOwner { require(owner != _owner); emit Owner(_owner); owner = _owner; } /// @inheritdoc IAlgebraFactory function setFarmingAddress(address _farmingAddress) external override onlyOwner { require(farmingAddress != _farmingAddress); emit FarmingAddress(_farmingAddress); farmingAddress = _farmingAddress; } /// @inheritdoc IAlgebraFactory function setVaultAddress(address _vaultAddress) external override onlyOwner { require(vaultAddress != _vaultAddress); emit VaultAddress(_vaultAddress); vaultAddress = _vaultAddress; } /// @inheritdoc IAlgebraFactory function setBaseFeeConfiguration( uint16 alpha1, uint16 alpha2, uint32 beta1, uint32 beta2, uint16 gamma1, uint16 gamma2, uint32 volumeBeta, uint16 volumeGamma, uint16 baseFee ) external override onlyOwner { require(uint256(alpha1) + uint256(alpha2) + uint256(baseFee) <= type(uint16).max, 'Max fee exceeded'); require(gamma1 != 0 && gamma2 != 0 && volumeGamma != 0, 'Gammas must be > 0'); baseFeeConfiguration = AdaptiveFee.Configuration(alpha1, alpha2, beta1, beta2, gamma1, gamma2, volumeBeta, volumeGamma, baseFee); emit FeeConfiguration(alpha1, alpha2, beta1, beta2, gamma1, gamma2, volumeBeta, volumeGamma, baseFee); } bytes32 internal constant POOL_INIT_CODE_HASH = 0x6ec6c9c8091d160c0aa74b2b14ba9c1717e95093bd3ac085cee99a49aab294a4; /// @notice Deterministically computes the pool address given the factory and PoolKey /// @param token0 first token /// @param token1 second token /// @return pool The contract address of the Algebra pool function computeAddress(address token0, address token1) internal view returns (address pool) { pool = address(uint256(keccak256(abi.encodePacked(hex'ff', poolDeployer, keccak256(abi.encode(token0, token1)), POOL_INIT_CODE_HASH)))); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /** * @title The interface for the Algebra Factory * @dev Credit to Uniswap Labs under GPL-2.0-or-later license: * https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces */ interface IAlgebraFactory { /** * @notice Emitted when the owner of the factory is changed * @param newOwner The owner after the owner was changed */ event Owner(address indexed newOwner); /** * @notice Emitted when the vault address is changed * @param newVaultAddress The vault address after the address was changed */ event VaultAddress(address indexed newVaultAddress); /** * @notice Emitted when a pool is created * @param token0 The first token of the pool by address sort order * @param token1 The second token of the pool by address sort order * @param pool The address of the created pool */ event Pool(address indexed token0, address indexed token1, address pool); /** * @notice Emitted when the farming address is changed * @param newFarmingAddress The farming address after the address was changed */ event FarmingAddress(address indexed newFarmingAddress); event FeeConfiguration( uint16 alpha1, uint16 alpha2, uint32 beta1, uint32 beta2, uint16 gamma1, uint16 gamma2, uint32 volumeBeta, uint16 volumeGamma, uint16 baseFee ); /** * @notice Returns the current owner of the factory * @dev Can be changed by the current owner via setOwner * @return The address of the factory owner */ function owner() external view returns (address); /** * @notice Returns the current poolDeployerAddress * @return The address of the poolDeployer */ function poolDeployer() external view returns (address); /** * @dev Is retrieved from the pools to restrict calling * certain functions not by a tokenomics contract * @return The tokenomics contract address */ function farmingAddress() external view returns (address); function vaultAddress() external view returns (address); /** * @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist * @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order * @param tokenA The contract address of either token0 or token1 * @param tokenB The contract address of the other token * @return pool The pool address */ function poolByPair(address tokenA, address tokenB) external view returns (address pool); /** * @notice Creates a pool for the given two tokens and fee * @param tokenA One of the two tokens in the desired pool * @param tokenB The other of the two tokens in the desired pool * @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved * from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments * are invalid. * @return pool The address of the newly created pool */ function createPool(address tokenA, address tokenB) external returns (address pool); /** * @notice Updates the owner of the factory * @dev Must be called by the current owner * @param _owner The new owner of the factory */ function setOwner(address _owner) external; /** * @dev updates tokenomics address on the factory * @param _farmingAddress The new tokenomics contract address */ function setFarmingAddress(address _farmingAddress) external; /** * @dev updates vault address on the factory * @param _vaultAddress The new vault contract address */ function setVaultAddress(address _vaultAddress) external; /** * @notice Changes initial fee configuration for new pools * @dev changes coefficients for sigmoids: α / (1 + e^( (β-x) / γ)) * alpha1 + alpha2 + baseFee (max possible fee) must be <= type(uint16).max * gammas must be > 0 * @param alpha1 max value of the first sigmoid * @param alpha2 max value of the second sigmoid * @param beta1 shift along the x-axis for the first sigmoid * @param beta2 shift along the x-axis for the second sigmoid * @param gamma1 horizontal stretch factor for the first sigmoid * @param gamma2 horizontal stretch factor for the second sigmoid * @param volumeBeta shift along the x-axis for the outer volume-sigmoid * @param volumeGamma horizontal stretch factor the outer volume-sigmoid * @param baseFee minimum possible fee */ function setBaseFeeConfiguration( uint16 alpha1, uint16 alpha2, uint32 beta1, uint32 beta2, uint16 gamma1, uint16 gamma2, uint32 volumeBeta, uint16 volumeGamma, uint16 baseFee ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /** * @title An interface for a contract that is capable of deploying Algebra Pools * @notice A contract that constructs a pool must implement this to pass arguments to the pool * @dev This is used to avoid having constructor arguments in the pool contract, which results in the init code hash * of the pool being constant allowing the CREATE2 address of the pool to be cheaply computed on-chain. * Credit to Uniswap Labs under GPL-2.0-or-later license: * https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces */ interface IAlgebraPoolDeployer { /** * @notice Emitted when the factory address is changed * @param factory The factory address after the address was changed */ event Factory(address indexed factory); /** * @notice Get the parameters to be used in constructing the pool, set transiently during pool creation. * @dev Called by the pool constructor to fetch the parameters of the pool * Returns dataStorage The pools associated dataStorage * Returns factory The factory address * Returns token0 The first token of the pool by address sort order * Returns token1 The second token of the pool by address sort order */ function parameters() external view returns ( address dataStorage, address factory, address token0, address token1 ); /** * @dev Deploys a pool with the given parameters by transiently setting the parameters storage slot and then * clearing it after deploying the pool. * @param dataStorage The pools associated dataStorage * @param factory The contract address of the Algebra factory * @param token0 The first token of the pool by address sort order * @param token1 The second token of the pool by address sort order * @return pool The deployed pool's address */ function deploy( address dataStorage, address factory, address token0, address token1 ) external returns (address pool); /** * @dev Sets the factory address to the poolDeployer for permissioned actions * @param factory The address of the Algebra factory */ function setFactory(address factory) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; pragma abicoder v2; import '../libraries/AdaptiveFee.sol'; interface IDataStorageOperator { event FeeConfiguration(AdaptiveFee.Configuration feeConfig); /** * @notice Returns data belonging to a certain timepoint * @param index The index of timepoint in the array * @dev There is more convenient function to fetch a timepoint: observe(). Which requires not an index but seconds * @return initialized Whether the timepoint has been initialized and the values are safe to use, * blockTimestamp The timestamp of the observation, * tickCumulative The tick multiplied by seconds elapsed for the life of the pool as of the timepoint timestamp, * secondsPerLiquidityCumulative The seconds per in range liquidity for the life of the pool as of the timepoint timestamp, * volatilityCumulative Cumulative standard deviation for the life of the pool as of the timepoint timestamp, * averageTick Time-weighted average tick, * volumePerLiquidityCumulative Cumulative swap volume per liquidity for the life of the pool as of the timepoint timestamp */ function timepoints(uint256 index) external view returns ( bool initialized, uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulative, uint88 volatilityCumulative, int24 averageTick, uint144 volumePerLiquidityCumulative ); /// @notice Initialize the dataStorage array by writing the first slot. Called once for the lifecycle of the timepoints array /// @param time The time of the dataStorage initialization, via block.timestamp truncated to uint32 /// @param tick Initial tick function initialize(uint32 time, int24 tick) external; /// @dev Reverts if an timepoint at or before the desired timepoint timestamp does not exist. /// 0 may be passed as `secondsAgo' to return the current cumulative values. /// If called with a timestamp falling between two timepoints, returns the counterfactual accumulator values /// at exactly the timestamp between the two timepoints. /// @param time The current block timestamp /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an timepoint /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return tickCumulative The cumulative tick since the pool was first initialized, as of `secondsAgo` /// @return secondsPerLiquidityCumulative The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of `secondsAgo` /// @return volatilityCumulative The cumulative volatility value since the pool was first initialized, as of `secondsAgo` /// @return volumePerAvgLiquidity The cumulative volume per liquidity value since the pool was first initialized, as of `secondsAgo` function getSingleTimepoint( uint32 time, uint32 secondsAgo, int24 tick, uint16 index, uint128 liquidity ) external view returns ( int56 tickCumulative, uint160 secondsPerLiquidityCumulative, uint112 volatilityCumulative, uint256 volumePerAvgLiquidity ); /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos` /// @dev Reverts if `secondsAgos` > oldest timepoint /// @param time The current block.timestamp /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an timepoint /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return tickCumulatives The cumulative tick since the pool was first initialized, as of each `secondsAgo` /// @return secondsPerLiquidityCumulatives The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo` /// @return volatilityCumulatives The cumulative volatility values since the pool was first initialized, as of each `secondsAgo` /// @return volumePerAvgLiquiditys The cumulative volume per liquidity values since the pool was first initialized, as of each `secondsAgo` function getTimepoints( uint32 time, uint32[] memory secondsAgos, int24 tick, uint16 index, uint128 liquidity ) external view returns ( int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulatives, uint112[] memory volatilityCumulatives, uint256[] memory volumePerAvgLiquiditys ); /// @notice Returns average volatility in the range from time-WINDOW to time /// @param time The current block.timestamp /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return TWVolatilityAverage The average volatility in the recent range /// @return TWVolumePerLiqAverage The average volume per liquidity in the recent range function getAverages( uint32 time, int24 tick, uint16 index, uint128 liquidity ) external view returns (uint112 TWVolatilityAverage, uint256 TWVolumePerLiqAverage); /// @notice Writes an dataStorage timepoint to the array /// @dev Writable at most once per block. Index represents the most recently written element. index must be tracked externally. /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param blockTimestamp The timestamp of the new timepoint /// @param tick The active tick at the time of the new timepoint /// @param liquidity The total in-range liquidity at the time of the new timepoint /// @param volumePerLiquidity The gmean(volumes)/liquidity at the time of the new timepoint /// @return indexUpdated The new index of the most recently written element in the dataStorage array function write( uint16 index, uint32 blockTimestamp, int24 tick, uint128 liquidity, uint128 volumePerLiquidity ) external returns (uint16 indexUpdated); /// @notice Changes fee configuration for the pool function changeFeeConfiguration(AdaptiveFee.Configuration calldata feeConfig) external; /// @notice Calculates gmean(volume/liquidity) for block /// @param liquidity The current in-range pool liquidity /// @param amount0 Total amount of swapped token0 /// @param amount1 Total amount of swapped token1 /// @return volumePerLiquidity gmean(volume/liquidity) capped by 100000 << 64 function calculateVolumePerLiquidity( uint128 liquidity, int256 amount0, int256 amount1 ) external pure returns (uint128 volumePerLiquidity); /// @return windowLength Length of window used to calculate averages function window() external view returns (uint32 windowLength); /// @notice Calculates fee based on combination of sigmoids /// @param time The current block.timestamp /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return fee The fee in hundredths of a bip, i.e. 1e-6 function getFee( uint32 time, int24 tick, uint16 index, uint128 liquidity ) external view returns (uint16 fee); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.7.6; import './Constants.sol'; /// @title AdaptiveFee /// @notice Calculates fee based on combination of sigmoids library AdaptiveFee { // alpha1 + alpha2 + baseFee must be <= type(uint16).max struct Configuration { uint16 alpha1; // max value of the first sigmoid uint16 alpha2; // max value of the second sigmoid uint32 beta1; // shift along the x-axis for the first sigmoid uint32 beta2; // shift along the x-axis for the second sigmoid uint16 gamma1; // horizontal stretch factor for the first sigmoid uint16 gamma2; // horizontal stretch factor for the second sigmoid uint32 volumeBeta; // shift along the x-axis for the outer volume-sigmoid uint16 volumeGamma; // horizontal stretch factor the outer volume-sigmoid uint16 baseFee; // minimum possible fee } /// @notice Calculates fee based on formula: /// baseFee + sigmoidVolume(sigmoid1(volatility, volumePerLiquidity) + sigmoid2(volatility, volumePerLiquidity)) /// maximum value capped by baseFee + alpha1 + alpha2 function getFee( uint88 volatility, uint256 volumePerLiquidity, Configuration memory config ) internal pure returns (uint16 fee) { uint256 sumOfSigmoids = sigmoid(volatility, config.gamma1, config.alpha1, config.beta1) + sigmoid(volatility, config.gamma2, config.alpha2, config.beta2); if (sumOfSigmoids > type(uint16).max) { // should be impossible, just in case sumOfSigmoids = type(uint16).max; } return uint16(config.baseFee + sigmoid(volumePerLiquidity, config.volumeGamma, uint16(sumOfSigmoids), config.volumeBeta)); // safe since alpha1 + alpha2 + baseFee _must_ be <= type(uint16).max } /// @notice calculates α / (1 + e^( (β-x) / γ)) /// that is a sigmoid with a maximum value of α, x-shifted by β, and stretched by γ /// @dev returns uint256 for fuzzy testing. Guaranteed that the result is not greater than alpha function sigmoid( uint256 x, uint16 g, uint16 alpha, uint256 beta ) internal pure returns (uint256 res) { if (x > beta) { x = x - beta; if (x >= 6 * uint256(g)) return alpha; // so x < 19 bits uint256 g8 = uint256(g)**8; // < 128 bits (8*16) uint256 ex = exp(x, g, g8); // < 155 bits res = (alpha * ex) / (g8 + ex); // in worst case: (16 + 155 bits) / 155 bits // so res <= alpha } else { x = beta - x; if (x >= 6 * uint256(g)) return 0; // so x < 19 bits uint256 g8 = uint256(g)**8; // < 128 bits (8*16) uint256 ex = g8 + exp(x, g, g8); // < 156 bits res = (alpha * g8) / ex; // in worst case: (16 + 128 bits) / 156 bits // g8 <= ex, so res <= alpha } } /// @notice calculates e^(x/g) * g^8 in a series, since (around zero): /// e^x = 1 + x + x^2/2 + ... + x^n/n! + ... /// e^(x/g) = 1 + x/g + x^2/(2*g^2) + ... + x^(n)/(g^n * n!) + ... function exp( uint256 x, uint16 g, uint256 gHighestDegree ) internal pure returns (uint256 res) { // calculating: // g**8 + x * g**7 + (x**2 * g**6) / 2 + (x**3 * g**5) / 6 + (x**4 * g**4) / 24 + (x**5 * g**3) / 120 + (x**6 * g^2) / 720 + x**7 * g / 5040 + x**8 / 40320 // x**8 < 152 bits (19*8) and g**8 < 128 bits (8*16) // so each summand < 152 bits and res < 155 bits uint256 xLowestDegree = x; res = gHighestDegree; // g**8 gHighestDegree /= g; // g**7 res += xLowestDegree * gHighestDegree; gHighestDegree /= g; // g**6 xLowestDegree *= x; // x**2 res += (xLowestDegree * gHighestDegree) / 2; gHighestDegree /= g; // g**5 xLowestDegree *= x; // x**3 res += (xLowestDegree * gHighestDegree) / 6; gHighestDegree /= g; // g**4 xLowestDegree *= x; // x**4 res += (xLowestDegree * gHighestDegree) / 24; gHighestDegree /= g; // g**3 xLowestDegree *= x; // x**5 res += (xLowestDegree * gHighestDegree) / 120; gHighestDegree /= g; // g**2 xLowestDegree *= x; // x**6 res += (xLowestDegree * gHighestDegree) / 720; xLowestDegree *= x; // x**7 res += (xLowestDegree * g) / 5040 + (xLowestDegree * x) / (40320); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.7.6; pragma abicoder v2; import './interfaces/IAlgebraFactory.sol'; import './interfaces/IDataStorageOperator.sol'; import './libraries/DataStorage.sol'; import './libraries/Sqrt.sol'; import './libraries/AdaptiveFee.sol'; import './libraries/Constants.sol'; contract DataStorageOperator is IDataStorageOperator { uint256 constant UINT16_MODULO = 65536; uint128 constant MAX_VOLUME_PER_LIQUIDITY = 100000 << 64; // maximum meaningful ratio of volume to liquidity using DataStorage for DataStorage.Timepoint[UINT16_MODULO]; DataStorage.Timepoint[UINT16_MODULO] public override timepoints; AdaptiveFee.Configuration public feeConfig; address private immutable pool; address private immutable factory; modifier onlyPool() { require(msg.sender == pool, 'only pool can call this'); _; } constructor(address _pool) { factory = msg.sender; pool = _pool; } /// @inheritdoc IDataStorageOperator function initialize(uint32 time, int24 tick) external override onlyPool { return timepoints.initialize(time, tick); } /// @inheritdoc IDataStorageOperator function changeFeeConfiguration(AdaptiveFee.Configuration calldata _feeConfig) external override { require(msg.sender == factory || msg.sender == IAlgebraFactory(factory).owner()); require(uint256(_feeConfig.alpha1) + uint256(_feeConfig.alpha2) + uint256(_feeConfig.baseFee) <= type(uint16).max, 'Max fee exceeded'); require(_feeConfig.gamma1 != 0 && _feeConfig.gamma2 != 0 && _feeConfig.volumeGamma != 0, 'Gammas must be > 0'); feeConfig = _feeConfig; emit FeeConfiguration(_feeConfig); } /// @inheritdoc IDataStorageOperator function getSingleTimepoint( uint32 time, uint32 secondsAgo, int24 tick, uint16 index, uint128 liquidity ) external view override onlyPool returns ( int56 tickCumulative, uint160 secondsPerLiquidityCumulative, uint112 volatilityCumulative, uint256 volumePerAvgLiquidity ) { uint16 oldestIndex; // check if we have overflow in the past uint16 nextIndex = index + 1; // considering overflow if (timepoints[nextIndex].initialized) { oldestIndex = nextIndex; } DataStorage.Timepoint memory result = timepoints.getSingleTimepoint(time, secondsAgo, tick, index, oldestIndex, liquidity); (tickCumulative, secondsPerLiquidityCumulative, volatilityCumulative, volumePerAvgLiquidity) = ( result.tickCumulative, result.secondsPerLiquidityCumulative, result.volatilityCumulative, result.volumePerLiquidityCumulative ); } /// @inheritdoc IDataStorageOperator function getTimepoints( uint32 time, uint32[] memory secondsAgos, int24 tick, uint16 index, uint128 liquidity ) external view override onlyPool returns ( int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulatives, uint112[] memory volatilityCumulatives, uint256[] memory volumePerAvgLiquiditys ) { return timepoints.getTimepoints(time, secondsAgos, tick, index, liquidity); } /// @inheritdoc IDataStorageOperator function getAverages( uint32 time, int24 tick, uint16 index, uint128 liquidity ) external view override onlyPool returns (uint112 TWVolatilityAverage, uint256 TWVolumePerLiqAverage) { return timepoints.getAverages(time, tick, index, liquidity); } /// @inheritdoc IDataStorageOperator function write( uint16 index, uint32 blockTimestamp, int24 tick, uint128 liquidity, uint128 volumePerLiquidity ) external override onlyPool returns (uint16 indexUpdated) { return timepoints.write(index, blockTimestamp, tick, liquidity, volumePerLiquidity); } /// @inheritdoc IDataStorageOperator function calculateVolumePerLiquidity( uint128 liquidity, int256 amount0, int256 amount1 ) external pure override returns (uint128 volumePerLiquidity) { uint256 volume = Sqrt.sqrtAbs(amount0) * Sqrt.sqrtAbs(amount1); uint256 volumeShifted; if (volume >= 2**192) volumeShifted = (type(uint256).max) / (liquidity > 0 ? liquidity : 1); else volumeShifted = (volume << 64) / (liquidity > 0 ? liquidity : 1); if (volumeShifted >= MAX_VOLUME_PER_LIQUIDITY) return MAX_VOLUME_PER_LIQUIDITY; else return uint128(volumeShifted); } /// @inheritdoc IDataStorageOperator function window() external pure override returns (uint32) { return DataStorage.WINDOW; } /// @inheritdoc IDataStorageOperator function getFee( uint32 _time, int24 _tick, uint16 _index, uint128 _liquidity ) external view override onlyPool returns (uint16 fee) { (uint88 volatilityAverage, uint256 volumePerLiqAverage) = timepoints.getAverages(_time, _tick, _index, _liquidity); return AdaptiveFee.getFee(volatilityAverage / 15, volumePerLiqAverage, feeConfig); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; library Constants { uint8 internal constant RESOLUTION = 96; uint256 internal constant Q96 = 0x1000000000000000000000000; uint256 internal constant Q128 = 0x100000000000000000000000000000000; // fee value in hundredths of a bip, i.e. 1e-6 uint16 internal constant BASE_FEE = 100; int24 internal constant TICK_SPACING = 60; // max(uint128) / ( (MAX_TICK - MIN_TICK) / TICK_SPACING ) uint128 internal constant MAX_LIQUIDITY_PER_TICK = 11505743598341114571880798222544994; uint32 internal constant MAX_LIQUIDITY_COOLDOWN = 1 days; uint8 internal constant MAX_COMMUNITY_FEE = 250; uint256 internal constant COMMUNITY_FEE_DENOMINATOR = 1000; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.7.6; import './FullMath.sol'; /// @title DataStorage /// @notice Provides price, liquidity, volatility data useful for a wide variety of system designs /// @dev Instances of stored dataStorage data, "timepoints", are collected in the dataStorage array /// Timepoints are overwritten when the full length of the dataStorage array is populated. /// The most recent timepoint is available by passing 0 to getSingleTimepoint() library DataStorage { uint32 public constant WINDOW = 1 days; uint256 private constant UINT16_MODULO = 65536; struct Timepoint { bool initialized; // whether or not the timepoint is initialized uint32 blockTimestamp; // the block timestamp of the timepoint int56 tickCumulative; // the tick accumulator, i.e. tick * time elapsed since the pool was first initialized uint160 secondsPerLiquidityCumulative; // the seconds per liquidity since the pool was first initialized uint88 volatilityCumulative; // the volatility accumulator; overflow after ~34800 years is desired :) int24 averageTick; // average tick at this blockTimestamp uint144 volumePerLiquidityCumulative; // the gmean(volumes)/liquidity accumulator } /// @notice Calculates volatility between two sequential timepoints with resampling to 1 sec frequency /// @param dt Timedelta between timepoints, must be within uint32 range /// @param tick0 The tick at the left timepoint, must be within int24 range /// @param tick1 The tick at the right timepoint, must be within int24 range /// @param avgTick0 The average tick at the left timepoint, must be within int24 range /// @param avgTick1 The average tick at the right timepoint, must be within int24 range /// @return volatility The volatility between two sequential timepoints /// If the requirements for the parameters are met, it always fits 88 bits function _volatilityOnRange( int256 dt, int256 tick0, int256 tick1, int256 avgTick0, int256 avgTick1 ) internal pure returns (uint256 volatility) { // On the time interval from the previous timepoint to the current // we can represent tick and average tick change as two straight lines: // tick = k*t + b, where k and b are some constants // avgTick = p*t + q, where p and q are some constants // we want to get sum of (tick(t) - avgTick(t))^2 for every t in the interval (0; dt] // so: (tick(t) - avgTick(t))^2 = ((k*t + b) - (p*t + q))^2 = (k-p)^2 * t^2 + 2(k-p)(b-q)t + (b-q)^2 // since everything except t is a constant, we need to use progressions for t and t^2: // sum(t) for t from 1 to dt = dt*(dt + 1)/2 = sumOfSequence // sum(t^2) for t from 1 to dt = dt*(dt+1)*(2dt + 1)/6 = sumOfSquares // so result will be: (k-p)^2 * sumOfSquares + 2(k-p)(b-q)*sumOfSequence + dt*(b-q)^2 int256 K = (tick1 - tick0) - (avgTick1 - avgTick0); // (k - p)*dt int256 B = (tick0 - avgTick0) * dt; // (b - q)*dt int256 sumOfSquares = (dt * (dt + 1) * (2 * dt + 1)); // sumOfSquares * 6 int256 sumOfSequence = (dt * (dt + 1)); // sumOfSequence * 2 volatility = uint256((K**2 * sumOfSquares + 6 * B * K * sumOfSequence + 6 * dt * B**2) / (6 * dt**2)); } /// @notice Transforms a previous timepoint into a new timepoint, given the passage of time and the current tick and liquidity values /// @dev blockTimestamp _must_ be chronologically equal to or greater than last.blockTimestamp, safe for 0 or 1 overflows /// @param last The specified timepoint to be used in creation of new timepoint /// @param blockTimestamp The timestamp of the new timepoint /// @param tick The active tick at the time of the new timepoint /// @param prevTick The active tick at the time of the last timepoint /// @param liquidity The total in-range liquidity at the time of the new timepoint /// @param averageTick The average tick at the time of the new timepoint /// @param volumePerLiquidity The gmean(volumes)/liquidity at the time of the new timepoint /// @return Timepoint The newly populated timepoint function createNewTimepoint( Timepoint memory last, uint32 blockTimestamp, int24 tick, int24 prevTick, uint128 liquidity, int24 averageTick, uint128 volumePerLiquidity ) private pure returns (Timepoint memory) { uint32 delta = blockTimestamp - last.blockTimestamp; last.initialized = true; last.blockTimestamp = blockTimestamp; last.tickCumulative += int56(tick) * delta; last.secondsPerLiquidityCumulative += ((uint160(delta) << 128) / (liquidity > 0 ? liquidity : 1)); // just timedelta if liquidity == 0 last.volatilityCumulative += uint88(_volatilityOnRange(delta, prevTick, tick, last.averageTick, averageTick)); // always fits 88 bits last.averageTick = averageTick; last.volumePerLiquidityCumulative += volumePerLiquidity; return last; } /// @notice comparator for 32-bit timestamps /// @dev safe for 0 or 1 overflows, a and b _must_ be chronologically before or equal to currentTime /// @param a A comparison timestamp from which to determine the relative position of `currentTime` /// @param b From which to determine the relative position of `currentTime` /// @param currentTime A timestamp truncated to 32 bits /// @return res Whether `a` is chronologically <= `b` function lteConsideringOverflow( uint32 a, uint32 b, uint32 currentTime ) private pure returns (bool res) { res = a > currentTime; if (res == b > currentTime) res = a <= b; // if both are on the same side } /// @dev guaranteed that the result is within the bounds of int24 /// returns int256 for fuzzy tests function _getAverageTick( Timepoint[UINT16_MODULO] storage self, uint32 time, int24 tick, uint16 index, uint16 oldestIndex, uint32 lastTimestamp, int56 lastTickCumulative ) internal view returns (int256 avgTick) { uint32 oldestTimestamp = self[oldestIndex].blockTimestamp; int56 oldestTickCumulative = self[oldestIndex].tickCumulative; if (lteConsideringOverflow(oldestTimestamp, time - WINDOW, time)) { if (lteConsideringOverflow(lastTimestamp, time - WINDOW, time)) { index -= 1; // considering underflow Timepoint storage startTimepoint = self[index]; avgTick = startTimepoint.initialized ? (lastTickCumulative - startTimepoint.tickCumulative) / (lastTimestamp - startTimepoint.blockTimestamp) : tick; } else { Timepoint memory startOfWindow = getSingleTimepoint(self, time, WINDOW, tick, index, oldestIndex, 0); // current-WINDOW last current // _________*____________*_______*_ // |||||||||||| avgTick = (lastTickCumulative - startOfWindow.tickCumulative) / (lastTimestamp - time + WINDOW); } } else { avgTick = (lastTimestamp == oldestTimestamp) ? tick : (lastTickCumulative - oldestTickCumulative) / (lastTimestamp - oldestTimestamp); } } /// @notice Fetches the timepoints beforeOrAt and atOrAfter a target, i.e. where [beforeOrAt, atOrAfter] is satisfied. /// The result may be the same timepoint, or adjacent timepoints. /// @dev The answer must be contained in the array, used when the target is located within the stored timepoint /// boundaries: older than the most recent timepoint and younger, or the same age as, the oldest timepoint /// @param self The stored dataStorage array /// @param time The current block.timestamp /// @param target The timestamp at which the reserved timepoint should be for /// @param lastIndex The index of the timepoint that was most recently written to the timepoints array /// @param oldestIndex The index of the oldest timepoint in the timepoints array /// @return beforeOrAt The timepoint recorded before, or at, the target /// @return atOrAfter The timepoint recorded at, or after, the target function binarySearch( Timepoint[UINT16_MODULO] storage self, uint32 time, uint32 target, uint16 lastIndex, uint16 oldestIndex ) private view returns (Timepoint storage beforeOrAt, Timepoint storage atOrAfter) { uint256 left = oldestIndex; // oldest timepoint uint256 right = lastIndex >= oldestIndex ? lastIndex : lastIndex + UINT16_MODULO; // newest timepoint considering one index overflow uint256 current = (left + right) >> 1; // "middle" point between the boundaries do { beforeOrAt = self[uint16(current)]; // checking the "middle" point between the boundaries (bool initializedBefore, uint32 timestampBefore) = (beforeOrAt.initialized, beforeOrAt.blockTimestamp); if (initializedBefore) { if (lteConsideringOverflow(timestampBefore, target, time)) { // is current point before or at `target`? atOrAfter = self[uint16(current + 1)]; // checking the next point after "middle" (bool initializedAfter, uint32 timestampAfter) = (atOrAfter.initialized, atOrAfter.blockTimestamp); if (initializedAfter) { if (lteConsideringOverflow(target, timestampAfter, time)) { // is the "next" point after or at `target`? return (beforeOrAt, atOrAfter); // the only fully correct way to finish } left = current + 1; // "next" point is before the `target`, so looking in the right half } else { // beforeOrAt is initialized and <= target, and next timepoint is uninitialized // should be impossible if initial boundaries and `target` are correct return (beforeOrAt, beforeOrAt); } } else { right = current - 1; // current point is after the `target`, so looking in the left half } } else { // we've landed on an uninitialized timepoint, keep searching higher // should be impossible if initial boundaries and `target` are correct left = current + 1; } current = (left + right) >> 1; // calculating the new "middle" point index after updating the bounds } while (true); atOrAfter = beforeOrAt; // code is unreachable, to suppress compiler warning assert(false); } /// @dev Reverts if an timepoint at or before the desired timepoint timestamp does not exist. /// 0 may be passed as `secondsAgo' to return the current cumulative values. /// If called with a timestamp falling between two timepoints, returns the counterfactual accumulator values /// at exactly the timestamp between the two timepoints. /// @param self The stored dataStorage array /// @param time The current block timestamp /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an timepoint /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param oldestIndex The index of the oldest timepoint /// @param liquidity The current in-range pool liquidity /// @return targetTimepoint desired timepoint or it's approximation function getSingleTimepoint( Timepoint[UINT16_MODULO] storage self, uint32 time, uint32 secondsAgo, int24 tick, uint16 index, uint16 oldestIndex, uint128 liquidity ) internal view returns (Timepoint memory targetTimepoint) { uint32 target = time - secondsAgo; // if target is newer than last timepoint if (secondsAgo == 0 || lteConsideringOverflow(self[index].blockTimestamp, target, time)) { Timepoint memory last = self[index]; if (last.blockTimestamp == target) { return last; } else { // otherwise, we need to add new timepoint int24 avgTick = int24(_getAverageTick(self, time, tick, index, oldestIndex, last.blockTimestamp, last.tickCumulative)); int24 prevTick = tick; { if (index != oldestIndex) { Timepoint memory prevLast; Timepoint storage _prevLast = self[index - 1]; // considering index underflow prevLast.blockTimestamp = _prevLast.blockTimestamp; prevLast.tickCumulative = _prevLast.tickCumulative; prevTick = int24((last.tickCumulative - prevLast.tickCumulative) / (last.blockTimestamp - prevLast.blockTimestamp)); } } return createNewTimepoint(last, target, tick, prevTick, liquidity, avgTick, 0); } } require(lteConsideringOverflow(self[oldestIndex].blockTimestamp, target, time), 'OLD'); (Timepoint memory beforeOrAt, Timepoint memory atOrAfter) = binarySearch(self, time, target, index, oldestIndex); if (target == atOrAfter.blockTimestamp) { return atOrAfter; // we're at the right boundary } if (target != beforeOrAt.blockTimestamp) { // we're in the middle uint32 timepointTimeDelta = atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp; uint32 targetDelta = target - beforeOrAt.blockTimestamp; // For gas savings the resulting point is written to beforeAt beforeOrAt.tickCumulative += ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) / timepointTimeDelta) * targetDelta; beforeOrAt.secondsPerLiquidityCumulative += uint160( (uint256(atOrAfter.secondsPerLiquidityCumulative - beforeOrAt.secondsPerLiquidityCumulative) * targetDelta) / timepointTimeDelta ); beforeOrAt.volatilityCumulative += ((atOrAfter.volatilityCumulative - beforeOrAt.volatilityCumulative) / timepointTimeDelta) * targetDelta; beforeOrAt.volumePerLiquidityCumulative += ((atOrAfter.volumePerLiquidityCumulative - beforeOrAt.volumePerLiquidityCumulative) / timepointTimeDelta) * targetDelta; } // we're at the left boundary or at the middle return beforeOrAt; } /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos` /// @dev Reverts if `secondsAgos` > oldest timepoint /// @param self The stored dataStorage array /// @param time The current block.timestamp /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an timepoint /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return tickCumulatives The tick * time elapsed since the pool was first initialized, as of each `secondsAgo` /// @return secondsPerLiquidityCumulatives The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo` /// @return volatilityCumulatives The cumulative volatility values since the pool was first initialized, as of each `secondsAgo` /// @return volumePerAvgLiquiditys The cumulative volume per liquidity values since the pool was first initialized, as of each `secondsAgo` function getTimepoints( Timepoint[UINT16_MODULO] storage self, uint32 time, uint32[] memory secondsAgos, int24 tick, uint16 index, uint128 liquidity ) internal view returns ( int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulatives, uint112[] memory volatilityCumulatives, uint256[] memory volumePerAvgLiquiditys ) { tickCumulatives = new int56[](secondsAgos.length); secondsPerLiquidityCumulatives = new uint160[](secondsAgos.length); volatilityCumulatives = new uint112[](secondsAgos.length); volumePerAvgLiquiditys = new uint256[](secondsAgos.length); uint16 oldestIndex; // check if we have overflow in the past uint16 nextIndex = index + 1; // considering overflow if (self[nextIndex].initialized) { oldestIndex = nextIndex; } Timepoint memory current; for (uint256 i = 0; i < secondsAgos.length; i++) { current = getSingleTimepoint(self, time, secondsAgos[i], tick, index, oldestIndex, liquidity); (tickCumulatives[i], secondsPerLiquidityCumulatives[i], volatilityCumulatives[i], volumePerAvgLiquiditys[i]) = ( current.tickCumulative, current.secondsPerLiquidityCumulative, current.volatilityCumulative, current.volumePerLiquidityCumulative ); } } /// @notice Returns average volatility in the range from time-WINDOW to time /// @param self The stored dataStorage array /// @param time The current block.timestamp /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return volatilityAverage The average volatility in the recent range /// @return volumePerLiqAverage The average volume per liquidity in the recent range function getAverages( Timepoint[UINT16_MODULO] storage self, uint32 time, int24 tick, uint16 index, uint128 liquidity ) internal view returns (uint88 volatilityAverage, uint256 volumePerLiqAverage) { uint16 oldestIndex; Timepoint storage oldest = self[0]; uint16 nextIndex = index + 1; // considering overflow if (self[nextIndex].initialized) { oldest = self[nextIndex]; oldestIndex = nextIndex; } Timepoint memory endOfWindow = getSingleTimepoint(self, time, 0, tick, index, oldestIndex, liquidity); uint32 oldestTimestamp = oldest.blockTimestamp; if (lteConsideringOverflow(oldestTimestamp, time - WINDOW, time)) { Timepoint memory startOfWindow = getSingleTimepoint(self, time, WINDOW, tick, index, oldestIndex, liquidity); return ( (endOfWindow.volatilityCumulative - startOfWindow.volatilityCumulative) / WINDOW, uint256(endOfWindow.volumePerLiquidityCumulative - startOfWindow.volumePerLiquidityCumulative) >> 57 ); } else if (time != oldestTimestamp) { uint88 _oldestVolatilityCumulative = oldest.volatilityCumulative; uint144 _oldestVolumePerLiquidityCumulative = oldest.volumePerLiquidityCumulative; return ( (endOfWindow.volatilityCumulative - _oldestVolatilityCumulative) / (time - oldestTimestamp), uint256(endOfWindow.volumePerLiquidityCumulative - _oldestVolumePerLiquidityCumulative) >> 57 ); } } /// @notice Initialize the dataStorage array by writing the first slot. Called once for the lifecycle of the timepoints array /// @param self The stored dataStorage array /// @param time The time of the dataStorage initialization, via block.timestamp truncated to uint32 /// @param tick Initial tick function initialize( Timepoint[UINT16_MODULO] storage self, uint32 time, int24 tick ) internal { require(!self[0].initialized); self[0].initialized = true; self[0].blockTimestamp = time; self[0].averageTick = tick; } /// @notice Writes an dataStorage timepoint to the array /// @dev Writable at most once per block. Index represents the most recently written element. index must be tracked externally. /// @param self The stored dataStorage array /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param blockTimestamp The timestamp of the new timepoint /// @param tick The active tick at the time of the new timepoint /// @param liquidity The total in-range liquidity at the time of the new timepoint /// @param volumePerLiquidity The gmean(volumes)/liquidity at the time of the new timepoint /// @return indexUpdated The new index of the most recently written element in the dataStorage array function write( Timepoint[UINT16_MODULO] storage self, uint16 index, uint32 blockTimestamp, int24 tick, uint128 liquidity, uint128 volumePerLiquidity ) internal returns (uint16 indexUpdated) { Timepoint storage _last = self[index]; // early return if we've already written an timepoint this block if (_last.blockTimestamp == blockTimestamp) { return index; } Timepoint memory last = _last; // get next index considering overflow indexUpdated = index + 1; uint16 oldestIndex; // check if we have overflow in the past if (self[indexUpdated].initialized) { oldestIndex = indexUpdated; } int24 avgTick = int24(_getAverageTick(self, blockTimestamp, tick, index, oldestIndex, last.blockTimestamp, last.tickCumulative)); int24 prevTick = tick; if (index != oldestIndex) { Timepoint storage _prevLast = self[index - 1]; // considering index underflow uint32 _prevLastBlockTimestamp = _prevLast.blockTimestamp; int56 _prevLastTickCumulative = _prevLast.tickCumulative; prevTick = int24((last.tickCumulative - _prevLastTickCumulative) / (last.blockTimestamp - _prevLastBlockTimestamp)); } self[indexUpdated] = createNewTimepoint(last, blockTimestamp, tick, prevTick, liquidity, avgTick, volumePerLiquidity); } }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.5.0 || ^0.6.0 || ^0.7.0 || ^0.8.0; library Sqrt { /// @notice Gets the square root of the absolute value of the parameter function sqrtAbs(int256 _x) internal pure returns (uint256 result) { // get abs value int256 mask = _x >> (256 - 1); uint256 x = uint256((_x ^ mask) - mask); if (x == 0) result = 0; else { uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // @dev Seven iterations should be enough. uint256 r1 = x / r; result = r < r1 ? r : r1; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0; /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDiv( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then use the Chinese Remainder Theorem to reconstruct // the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2**256 + prod0 uint256 prod0 = a * b; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(a, b, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1); // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { assembly { result := div(prod0, denominator) } return result; } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0] // Compute remainder using mulmod // Subtract 256 bit remainder from 512 bit number assembly { let remainder := mulmod(a, b, denominator) prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. uint256 twos = -denominator & denominator; // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } prod0 |= prod1 * twos; // Invert denominator mod 2**256 // Now that denominator is an odd number, it has an inverse // modulo 2**256 such that denominator * inv = 1 mod 2**256. // Compute the inverse by starting with a seed that is correct // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use Newton-Raphson iteration to improve the precision. // Thanks to Hensel's lifting lemma, this also works in modular // arithmetic, doubling the correct bits in each step. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // inverse mod 2**256 // Because the division is now exact we can divide by multiplying // with the modular inverse of denominator. This will give us the // correct result modulo 2**256. Since the preconditions guarantee // that the outcome is less than 2**256, this is the final result. // We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inv; return result; } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { if (a == 0 || ((result = a * b) / a == b)) { require(denominator > 0); assembly { result := add(div(result, denominator), gt(mod(result, denominator), 0)) } } else { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } } /// @notice Returns ceil(x / y) /// @dev division by 0 has unspecified behavior, and must be checked externally /// @param x The dividend /// @param y The divisor /// @return z The quotient, ceil(x / y) function divRoundingUp(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { z := add(div(x, y), gt(mod(x, y), 0)) } } }
{ "optimizer": { "enabled": true, "runs": 0 }, "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_poolDeployer","type":"address"},{"internalType":"address","name":"_vaultAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newFarmingAddress","type":"address"}],"name":"FarmingAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"alpha1","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"alpha2","type":"uint16"},{"indexed":false,"internalType":"uint32","name":"beta1","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"beta2","type":"uint32"},{"indexed":false,"internalType":"uint16","name":"gamma1","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"gamma2","type":"uint16"},{"indexed":false,"internalType":"uint32","name":"volumeBeta","type":"uint32"},{"indexed":false,"internalType":"uint16","name":"volumeGamma","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"baseFee","type":"uint16"}],"name":"FeeConfiguration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"Owner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"Pool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newVaultAddress","type":"address"}],"name":"VaultAddress","type":"event"},{"inputs":[],"name":"baseFeeConfiguration","outputs":[{"internalType":"uint16","name":"alpha1","type":"uint16"},{"internalType":"uint16","name":"alpha2","type":"uint16"},{"internalType":"uint32","name":"beta1","type":"uint32"},{"internalType":"uint32","name":"beta2","type":"uint32"},{"internalType":"uint16","name":"gamma1","type":"uint16"},{"internalType":"uint16","name":"gamma2","type":"uint16"},{"internalType":"uint32","name":"volumeBeta","type":"uint32"},{"internalType":"uint16","name":"volumeGamma","type":"uint16"},{"internalType":"uint16","name":"baseFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"createPool","outputs":[{"internalType":"address","name":"pool","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"farmingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"poolByPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolDeployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"alpha1","type":"uint16"},{"internalType":"uint16","name":"alpha2","type":"uint16"},{"internalType":"uint32","name":"beta1","type":"uint32"},{"internalType":"uint32","name":"beta2","type":"uint32"},{"internalType":"uint16","name":"gamma1","type":"uint16"},{"internalType":"uint16","name":"gamma2","type":"uint16"},{"internalType":"uint32","name":"volumeBeta","type":"uint32"},{"internalType":"uint16","name":"volumeGamma","type":"uint16"},{"internalType":"uint16","name":"baseFee","type":"uint16"}],"name":"setBaseFeeConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_farmingAddress","type":"address"}],"name":"setFarmingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vaultAddress","type":"address"}],"name":"setVaultAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101c0604052610b5460a0819052612ee060c05261016860e05261ea6061010052603b6101205261213461014052600061016052600a6101805260646101a0526003805461ffff191690911763ffff00001916632ee000001763ffffffff60201b1916650168000000001763ffffffff60401b191669ea6000000000000000001761ffff60601b19166c3b0000000000000000000000001761ffff60701b191661084d60721b1765ffffffffffff60801b1916600560a11b1761ffff60b01b1916601960b21b1790553480156100d457600080fd5b506040516135863803806135868339810160408190526100f391610182565b600080546001600160a01b03191633908117825560405190917fa5e220c2c27d986cc8efeafa8f34ba6ea6bf96a34e146b29b6bdd8587771b13091a260609190911b6001600160601b031916608052600280546001600160a01b0319166001600160a01b039092169190911790556101b4565b80516001600160a01b038116811461017d57600080fd5b919050565b60008060408385031215610194578182fd5b61019d83610166565b91506101ab60208401610166565b90509250929050565b60805160601c6133ab6101db600039806101ef52806107b152806108e152506133ab6000f3fe608060405234801561001057600080fd5b50600436106100995760003560e01c806313af40351461009e5780633119049a146100b3578063430bf08a146100d15780635d6d7e93146100d957806385535cc5146100ec5780638a2ade58146100ff5780638da5cb5b146101075780639832853a1461010f578063b001f6181461012c578063d9a641e11461013f578063e343361514610152575b600080fd5b6100b16100ac3660046109b2565b610165565b005b6100bb6101ed565b6040516100c89190610b15565b60405180910390f35b6100bb610211565b6100b16100e7366004610a29565b610220565b6100b16100fa3660046109b2565b6104b6565b6100bb61053e565b6100bb61054d565b61011761055c565b6040516100c899989796959493929190610c7a565b6100b161013a3660046109b2565b6105bc565b6100bb61014d3660046109f1565b610644565b6100bb6101603660046109f1565b61066a565b6000546001600160a01b0316331461017c57600080fd5b6000546001600160a01b038281169116141561019757600080fd5b6040516001600160a01b038216907fa5e220c2c27d986cc8efeafa8f34ba6ea6bf96a34e146b29b6bdd8587771b13090600090a2600080546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000081565b6002546001600160a01b031681565b6000546001600160a01b0316331461023757600080fd5b61ffff8981168982160182821601111561026c5760405162461bcd60e51b815260040161026390610b9a565b60405180910390fd5b61ffff851615801590610282575061ffff841615155b8015610291575061ffff821615155b6102ad5760405162461bcd60e51b815260040161026390610b6e565b6040518061012001604052808a61ffff1681526020018961ffff1681526020018863ffffffff1681526020018763ffffffff1681526020018661ffff1681526020018561ffff1681526020018463ffffffff1681526020018361ffff1681526020018261ffff16815250600360008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a81548161ffff021916908361ffff16021790555060408201518160000160046101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160086101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548161ffff021916908361ffff16021790555060c08201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160146101000a81548161ffff021916908361ffff1602179055506101008201518160000160166101000a81548161ffff021916908361ffff1602179055509050507f4035ab409f15e202f9f114632e1fb14a0552325955722be18503403e7f98730c8989898989898989896040516104a399989796959493929190610c7a565b60405180910390a1505050505050505050565b6000546001600160a01b031633146104cd57600080fd5b6002546001600160a01b03828116911614156104e857600080fd5b6040516001600160a01b038216907fb9c265ae4414f501736ec5d4961edc3309e4385eb2ff3feeecb30fb36621dd8390600090a2600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031681565b6000546001600160a01b031681565b60035461ffff8082169162010000810482169163ffffffff600160201b8304811692600160401b8104821692600160601b8204811692600160701b8304821692600160801b810490911691600160a01b8204811691600160b01b90041689565b6000546001600160a01b031633146105d357600080fd5b6001546001600160a01b03828116911614156105ee57600080fd5b6040516001600160a01b038216907f56b9e8342f530796ceed0d5529abdcdeae6e4f2ac1dc456ceb73bbda898e0cd390600090a2600180546001600160a01b0319166001600160a01b0392909216919091179055565b60046020908152600092835260408084209091529082529020546001600160a01b031681565b6000816001600160a01b0316836001600160a01b0316141561068b57600080fd5b600080836001600160a01b0316856001600160a01b0316106106ae5783856106b1565b84845b90925090506001600160a01b0382166106c957600080fd5b6001600160a01b038281166000908152600460209081526040808320858516845290915290205416156106fb57600080fd5b600061070783836108dd565b6040516107139061097a565b61071d9190610b15565b604051809103906000f080158015610739573d6000803e3d6000fd5b50604051631c7004cb60e01b81529091506001600160a01b03821690631c7004cb9061076a90600390600401610bc4565b600060405180830381600087803b15801561078457600080fd5b505af1158015610798573d6000803e3d6000fd5b5050604051637ec15b9d60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016925063fd82b73a91506107ee908490309088908890600401610b43565b602060405180830381600087803b15801561080857600080fd5b505af115801561081c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084091906109d5565b6001600160a01b03808516600081815260046020818152604080842089871680865290835281852080549789166001600160a01b031998891681179091559383528185208686529092529283902080549095169091179093555192965090917f91ccaa7a278130b65168c3a0c8d3bcae84cf5e43704342bd3ec0b59e59c036db906108cc908890610b15565b60405180910390a350505092915050565b60007f00000000000000000000000000000000000000000000000000000000000000008383604051602001610913929190610b29565b60408051601f1981840301815290829052805160209182012061095b939290917f6ec6c9c8091d160c0aa74b2b14ba9c1717e95093bd3ac085cee99a49aab294a49101610ae2565b60408051601f1981840301815291905280516020909101209392505050565b6126b780610ce883390190565b803561ffff8116811461099957600080fd5b919050565b803563ffffffff8116811461099957600080fd5b6000602082840312156109c3578081fd5b81356109ce81610ccf565b9392505050565b6000602082840312156109e6578081fd5b81516109ce81610ccf565b60008060408385031215610a03578081fd5b8235610a0e81610ccf565b91506020830135610a1e81610ccf565b809150509250929050565b60008060008060008060008060006101208a8c031215610a47578485fd5b610a508a610987565b9850610a5e60208b01610987565b9750610a6c60408b0161099e565b9650610a7a60608b0161099e565b9550610a8860808b01610987565b9450610a9660a08b01610987565b9350610aa460c08b0161099e565b9250610ab260e08b01610987565b9150610ac16101008b01610987565b90509295985092959850929598565b61ffff169052565b63ffffffff169052565b6001600160f81b0319815260609390931b6001600160601b03191660018401526015830191909152603582015260550190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b602080825260129082015271047616d6d6173206d757374206265203e20360741b604082015260600190565b60208082526010908201526f13585e0819995948195e18d95959195960821b604082015260600190565b815461012082019061ffff610bdb84828416610ad0565b610bed60208501828460101c16610ad0565b63ffffffff610c0460408601828560201c16610ad8565b610c1660608601828560401c16610ad8565b610c2860808601838560601c16610ad0565b610c3a60a08601838560701c16610ad0565b610c4c60c08601828560801c16610ad8565b50610c5f60e08501828460a01c16610ad0565b610c726101008501828460b01c16610ad0565b505092915050565b61ffff998a168152978916602089015263ffffffff96871660408901529486166060880152928716608087015290861660a086015290921660c084015290831660e08301529091166101008201526101200190565b6001600160a01b0381168114610ce457600080fd5b5056fe60c06040523480156200001157600080fd5b50604051620026b7380380620026b7833981016040819052620000349162000051565b33606090811b60a0521b6001600160601b03191660805262000081565b60006020828403121562000063578081fd5b81516001600160a01b03811681146200007a578182fd5b9392505050565b60805160601c60a05160601c6125ee620000c9600039806102ba52806102e35250806101f152806104b65280610638528061070c528061077c528061089c52506125ee6000f3fe608060405234801561001057600080fd5b50600436106100995760003560e01c806314c540791461009e5780631c7004cb146100ca5780631dd486f2146100df5780631e5eb1d0146100ff57806336e52fee1461011c578063461645bf1461013c578063475fb80c1461015157806374eceae614610164578063bc2e01811461018a578063c53a182f146101ab578063fd31e988146101be575b600080fd5b6100b16100ac366004611fc8565b6101e1565b6040516100c19493929190612198565b60405180910390f35b6100dd6100d8366004611d76565b6102af565b005b6100f26100ed366004611ddc565b6104a9565b6040516100c1919061236c565b61010761050c565b6040516100c19998979695949392919061237b565b61012f61012a366004611d8e565b61056e565b6040516100c19190612358565b610144610626565b6040516100c191906123d0565b6100dd61015f366004611f3d565b61062d565b610177610172366004611e44565b610685565b6040516100c1979695949392919061213f565b61019d610198366004611f71565b6106fe565b6040516100c192919061233f565b6100f26101b9366004611f71565b61076f565b6101d16101cc366004611e5c565b61088c565b6040516100c1949392919061209c565b6000808080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102375760405162461bcd60e51b815260040161022e906121f6565b60405180910390fd5b6000600187018161ffff821662010000811061024f57fe5b600202015460ff1615610260578091505b6000610271818d8d8d8d888e6108fb565b60408101516060820151608083015160c090930151919f909e506001600160581b039092169c506001600160901b03169a5098505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061038757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561033a57600080fd5b505afa15801561034e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103729190611d4f565b6001600160a01b0316336001600160a01b0316145b61039057600080fd5b61ffff6103a561012083016101008401611dc0565b61ffff166103b96040840160208501611dc0565b61ffff166103ca6020850185611dc0565b61ffff16010111156103ee5760405162461bcd60e51b815260040161022e90612227565b6103fe60a0820160808301611dc0565b61ffff1615801590610422575061041b60c0820160a08301611dc0565b61ffff1615155b8015610441575061043a610100820160e08301611dc0565b61ffff1615155b61045d5760405162461bcd60e51b815260040161022e906121ca565b806202000061046c8282612401565b9050507f86821edb04a8df5bac675c23c1eb986257da59363579c86d977a66fa59896b9d8160405161049e9190612251565b60405180910390a150565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104f35760405162461bcd60e51b815260040161022e906121f6565b61050260008787878787610eca565b9695505050505050565b620200005461ffff8082169162010000810482169163ffffffff600160201b8304811692600160401b8104821692600160601b8204811692600160701b8304821692600160801b810490911691600160a01b8204811691600160b01b90041689565b60008061057a83611178565b61058385611178565b0290506000600160c01b82106105c8576000866001600160801b0316116105ab5760016105ad565b855b6001600160801b0316600019816105c057fe5b0490506105fb565b6000866001600160801b0316116105e05760016105e2565b855b6001600160801b0316604083901b816105f757fe5b0490505b610c3560451b811061061657610c3560451b9250505061061f565b915061061f9050565b9392505050565b6201518090565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106755760405162461bcd60e51b815260040161022e906121f6565b610681600083836112c8565b5050565b60008162010000811061069757600080fd5b600290810291909101805460019091015460ff82169350610100820463ffffffff1692600160281b830460060b92600160601b90046001600160a01b0316916001600160581b03811691600160581b8204900b90600160701b90046001600160901b031687565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107495760405162461bcd60e51b815260040161022e906121f6565b610757600087878787611327565b6001600160581b039091169250905094509492505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107b95760405162461bcd60e51b815260040161022e906121f6565b6000806107c98188888888611327565b9150915061087f600f836001600160581b0316816107e357fe5b6040805161012081018252620200005461ffff80821683526201000082048116602084015263ffffffff600160201b8304811694840194909452600160401b820484166060840152600160601b820481166080840152600160701b8204811660a0840152600160801b820490931660c0830152600160a01b8104831660e0830152600160b01b90049091166101008201529190049083906114a6565b925050505b949350505050565b6060808080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108d95760405162461bcd60e51b815260040161022e906121f6565b6108e860008a8a8a8a8a611538565b929c919b50995090975095505050505050565b610903611ccf565b85870363ffffffff871615806109405750610940898661ffff1662010000811061092957fe5b6002020154610100900463ffffffff16828a61176c565b15610ac3576000898661ffff1662010000811061095957fe5b6040805160e081018252600292830293909301805460ff811615158552610100810463ffffffff90811660208701819052600160281b8304600690810b810b900b94870194909452600160601b9091046001600160a01b031660608601526001909101546001600160581b0381166080860152600160581b8104840b840b90930b60a0850152600160701b9092046001600160901b031660c084015291925083161415610a09579150610ebf9050565b6000610a228b8b8a8a8a87602001518860400151611795565b90508761ffff88811690881614610aa857610a3b611ccf565b60008d60018b0361ffff16620100008110610a5257fe5b60020201805463ffffffff610100820481166020808701829052600160281b909304600690810b810b810b6040808901829052948b0151948b0151959650919093039091169203900b81610aa257fe5b05925050505b610ab883858b848a8760006118ff565b945050505050610ebf565b610ad8898561ffff1662010000811061092957fe5b610b0f576040805162461bcd60e51b815260206004820152600360248201526213d31160ea1b604482015290519081900360640190fd5b600080610b1f8b8b858a8a611a03565b6040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900460060b60060b60060b815260200160008201600c9054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016001820160009054906101000a90046001600160581b03166001600160581b03166001600160581b0316815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a90046001600160901b03166001600160901b03166001600160901b03168152505091506040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900460060b60060b60060b815260200160008201600c9054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016001820160009054906101000a90046001600160581b03166001600160581b03166001600160581b0316815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a90046001600160901b03166001600160901b03166001600160901b0316815250509150806020015163ffffffff168363ffffffff161415610d6b579250610ebf915050565b816020015163ffffffff168363ffffffff1614610eba5760008260200151826020015103905060008360200151850390508063ffffffff168263ffffffff16856040015185604001510360060b81610dbf57fe5b0502846040018181510191509060060b908160060b815250508163ffffffff168163ffffffff1685606001518560600151036001600160a01b03160281610e0257fe5b0484606001818151019150906001600160a01b031690816001600160a01b0316815250508063ffffffff168263ffffffff1685608001518560800151036001600160581b031681610e4f57fe5b040284608001818151019150906001600160581b031690816001600160581b0316815250508063ffffffff168263ffffffff168560c001518560c00151036001600160901b031681610e9d57fe5b60c0870180516001600160901b0393909204939093020116905250505b509150505b979650505050505050565b600080878761ffff16620100008110610edf57fe5b60020201805490915063ffffffff878116610100909204161415610f065786915050610502565b6040805160e081018252825460ff811615158252610100810463ffffffff166020830152600160281b8104600690810b810b900b92820192909252600160601b9091046001600160a01b031660608201526001808301546001600160581b0381166080840152600160581b8104600290810b810b900b60a0840152600160701b90046001600160901b031660c08301528801925060008961ffff8516620100008110610fae57fe5b600202015460ff1615610fbe5750825b6000610fd78b8a8a8d8688602001518960400151611795565b90508761ffff8b8116908416146110485760008c60018d0361ffff16620100008110610fff57fe5b6002020180546020870151604088015192935063ffffffff6101008304811693600160281b909304600690810b939285900390911691839003900b8161104157fe5b0593505050505b611057848b8b848c878d6118ff565b8c8761ffff1662010000811061106957fe5b825160029182029290920180546020850151604086015160608701516001600160a01b0316600160601b026001600160601b0360069290920b66ffffffffffffff16600160281b02600160281b600160601b031963ffffffff9094166101000264ffffffff001998151560ff1990961695909517979097169390931791909116949094179390931692909217825560808301516001909201805460a085015160c0909501516001600160901b0316600160701b026001600160701b039590930b62ffffff16600160581b0262ffffff60581b196001600160581b039095166001600160581b03199092169190911793909316929092179290921691909117905550505050509695505050505050565b600060ff82901d8083188190038061119357600092506112c1565b806001600160801b82106111ac5760809190911c9060401b5b600160401b82106111c25760409190911c9060201b5b600160201b82106111d85760209190911c9060101b5b6201000082106111ed5760109190911c9060081b5b61010082106112015760089190911c9060041b5b601082106112145760049190911c9060021b5b600882106112205760011b5b600181848161122b57fe5b048201901c9050600181848161123d57fe5b048201901c9050600181848161124f57fe5b048201901c9050600181848161126157fe5b048201901c9050600181848161127357fe5b048201901c9050600181848161128557fe5b048201901c9050600181848161129757fe5b048201901c905060008184816112a957fe5b0490508082106112b957806112bb565b815b95505050505b5050919050565b825460ff16156112d757600080fd5b825463ffffffff9290921661010002600160ff19909316831764ffffffff0019161783559101805462ffffff60581b1916600160581b62ffffff60029490940b9390931692909202919091179055565b6000808087600186018161ffff821662010000811061134257fe5b600202015460ff161561136b57898161ffff1662010000811061136157fe5b6002020191508092505b600061137d8b8b60008c8c898d6108fb565b8354909150610100900463ffffffff1661139e816201517f198d018d61176c565b156114065760006113b78d8d620151808e8e8b8f6108fb565b90506201518063ffffffff1681608001518460800151036001600160581b0316816113de57fe5b0460398260c001518560c00151036001600160901b0316901c9750975050505050505061149c565b8063ffffffff168b63ffffffff16146114965760008460010160009054906101000a90046001600160581b03169050600085600101600e9054906101000a90046001600160901b03169050828d0363ffffffff16828560800151036001600160581b03168161147157fe5b046039828660c00151036001600160901b0316901c985098505050505050505061149c565b50505050505b9550959350505050565b6000806114d0856001600160581b03168460a001518560200151866060015163ffffffff16611b0a565b6114f7866001600160581b031685608001518660000151876040015163ffffffff16611b0a565b01905061ffff811115611509575061ffff5b611523848460e00151838660c0015163ffffffff16611b0a565b83610100015161ffff16019150509392505050565b60608060608087516001600160401b038111801561155557600080fd5b5060405190808252806020026020018201604052801561157f578160200160208202803683370190505b50935087516001600160401b038111801561159957600080fd5b506040519080825280602002602001820160405280156115c3578160200160208202803683370190505b50925087516001600160401b03811180156115dd57600080fd5b50604051908082528060200260200182016040528015611607578160200160208202803683370190505b50915087516001600160401b038111801561162157600080fd5b5060405190808252806020026020018201604052801561164b578160200160208202803683370190505b5090506000600187018b61ffff821662010000811061166657fe5b600202015460ff1615611677578091505b61167f611ccf565b60005b8b5181101561175b576116ad8e8e8e848151811061169c57fe5b60200260200101518e8e898f6108fb565b91508160400151826060015183608001518460c00151816001600160581b03169150806001600160901b031690508b85815181106116e757fe5b602002602001018b86815181106116fa57fe5b602002602001018b878151811061170d57fe5b602002602001018b888151811061172057fe5b60209081029190910101939093526001600160701b039093169091526001600160a01b039092169052600691820b90910b9052600101611682565b505050509650965096509692505050565b63ffffffff80821684821681109184161181141561061f57505063ffffffff9081169116111590565b600080888561ffff166201000081106117aa57fe5b6002020154610100900463ffffffff16905060008961ffff87166201000081106117d057fe5b6002020154600160281b900460060b90506117f2826201517f198b018b61176c565b156118b85761180785620151808b038b61176c565b156118755760018703965060008a8861ffff1662010000811061182657fe5b60020201805490915060ff1661183f578860020b61186a565b805463ffffffff6101008204811688031690600160281b9004600690810b8703900b8161186857fe5b055b60060b9350506118b3565b600061188a8b8b620151808c8c8c60006108fb565b9050620151808a87030163ffffffff168160400151860360060b816118ab57fe5b0560060b9350505b6118f2565b8163ffffffff168563ffffffff16146118e75781850363ffffffff1681850360060b816118e157fe5b056118ec565b8760020b5b60060b92505b5050979650505050505050565b611907611ccf565b60208801805160018a5263ffffffff89811690925260408a018051918a0392831660028a900b02909101600690810b900b90526001600160801b03851661194f576001611951565b845b6001600160801b031663ffffffff60801b608083901b168161196f57fe5b0489606001818151019150906001600160a01b031690816001600160a01b0316815250506119b68163ffffffff168760020b8960020b8c60a0015160020b8860020b611bb2565b60808a018051919091016001600160581b031690525050600291820b90910b60a087015260c0860180516001600160801b03929092169091016001600160901b0316905250929392505050565b60008061ffff8084169082908616821115611a2757620100008661ffff1601611a2d565b8561ffff165b905081810160011c5b898161ffff16620100008110611a4857fe5b60020201805490955060ff811690610100900463ffffffff168115611af557611a72818b8d61176c565b15611ae9578b8360010161ffff16620100008110611a8c57fe5b60020201805490965060ff811690610100900463ffffffff168115611ad257611ab68c828f61176c565b15611ac7575050505050505061149c565b846001019650611ae2565b5087965061149c95505050505050565b5050611af0565b6001830393505b611afc565b8260010194505b50505081810160011c611a36565b600081851115611b645781850394508361ffff166006028510611b32575061ffff8216610884565b600861ffff85160a6000611b47878784611c07565b9050808201818661ffff160281611b5a57fe5b0492505050610884565b93810393600661ffff8516028510611b7e57506000610884565b600861ffff85160a6000611b93878784611c07565b8201905080828661ffff160281611ba657fe5b04979650505050505050565b6000828203858503038386038702600180890189026002808b02929092018102916006818c0a81029180870a8502868802850283020190860a8d029091020181611bf857fe5b059a9950505050505050505050565b808361ffff84168281611c1657fe5b049250828102820191508361ffff168381611c2d57fe5b0492508402600281840204820191508361ffff168381611c4957fe5b0492508402600681840204820191508361ffff168381611c6557fe5b0492508402601881840204820191508361ffff168381611c8157fe5b0492508402607881840204820191508361ffff168381611c9d57fe5b04925084026102d08184020491909101908402619d80818602046113b061ffff86168302040182019150509392505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b8035600281900b8114611d1d57600080fd5b919050565b80356001600160801b0381168114611d1d57600080fd5b8035611d1d816125bc565b8035611d1d816125cf565b600060208284031215611d60578081fd5b81516001600160a01b038116811461061f578182fd5b60006101208284031215611d88578081fd5b50919050565b600080600060608486031215611da2578182fd5b611dab84611d22565b95602085013595506040909401359392505050565b600060208284031215611dd1578081fd5b813561061f816125bc565b600080600080600060a08688031215611df3578081fd5b8535611dfe816125bc565b94506020860135611e0e816125cf565b9350611e1c60408701611d0b565b9250611e2a60608701611d22565b9150611e3860808701611d22565b90509295509295909350565b600060208284031215611e55578081fd5b5035919050565b600080600080600060a08688031215611e73578081fd5b8535611e7e816125cf565b94506020868101356001600160401b0380821115611e9a578384fd5b818901915089601f830112611ead578384fd5b813581811115611eb957fe5b83810260405185828201018181108582111715611ed257fe5b604052828152858101935084860182860187018e1015611ef0578788fd5b8795505b83861015611f1957611f0581611d44565b855260019590950194938601938601611ef4565b50809950505050505050611f2f60408701611d0b565b9250611e2a60608701611d39565b60008060408385031215611f4f578182fd5b8235611f5a816125cf565b9150611f6860208401611d0b565b90509250929050565b60008060008060808587031215611f86578384fd5b8435611f91816125cf565b9350611f9f60208601611d0b565b92506040850135611faf816125bc565b9150611fbd60608601611d22565b905092959194509250565b600080600080600060a08688031215611fdf578081fd5b8535611fea816125cf565b94506020860135611ffa816125cf565b935061200860408701611d0b565b92506060860135611e2a816125bc565b6000815180845260208085019450808401835b838110156120505781516001600160701b03168752958201959082019060010161202b565b509495945050505050565b6000815180845260208085019450808401835b838110156120505781518752958201959082019060010161206e565b61ffff169052565b63ffffffff169052565b6080808252855190820181905260009060209060a0840190828901845b828110156120d857815160060b845292840192908401906001016120b9565b50505083810382850152865180825287830191830190845b818110156121155783516001600160a01b0316835292840192918401916001016120f0565b505084810360408601526121298188612018565b925050508281036060840152610ebf818561205b565b961515875263ffffffff95909516602087015260069390930b60408601526001600160a01b039190911660608501526001600160581b0316608084015260020b60a08301526001600160901b031660c082015260e00190565b60069490940b84526001600160a01b039290921660208401526001600160701b03166040830152606082015260800190565b602080825260129082015271047616d6d6173206d757374206265203e20360741b604082015260600190565b6020808252601790820152766f6e6c7920706f6f6c2063616e2063616c6c207468697360481b604082015260600190565b60208082526010908201526f13585e0819995948195e18d95959195960821b604082015260600190565b61012081018235612261816125bc565b61ffff16825261227360208401611d39565b612280602084018261208a565b5061228d60408401611d44565b61229a6040840182612092565b506122a760608401611d44565b6122b46060840182612092565b506122c160808401611d39565b6122ce608084018261208a565b506122db60a08401611d39565b6122e860a084018261208a565b506122f560c08401611d44565b61230260c0840182612092565b5061230f60e08401611d39565b61231c60e084018261208a565b5061010061232b818501611d39565b6123378285018261208a565b505092915050565b6001600160701b03929092168252602082015260400190565b6001600160801b0391909116815260200190565b61ffff91909116815260200190565b61ffff998a168152978916602089015263ffffffff96871660408901529486166060880152928716608087015290861660a086015290921660c084015290831660e08301529091166101008201526101200190565b63ffffffff91909116815260200190565b600081356123ee816125bc565b92915050565b600081356123ee816125cf565b813561240c816125bc565b815461ffff191661ffff9190911617808255602083013561242c816125bc565b63ffff00008160101b1663ffff00001983161783555050612458612452604084016123f4565b82612576565b61246d612467606084016123f4565b82612599565b61248261247c608084016123e1565b826124d7565b61249761249160a084016123e1565b826124f6565b6124ac6124a660c084016123f4565b82612515565b6124c16124bb60e084016123e1565b82612538565b6106816124d161010084016123e1565b82612557565b805461ffff60601b191660609290921b61ffff60601b16919091179055565b805461ffff60701b191660709290921b61ffff60701b16919091179055565b805463ffffffff60801b191660809290921b63ffffffff60801b16919091179055565b805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b805463ffffffff60201b191660209290921b63ffffffff60201b16919091179055565b805463ffffffff60401b191660409290921b63ffffffff60401b16919091179055565b61ffff811681146125cc57600080fd5b50565b63ffffffff811681146125cc57600080fdfea164736f6c6343000706000aa164736f6c6343000706000a0000000000000000000000002d98e2fa9da15aa6dc9581ab097ced7af697cb92000000000000000000000000476307dac3fd170166e007fcaa14f0a129721463
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100995760003560e01c806313af40351461009e5780633119049a146100b3578063430bf08a146100d15780635d6d7e93146100d957806385535cc5146100ec5780638a2ade58146100ff5780638da5cb5b146101075780639832853a1461010f578063b001f6181461012c578063d9a641e11461013f578063e343361514610152575b600080fd5b6100b16100ac3660046109b2565b610165565b005b6100bb6101ed565b6040516100c89190610b15565b60405180910390f35b6100bb610211565b6100b16100e7366004610a29565b610220565b6100b16100fa3660046109b2565b6104b6565b6100bb61053e565b6100bb61054d565b61011761055c565b6040516100c899989796959493929190610c7a565b6100b161013a3660046109b2565b6105bc565b6100bb61014d3660046109f1565b610644565b6100bb6101603660046109f1565b61066a565b6000546001600160a01b0316331461017c57600080fd5b6000546001600160a01b038281169116141561019757600080fd5b6040516001600160a01b038216907fa5e220c2c27d986cc8efeafa8f34ba6ea6bf96a34e146b29b6bdd8587771b13090600090a2600080546001600160a01b0319166001600160a01b0392909216919091179055565b7f0000000000000000000000002d98e2fa9da15aa6dc9581ab097ced7af697cb9281565b6002546001600160a01b031681565b6000546001600160a01b0316331461023757600080fd5b61ffff8981168982160182821601111561026c5760405162461bcd60e51b815260040161026390610b9a565b60405180910390fd5b61ffff851615801590610282575061ffff841615155b8015610291575061ffff821615155b6102ad5760405162461bcd60e51b815260040161026390610b6e565b6040518061012001604052808a61ffff1681526020018961ffff1681526020018863ffffffff1681526020018763ffffffff1681526020018661ffff1681526020018561ffff1681526020018463ffffffff1681526020018361ffff1681526020018261ffff16815250600360008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a81548161ffff021916908361ffff16021790555060408201518160000160046101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160086101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548161ffff021916908361ffff16021790555060c08201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060e08201518160000160146101000a81548161ffff021916908361ffff1602179055506101008201518160000160166101000a81548161ffff021916908361ffff1602179055509050507f4035ab409f15e202f9f114632e1fb14a0552325955722be18503403e7f98730c8989898989898989896040516104a399989796959493929190610c7a565b60405180910390a1505050505050505050565b6000546001600160a01b031633146104cd57600080fd5b6002546001600160a01b03828116911614156104e857600080fd5b6040516001600160a01b038216907fb9c265ae4414f501736ec5d4961edc3309e4385eb2ff3feeecb30fb36621dd8390600090a2600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031681565b6000546001600160a01b031681565b60035461ffff8082169162010000810482169163ffffffff600160201b8304811692600160401b8104821692600160601b8204811692600160701b8304821692600160801b810490911691600160a01b8204811691600160b01b90041689565b6000546001600160a01b031633146105d357600080fd5b6001546001600160a01b03828116911614156105ee57600080fd5b6040516001600160a01b038216907f56b9e8342f530796ceed0d5529abdcdeae6e4f2ac1dc456ceb73bbda898e0cd390600090a2600180546001600160a01b0319166001600160a01b0392909216919091179055565b60046020908152600092835260408084209091529082529020546001600160a01b031681565b6000816001600160a01b0316836001600160a01b0316141561068b57600080fd5b600080836001600160a01b0316856001600160a01b0316106106ae5783856106b1565b84845b90925090506001600160a01b0382166106c957600080fd5b6001600160a01b038281166000908152600460209081526040808320858516845290915290205416156106fb57600080fd5b600061070783836108dd565b6040516107139061097a565b61071d9190610b15565b604051809103906000f080158015610739573d6000803e3d6000fd5b50604051631c7004cb60e01b81529091506001600160a01b03821690631c7004cb9061076a90600390600401610bc4565b600060405180830381600087803b15801561078457600080fd5b505af1158015610798573d6000803e3d6000fd5b5050604051637ec15b9d60e11b81526001600160a01b037f0000000000000000000000002d98e2fa9da15aa6dc9581ab097ced7af697cb9216925063fd82b73a91506107ee908490309088908890600401610b43565b602060405180830381600087803b15801561080857600080fd5b505af115801561081c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084091906109d5565b6001600160a01b03808516600081815260046020818152604080842089871680865290835281852080549789166001600160a01b031998891681179091559383528185208686529092529283902080549095169091179093555192965090917f91ccaa7a278130b65168c3a0c8d3bcae84cf5e43704342bd3ec0b59e59c036db906108cc908890610b15565b60405180910390a350505092915050565b60007f0000000000000000000000002d98e2fa9da15aa6dc9581ab097ced7af697cb928383604051602001610913929190610b29565b60408051601f1981840301815290829052805160209182012061095b939290917f6ec6c9c8091d160c0aa74b2b14ba9c1717e95093bd3ac085cee99a49aab294a49101610ae2565b60408051601f1981840301815291905280516020909101209392505050565b6126b780610ce883390190565b803561ffff8116811461099957600080fd5b919050565b803563ffffffff8116811461099957600080fd5b6000602082840312156109c3578081fd5b81356109ce81610ccf565b9392505050565b6000602082840312156109e6578081fd5b81516109ce81610ccf565b60008060408385031215610a03578081fd5b8235610a0e81610ccf565b91506020830135610a1e81610ccf565b809150509250929050565b60008060008060008060008060006101208a8c031215610a47578485fd5b610a508a610987565b9850610a5e60208b01610987565b9750610a6c60408b0161099e565b9650610a7a60608b0161099e565b9550610a8860808b01610987565b9450610a9660a08b01610987565b9350610aa460c08b0161099e565b9250610ab260e08b01610987565b9150610ac16101008b01610987565b90509295985092959850929598565b61ffff169052565b63ffffffff169052565b6001600160f81b0319815260609390931b6001600160601b03191660018401526015830191909152603582015260550190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b602080825260129082015271047616d6d6173206d757374206265203e20360741b604082015260600190565b60208082526010908201526f13585e0819995948195e18d95959195960821b604082015260600190565b815461012082019061ffff610bdb84828416610ad0565b610bed60208501828460101c16610ad0565b63ffffffff610c0460408601828560201c16610ad8565b610c1660608601828560401c16610ad8565b610c2860808601838560601c16610ad0565b610c3a60a08601838560701c16610ad0565b610c4c60c08601828560801c16610ad8565b50610c5f60e08501828460a01c16610ad0565b610c726101008501828460b01c16610ad0565b505092915050565b61ffff998a168152978916602089015263ffffffff96871660408901529486166060880152928716608087015290861660a086015290921660c084015290831660e08301529091166101008201526101200190565b6001600160a01b0381168114610ce457600080fd5b5056fe60c06040523480156200001157600080fd5b50604051620026b7380380620026b7833981016040819052620000349162000051565b33606090811b60a0521b6001600160601b03191660805262000081565b60006020828403121562000063578081fd5b81516001600160a01b03811681146200007a578182fd5b9392505050565b60805160601c60a05160601c6125ee620000c9600039806102ba52806102e35250806101f152806104b65280610638528061070c528061077c528061089c52506125ee6000f3fe608060405234801561001057600080fd5b50600436106100995760003560e01c806314c540791461009e5780631c7004cb146100ca5780631dd486f2146100df5780631e5eb1d0146100ff57806336e52fee1461011c578063461645bf1461013c578063475fb80c1461015157806374eceae614610164578063bc2e01811461018a578063c53a182f146101ab578063fd31e988146101be575b600080fd5b6100b16100ac366004611fc8565b6101e1565b6040516100c19493929190612198565b60405180910390f35b6100dd6100d8366004611d76565b6102af565b005b6100f26100ed366004611ddc565b6104a9565b6040516100c1919061236c565b61010761050c565b6040516100c19998979695949392919061237b565b61012f61012a366004611d8e565b61056e565b6040516100c19190612358565b610144610626565b6040516100c191906123d0565b6100dd61015f366004611f3d565b61062d565b610177610172366004611e44565b610685565b6040516100c1979695949392919061213f565b61019d610198366004611f71565b6106fe565b6040516100c192919061233f565b6100f26101b9366004611f71565b61076f565b6101d16101cc366004611e5c565b61088c565b6040516100c1949392919061209c565b6000808080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102375760405162461bcd60e51b815260040161022e906121f6565b60405180910390fd5b6000600187018161ffff821662010000811061024f57fe5b600202015460ff1615610260578091505b6000610271818d8d8d8d888e6108fb565b60408101516060820151608083015160c090930151919f909e506001600160581b039092169c506001600160901b03169a5098505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061038757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561033a57600080fd5b505afa15801561034e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103729190611d4f565b6001600160a01b0316336001600160a01b0316145b61039057600080fd5b61ffff6103a561012083016101008401611dc0565b61ffff166103b96040840160208501611dc0565b61ffff166103ca6020850185611dc0565b61ffff16010111156103ee5760405162461bcd60e51b815260040161022e90612227565b6103fe60a0820160808301611dc0565b61ffff1615801590610422575061041b60c0820160a08301611dc0565b61ffff1615155b8015610441575061043a610100820160e08301611dc0565b61ffff1615155b61045d5760405162461bcd60e51b815260040161022e906121ca565b806202000061046c8282612401565b9050507f86821edb04a8df5bac675c23c1eb986257da59363579c86d977a66fa59896b9d8160405161049e9190612251565b60405180910390a150565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104f35760405162461bcd60e51b815260040161022e906121f6565b61050260008787878787610eca565b9695505050505050565b620200005461ffff8082169162010000810482169163ffffffff600160201b8304811692600160401b8104821692600160601b8204811692600160701b8304821692600160801b810490911691600160a01b8204811691600160b01b90041689565b60008061057a83611178565b61058385611178565b0290506000600160c01b82106105c8576000866001600160801b0316116105ab5760016105ad565b855b6001600160801b0316600019816105c057fe5b0490506105fb565b6000866001600160801b0316116105e05760016105e2565b855b6001600160801b0316604083901b816105f757fe5b0490505b610c3560451b811061061657610c3560451b9250505061061f565b915061061f9050565b9392505050565b6201518090565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106755760405162461bcd60e51b815260040161022e906121f6565b610681600083836112c8565b5050565b60008162010000811061069757600080fd5b600290810291909101805460019091015460ff82169350610100820463ffffffff1692600160281b830460060b92600160601b90046001600160a01b0316916001600160581b03811691600160581b8204900b90600160701b90046001600160901b031687565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107495760405162461bcd60e51b815260040161022e906121f6565b610757600087878787611327565b6001600160581b039091169250905094509492505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107b95760405162461bcd60e51b815260040161022e906121f6565b6000806107c98188888888611327565b9150915061087f600f836001600160581b0316816107e357fe5b6040805161012081018252620200005461ffff80821683526201000082048116602084015263ffffffff600160201b8304811694840194909452600160401b820484166060840152600160601b820481166080840152600160701b8204811660a0840152600160801b820490931660c0830152600160a01b8104831660e0830152600160b01b90049091166101008201529190049083906114a6565b925050505b949350505050565b6060808080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108d95760405162461bcd60e51b815260040161022e906121f6565b6108e860008a8a8a8a8a611538565b929c919b50995090975095505050505050565b610903611ccf565b85870363ffffffff871615806109405750610940898661ffff1662010000811061092957fe5b6002020154610100900463ffffffff16828a61176c565b15610ac3576000898661ffff1662010000811061095957fe5b6040805160e081018252600292830293909301805460ff811615158552610100810463ffffffff90811660208701819052600160281b8304600690810b810b900b94870194909452600160601b9091046001600160a01b031660608601526001909101546001600160581b0381166080860152600160581b8104840b840b90930b60a0850152600160701b9092046001600160901b031660c084015291925083161415610a09579150610ebf9050565b6000610a228b8b8a8a8a87602001518860400151611795565b90508761ffff88811690881614610aa857610a3b611ccf565b60008d60018b0361ffff16620100008110610a5257fe5b60020201805463ffffffff610100820481166020808701829052600160281b909304600690810b810b810b6040808901829052948b0151948b0151959650919093039091169203900b81610aa257fe5b05925050505b610ab883858b848a8760006118ff565b945050505050610ebf565b610ad8898561ffff1662010000811061092957fe5b610b0f576040805162461bcd60e51b815260206004820152600360248201526213d31160ea1b604482015290519081900360640190fd5b600080610b1f8b8b858a8a611a03565b6040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900460060b60060b60060b815260200160008201600c9054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016001820160009054906101000a90046001600160581b03166001600160581b03166001600160581b0316815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a90046001600160901b03166001600160901b03166001600160901b03168152505091506040518060e00160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160059054906101000a900460060b60060b60060b815260200160008201600c9054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016001820160009054906101000a90046001600160581b03166001600160581b03166001600160581b0316815260200160018201600b9054906101000a900460020b60020b60020b815260200160018201600e9054906101000a90046001600160901b03166001600160901b03166001600160901b0316815250509150806020015163ffffffff168363ffffffff161415610d6b579250610ebf915050565b816020015163ffffffff168363ffffffff1614610eba5760008260200151826020015103905060008360200151850390508063ffffffff168263ffffffff16856040015185604001510360060b81610dbf57fe5b0502846040018181510191509060060b908160060b815250508163ffffffff168163ffffffff1685606001518560600151036001600160a01b03160281610e0257fe5b0484606001818151019150906001600160a01b031690816001600160a01b0316815250508063ffffffff168263ffffffff1685608001518560800151036001600160581b031681610e4f57fe5b040284608001818151019150906001600160581b031690816001600160581b0316815250508063ffffffff168263ffffffff168560c001518560c00151036001600160901b031681610e9d57fe5b60c0870180516001600160901b0393909204939093020116905250505b509150505b979650505050505050565b600080878761ffff16620100008110610edf57fe5b60020201805490915063ffffffff878116610100909204161415610f065786915050610502565b6040805160e081018252825460ff811615158252610100810463ffffffff166020830152600160281b8104600690810b810b900b92820192909252600160601b9091046001600160a01b031660608201526001808301546001600160581b0381166080840152600160581b8104600290810b810b900b60a0840152600160701b90046001600160901b031660c08301528801925060008961ffff8516620100008110610fae57fe5b600202015460ff1615610fbe5750825b6000610fd78b8a8a8d8688602001518960400151611795565b90508761ffff8b8116908416146110485760008c60018d0361ffff16620100008110610fff57fe5b6002020180546020870151604088015192935063ffffffff6101008304811693600160281b909304600690810b939285900390911691839003900b8161104157fe5b0593505050505b611057848b8b848c878d6118ff565b8c8761ffff1662010000811061106957fe5b825160029182029290920180546020850151604086015160608701516001600160a01b0316600160601b026001600160601b0360069290920b66ffffffffffffff16600160281b02600160281b600160601b031963ffffffff9094166101000264ffffffff001998151560ff1990961695909517979097169390931791909116949094179390931692909217825560808301516001909201805460a085015160c0909501516001600160901b0316600160701b026001600160701b039590930b62ffffff16600160581b0262ffffff60581b196001600160581b039095166001600160581b03199092169190911793909316929092179290921691909117905550505050509695505050505050565b600060ff82901d8083188190038061119357600092506112c1565b806001600160801b82106111ac5760809190911c9060401b5b600160401b82106111c25760409190911c9060201b5b600160201b82106111d85760209190911c9060101b5b6201000082106111ed5760109190911c9060081b5b61010082106112015760089190911c9060041b5b601082106112145760049190911c9060021b5b600882106112205760011b5b600181848161122b57fe5b048201901c9050600181848161123d57fe5b048201901c9050600181848161124f57fe5b048201901c9050600181848161126157fe5b048201901c9050600181848161127357fe5b048201901c9050600181848161128557fe5b048201901c9050600181848161129757fe5b048201901c905060008184816112a957fe5b0490508082106112b957806112bb565b815b95505050505b5050919050565b825460ff16156112d757600080fd5b825463ffffffff9290921661010002600160ff19909316831764ffffffff0019161783559101805462ffffff60581b1916600160581b62ffffff60029490940b9390931692909202919091179055565b6000808087600186018161ffff821662010000811061134257fe5b600202015460ff161561136b57898161ffff1662010000811061136157fe5b6002020191508092505b600061137d8b8b60008c8c898d6108fb565b8354909150610100900463ffffffff1661139e816201517f198d018d61176c565b156114065760006113b78d8d620151808e8e8b8f6108fb565b90506201518063ffffffff1681608001518460800151036001600160581b0316816113de57fe5b0460398260c001518560c00151036001600160901b0316901c9750975050505050505061149c565b8063ffffffff168b63ffffffff16146114965760008460010160009054906101000a90046001600160581b03169050600085600101600e9054906101000a90046001600160901b03169050828d0363ffffffff16828560800151036001600160581b03168161147157fe5b046039828660c00151036001600160901b0316901c985098505050505050505061149c565b50505050505b9550959350505050565b6000806114d0856001600160581b03168460a001518560200151866060015163ffffffff16611b0a565b6114f7866001600160581b031685608001518660000151876040015163ffffffff16611b0a565b01905061ffff811115611509575061ffff5b611523848460e00151838660c0015163ffffffff16611b0a565b83610100015161ffff16019150509392505050565b60608060608087516001600160401b038111801561155557600080fd5b5060405190808252806020026020018201604052801561157f578160200160208202803683370190505b50935087516001600160401b038111801561159957600080fd5b506040519080825280602002602001820160405280156115c3578160200160208202803683370190505b50925087516001600160401b03811180156115dd57600080fd5b50604051908082528060200260200182016040528015611607578160200160208202803683370190505b50915087516001600160401b038111801561162157600080fd5b5060405190808252806020026020018201604052801561164b578160200160208202803683370190505b5090506000600187018b61ffff821662010000811061166657fe5b600202015460ff1615611677578091505b61167f611ccf565b60005b8b5181101561175b576116ad8e8e8e848151811061169c57fe5b60200260200101518e8e898f6108fb565b91508160400151826060015183608001518460c00151816001600160581b03169150806001600160901b031690508b85815181106116e757fe5b602002602001018b86815181106116fa57fe5b602002602001018b878151811061170d57fe5b602002602001018b888151811061172057fe5b60209081029190910101939093526001600160701b039093169091526001600160a01b039092169052600691820b90910b9052600101611682565b505050509650965096509692505050565b63ffffffff80821684821681109184161181141561061f57505063ffffffff9081169116111590565b600080888561ffff166201000081106117aa57fe5b6002020154610100900463ffffffff16905060008961ffff87166201000081106117d057fe5b6002020154600160281b900460060b90506117f2826201517f198b018b61176c565b156118b85761180785620151808b038b61176c565b156118755760018703965060008a8861ffff1662010000811061182657fe5b60020201805490915060ff1661183f578860020b61186a565b805463ffffffff6101008204811688031690600160281b9004600690810b8703900b8161186857fe5b055b60060b9350506118b3565b600061188a8b8b620151808c8c8c60006108fb565b9050620151808a87030163ffffffff168160400151860360060b816118ab57fe5b0560060b9350505b6118f2565b8163ffffffff168563ffffffff16146118e75781850363ffffffff1681850360060b816118e157fe5b056118ec565b8760020b5b60060b92505b5050979650505050505050565b611907611ccf565b60208801805160018a5263ffffffff89811690925260408a018051918a0392831660028a900b02909101600690810b900b90526001600160801b03851661194f576001611951565b845b6001600160801b031663ffffffff60801b608083901b168161196f57fe5b0489606001818151019150906001600160a01b031690816001600160a01b0316815250506119b68163ffffffff168760020b8960020b8c60a0015160020b8860020b611bb2565b60808a018051919091016001600160581b031690525050600291820b90910b60a087015260c0860180516001600160801b03929092169091016001600160901b0316905250929392505050565b60008061ffff8084169082908616821115611a2757620100008661ffff1601611a2d565b8561ffff165b905081810160011c5b898161ffff16620100008110611a4857fe5b60020201805490955060ff811690610100900463ffffffff168115611af557611a72818b8d61176c565b15611ae9578b8360010161ffff16620100008110611a8c57fe5b60020201805490965060ff811690610100900463ffffffff168115611ad257611ab68c828f61176c565b15611ac7575050505050505061149c565b846001019650611ae2565b5087965061149c95505050505050565b5050611af0565b6001830393505b611afc565b8260010194505b50505081810160011c611a36565b600081851115611b645781850394508361ffff166006028510611b32575061ffff8216610884565b600861ffff85160a6000611b47878784611c07565b9050808201818661ffff160281611b5a57fe5b0492505050610884565b93810393600661ffff8516028510611b7e57506000610884565b600861ffff85160a6000611b93878784611c07565b8201905080828661ffff160281611ba657fe5b04979650505050505050565b6000828203858503038386038702600180890189026002808b02929092018102916006818c0a81029180870a8502868802850283020190860a8d029091020181611bf857fe5b059a9950505050505050505050565b808361ffff84168281611c1657fe5b049250828102820191508361ffff168381611c2d57fe5b0492508402600281840204820191508361ffff168381611c4957fe5b0492508402600681840204820191508361ffff168381611c6557fe5b0492508402601881840204820191508361ffff168381611c8157fe5b0492508402607881840204820191508361ffff168381611c9d57fe5b04925084026102d08184020491909101908402619d80818602046113b061ffff86168302040182019150509392505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b8035600281900b8114611d1d57600080fd5b919050565b80356001600160801b0381168114611d1d57600080fd5b8035611d1d816125bc565b8035611d1d816125cf565b600060208284031215611d60578081fd5b81516001600160a01b038116811461061f578182fd5b60006101208284031215611d88578081fd5b50919050565b600080600060608486031215611da2578182fd5b611dab84611d22565b95602085013595506040909401359392505050565b600060208284031215611dd1578081fd5b813561061f816125bc565b600080600080600060a08688031215611df3578081fd5b8535611dfe816125bc565b94506020860135611e0e816125cf565b9350611e1c60408701611d0b565b9250611e2a60608701611d22565b9150611e3860808701611d22565b90509295509295909350565b600060208284031215611e55578081fd5b5035919050565b600080600080600060a08688031215611e73578081fd5b8535611e7e816125cf565b94506020868101356001600160401b0380821115611e9a578384fd5b818901915089601f830112611ead578384fd5b813581811115611eb957fe5b83810260405185828201018181108582111715611ed257fe5b604052828152858101935084860182860187018e1015611ef0578788fd5b8795505b83861015611f1957611f0581611d44565b855260019590950194938601938601611ef4565b50809950505050505050611f2f60408701611d0b565b9250611e2a60608701611d39565b60008060408385031215611f4f578182fd5b8235611f5a816125cf565b9150611f6860208401611d0b565b90509250929050565b60008060008060808587031215611f86578384fd5b8435611f91816125cf565b9350611f9f60208601611d0b565b92506040850135611faf816125bc565b9150611fbd60608601611d22565b905092959194509250565b600080600080600060a08688031215611fdf578081fd5b8535611fea816125cf565b94506020860135611ffa816125cf565b935061200860408701611d0b565b92506060860135611e2a816125bc565b6000815180845260208085019450808401835b838110156120505781516001600160701b03168752958201959082019060010161202b565b509495945050505050565b6000815180845260208085019450808401835b838110156120505781518752958201959082019060010161206e565b61ffff169052565b63ffffffff169052565b6080808252855190820181905260009060209060a0840190828901845b828110156120d857815160060b845292840192908401906001016120b9565b50505083810382850152865180825287830191830190845b818110156121155783516001600160a01b0316835292840192918401916001016120f0565b505084810360408601526121298188612018565b925050508281036060840152610ebf818561205b565b961515875263ffffffff95909516602087015260069390930b60408601526001600160a01b039190911660608501526001600160581b0316608084015260020b60a08301526001600160901b031660c082015260e00190565b60069490940b84526001600160a01b039290921660208401526001600160701b03166040830152606082015260800190565b602080825260129082015271047616d6d6173206d757374206265203e20360741b604082015260600190565b6020808252601790820152766f6e6c7920706f6f6c2063616e2063616c6c207468697360481b604082015260600190565b60208082526010908201526f13585e0819995948195e18d95959195960821b604082015260600190565b61012081018235612261816125bc565b61ffff16825261227360208401611d39565b612280602084018261208a565b5061228d60408401611d44565b61229a6040840182612092565b506122a760608401611d44565b6122b46060840182612092565b506122c160808401611d39565b6122ce608084018261208a565b506122db60a08401611d39565b6122e860a084018261208a565b506122f560c08401611d44565b61230260c0840182612092565b5061230f60e08401611d39565b61231c60e084018261208a565b5061010061232b818501611d39565b6123378285018261208a565b505092915050565b6001600160701b03929092168252602082015260400190565b6001600160801b0391909116815260200190565b61ffff91909116815260200190565b61ffff998a168152978916602089015263ffffffff96871660408901529486166060880152928716608087015290861660a086015290921660c084015290831660e08301529091166101008201526101200190565b63ffffffff91909116815260200190565b600081356123ee816125bc565b92915050565b600081356123ee816125cf565b813561240c816125bc565b815461ffff191661ffff9190911617808255602083013561242c816125bc565b63ffff00008160101b1663ffff00001983161783555050612458612452604084016123f4565b82612576565b61246d612467606084016123f4565b82612599565b61248261247c608084016123e1565b826124d7565b61249761249160a084016123e1565b826124f6565b6124ac6124a660c084016123f4565b82612515565b6124c16124bb60e084016123e1565b82612538565b6106816124d161010084016123e1565b82612557565b805461ffff60601b191660609290921b61ffff60601b16919091179055565b805461ffff60701b191660709290921b61ffff60701b16919091179055565b805463ffffffff60801b191660809290921b63ffffffff60801b16919091179055565b805461ffff60a01b191660a09290921b61ffff60a01b16919091179055565b805461ffff60b01b191660b09290921b61ffff60b01b16919091179055565b805463ffffffff60201b191660209290921b63ffffffff60201b16919091179055565b805463ffffffff60401b191660409290921b63ffffffff60401b16919091179055565b61ffff811681146125cc57600080fd5b50565b63ffffffff811681146125cc57600080fdfea164736f6c6343000706000aa164736f6c6343000706000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002d98e2fa9da15aa6dc9581ab097ced7af697cb92000000000000000000000000476307dac3fd170166e007fcaa14f0a129721463
-----Decoded View---------------
Arg [0] : _poolDeployer (address): 0x2D98E2FA9da15aa6dC9581AB097Ced7af697CB92
Arg [1] : _vaultAddress (address): 0x476307DaC3FD170166e007FCaA14F0A129721463
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000002d98e2fa9da15aa6dc9581ab097ced7af697cb92
Arg [1] : 000000000000000000000000476307dac3fd170166e007fcaa14f0a129721463
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ 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.