Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Quoter
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 1000000
- EVM Version
- default
- Verified at
- 2024-03-11T10:38:50.309867Z
Constructor Arguments
0x000000000000000000000000d8676fbdfa5b56bb2298d452c9768f51e80e34ae0000000000000000000000003fb787101dc6be47cfe18aeee15404dcc842e6af0000000000000000000000005822a45b05d08028baa3d19626870076d26bc460
Arg [0] (address) : 0xd8676fbdfa5b56bb2298d452c9768f51e80e34ae
Arg [1] (address) : 0x3fb787101dc6be47cfe18aeee15404dcc842e6af
Arg [2] (address) : 0x5822a45b05d08028baa3d19626870076d26bc460
contracts/lens/Quoter.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity =0.7.6;pragma abicoder v2;import '@cryptoalgebra/core/contracts/libraries/SafeCast.sol';import '@cryptoalgebra/core/contracts/libraries/TickMath.sol';import '@cryptoalgebra/core/contracts/libraries/FullMath.sol';import '@cryptoalgebra/core/contracts/interfaces/IAlgebraPool.sol';import '@cryptoalgebra/core/contracts/interfaces/callback/IAlgebraSwapCallback.sol';import '../interfaces/IQuoter.sol';import '../base/PeripheryImmutableState.sol';import '../libraries/Path.sol';import '../libraries/PoolAddress.sol';import '../libraries/CallbackValidation.sol';/// @title Provides quotes for swaps/// @notice Allows getting the expected amount out or amount in for a given swap without executing the swap/// @dev These functions are not gas efficient and should _not_ be called on chain. Instead, optimistically execute/// the swap and check the amounts in the callback./// Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-peripherycontract Quoter is IQuoter, IAlgebraSwapCallback, PeripheryImmutableState {using Path for bytes;using SafeCast for uint256;/// @dev Transient storage variable used to check a safety condition in exact output swaps.uint256 private amountOutCached;constructor(address _factory,address _WNativeToken,address _poolDeployer) PeripheryImmutableState(_factory, _WNativeToken, _poolDeployer) {}function getPool(address tokenA, address tokenB) private view returns (IAlgebraPool) {return IAlgebraPool(PoolAddress.computeAddress(poolDeployer, PoolAddress.getPoolKey(tokenA, tokenB)));}/// @inheritdoc IAlgebraSwapCallback
contracts/base/PeripheryImmutableState.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity =0.7.6;import '../interfaces/IPeripheryImmutableState.sol';/// @title Immutable state/// @notice Immutable state used by periphery contracts/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-peripheryabstract contract PeripheryImmutableState is IPeripheryImmutableState {/// @inheritdoc IPeripheryImmutableStateaddress public immutable override factory;/// @inheritdoc IPeripheryImmutableStateaddress public immutable override poolDeployer;/// @inheritdoc IPeripheryImmutableStateaddress public immutable override WNativeToken;constructor(address _factory,address _WNativeToken,address _poolDeployer) {factory = _factory;poolDeployer = _poolDeployer;WNativeToken = _WNativeToken;}}
@cryptoalgebra/core/contracts/interfaces/IAlgebraPool.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;import './pool/IAlgebraPoolImmutables.sol';import './pool/IAlgebraPoolState.sol';import './pool/IAlgebraPoolDerivedState.sol';import './pool/IAlgebraPoolActions.sol';import './pool/IAlgebraPoolPermissionedActions.sol';import './pool/IAlgebraPoolEvents.sol';/*** @title The interface for a Algebra Pool* @dev The pool interface is broken up into many smaller pieces.* Credit to Uniswap Labs under GPL-2.0-or-later license:* https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces*/interface IAlgebraPool isIAlgebraPoolImmutables,IAlgebraPoolState,IAlgebraPoolDerivedState,IAlgebraPoolActions,IAlgebraPoolPermissionedActions,IAlgebraPoolEvents{// used only for combining interfaces}
@cryptoalgebra/core/contracts/interfaces/IDataStorageOperator.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;pragma abicoder v2;import '../libraries/AdaptiveFee.sol';interface IDataStorageOperator {event FeeConfiguration(bool zto, 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: getTimepoints(). 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)externalviewreturns (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 tickfunction 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.
@cryptoalgebra/core/contracts/interfaces/callback/IAlgebraSwapCallback.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Callback for IAlgebraPoolActions#swap/// @notice Any contract that calls IAlgebraPoolActions#swap must implement this interface/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-core/tree/main/contracts/interfacesinterface IAlgebraSwapCallback {/// @notice Called to `msg.sender` after executing a swap via IAlgebraPool#swap./// @dev In the implementation you must pay the pool tokens owed for the swap./// The caller of this method must be checked to be a AlgebraPool deployed by the canonical AlgebraFactory./// amount0Delta and amount1Delta can both be 0 if no tokens were swapped./// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by/// the end of the swap. If positive, the callback must send that amount of token0 to the pool./// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by/// the end of the swap. If positive, the callback must send that amount of token1 to the pool./// @param data Any data passed through by the caller via the IAlgebraPoolActions#swap callfunction algebraSwapCallback(int256 amount0Delta,int256 amount1Delta,bytes calldata data) external;}
@cryptoalgebra/core/contracts/interfaces/pool/IAlgebraPoolActions.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Permissionless pool actions/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-core/tree/main/contracts/interfacesinterface IAlgebraPoolActions {/*** @notice Sets the initial price for the pool* @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value* @param price the initial sqrt price of the pool as a Q64.96*/function initialize(uint160 price) external;/*** @notice Adds liquidity for the given recipient/bottomTick/topTick position* @dev The caller of this method receives a callback in the form of IAlgebraMintCallback# AlgebraMintCallback* in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends* on bottomTick, topTick, the amount of liquidity, and the current price.* @param sender The address which will receive potential surplus of paid tokens* @param recipient The address for which the liquidity will be created* @param bottomTick The lower tick of the position in which to add liquidity* @param topTick The upper tick of the position in which to add liquidity* @param amount The desired amount of liquidity to mint* @param data Any data that should be passed through to the callback* @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback* @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback* @return liquidityActual The actual minted amount of liquidity*/function mint(address sender,address recipient,int24 bottomTick,int24 topTick,uint128 amount,bytes calldata data)externalreturns (uint256 amount0,uint256 amount1,
@cryptoalgebra/core/contracts/interfaces/pool/IAlgebraPoolDerivedState.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/*** @title Pool state that is not stored* @notice Contains view functions to provide information about the pool that is computed rather than stored on the* blockchain. The functions here may have variable gas costs.* @dev Credit to Uniswap Labs under GPL-2.0-or-later license:* https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces*/interface IAlgebraPoolDerivedState {/*** @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp* @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing* the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,* you must call it with secondsAgos = [3600, 0].* @dev The time weighted average tick represents the geometric time weighted average price of the pool, in* log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.* @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned* @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp* @return secondsPerLiquidityCumulatives Cumulative seconds per liquidity-in-range value as of each `secondsAgos`* from the current block timestamp* @return volatilityCumulatives Cumulative standard deviation as of each `secondsAgos`* @return volumePerAvgLiquiditys Cumulative swap volume per liquidity as of each `secondsAgos`*/function getTimepoints(uint32[] calldata secondsAgos)externalviewreturns (int56[] memory tickCumulatives,uint160[] memory secondsPerLiquidityCumulatives,uint112[] memory volatilityCumulatives,uint256[] memory volumePerAvgLiquiditys);/*** @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range* @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.* I.e., snapshots cannot be compared if a position is not held for the entire period between when the first* snapshot is taken and the second snapshot is taken.* @param bottomTick The lower tick of the range
@cryptoalgebra/core/contracts/interfaces/pool/IAlgebraPoolEvents.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Events emitted by a pool/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-core/tree/main/contracts/interfacesinterface IAlgebraPoolEvents {/*** @notice Emitted exactly once by a pool when #initialize is first called on the pool* @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize* @param price The initial sqrt price of the pool, as a Q64.96* @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool*/event Initialize(uint160 price, int24 tick);/*** @notice Emitted when liquidity is minted for a given position* @param sender The address that minted the liquidity* @param owner The owner of the position and recipient of any minted liquidity* @param bottomTick The lower tick of the position* @param topTick The upper tick of the position* @param liquidityAmount The amount of liquidity minted to the position range* @param amount0 How much token0 was required for the minted liquidity* @param amount1 How much token1 was required for the minted liquidity*/event Mint(address sender,address indexed owner,int24 indexed bottomTick,int24 indexed topTick,uint128 liquidityAmount,uint256 amount0,uint256 amount1);/*** @notice Emitted when fees are collected by the owner of a position* @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees* @param owner The owner of the position for which fees are collected* @param recipient The address that received fees* @param bottomTick The lower tick of the position
@cryptoalgebra/core/contracts/interfaces/pool/IAlgebraPoolImmutables.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;import '../IDataStorageOperator.sol';/// @title Pool state that never changes/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-core/tree/main/contracts/interfacesinterface IAlgebraPoolImmutables {/*** @notice The contract that stores all the timepoints and can perform actions with them* @return The operator address*/function dataStorageOperator() external view returns (address);/*** @notice The contract that deployed the pool, which must adhere to the IAlgebraFactory interface* @return The contract address*/function factory() external view returns (address);/*** @notice The first of the two tokens of the pool, sorted by address* @return The token contract address*/function token0() external view returns (address);/*** @notice The second of the two tokens of the pool, sorted by address* @return The token contract address*/function token1() external view returns (address);/*** @notice The maximum amount of position liquidity that can use any tick in the range* @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and* also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool* @return The max amount of liquidity per tick*/function maxLiquidityPerTick() external view returns (uint128);}
@cryptoalgebra/core/contracts/interfaces/pool/IAlgebraPoolPermissionedActions.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/*** @title Permissioned pool actions* @notice Contains pool methods that may only be called by the factory owner or tokenomics* @dev Credit to Uniswap Labs under GPL-2.0-or-later license:* https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces*/interface IAlgebraPoolPermissionedActions {/*** @notice Set the community's % share of the fees. Cannot exceed 25% (250)* @param communityFee0 new community fee percent for token0 of the pool in thousandths (1e-3)* @param communityFee1 new community fee percent for token1 of the pool in thousandths (1e-3)*/function setCommunityFee(uint8 communityFee0, uint8 communityFee1) external;/// @notice Set the new tick spacing values. Only factory owner/// @param newTickSpacing The new tick spacing valuefunction setTickSpacing(int24 newTickSpacing) external;/*** @notice Sets an active incentive* @param virtualPoolAddress The address of a virtual pool associated with the incentive*/function setIncentive(address virtualPoolAddress) external;/*** @notice Sets new lock time for added liquidity* @param newLiquidityCooldown The time in seconds*/function setLiquidityCooldown(uint32 newLiquidityCooldown) external;}
@cryptoalgebra/core/contracts/interfaces/pool/IAlgebraPoolState.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Pool state that can change/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-core/tree/main/contracts/interfacesinterface IAlgebraPoolState {/*** @notice The globalState structure in the pool stores many values but requires only one slot* and is exposed as a single method to save gas when accessed externally.* @return price The current price of the pool as a sqrt(token1/token0) Q64.96 value;* Returns tick The current tick of the pool, i.e. according to the last tick transition that was run;* Returns This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(price) if the price is on a tick* boundary;* Returns feeZto The last pool fee value for ZtO swaps in hundredths of a bip, i.e. 1e-6;* Returns feeOtz The last pool fee value for OtZ swaps in hundredths of a bip, i.e. 1e-6;* Returns timepointIndex The index of the last written timepoint;* Returns communityFeeToken0 The community fee percentage of the swap fee in thousandths (1e-3) for token0;* Returns communityFeeToken1 The community fee percentage of the swap fee in thousandths (1e-3) for token1;* Returns unlocked Whether the pool is currently locked to reentrancy;*/function globalState()externalviewreturns (uint160 price,int24 tick,uint16 feeZto,uint16 feeOtz,uint16 timepointIndex,uint8 communityFeeToken0,uint8 communityFeeToken1,bool unlocked);/*** @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool* @dev This value can overflow the uint256*/function totalFeeGrowth0Token() external view returns (uint256);
@cryptoalgebra/core/contracts/libraries/AdaptiveFee.sol
// SPDX-License-Identifier: BUSL-1.1pragma solidity =0.7.6;import './Constants.sol';/// @title AdaptiveFee/// @notice Calculates fee based on combination of sigmoidslibrary AdaptiveFee {// alpha1 + alpha2 + baseFee must be <= type(uint16).maxstruct Configuration {uint16 alpha1; // max value of the first sigmoiduint16 alpha2; // max value of the second sigmoiduint32 beta1; // shift along the x-axis for the first sigmoiduint32 beta2; // shift along the x-axis for the second sigmoiduint16 gamma1; // horizontal stretch factor for the first sigmoiduint16 gamma2; // horizontal stretch factor for the second sigmoiduint32 volumeBeta; // shift along the x-axis for the outer volume-sigmoiduint16 volumeGamma; // horizontal stretch factor the outer volume-sigmoiduint16 baseFee; // minimum possible fee}/// @notice Calculates fee based on formula:/// baseFee + sigmoidVolume(sigmoid1(volatility, volumePerLiquidity) + sigmoid2(volatility, volumePerLiquidity))/// maximum value capped by baseFee + alpha1 + alpha2function 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 casesumOfSigmoids = 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) / γ))
@cryptoalgebra/core/contracts/libraries/Constants.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma 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-6uint16 internal constant BASE_FEE = 100;int24 internal constant MAX_TICK_SPACING = 500;// max(uint128) / (MAX_TICK - MIN_TICK)uint128 internal constant MAX_LIQUIDITY_PER_TICK = 191757638537527648490752896198553;uint32 internal constant MAX_LIQUIDITY_COOLDOWN = 1 days;uint8 internal constant MAX_COMMUNITY_FEE = 250;uint256 internal constant COMMUNITY_FEE_DENOMINATOR = 1000;}
@cryptoalgebra/core/contracts/libraries/FullMath.sol
// SPDX-License-Identifier: MITpragma 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 bitslibrary 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/muldivfunction 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 + prod0uint256 prod0 = a * b; // Least significant 256 bits of the productuint256 prod1; // Most significant 256 bits of the productassembly {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 == 0require(denominator > prod1);// Handle non-overflow cases, 256 by 256 divisionif (prod1 == 0) {assembly {result := div(prod0, denominator)}return result;}
@cryptoalgebra/core/contracts/libraries/SafeCast.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Safe casting methods/// @notice Contains methods for safely casting between types/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-core/blob/main/contracts/librarieslibrary SafeCast {/// @notice Cast a uint256 to a uint160, revert on overflow/// @param y The uint256 to be downcasted/// @return z The downcasted integer, now type uint160function toUint160(uint256 y) internal pure returns (uint160 z) {require((z = uint160(y)) == y);}/// @notice Cast a int256 to a int128, revert on overflow or underflow/// @param y The int256 to be downcasted/// @return z The downcasted integer, now type int128function toInt128(int256 y) internal pure returns (int128 z) {require((z = int128(y)) == y);}/// @notice Cast a uint256 to a int256, revert on overflow/// @param y The uint256 to be casted/// @return z The casted integer, now type int256function toInt256(uint256 y) internal pure returns (int256 z) {require(y < 2**255);z = int256(y);}}
@cryptoalgebra/core/contracts/libraries/TickMath.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Math library for computing sqrt prices from ticks and vice versa/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports/// prices between 2**-128 and 2**128/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-core/blob/main/contracts/librarieslibrary TickMath {/// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128int24 internal constant MIN_TICK = -887272;/// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128int24 internal constant MAX_TICK = -MIN_TICK;/// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)uint160 internal constant MIN_SQRT_RATIO = 4295128739;/// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;/// @notice Calculates sqrt(1.0001^tick) * 2^96/// @dev Throws if |tick| > max tick/// @param tick The input tick for the above formula/// @return price A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)/// at the given tickfunction getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 price) {// get abs valueint24 mask = tick >> (24 - 1);uint256 absTick = uint256((tick ^ mask) - mask);require(absTick <= uint256(MAX_TICK), 'T');uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
contracts/interfaces/IPeripheryImmutableState.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Immutable state/// @notice Functions that return immutable state of the router/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-peripheryinterface IPeripheryImmutableState {/// @return Returns the address of the Algebra factoryfunction factory() external view returns (address);/// @return Returns the address of the pool Deployerfunction poolDeployer() external view returns (address);/// @return Returns the address of WNativeTokenfunction WNativeToken() external view returns (address);}
contracts/interfaces/IQuoter.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.7.5;pragma abicoder v2;/// @title Quoter Interface/// @notice Supports quoting the calculated amounts from exact input or exact output swaps/// @dev These functions are not marked view because they rely on calling non-view functions and reverting/// to compute the result. They are also not gas efficient and should not be called on-chain./// Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-peripheryinterface IQuoter {/// @notice Returns the amount out received for a given exact input swap without executing the swap/// @param path The path of the swap, i.e. each token pair/// @param amountIn The amount of the first token to swap/// @return amountOut The amount of the last token that would be receivedfunction quoteExactInput(bytes memory path, uint256 amountIn)externalreturns (uint256 amountOut, uint16[] memory fees);/// @notice Returns the amount out received for a given exact input but for a swap of a single pool/// @param tokenIn The token being swapped in/// @param tokenOut The token being swapped out/// @param amountIn The desired input amount/// @param limitSqrtPrice The price limit of the pool that cannot be exceeded by the swap/// @return amountOut The amount of `tokenOut` that would be receivedfunction quoteExactInputSingle(address tokenIn,address tokenOut,uint256 amountIn,uint160 limitSqrtPrice) external returns (uint256 amountOut, uint16 fee);/// @notice Returns the amount in required for a given exact output swap without executing the swap/// @param path The path of the swap, i.e. each token pair. Path must be provided in reverse order/// @param amountOut The amount of the last token to receive/// @return amountIn The amount of first token required to be paidfunction quoteExactOutput(bytes memory path, uint256 amountOut)externalreturns (uint256 amountIn, uint16[] memory fees);/// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool
contracts/libraries/BytesLib.sol
// SPDX-License-Identifier: GPL-2.0-or-later/*** @title Solidity Bytes Arrays Utils* @author Gonçalo Sá <goncalo.sa@consensys.net>** @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.* The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.*/pragma solidity >=0.5.0 <0.8.0;library BytesLib {function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {require(_length + 31 >= _length, 'slice_overflow');require(_start + _length >= _start, 'slice_overflow');require(_bytes.length >= _start + _length, 'slice_outOfBounds');bytes memory tempBytes;assembly {switch iszero(_length)case 0 {// Get a location of some free memory and store it in tempBytes as// Solidity does for memory variables.tempBytes := mload(0x40)// The first word of the slice result is potentially a partial// word read from the original array. To read it, we calculate// the length of that partial word and start copying that many// bytes into the array. The first word we copy will start with// data we don't care about, but the last `lengthmod` bytes will// land at the beginning of the contents of the new array. When// we're done copying, we overwrite the full first word with// the actual length of the slice.let lengthmod := and(_length, 31)// The multiplication in the next line is necessary// because when slicing multiples of 32 bytes (lengthmod == 0)// the following copy loop was copying the origin's length// and then ending prematurely not copying everything it should.let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))let end := add(mc, _length)
contracts/libraries/CallbackValidation.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity =0.7.6;import '@cryptoalgebra/core/contracts/interfaces/IAlgebraPool.sol';import './PoolAddress.sol';/// @notice Provides validation for callbacks from Algebra Pools/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-peripherylibrary CallbackValidation {/// @notice Returns the address of a valid Algebra Pool/// @param poolDeployer The contract address of the Algebra pool deployer/// @param tokenA The contract address of either token0 or token1/// @param tokenB The contract address of the other token/// @return pool The V3 pool contract addressfunction verifyCallback(address poolDeployer,address tokenA,address tokenB) internal view returns (IAlgebraPool pool) {return verifyCallback(poolDeployer, PoolAddress.getPoolKey(tokenA, tokenB));}/// @notice Returns the address of a valid Algebra Pool/// @param poolDeployer The contract address of the Algebra pool deployer/// @param poolKey The identifying key of the V3 pool/// @return pool The V3 pool contract addressfunction verifyCallback(address poolDeployer, PoolAddress.PoolKey memory poolKey)internalviewreturns (IAlgebraPool pool){pool = IAlgebraPool(PoolAddress.computeAddress(poolDeployer, poolKey));require(msg.sender == address(pool));}}
contracts/libraries/Path.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.6.0;import './BytesLib.sol';/// @title Functions for manipulating path data for multihop swaps/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-peripherylibrary Path {using BytesLib for bytes;/// @dev The length of the bytes encoded addressuint256 private constant ADDR_SIZE = 20;/// @dev The length of the bytes encoded feeuint256 private constant FEE_SIZE = 3;/// @dev The offset of a single token address and pool feeuint256 private constant NEXT_OFFSET = ADDR_SIZE;/// @dev The offset of an encoded pool keyuint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE;/// @dev The minimum length of an encoding that contains 2 or more poolsuint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET;/// @notice Returns true iff the path contains two or more pools/// @param path The encoded swap path/// @return True if path contains two or more pools, otherwise falsefunction hasMultiplePools(bytes memory path) internal pure returns (bool) {return path.length >= MULTIPLE_POOLS_MIN_LENGTH;}/// @notice Returns the number of pools in the path/// @param path The encoded swap path/// @return The number of pools in the pathfunction numPools(bytes memory path) internal pure returns (uint256) {// Ignore the first token address. From then on every fee and token offset indicates a pool.return ((path.length - ADDR_SIZE) / NEXT_OFFSET);}/// @notice Decodes the first pool in path/// @param path The bytes encoded swap path/// @return tokenA The first token of the given pool
contracts/libraries/PoolAddress.sol
// SPDX-License-Identifier: GPL-2.0-or-laterpragma solidity >=0.5.0;/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee/// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:/// https://github.com/Uniswap/v3-peripherylibrary PoolAddress {bytes32 internal constant POOL_INIT_CODE_HASH = 0x6c1bebd370ba84753516bc1393c0d0a6c645856da55f5393ac8ab3d6dbc861d3;/// @notice The identifying key of the poolstruct PoolKey {address token0;address token1;}/// @notice Returns PoolKey: the ordered tokens with the matched fee levels/// @param tokenA The first token of a pool, unsorted/// @param tokenB The second token of a pool, unsorted/// @return Poolkey The pool details with ordered token0 and token1 assignmentsfunction getPoolKey(address tokenA, address tokenB) internal pure returns (PoolKey memory) {if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);return PoolKey({token0: tokenA, token1: tokenB});}/// @notice Deterministically computes the pool address given the factory and PoolKey/// @param factory The Algebra factory contract address/// @param key The PoolKey/// @return pool The contract address of the V3 poolfunction computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {require(key.token0 < key.token1);pool = address(uint256(keccak256(abi.encodePacked(hex'ff',factory,keccak256(abi.encode(key.token0, key.token1)),POOL_INIT_CODE_HASH)))
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":1000000,"enabled":true},"metadata":{"bytecodeHash":"none"},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_WNativeToken","internalType":"address"},{"type":"address","name":"_poolDeployer","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"WNativeToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[],"name":"algebraSwapCallback","inputs":[{"type":"int256","name":"amount0Delta","internalType":"int256"},{"type":"int256","name":"amount1Delta","internalType":"int256"},{"type":"bytes","name":"path","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"factory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"poolDeployer","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint16[]","name":"fees","internalType":"uint16[]"}],"name":"quoteExactInput","inputs":[{"type":"bytes","name":"path","internalType":"bytes"},{"type":"uint256","name":"amountIn","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint16","name":"fee","internalType":"uint16"}],"name":"quoteExactInputSingle","inputs":[{"type":"address","name":"tokenIn","internalType":"address"},{"type":"address","name":"tokenOut","internalType":"address"},{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint160","name":"limitSqrtPrice","internalType":"uint160"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint16[]","name":"fees","internalType":"uint16[]"}],"name":"quoteExactOutput","inputs":[{"type":"bytes","name":"path","internalType":"bytes"},{"type":"uint256","name":"amountOut","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint16","name":"fee","internalType":"uint16"}],"name":"quoteExactOutputSingle","inputs":[{"type":"address","name":"tokenIn","internalType":"address"},{"type":"address","name":"tokenOut","internalType":"address"},{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint160","name":"limitSqrtPrice","internalType":"uint160"}]}]
Contract Creation Code
0x60e06040523480156200001157600080fd5b50604051620014f9380380620014f9833981016040819052620000349162000078565b6001600160601b0319606093841b811660805290831b811660a052911b1660c052620000c1565b80516001600160a01b03811681146200007357600080fd5b919050565b6000806000606084860312156200008d578283fd5b62000098846200005b565b9250620000a8602085016200005b565b9150620000b8604085016200005b565b90509250925092565b60805160601c60a05160601c60c05160601c6113f862000101600039806105b4525080610165528061059052806108a952508061078552506113f86000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638af3ac851161005b5780638af3ac85146101025780639e73c81d1461010a578063c45a01551461011d578063cdca17531461012557610088565b80632c8958f61461008d5780632d9ebd1d146100a25780632f80bb1d146100cc5780633119049a146100ed575b600080fd5b6100a061009b366004610ff9565b610138565b005b6100b56100b0366004610f41565b610323565b6040516100c3929190611320565b60405180910390f35b6100df6100da366004610f93565b6104b9565b6040516100c39291906112cf565b6100f561058e565b6040516100c39190611212565b6100f56105b2565b6100b5610118366004610f41565b6105d6565b6100f5610783565b6100df610133366004610f93565b6107a7565b60008313806101475750600082135b61015057600080fd5b60008061015c83610864565b9150915061018b7f00000000000000000000000000000000000000000000000000000000000000008383610885565b5060008060008088136101d1578473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16108789600003610206565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161088886000035b925092509250600061021886866108a2565b905060008060008373ffffffffffffffffffffffffffffffffffffffff1663e76c01e46040518163ffffffff1660e01b81526004016101006040518083038186803b15801561026657600080fd5b505afa15801561027a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029e91906110ba565b505050509350935050508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16106102e157806102e3565b815b925086156102fc57604051858152836020820152604081fd5b6000541561031257600054851461031257600080fd5b604051868152836020820152604081fd5b60008073ffffffffffffffffffffffffffffffffffffffff8086169087161061034c87876108a2565b73ffffffffffffffffffffffffffffffffffffffff1663128acb083083610372896108e0565b73ffffffffffffffffffffffffffffffffffffffff89161561039457886103ba565b856103b35773fffd8963efd1fc6a506488495d951d5263988d256103ba565b6401000276a45b8c8c6040516020016103cd9291906111d8565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016103fc959493929190611233565b6040805180830381600087803b15801561041557600080fd5b505af1925050508015610463575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261046091810190610fd6565b60015b6104ac573d808015610491576040519150601f19603f3d011682016040523d82523d6000602084013e610496565b606091505b506104a081610912565b90945092506104af9050565b50505b5094509492505050565b600060606104c6846109cd565b67ffffffffffffffff811180156104dc57600080fd5b50604051908082528060200260200182016040528015610506578160200160208202803683370190505b50905060005b6000610517866109e5565b905060008061052588610864565b9150915061053681838960006105d6565b86868151811061054257fe5b602002602001018161ffff1661ffff168152508198505050821561057057610569886109ed565b975061057c565b86955050505050610587565b50505060010161050c565b9250929050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008073ffffffffffffffffffffffffffffffffffffffff808616878216109084166106025760008590555b61060c87876108a2565b73ffffffffffffffffffffffffffffffffffffffff1663128acb083083610632896108e0565b60000373ffffffffffffffffffffffffffffffffffffffff891615610657578861067d565b856106765773fffd8963efd1fc6a506488495d951d5263988d2561067d565b6401000276a45b8b8d6040516020016106909291906111d8565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016106bf959493929190611233565b6040805180830381600087803b1580156106d857600080fd5b505af1925050508015610726575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261072391810190610fd6565b60015b6104ac573d808015610754576040519150601f19603f3d011682016040523d82523d6000602084013e610759565b606091505b5073ffffffffffffffffffffffffffffffffffffffff851661077a57600080555b6104a081610912565b7f000000000000000000000000000000000000000000000000000000000000000081565b600060606107b4846109cd565b67ffffffffffffffff811180156107ca57600080fd5b506040519080825280602002602001820160405280156107f4578160200160208202803683370190505b50905060005b6000610805866109e5565b905060008061081388610864565b915091506108248282896000610323565b86868151811061083057fe5b602002602001018161ffff1661ffff168152508198505050821561057057610857886109ed565b97505050506001016107fa565b6000806108718382610a08565b915061087e836014610a08565b9050915091565b600061089a846108958585610b08565b610b77565b949350505050565b60006108d77f00000000000000000000000000000000000000000000000000000000000000006108d28585610b08565b610ba7565b90505b92915050565b60007f8000000000000000000000000000000000000000000000000000000000000000821061090e57600080fd5b5090565b60008082516040146109b057604483511015610963576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095a90611298565b60405180910390fd5b6004830192508280602001905181019061097d9190611047565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095a9190611285565b828060200190518101906109c49190611163565b91509150915091565b6000601480835103816109dc57fe5b0490505b919050565b51603c111590565b60606108da60148084510384610ccf9092919063ffffffff16565b600081826014011015610a7c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b8160140183511015610aef57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b5001602001516c01000000000000000000000000900490565b610b10610eb6565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115610b48579091905b506040805180820190915273ffffffffffffffffffffffffffffffffffffffff92831681529116602082015290565b6000610b838383610ba7565b90503373ffffffffffffffffffffffffffffffffffffffff8216146108da57600080fd5b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610610be957600080fd5b5080516020918201516040805173ffffffffffffffffffffffffffffffffffffffff938416818601529290911682820152805180830382018152606080840183528151918501919091207fff00000000000000000000000000000000000000000000000000000000000000608085015294901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608183015260958201939093527f6c1bebd370ba84753516bc1393c0d0a6c645856da55f5393ac8ab3d6dbc861d360b5808301919091528351808303909101815260d5909101909252815191012090565b60608182601f011015610d4357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b828284011015610db457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b81830184511015610e2657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015290519081900360640190fd5b606082158015610e455760405191506000825260208201604052610ead565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015610e7e578051835260209283019201610e66565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015290565b600082601f830112610edd578081fd5b8135610ef0610eeb82611356565b611332565b818152846020838601011115610f04578283fd5b816020850160208301379081016020019190915292915050565b805161ffff811681146109e057600080fd5b805160ff811681146109e057600080fd5b60008060008060808587031215610f56578384fd5b8435610f61816113c6565b93506020850135610f71816113c6565b9250604085013591506060850135610f88816113c6565b939692955090935050565b60008060408385031215610fa5578182fd5b823567ffffffffffffffff811115610fbb578283fd5b610fc785828601610ecd565b95602094909401359450505050565b60008060408385031215610fe8578182fd5b505080516020909101519092909150565b60008060006060848603121561100d578283fd5b8335925060208401359150604084013567ffffffffffffffff811115611031578182fd5b61103d86828701610ecd565b9150509250925092565b600060208284031215611058578081fd5b815167ffffffffffffffff81111561106e578182fd5b8201601f8101841361107e578182fd5b805161108c610eeb82611356565b8181528560208385010111156110a0578384fd5b6110b1826020830160208601611396565b95945050505050565b600080600080600080600080610100898b0312156110d6578384fd5b88516110e1816113c6565b8098505060208901518060020b81146110f8578485fd5b965061110660408a01610f1e565b955061111460608a01610f1e565b945061112260808a01610f1e565b935061113060a08a01610f30565b925061113e60c08a01610f30565b915060e08901518015158114611152578182fd5b809150509295985092959890939650565b60008060408385031215611175578182fd5b8251915061118560208401610f1e565b90509250929050565b600081518084526111a6816020860160208601611396565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606093841b811682529190921b16601482015260280190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff8088168352861515602084015285604084015280851660608401525060a0608083015261127a60a083018461118e565b979650505050505050565b6000602082526108d7602083018461118e565b60208082526010908201527f556e6578706563746564206572726f7200000000000000000000000000000000604082015260600190565b60006040820184835260206040818501528185518084526060860191508287019350845b8181101561131357845161ffff16835293830193918301916001016112f3565b5090979650505050505050565b91825261ffff16602082015260400190565b60405181810167ffffffffffffffff8111828210171561134e57fe5b604052919050565b600067ffffffffffffffff82111561136a57fe5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b838110156113b1578181015183820152602001611399565b838111156113c0576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff811681146113e857600080fd5b5056fea164736f6c6343000706000a000000000000000000000000d8676fbdfa5b56bb2298d452c9768f51e80e34ae0000000000000000000000003fb787101dc6be47cfe18aeee15404dcc842e6af0000000000000000000000005822a45b05d08028baa3d19626870076d26bc460
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c80638af3ac851161005b5780638af3ac85146101025780639e73c81d1461010a578063c45a01551461011d578063cdca17531461012557610088565b80632c8958f61461008d5780632d9ebd1d146100a25780632f80bb1d146100cc5780633119049a146100ed575b600080fd5b6100a061009b366004610ff9565b610138565b005b6100b56100b0366004610f41565b610323565b6040516100c3929190611320565b60405180910390f35b6100df6100da366004610f93565b6104b9565b6040516100c39291906112cf565b6100f561058e565b6040516100c39190611212565b6100f56105b2565b6100b5610118366004610f41565b6105d6565b6100f5610783565b6100df610133366004610f93565b6107a7565b60008313806101475750600082135b61015057600080fd5b60008061015c83610864565b9150915061018b7f0000000000000000000000005822a45b05d08028baa3d19626870076d26bc4608383610885565b5060008060008088136101d1578473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16108789600003610206565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161088886000035b925092509250600061021886866108a2565b905060008060008373ffffffffffffffffffffffffffffffffffffffff1663e76c01e46040518163ffffffff1660e01b81526004016101006040518083038186803b15801561026657600080fd5b505afa15801561027a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029e91906110ba565b505050509350935050508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16106102e157806102e3565b815b925086156102fc57604051858152836020820152604081fd5b6000541561031257600054851461031257600080fd5b604051868152836020820152604081fd5b60008073ffffffffffffffffffffffffffffffffffffffff8086169087161061034c87876108a2565b73ffffffffffffffffffffffffffffffffffffffff1663128acb083083610372896108e0565b73ffffffffffffffffffffffffffffffffffffffff89161561039457886103ba565b856103b35773fffd8963efd1fc6a506488495d951d5263988d256103ba565b6401000276a45b8c8c6040516020016103cd9291906111d8565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016103fc959493929190611233565b6040805180830381600087803b15801561041557600080fd5b505af1925050508015610463575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261046091810190610fd6565b60015b6104ac573d808015610491576040519150601f19603f3d011682016040523d82523d6000602084013e610496565b606091505b506104a081610912565b90945092506104af9050565b50505b5094509492505050565b600060606104c6846109cd565b67ffffffffffffffff811180156104dc57600080fd5b50604051908082528060200260200182016040528015610506578160200160208202803683370190505b50905060005b6000610517866109e5565b905060008061052588610864565b9150915061053681838960006105d6565b86868151811061054257fe5b602002602001018161ffff1661ffff168152508198505050821561057057610569886109ed565b975061057c565b86955050505050610587565b50505060010161050c565b9250929050565b7f0000000000000000000000005822a45b05d08028baa3d19626870076d26bc46081565b7f0000000000000000000000003fb787101dc6be47cfe18aeee15404dcc842e6af81565b60008073ffffffffffffffffffffffffffffffffffffffff808616878216109084166106025760008590555b61060c87876108a2565b73ffffffffffffffffffffffffffffffffffffffff1663128acb083083610632896108e0565b60000373ffffffffffffffffffffffffffffffffffffffff891615610657578861067d565b856106765773fffd8963efd1fc6a506488495d951d5263988d2561067d565b6401000276a45b8b8d6040516020016106909291906111d8565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016106bf959493929190611233565b6040805180830381600087803b1580156106d857600080fd5b505af1925050508015610726575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261072391810190610fd6565b60015b6104ac573d808015610754576040519150601f19603f3d011682016040523d82523d6000602084013e610759565b606091505b5073ffffffffffffffffffffffffffffffffffffffff851661077a57600080555b6104a081610912565b7f000000000000000000000000d8676fbdfa5b56bb2298d452c9768f51e80e34ae81565b600060606107b4846109cd565b67ffffffffffffffff811180156107ca57600080fd5b506040519080825280602002602001820160405280156107f4578160200160208202803683370190505b50905060005b6000610805866109e5565b905060008061081388610864565b915091506108248282896000610323565b86868151811061083057fe5b602002602001018161ffff1661ffff168152508198505050821561057057610857886109ed565b97505050506001016107fa565b6000806108718382610a08565b915061087e836014610a08565b9050915091565b600061089a846108958585610b08565b610b77565b949350505050565b60006108d77f0000000000000000000000005822a45b05d08028baa3d19626870076d26bc4606108d28585610b08565b610ba7565b90505b92915050565b60007f8000000000000000000000000000000000000000000000000000000000000000821061090e57600080fd5b5090565b60008082516040146109b057604483511015610963576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095a90611298565b60405180910390fd5b6004830192508280602001905181019061097d9190611047565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095a9190611285565b828060200190518101906109c49190611163565b91509150915091565b6000601480835103816109dc57fe5b0490505b919050565b51603c111590565b60606108da60148084510384610ccf9092919063ffffffff16565b600081826014011015610a7c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b8160140183511015610aef57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b5001602001516c01000000000000000000000000900490565b610b10610eb6565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115610b48579091905b506040805180820190915273ffffffffffffffffffffffffffffffffffffffff92831681529116602082015290565b6000610b838383610ba7565b90503373ffffffffffffffffffffffffffffffffffffffff8216146108da57600080fd5b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610610be957600080fd5b5080516020918201516040805173ffffffffffffffffffffffffffffffffffffffff938416818601529290911682820152805180830382018152606080840183528151918501919091207fff00000000000000000000000000000000000000000000000000000000000000608085015294901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608183015260958201939093527f6c1bebd370ba84753516bc1393c0d0a6c645856da55f5393ac8ab3d6dbc861d360b5808301919091528351808303909101815260d5909101909252815191012090565b60608182601f011015610d4357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b828284011015610db457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b81830184511015610e2657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015290519081900360640190fd5b606082158015610e455760405191506000825260208201604052610ead565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015610e7e578051835260209283019201610e66565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015290565b600082601f830112610edd578081fd5b8135610ef0610eeb82611356565b611332565b818152846020838601011115610f04578283fd5b816020850160208301379081016020019190915292915050565b805161ffff811681146109e057600080fd5b805160ff811681146109e057600080fd5b60008060008060808587031215610f56578384fd5b8435610f61816113c6565b93506020850135610f71816113c6565b9250604085013591506060850135610f88816113c6565b939692955090935050565b60008060408385031215610fa5578182fd5b823567ffffffffffffffff811115610fbb578283fd5b610fc785828601610ecd565b95602094909401359450505050565b60008060408385031215610fe8578182fd5b505080516020909101519092909150565b60008060006060848603121561100d578283fd5b8335925060208401359150604084013567ffffffffffffffff811115611031578182fd5b61103d86828701610ecd565b9150509250925092565b600060208284031215611058578081fd5b815167ffffffffffffffff81111561106e578182fd5b8201601f8101841361107e578182fd5b805161108c610eeb82611356565b8181528560208385010111156110a0578384fd5b6110b1826020830160208601611396565b95945050505050565b600080600080600080600080610100898b0312156110d6578384fd5b88516110e1816113c6565b8098505060208901518060020b81146110f8578485fd5b965061110660408a01610f1e565b955061111460608a01610f1e565b945061112260808a01610f1e565b935061113060a08a01610f30565b925061113e60c08a01610f30565b915060e08901518015158114611152578182fd5b809150509295985092959890939650565b60008060408385031215611175578182fd5b8251915061118560208401610f1e565b90509250929050565b600081518084526111a6816020860160208601611396565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606093841b811682529190921b16601482015260280190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff8088168352861515602084015285604084015280851660608401525060a0608083015261127a60a083018461118e565b979650505050505050565b6000602082526108d7602083018461118e565b60208082526010908201527f556e6578706563746564206572726f7200000000000000000000000000000000604082015260600190565b60006040820184835260206040818501528185518084526060860191508287019350845b8181101561131357845161ffff16835293830193918301916001016112f3565b5090979650505050505050565b91825261ffff16602082015260400190565b60405181810167ffffffffffffffff8111828210171561134e57fe5b604052919050565b600067ffffffffffffffff82111561136a57fe5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b838110156113b1578181015183820152602001611399565b838111156113c0576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff811681146113e857600080fd5b5056fea164736f6c6343000706000a