More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 657,207 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Exact Input Sing... | 8635496 | 2 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635475 | 5 mins ago | IN | 0 GLMR | 0.2780576 | ||||
Exact Input Sing... | 8635475 | 5 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635471 | 5 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635466 | 6 mins ago | IN | 0 GLMR | 0.22602472 | ||||
Exact Input Sing... | 8635466 | 6 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input | 8635466 | 6 mins ago | IN | 0 GLMR | 0.24232213 | ||||
Exact Input | 8635463 | 6 mins ago | IN | 0 GLMR | 0.78417549 | ||||
Exact Input Sing... | 8635461 | 6 mins ago | IN | 0 GLMR | 0.21843592 | ||||
Exact Input Sing... | 8635461 | 6 mins ago | IN | 0 GLMR | 0.2263124 | ||||
Exact Input | 8635461 | 6 mins ago | IN | 0 GLMR | 0.24772704 | ||||
Exact Input Sing... | 8635457 | 7 mins ago | IN | 0 GLMR | 0.2263124 | ||||
Exact Input Sing... | 8635455 | 7 mins ago | IN | 0 GLMR | 0.22573704 | ||||
Exact Input Sing... | 8635437 | 9 mins ago | IN | 30 GLMR | 0.16954 | ||||
Exact Input Sing... | 8635436 | 9 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635422 | 10 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635422 | 10 mins ago | IN | 0 GLMR | 0.28013336 | ||||
Exact Input Sing... | 8635416 | 11 mins ago | IN | 0 GLMR | 0.28013336 | ||||
Exact Input Sing... | 8635413 | 11 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635404 | 12 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635399 | 12 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635395 | 13 mins ago | IN | 0 GLMR | 0.23276288 | ||||
Exact Input Sing... | 8635390 | 13 mins ago | IN | 0 GLMR | 0.23305056 | ||||
Exact Input Sing... | 8635384 | 14 mins ago | IN | 0 GLMR | 0.23305056 | ||||
Exact Input Sing... | 8635380 | 14 mins ago | IN | 0 GLMR | 0.23276288 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
8635437 | 9 mins ago | 30 GLMR | ||||
8635436 | 9 mins ago | 905.22098238 GLMR | ||||
8635436 | 9 mins ago | 905.22098238 GLMR | ||||
8635279 | 25 mins ago | 1,520.01703749 GLMR | ||||
8635279 | 25 mins ago | 1,520.01703749 GLMR | ||||
8635275 | 25 mins ago | 1,241.25859767 GLMR | ||||
8635275 | 25 mins ago | 1,241.25859767 GLMR | ||||
8635258 | 27 mins ago | 2,255.51345468 GLMR | ||||
8635233 | 30 mins ago | 4,615.81298557 GLMR | ||||
8635228 | 30 mins ago | 1,954.19320406 GLMR | ||||
8635219 | 31 mins ago | 5,586.05439253 GLMR | ||||
8635215 | 32 mins ago | 1,423.0154008 GLMR | ||||
8635209 | 32 mins ago | 1,795.52926888 GLMR | ||||
8635201 | 33 mins ago | 1,867.45857162 GLMR | ||||
8635180 | 35 mins ago | 145 GLMR | ||||
8635167 | 37 mins ago | 140 GLMR | ||||
8635166 | 37 mins ago | 1,406.62300613 GLMR | ||||
8635166 | 37 mins ago | 1,406.62300613 GLMR | ||||
8635162 | 37 mins ago | 150 GLMR | ||||
8635148 | 39 mins ago | 60 GLMR | ||||
8635137 | 40 mins ago | 153 GLMR | ||||
8635132 | 40 mins ago | 140 GLMR | ||||
8635108 | 43 mins ago | 184 GLMR | ||||
8635079 | 46 mins ago | 1,942.30188542 GLMR | ||||
8635078 | 46 mins ago | 716 GLMR |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SwapRouter
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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/interfaces/IAlgebraPool.sol'; import './interfaces/ISwapRouter.sol'; import './base/PeripheryImmutableState.sol'; import './base/PeripheryValidation.sol'; import './base/PeripheryPaymentsWithFee.sol'; import './base/Multicall.sol'; import './base/SelfPermit.sol'; import './libraries/Path.sol'; import './libraries/PoolAddress.sol'; import './libraries/CallbackValidation.sol'; import './interfaces/external/IWNativeToken.sol'; /// @title Algebra Swap Router /// @notice Router for stateless execution of swaps against Algebra /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery contract SwapRouter is ISwapRouter, PeripheryImmutableState, PeripheryValidation, PeripheryPaymentsWithFee, Multicall, SelfPermit { using Path for bytes; using SafeCast for uint256; /// @dev Used as the placeholder value for amountInCached, because the computed amount in for an exact output swap /// can never actually be this value uint256 private constant DEFAULT_AMOUNT_IN_CACHED = type(uint256).max; /// @dev Transient storage variable used for returning the computed amount in for an exact output swap. uint256 private amountInCached = DEFAULT_AMOUNT_IN_CACHED; constructor( address _factory, address _WNativeToken, address _poolDeployer ) PeripheryImmutableState(_factory, _WNativeToken, _poolDeployer) {} /// @dev Returns the pool for the given token pair and fee. The pool contract may or may not exist. function getPool(address tokenA, address tokenB) private view returns (IAlgebraPool) { return IAlgebraPool(PoolAddress.computeAddress(poolDeployer, PoolAddress.getPoolKey(tokenA, tokenB))); } struct SwapCallbackData { bytes path; address payer; } /// @inheritdoc IAlgebraSwapCallback function algebraSwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata _data ) external override { require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported SwapCallbackData memory data = abi.decode(_data, (SwapCallbackData)); (address tokenIn, address tokenOut) = data.path.decodeFirstPool(); CallbackValidation.verifyCallback(poolDeployer, tokenIn, tokenOut); (bool isExactInput, uint256 amountToPay) = amount0Delta > 0 ? (tokenIn < tokenOut, uint256(amount0Delta)) : (tokenOut < tokenIn, uint256(amount1Delta)); if (isExactInput) { pay(tokenIn, data.payer, msg.sender, amountToPay); } else { // either initiate the next swap or pay if (data.path.hasMultiplePools()) { data.path = data.path.skipToken(); exactOutputInternal(amountToPay, msg.sender, 0, data); } else { amountInCached = amountToPay; tokenIn = tokenOut; // swap in/out because exact output swaps are reversed pay(tokenIn, data.payer, msg.sender, amountToPay); } } } /// @dev Performs a single exact input swap function exactInputInternal( uint256 amountIn, address recipient, uint160 limitSqrtPrice, SwapCallbackData memory data ) private returns (uint256 amountOut) { if (recipient == address(0)) recipient = address(this); // allow swapping to the router address with address 0 (address tokenIn, address tokenOut) = data.path.decodeFirstPool(); bool zeroToOne = tokenIn < tokenOut; (int256 amount0, int256 amount1) = getPool(tokenIn, tokenOut).swap( recipient, zeroToOne, amountIn.toInt256(), limitSqrtPrice == 0 ? (zeroToOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) : limitSqrtPrice, abi.encode(data) ); return uint256(-(zeroToOne ? amount1 : amount0)); } /// @inheritdoc ISwapRouter function exactInputSingle(ExactInputSingleParams calldata params) external payable override checkDeadline(params.deadline) returns (uint256 amountOut) { amountOut = exactInputInternal( params.amountIn, params.recipient, params.limitSqrtPrice, SwapCallbackData({path: abi.encodePacked(params.tokenIn, params.tokenOut), payer: msg.sender}) ); require(amountOut >= params.amountOutMinimum, 'Too little received'); } /// @inheritdoc ISwapRouter function exactInput(ExactInputParams memory params) external payable override checkDeadline(params.deadline) returns (uint256 amountOut) { address payer = msg.sender; // msg.sender pays for the first hop while (true) { bool hasMultiplePools = params.path.hasMultiplePools(); // the outputs of prior swaps become the inputs to subsequent ones params.amountIn = exactInputInternal( params.amountIn, hasMultiplePools ? address(this) : params.recipient, // for intermediate swaps, this contract custodies 0, SwapCallbackData({ path: params.path.getFirstPool(), // only the first pool in the path is necessary payer: payer }) ); // decide whether to continue or terminate if (hasMultiplePools) { payer = address(this); // at this point, the caller has paid params.path = params.path.skipToken(); } else { amountOut = params.amountIn; break; } } require(amountOut >= params.amountOutMinimum, 'Too little received'); } /// @inheritdoc ISwapRouter function exactInputSingleSupportingFeeOnTransferTokens(ExactInputSingleParams calldata params) external override checkDeadline(params.deadline) returns (uint256 amountOut) { SwapCallbackData memory data = SwapCallbackData({ path: abi.encodePacked(params.tokenIn, params.tokenOut), payer: msg.sender }); address recipient = params.recipient == address(0) ? address(this) : params.recipient; bool zeroToOne = params.tokenIn < params.tokenOut; (int256 amount0, int256 amount1) = getPool(params.tokenIn, params.tokenOut).swapSupportingFeeOnInputTokens( msg.sender, recipient, zeroToOne, params.amountIn.toInt256(), params.limitSqrtPrice == 0 ? (zeroToOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) : params.limitSqrtPrice, abi.encode(data) ); amountOut = uint256(-(zeroToOne ? amount1 : amount0)); require(amountOut >= params.amountOutMinimum, 'Too little received'); } /// @dev Performs a single exact output swap function exactOutputInternal( uint256 amountOut, address recipient, uint160 limitSqrtPrice, SwapCallbackData memory data ) private returns (uint256 amountIn) { if (recipient == address(0)) recipient = address(this); // allow swapping to the router address with address 0 (address tokenOut, address tokenIn) = data.path.decodeFirstPool(); bool zeroToOne = tokenIn < tokenOut; (int256 amount0Delta, int256 amount1Delta) = getPool(tokenIn, tokenOut).swap( recipient, zeroToOne, -amountOut.toInt256(), limitSqrtPrice == 0 ? (zeroToOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) : limitSqrtPrice, abi.encode(data) ); uint256 amountOutReceived; (amountIn, amountOutReceived) = zeroToOne ? (uint256(amount0Delta), uint256(-amount1Delta)) : (uint256(amount1Delta), uint256(-amount0Delta)); // it's technically possible to not receive the full output amount, // so if no price limit has been specified, require this possibility away if (limitSqrtPrice == 0) require(amountOutReceived == amountOut); } /// @inheritdoc ISwapRouter function exactOutputSingle(ExactOutputSingleParams calldata params) external payable override checkDeadline(params.deadline) returns (uint256 amountIn) { // avoid an SLOAD by using the swap return data amountIn = exactOutputInternal( params.amountOut, params.recipient, params.limitSqrtPrice, SwapCallbackData({path: abi.encodePacked(params.tokenOut, params.tokenIn), payer: msg.sender}) ); require(amountIn <= params.amountInMaximum, 'Too much requested'); amountInCached = DEFAULT_AMOUNT_IN_CACHED; // has to be reset even though we don't use it in the single hop case } /// @inheritdoc ISwapRouter function exactOutput(ExactOutputParams calldata params) external payable override checkDeadline(params.deadline) returns (uint256 amountIn) { // it's okay that the payer is fixed to msg.sender here, as they're only paying for the "final" exact output // swap, which happens first, and subsequent swaps are paid for within nested callback frames exactOutputInternal( params.amountOut, params.recipient, 0, SwapCallbackData({path: params.path, payer: msg.sender}) ); amountIn = amountInCached; require(amountIn <= params.amountInMaximum, 'Too much requested'); amountInCached = DEFAULT_AMOUNT_IN_CACHED; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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/interfaces interface 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 call function algebraSwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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 is IAlgebraPoolImmutables, IAlgebraPoolState, IAlgebraPoolDerivedState, IAlgebraPoolActions, IAlgebraPoolPermissionedActions, IAlgebraPoolEvents { // used only for combining interfaces }
// 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: 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) 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: GPL-2.0-or-later pragma 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/interfaces interface 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 ) external returns ( uint256 amount0, uint256 amount1, uint128 liquidityActual ); /** * @notice Collects tokens owed to a position * @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity. * Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or * amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the * actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity. * @param recipient The address which should receive the fees collected * @param bottomTick The lower tick of the position for which to collect fees * @param topTick The upper tick of the position for which to collect fees * @param amount0Requested How much token0 should be withdrawn from the fees owed * @param amount1Requested How much token1 should be withdrawn from the fees owed * @return amount0 The amount of fees collected in token0 * @return amount1 The amount of fees collected in token1 */ function collect( address recipient, int24 bottomTick, int24 topTick, uint128 amount0Requested, uint128 amount1Requested ) external returns (uint128 amount0, uint128 amount1); /** * @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position * @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0 * @dev Fees must be collected separately via a call to #collect * @param bottomTick The lower tick of the position for which to burn liquidity * @param topTick The upper tick of the position for which to burn liquidity * @param amount How much liquidity to burn * @return amount0 The amount of token0 sent to the recipient * @return amount1 The amount of token1 sent to the recipient */ function burn( int24 bottomTick, int24 topTick, uint128 amount ) external returns (uint256 amount0, uint256 amount1); /** * @notice Swap token0 for token1, or token1 for token0 * @dev The caller of this method receives a callback in the form of IAlgebraSwapCallback# AlgebraSwapCallback * @param recipient The address to receive the output of the swap * @param zeroToOne The direction of the swap, true for token0 to token1, false for token1 to token0 * @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative) * @param limitSqrtPrice The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this * value after the swap. If one for zero, the price cannot be greater than this value after the swap * @param data Any data to be passed through to the callback. If using the Router it should contain * SwapRouter#SwapCallbackData * @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive * @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive */ function swap( address recipient, bool zeroToOne, int256 amountSpecified, uint160 limitSqrtPrice, bytes calldata data ) external returns (int256 amount0, int256 amount1); /** * @notice Swap token0 for token1, or token1 for token0 (tokens that have fee on transfer) * @dev The caller of this method receives a callback in the form of I AlgebraSwapCallback# AlgebraSwapCallback * @param sender The address called this function (Comes from the Router) * @param recipient The address to receive the output of the swap * @param zeroToOne The direction of the swap, true for token0 to token1, false for token1 to token0 * @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative) * @param limitSqrtPrice The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this * value after the swap. If one for zero, the price cannot be greater than this value after the swap * @param data Any data to be passed through to the callback. If using the Router it should contain * SwapRouter#SwapCallbackData * @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive * @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive */ function swapSupportingFeeOnInputTokens( address sender, address recipient, bool zeroToOne, int256 amountSpecified, uint160 limitSqrtPrice, bytes calldata data ) external returns (int256 amount0, int256 amount1); /** * @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback * @dev The caller of this method receives a callback in the form of IAlgebraFlashCallback# AlgebraFlashCallback * @dev All excess tokens paid in the callback are distributed to liquidity providers as an additional fee. So this method can be used * to donate underlying tokens to currently in-range liquidity providers by calling with 0 amount{0,1} and sending * the donation amount(s) from the callback * @param recipient The address which will receive the token0 and token1 amounts * @param amount0 The amount of token0 to send * @param amount1 The amount of token1 to send * @param data Any data to be passed through to the callback */ function flash( address recipient, uint256 amount0, uint256 amount1, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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) external view returns ( 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 * @param topTick The upper tick of the range * @return innerTickCumulative The snapshot of the tick accumulator for the range * @return innerSecondsSpentPerLiquidity The snapshot of seconds per liquidity for the range * @return innerSecondsSpent The snapshot of the number of seconds during which the price was in this range */ function getInnerCumulatives(int24 bottomTick, int24 topTick) external view returns ( int56 innerTickCumulative, uint160 innerSecondsSpentPerLiquidity, uint32 innerSecondsSpent ); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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/interfaces interface 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 * @param topTick The upper tick of the position * @param amount0 The amount of token0 fees collected * @param amount1 The amount of token1 fees collected */ event Collect(address indexed owner, address recipient, int24 indexed bottomTick, int24 indexed topTick, uint128 amount0, uint128 amount1); /** * @notice Emitted when a position's liquidity is removed * @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect * @param owner The owner of the position for which liquidity is removed * @param bottomTick The lower tick of the position * @param topTick The upper tick of the position * @param liquidityAmount The amount of liquidity to remove * @param amount0 The amount of token0 withdrawn * @param amount1 The amount of token1 withdrawn */ event Burn(address indexed owner, int24 indexed bottomTick, int24 indexed topTick, uint128 liquidityAmount, uint256 amount0, uint256 amount1); /** * @notice Emitted by the pool for any swaps between token0 and token1 * @param sender The address that initiated the swap call, and that received the callback * @param recipient The address that received the output of the swap * @param amount0 The delta of the token0 balance of the pool * @param amount1 The delta of the token1 balance of the pool * @param price The sqrt(price) of the pool after the swap, as a Q64.96 * @param liquidity The liquidity of the pool after the swap * @param tick The log base 1.0001 of price of the pool after the swap */ event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 price, uint128 liquidity, int24 tick); /** * @notice Emitted by the pool for any flashes of token0/token1 * @param sender The address that initiated the swap call, and that received the callback * @param recipient The address that received the tokens from flash * @param amount0 The amount of token0 that was flashed * @param amount1 The amount of token1 that was flashed * @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee * @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee */ event Flash(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1, uint256 paid0, uint256 paid1); /** * @notice Emitted when the community fee is changed by the pool * @param communityFee0New The updated value of the token0 community fee percent * @param communityFee1New The updated value of the token1 community fee percent */ event CommunityFee(uint8 communityFee0New, uint8 communityFee1New); /** * @notice Emitted when new activeIncentive is set * @param virtualPoolAddress The address of a virtual pool associated with the current active incentive */ event Incentive(address indexed virtualPoolAddress); /** * @notice Emitted when the fee changes * @param fee The value of the token fee */ event Fee(uint16 fee); /** * @notice Emitted when the LiquidityCooldown changes * @param liquidityCooldown The value of locktime for added liquidity */ event LiquidityCooldown(uint32 liquidityCooldown); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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/interfaces interface 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 pool tick spacing * @dev Ticks can only be used at multiples of this value * e.g.: a tickSpacing of 60 means ticks can be initialized every 60th tick, i.e., ..., -120, -60, 0, 60, 120, ... * This value is an int24 to avoid casting even though it is always positive. * @return The tick spacing */ function tickSpacing() external view returns (int24); /** * @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); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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 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; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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/interfaces interface 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 fee The last pool fee value 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() external view returns ( uint160 price, int24 tick, uint16 fee, 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); /** * @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool * @dev This value can overflow the uint256 */ function totalFeeGrowth1Token() external view returns (uint256); /** * @notice The currently in range liquidity available to the pool * @dev This value has no relationship to the total liquidity across all ticks. * Returned value cannot exceed type(uint128).max */ function liquidity() external view returns (uint128); /** * @notice Look up information about a specific tick in the pool * @dev This is a public structure, so the `return` natspec tags are omitted. * @param tick The tick to look up * @return liquidityTotal the total amount of position liquidity that uses the pool either as tick lower or * tick upper; * Returns liquidityDelta how much liquidity changes when the pool price crosses the tick; * Returns outerFeeGrowth0Token the fee growth on the other side of the tick from the current tick in token0; * Returns outerFeeGrowth1Token the fee growth on the other side of the tick from the current tick in token1; * Returns outerTickCumulative the cumulative tick value on the other side of the tick from the current tick; * Returns outerSecondsPerLiquidity the seconds spent per liquidity on the other side of the tick from the current tick; * Returns outerSecondsSpent the seconds spent on the other side of the tick from the current tick; * Returns initialized Set to true if the tick is initialized, i.e. liquidityTotal is greater than 0 * otherwise equal to false. Outside values can only be used if the tick is initialized. * In addition, these values are only relative and must be used only in comparison to previous snapshots for * a specific position. */ function ticks(int24 tick) external view returns ( uint128 liquidityTotal, int128 liquidityDelta, uint256 outerFeeGrowth0Token, uint256 outerFeeGrowth1Token, int56 outerTickCumulative, uint160 outerSecondsPerLiquidity, uint32 outerSecondsSpent, bool initialized ); /** @notice Returns 256 packed tick initialized boolean values. See TickTable for more information */ function tickTable(int16 wordPosition) external view returns (uint256); /** * @notice Returns the information about a position by the position's key * @dev This is a public mapping of structures, so the `return` natspec tags are omitted. * @param key The position's key is a hash of a preimage composed by the owner, bottomTick and topTick * @return liquidityAmount The amount of liquidity in the position; * Returns lastLiquidityAddTimestamp Timestamp of last adding of liquidity; * Returns innerFeeGrowth0Token Fee growth of token0 inside the tick range as of the last mint/burn/poke; * Returns innerFeeGrowth1Token Fee growth of token1 inside the tick range as of the last mint/burn/poke; * Returns fees0 The computed amount of token0 owed to the position as of the last mint/burn/poke; * Returns fees1 The computed amount of token1 owed to the position as of the last mint/burn/poke */ function positions(bytes32 key) external view returns ( uint128 liquidityAmount, uint32 lastLiquidityAddTimestamp, uint256 innerFeeGrowth0Token, uint256 innerFeeGrowth1Token, uint128 fees0, uint128 fees1 ); /** * @notice Returns data about a specific timepoint index * @param index The element of the timepoints array to fetch * @dev You most likely want to use #getTimepoints() instead of this method to get an timepoint as of some amount of time * ago, rather than at a specific index in the array. * This is a public mapping of structures, so the `return` natspec tags are omitted. * @return initialized whether the timepoint has been initialized and the values are safe to use; * Returns blockTimestamp The timestamp of the timepoint; * Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the timepoint timestamp; * Returns secondsPerLiquidityCumulative the seconds per in range liquidity for the life of the pool as of the timepoint timestamp; * Returns volatilityCumulative Cumulative standard deviation for the life of the pool as of the timepoint timestamp; * Returns averageTick Time-weighted average tick; * Returns 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 Returns the information about active incentive * @dev if there is no active incentive at the moment, virtualPool,endTimestamp,startTimestamp would be equal to 0 * @return virtualPool The address of a virtual pool associated with the current active incentive */ function activeIncentive() external view returns (address virtualPool); /** * @notice Returns the lock time for added liquidity */ function liquidityCooldown() external view returns (uint32 cooldownInSeconds); }
// 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: 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: GPL-2.0-or-later pragma solidity >=0.7.0; /// @title Optimized overflow and underflow safe math operations /// @notice Contains methods for doing math operations that revert on overflow or underflow for minimal gas cost /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/blob/main/contracts/libraries library LowGasSafeMath { /// @notice Returns x + y, reverts if sum overflows uint256 /// @param x The augend /// @param y The addend /// @return z The sum of x and y function add(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x + y) >= x); } /// @notice Returns x - y, reverts if underflows /// @param x The minuend /// @param y The subtrahend /// @return z The difference of x and y function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { require((z = x - y) <= x); } /// @notice Returns x * y, reverts if overflows /// @param x The multiplicand /// @param y The multiplier /// @return z The product of x and y function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { require(x == 0 || (z = x * y) / x == y); } /// @notice Returns x + y, reverts if overflows or underflows /// @param x The augend /// @param y The addend /// @return z The sum of x and y function add(int256 x, int256 y) internal pure returns (int256 z) { require((z = x + y) >= x == (y >= 0)); } /// @notice Returns x - y, reverts if overflows or underflows /// @param x The minuend /// @param y The subtrahend /// @return z The difference of x and y function sub(int256 x, int256 y) internal pure returns (int256 z) { require((z = x - y) <= x == (y >= 0)); } /// @notice Returns x + y, reverts if overflows or underflows /// @param x The augend /// @param y The addend /// @return z The sum of x and y function add128(uint128 x, uint128 y) internal pure returns (uint128 z) { require((z = x + y) >= x); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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/libraries library 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 uint160 function 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 int128 function 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 int256 function toInt256(uint256 y) internal pure returns (int256 z) { require(y < 2**255); z = int256(y); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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/libraries library TickMath { /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 int24 internal constant MIN_TICK = -887272; /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 int24 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 tick function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 price) { // get abs value int24 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; if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; if (tick > 0) ratio = type(uint256).max / ratio; // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. // we then downcast because we know the result always fits within 160 bits due to our tick input constraint // we round up in the division so getTickAtSqrtRatio of the output price is always consistent price = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); } /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio /// @dev Throws in case price < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may /// ever return. /// @param price The sqrt ratio for which to compute the tick as a Q64.96 /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio function getTickAtSqrtRatio(uint160 price) internal pure returns (int24 tick) { // second inequality must be < because the price can never reach the price at the max tick require(price >= MIN_SQRT_RATIO && price < MAX_SQRT_RATIO, 'R'); uint256 ratio = uint256(price) << 32; uint256 r = ratio; uint256 msb = 0; assembly { let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(5, gt(r, 0xFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(4, gt(r, 0xFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(3, gt(r, 0xFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(2, gt(r, 0xF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(1, gt(r, 0x3)) msb := or(msb, f) r := shr(f, r) } assembly { let f := gt(r, 0x1) msb := or(msb, f) } if (msb >= 128) r = ratio >> (msb - 127); else r = ratio << (127 - msb); int256 log_2 = (int256(msb) - 128) << 64; assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(63, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(62, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(61, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(60, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(59, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(58, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(57, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(56, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(55, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(54, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(53, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(52, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(51, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(50, f)) } int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= price ? tickHi : tickLow; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens, * given `owner`'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; /// @title Function for getting block timestamp /// @dev Base contract that is overridden for tests abstract contract BlockTimestamp { /// @dev Method that exists purely to be overridden for tests /// @return The current block timestamp function _blockTimestamp() internal view virtual returns (uint256) { return block.timestamp; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; pragma abicoder v2; import '../interfaces/IMulticall.sol'; /// @title Multicall /// @notice Enables calling multiple methods in a single call to the contract abstract contract Multicall is IMulticall { /// @inheritdoc IMulticall function multicall(bytes[] calldata data) external payable override returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); if (!success) { // Next 5 lines from https://ethereum.stackexchange.com/a/83577 if (result.length < 68) revert(); assembly { result := add(result, 0x04) } revert(abi.decode(result, (string))); } results[i] = result; } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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-periphery abstract contract PeripheryImmutableState is IPeripheryImmutableState { /// @inheritdoc IPeripheryImmutableState address public immutable override factory; /// @inheritdoc IPeripheryImmutableState address public immutable override poolDeployer; /// @inheritdoc IPeripheryImmutableState address public immutable override WNativeToken; constructor( address _factory, address _WNativeToken, address _poolDeployer ) { factory = _factory; poolDeployer = _poolDeployer; WNativeToken = _WNativeToken; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '../interfaces/IPeripheryPayments.sol'; import '../interfaces/external/IWNativeToken.sol'; import '../libraries/TransferHelper.sol'; import './PeripheryImmutableState.sol'; /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery abstract contract PeripheryPayments is IPeripheryPayments, PeripheryImmutableState { receive() external payable { require(msg.sender == WNativeToken, 'Not WNativeToken'); } /// @inheritdoc IPeripheryPayments function unwrapWNativeToken(uint256 amountMinimum, address recipient) external payable override { uint256 balanceWNativeToken = IWNativeToken(WNativeToken).balanceOf(address(this)); require(balanceWNativeToken >= amountMinimum, 'Insufficient WNativeToken'); if (balanceWNativeToken > 0) { IWNativeToken(WNativeToken).withdraw(balanceWNativeToken); TransferHelper.safeTransferNative(recipient, balanceWNativeToken); } } /// @inheritdoc IPeripheryPayments function sweepToken( address token, uint256 amountMinimum, address recipient ) external payable override { uint256 balanceToken = IERC20(token).balanceOf(address(this)); require(balanceToken >= amountMinimum, 'Insufficient token'); if (balanceToken > 0) { TransferHelper.safeTransfer(token, recipient, balanceToken); } } /// @inheritdoc IPeripheryPayments function refundNativeToken() external payable override { if (address(this).balance > 0) TransferHelper.safeTransferNative(msg.sender, address(this).balance); } /// @param token The token to pay /// @param payer The entity that must pay /// @param recipient The entity that will receive payment /// @param value The amount to pay function pay( address token, address payer, address recipient, uint256 value ) internal { if (token == WNativeToken && address(this).balance >= value) { // pay with WNativeToken IWNativeToken(WNativeToken).deposit{value: value}(); // wrap only what is needed to pay IWNativeToken(WNativeToken).transfer(recipient, value); } else if (payer == address(this)) { // pay with tokens already in the contract (for the exact input multihop case) TransferHelper.safeTransfer(token, recipient, value); } else { // pull payment TransferHelper.safeTransferFrom(token, payer, recipient, value); } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@cryptoalgebra/core/contracts/libraries/LowGasSafeMath.sol'; import './PeripheryPayments.sol'; import '../interfaces/IPeripheryPaymentsWithFee.sol'; import '../interfaces/external/IWNativeToken.sol'; import '../libraries/TransferHelper.sol'; /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery abstract contract PeripheryPaymentsWithFee is PeripheryPayments, IPeripheryPaymentsWithFee { using LowGasSafeMath for uint256; /// @inheritdoc IPeripheryPaymentsWithFee function unwrapWNativeTokenWithFee( uint256 amountMinimum, address recipient, uint256 feeBips, address feeRecipient ) public payable override { require(feeBips > 0 && feeBips <= 100); uint256 balanceWNativeToken = IWNativeToken(WNativeToken).balanceOf(address(this)); require(balanceWNativeToken >= amountMinimum, 'Insufficient WNativeToken'); if (balanceWNativeToken > 0) { IWNativeToken(WNativeToken).withdraw(balanceWNativeToken); uint256 feeAmount = balanceWNativeToken.mul(feeBips) / 10_000; if (feeAmount > 0) TransferHelper.safeTransferNative(feeRecipient, feeAmount); TransferHelper.safeTransferNative(recipient, balanceWNativeToken - feeAmount); } } /// @inheritdoc IPeripheryPaymentsWithFee function sweepTokenWithFee( address token, uint256 amountMinimum, address recipient, uint256 feeBips, address feeRecipient ) public payable override { require(feeBips > 0 && feeBips <= 100); uint256 balanceToken = IERC20(token).balanceOf(address(this)); require(balanceToken >= amountMinimum, 'Insufficient token'); if (balanceToken > 0) { uint256 feeAmount = balanceToken.mul(feeBips) / 10_000; if (feeAmount > 0) TransferHelper.safeTransfer(token, feeRecipient, feeAmount); TransferHelper.safeTransfer(token, recipient, balanceToken - feeAmount); } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; import './BlockTimestamp.sol'; /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery abstract contract PeripheryValidation is BlockTimestamp { modifier checkDeadline(uint256 deadline) { require(_blockTimestamp() <= deadline, 'Transaction too old'); _; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts/drafts/IERC20Permit.sol'; import '../interfaces/ISelfPermit.sol'; import '../interfaces/external/IERC20PermitAllowed.sol'; /// @title Self Permit /// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route /// @dev These functions are expected to be embedded in multicalls to allow EOAs to approve a contract and call a function /// that requires an approval in a single transaction. abstract contract SelfPermit is ISelfPermit { /// @inheritdoc ISelfPermit function selfPermit( address token, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public payable override { IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s); } /// @inheritdoc ISelfPermit function selfPermitIfNecessary( address token, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external payable override { if (IERC20(token).allowance(msg.sender, address(this)) < value) selfPermit(token, value, deadline, v, r, s); } /// @inheritdoc ISelfPermit function selfPermitAllowed( address token, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public payable override { IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s); } /// @inheritdoc ISelfPermit function selfPermitAllowedIfNecessary( address token, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external payable override { if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) selfPermitAllowed(token, nonce, expiry, v, r, s); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Interface for permit /// @notice Interface used by DAI/CHAI for permit interface IERC20PermitAllowed { /// @notice Approve the spender to spend some tokens via the holder signature /// @dev This is the permit interface used by DAI and CHAI /// @param holder The address of the token holder, the token owner /// @param spender The address of the token spender /// @param nonce The holder's nonce, increases at each call to permit /// @param expiry The timestamp at which the permit is no longer valid /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0 /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; /// @title Interface for WNativeToken interface IWNativeToken is IERC20 { /// @notice Deposit ether to get wrapped ether function deposit() external payable; /// @notice Withdraw wrapped ether to get ether function withdraw(uint256) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Multicall interface /// @notice Enables calling multiple methods in a single call to the contract interface IMulticall { /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed /// @dev The `msg.value` should not be trusted for any method callable from multicall. /// @param data The encoded function data for each of the calls to make to this contract /// @return results The results from each of the calls passed in via data function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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-periphery interface IPeripheryImmutableState { /// @return Returns the address of the Algebra factory function factory() external view returns (address); /// @return Returns the address of the pool Deployer function poolDeployer() external view returns (address); /// @return Returns the address of WNativeToken function WNativeToken() external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; /// @title Periphery Payments /// @notice Functions to ease deposits and withdrawals of NativeToken /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery interface IPeripheryPayments { /// @notice Unwraps the contract's WNativeToken balance and sends it to recipient as NativeToken. /// @dev The amountMinimum parameter prevents malicious contracts from stealing WNativeToken from users. /// @param amountMinimum The minimum amount of WNativeToken to unwrap /// @param recipient The address receiving NativeToken function unwrapWNativeToken(uint256 amountMinimum, address recipient) external payable; /// @notice Refunds any NativeToken balance held by this contract to the `msg.sender` /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps /// that use ether for the input amount function refundNativeToken() external payable; /// @notice Transfers the full amount of a token held by this contract to recipient /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users /// @param token The contract address of the token which will be transferred to `recipient` /// @param amountMinimum The minimum amount of token required for a transfer /// @param recipient The destination address of the token function sweepToken( address token, uint256 amountMinimum, address recipient ) external payable; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; import './IPeripheryPayments.sol'; /// @title Periphery Payments /// @notice Functions to ease deposits and withdrawals of NativeToken /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery interface IPeripheryPaymentsWithFee is IPeripheryPayments { /// @notice Unwraps the contract's WNativeToken balance and sends it to recipient as NativeToken, with a percentage between /// 0 (exclusive), and 1 (inclusive) going to feeRecipient /// @dev The amountMinimum parameter prevents malicious contracts from stealing WNativeToken from users. function unwrapWNativeTokenWithFee( uint256 amountMinimum, address recipient, uint256 feeBips, address feeRecipient ) external payable; /// @notice Transfers the full amount of a token held by this contract to recipient, with a percentage between /// 0 (exclusive) and 1 (inclusive) going to feeRecipient /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users function sweepTokenWithFee( address token, uint256 amountMinimum, address recipient, uint256 feeBips, address feeRecipient ) external payable; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; /// @title Self Permit /// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route interface ISelfPermit { /// @notice Permits this contract to spend a given token from `msg.sender` /// @dev The `owner` is always msg.sender and the `spender` is always address(this). /// @param token The address of the token spent /// @param value The amount that can be spent of token /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` function selfPermit( address token, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external payable; /// @notice Permits this contract to spend a given token from `msg.sender` /// @dev The `owner` is always msg.sender and the `spender` is always address(this). /// Can be used instead of #selfPermit to prevent calls from failing due to a frontrun of a call to #selfPermit /// @param token The address of the token spent /// @param value The amount that can be spent of token /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` function selfPermitIfNecessary( address token, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external payable; /// @notice Permits this contract to spend the sender's tokens for permit signatures that have the `allowed` parameter /// @dev The `owner` is always msg.sender and the `spender` is always address(this) /// @param token The address of the token spent /// @param nonce The current nonce of the owner /// @param expiry The timestamp at which the permit is no longer valid /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` function selfPermitAllowed( address token, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external payable; /// @notice Permits this contract to spend the sender's tokens for permit signatures that have the `allowed` parameter /// @dev The `owner` is always msg.sender and the `spender` is always address(this) /// Can be used instead of #selfPermitAllowed to prevent calls from failing due to a frontrun of a call to #selfPermitAllowed. /// @param token The address of the token spent /// @param nonce The current nonce of the owner /// @param expiry The timestamp at which the permit is no longer valid /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` function selfPermitAllowedIfNecessary( address token, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external payable; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@cryptoalgebra/core/contracts/interfaces/callback/IAlgebraSwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Algebra /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery interface ISwapRouter is IAlgebraSwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 limitSqrtPrice; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 limitSqrtPrice; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @dev Unlike standard swaps, handles transferring from user before the actual swap. /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInputSingleSupportingFeeOnTransferTokens(ExactInputSingleParams calldata params) external returns (uint256 amountOut); }
// SPDX-License-Identifier: GPL-2.0-or-later /** * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @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) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_start + 20 >= _start, 'toAddress_overflow'); require(_bytes.length >= _start + 20, 'toAddress_outOfBounds'); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) { require(_start + 3 >= _start, 'toUint24_overflow'); require(_bytes.length >= _start + 3, 'toUint24_outOfBounds'); uint24 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x3), _start)) } return tempUint; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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-periphery library 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 address function 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 address function verifyCallback(address poolDeployer, PoolAddress.PoolKey memory poolKey) internal view returns (IAlgebraPool pool) { pool = IAlgebraPool(PoolAddress.computeAddress(poolDeployer, poolKey)); require(msg.sender == address(pool)); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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-periphery library Path { using BytesLib for bytes; /// @dev The length of the bytes encoded address uint256 private constant ADDR_SIZE = 20; /// @dev The length of the bytes encoded fee uint256 private constant FEE_SIZE = 3; /// @dev The offset of a single token address and pool fee uint256 private constant NEXT_OFFSET = ADDR_SIZE; /// @dev The offset of an encoded pool key uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; /// @dev The minimum length of an encoding that contains 2 or more pools uint256 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 false function 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 path function 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 /// @return tokenB The second token of the given pool function decodeFirstPool(bytes memory path) internal pure returns (address tokenA, address tokenB) { tokenA = path.toAddress(0); tokenB = path.toAddress(NEXT_OFFSET); } /// @notice Gets the segment corresponding to the first pool in the path /// @param path The bytes encoded swap path /// @return The segment containing all data necessary to target the first pool in the path function getFirstPool(bytes memory path) internal pure returns (bytes memory) { return path.slice(0, POP_OFFSET); } /// @notice Skips a token + fee element from the buffer and returns the remainder /// @param path The swap path /// @return The remaining token + fee elements in the path function skipToken(bytes memory path) internal pure returns (bytes memory) { return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma 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-periphery library PoolAddress { bytes32 internal constant POOL_INIT_CODE_HASH = 0x424896f6cdc5182412012e0779626543e1dc4b12e1c45ee5718ae92f10ad97f2; /// @notice The identifying key of the pool struct 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 assignments function 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 pool function 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 ) ) ) ); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-periphery library TransferHelper { /// @notice Transfers tokens from the targeted address to the given destination /// @notice Errors with 'STF' if transfer fails /// @param token The contract address of the token to be transferred /// @param from The originating address from which the tokens will be transferred /// @param to The destination address of the transfer /// @param value The amount to be transferred function safeTransferFrom( address token, address from, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call( abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value) ); require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); } /// @notice Transfers tokens from msg.sender to a recipient /// @dev Errors with ST if transfer fails /// @param token The contract address of the token which will be transferred /// @param to The recipient of the transfer /// @param value The value of the transfer function safeTransfer( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); } /// @notice Approves the stipulated contract to spend the given allowance in the given token /// @dev Errors with 'SA' if transfer fails /// @param token The contract address of the token to be approved /// @param to The target of the approval /// @param value The amount of the given token the target will be allowed to spend function safeApprove( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); } /// @notice Transfers NativeToken to the recipient address /// @dev Fails with `STE` /// @param to The destination of the transfer /// @param value The value to be transferred function safeTransferNative(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'STE'); } }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "bytecodeHash": "none" }, "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":"_factory","type":"address"},{"internalType":"address","name":"_WNativeToken","type":"address"},{"internalType":"address","name":"_poolDeployer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WNativeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"algebraSwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"internalType":"struct ISwapRouter.ExactInputParams","name":"params","type":"tuple"}],"name":"exactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"internalType":"uint160","name":"limitSqrtPrice","type":"uint160"}],"internalType":"struct ISwapRouter.ExactInputSingleParams","name":"params","type":"tuple"}],"name":"exactInputSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"internalType":"uint160","name":"limitSqrtPrice","type":"uint160"}],"internalType":"struct ISwapRouter.ExactInputSingleParams","name":"params","type":"tuple"}],"name":"exactInputSingleSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct ISwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"},{"internalType":"uint160","name":"limitSqrtPrice","type":"uint160"}],"internalType":"struct ISwapRouter.ExactOutputSingleParams","name":"params","type":"tuple"}],"name":"exactOutputSingle","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"poolDeployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundNativeToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowed","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowedIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"sweepToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"feeBips","type":"uint256"},{"internalType":"address","name":"feeRecipient","type":"address"}],"name":"sweepTokenWithFee","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"unwrapWNativeToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"feeBips","type":"uint256"},{"internalType":"address","name":"feeRecipient","type":"address"}],"name":"unwrapWNativeTokenWithFee","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e06040526000196000553480156200001757600080fd5b50604051620032c8380380620032c88339810160408190526200003a916200007e565b6001600160601b0319606093841b811660805290831b811660a052911b1660c052620000c7565b80516001600160a01b03811681146200007957600080fd5b919050565b60008060006060848603121562000093578283fd5b6200009e8462000061565b9250620000ae6020850162000061565b9150620000be6040850162000061565b90509250925092565b60805160601c60a05160601c60c05160601c6131996200012f6000398061016552806105ed528061071752806107b152806111075280611231528061190d528061196d52806119ee5250806103e752806104f55280611e255250806110c752506131996000f3fe6080604052600436106101485760003560e01c8063bc651188116100c0578063db3e219811610074578063e0e189a011610059578063e0e189a01461036d578063f28c049814610380578063f3995c6714610393576101f3565b8063db3e219814610347578063df2ab5bb1461035a576101f3565b8063c2e3140a116100a5578063c2e3140a1461030c578063c45a01551461031f578063c60696ec14610334576101f3565b8063bc651188146102e6578063c04b8d59146102f9576101f3565b806369bc35b211610117578063a4a78f0c116100fc578063a4a78f0c14610286578063ac9650d814610299578063b87d2524146102b9576101f3565b806369bc35b21461025e5780638af3ac8514610271576101f3565b80632c8958f6146101f85780633119049a1461021857806341865270146102435780634659a4941461024b576101f3565b366101f3573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420574e6174697665546f6b656e00000000000000000000000000000000604482015290519081900360640190fd5b005b600080fd5b34801561020457600080fd5b506101f1610213366004612abf565b6103a6565b34801561022457600080fd5b5061022d6104f3565b60405161023a9190612e4f565b60405180910390f35b6101f1610517565b6101f16102593660046129cd565b610529565b6101f161026c366004612d43565b6105e9565b34801561027d57600080fd5b5061022d6107af565b6101f16102943660046129cd565b6107d3565b6102ac6102a7366004612a2d565b6108b0565b60405161023a9190612f1d565b3480156102c557600080fd5b506102d96102d4366004612c58565b610a13565b60405161023a9190613064565b6102d96102f4366004612c58565b610d5a565b6102d9610307366004612bad565b610eb1565b6101f161031a3660046129cd565b611010565b34801561032b57600080fd5b5061022d6110c5565b6101f1610342366004612d72565b6110e9565b6102d9610355366004612ca1565b6112ff565b6101f161036836600461292e565b61147e565b6101f161037b36600461296f565b61159b565b6102d961038e366004612c69565b611701565b6101f16103a13660046129cd565b611835565b60008413806103b55750600083135b6103be57600080fd5b60006103cc82840184612cb3565b90506000806103de83600001516118cd565b9150915061040d7f000000000000000000000000000000000000000000000000000000000000000083836118ee565b506000806000891361044e578373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16108861047f565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610895b91509150811561049e57610499848660200151338461190b565b6104e8565b84516104a990611ae9565b156104ce5784516104b990611af5565b85526104c88133600088611b16565b506104e8565b806000819055508293506104e8848660200151338461190b565b505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b4715610527576105273347611ccc565b565b604080517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101879052606481018690526001608482015260ff851660a482015260c4810184905260e48101839052905173ffffffffffffffffffffffffffffffffffffffff881691638fcbaf0c9161010480830192600092919082900301818387803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561067257600080fd5b505afa158015610686573d6000803e3d6000fd5b505050506040513d602081101561069c57600080fd5b505190508281101561070f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156107aa577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561078857600080fd5b505af115801561079c573d6000803e3d6000fd5b505050506107aa8282611ccc565b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015290517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561086857600080fd5b505afa15801561087c573d6000803e3d6000fd5b505050506040513d602081101561089257600080fd5b505110156108a8576108a8868686868686610529565b505050505050565b60608167ffffffffffffffff811180156108c957600080fd5b506040519080825280602002602001820160405280156108fd57816020015b60608152602001906001900390816108e85790505b50905060005b82811015610a0c576000803086868581811061091b57fe5b905060200281019061092d919061306d565b60405161093b929190612e3f565b600060405180830381855af49150503d8060008114610976576040519150601f19603f3d011682016040523d82523d6000602084013e61097b565b606091505b5091509150816109ea5760448151101561099457600080fd5b600481019050808060200190518101906109ae9190612b3a565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e19190612f9b565b60405180910390fd5b808484815181106109f757fe5b60209081029190910101525050600101610903565b5092915050565b6000816060013580610a23611e1a565b1115610a9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6040805180820190915260009080610aab6020870187612912565b610abb6040880160208901612912565b604051602001610acc929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250905060008073ffffffffffffffffffffffffffffffffffffffff16856040016020810190610b289190612912565b73ffffffffffffffffffffffffffffffffffffffff1614610b5857610b536060860160408701612912565b610b5a565b305b90506000610b6e6040870160208801612912565b73ffffffffffffffffffffffffffffffffffffffff16610b916020880188612912565b73ffffffffffffffffffffffffffffffffffffffff16109050600080610bd2610bbd60208a018a612912565b610bcd60408b0160208c01612912565b611e1e565b73ffffffffffffffffffffffffffffffffffffffff166371334694338686610bfd8d60800135611e5a565b8d60c0016020810190610c109190612912565b73ffffffffffffffffffffffffffffffffffffffff1615610c43578d60c0016020810190610c3e9190612912565b610c69565b88610c625773fffd8963efd1fc6a506488495d951d5263988d25610c69565b6401000276a45b8b604051602001610c7a919061301c565b6040516020818303038152906040526040518763ffffffff1660e01b8152600401610caa96959493929190612e70565b6040805180830381600087803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb9190612a9c565b9150915082610d0a5781610d0c565b805b60000396508760a00135871015610d4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b505050505050919050565b6000816060013580610d6a611e1a565b1115610dd757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b610e6b6080840135610def6060860160408701612912565b610dff60e0870160c08801612912565b6040805180820190915280610e1760208a018a612912565b610e2760408b0160208c01612912565b604051602001610e38929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b91508260a00135821015610eab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b50919050565b6000816040015180610ec1611e1a565b1115610f2e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b335b6000610f3f8560000151611ae9565b9050610f98856060015182610f58578660200151610f5a565b305b60006040518060400160405280610f748b6000015161200c565b81526020018773ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b60608601528015610fb8578451309250610fb190611af5565b8552610fc5565b8460600151935050610fcb565b50610f30565b8360800151831015611009576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b5050919050565b604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051869173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561108557600080fd5b505afa158015611099573d6000803e3d6000fd5b505050506040513d60208110156110af57600080fd5b505110156108a8576108a8868686868686611835565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000821180156110fa575060648211155b61110357600080fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561118c57600080fd5b505afa1580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b505190508481101561122957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156112f8577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156112a257600080fd5b505af11580156112b6573d6000803e3d6000fd5b5050505060006127106112d2858461201b90919063ffffffff16565b816112d957fe5b04905080156112ec576112ec8382611ccc565b6108a885828403611ccc565b5050505050565b600081608001358061130f611e1a565b111561137c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b61141460a08401356113946080860160608701612912565b6113a5610100870160e08801612912565b60405180604001604052808860200160208101906113c39190612912565b6113d060208b018b612912565b6040516020016113e1929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611b16565b91508260c00135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055919050565b60008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d602081101561151157600080fd5b505190508281101561158457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156115955761159584838361203f565b50505050565b6000821180156115ac575060648211155b6115b557600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561161e57600080fd5b505afa158015611632573d6000803e3d6000fd5b505050506040513d602081101561164857600080fd5b50519050848110156116bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156108a85760006127106116d0838661201b565b816116d757fe5b04905080156116eb576116eb87848361203f565b6116f8878683850361203f565b50505050505050565b6000816040013580611711611e1a565b111561177e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6117f160608401356117966040860160208701612912565b60408051808201909152600090806117ae898061306d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525033602090910152611b16565b5060005491508260800135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b604080517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018790526064810186905260ff8516608482015260a4810184905260c48101839052905173ffffffffffffffffffffffffffffffffffffffff88169163d505accf9160e480830192600092919082900301818387803b1580156105c957600080fd5b6000806118da8382612214565b91506118e7836014612214565b9050915091565b6000611903846118fe8585612314565b612383565b949350505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156119665750804710155b15611aaf577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119d357600080fd5b505af11580156119e7573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611a7d57600080fd5b505af1158015611a91573d6000803e3d6000fd5b505050506040513d6020811015611aa757600080fd5b506115959050565b73ffffffffffffffffffffffffffffffffffffffff8316301415611add57611ad884838361203f565b611595565b611595848484846123b3565b8051603c11155b919050565b6060611b10601480845103846125909092919063ffffffff16565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8416611b37573093505b600080611b4784600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80831690821610600080611b758486611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611b9b8e611e5a565b60000373ffffffffffffffffffffffffffffffffffffffff8d1615611bc0578c611be6565b87611bdf5773fffd8963efd1fc6a506488495d951d5263988d25611be6565b6401000276a45b8c604051602001611bf7919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611c26959493929190612ecb565b6040805180830381600087803b158015611c3f57600080fd5b505af1158015611c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c779190612a9c565b91509150600083611c8c578183600003611c92565b82826000035b909750905073ffffffffffffffffffffffffffffffffffffffff8916611cbe578a8114611cbe57600080fd5b505050505050949350505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040518082805190602001908083835b60208310611d4357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611d06565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611da5576040519150601f19603f3d011682016040523d82523d6000602084013e611daa565b606091505b50509050806107aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354450000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b4290565b6000611e537f0000000000000000000000000000000000000000000000000000000000000000611e4e8585612314565b612777565b9392505050565b60007f80000000000000000000000000000000000000000000000000000000000000008210611e8857600080fd5b5090565b600073ffffffffffffffffffffffffffffffffffffffff8416611ead573093505b600080611ebd84600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80821690831610600080611eeb8585611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611f118e611e5a565b73ffffffffffffffffffffffffffffffffffffffff8d1615611f33578c611f59565b87611f525773fffd8963efd1fc6a506488495d951d5263988d25611f59565b6401000276a45b8c604051602001611f6a919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611f99959493929190612ecb565b6040805180830381600087803b158015611fb257600080fd5b505af1158015611fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fea9190612a9c565b9150915082611ff95781611ffb565b805b6000039a9950505050505050505050565b6060611b108260006028612590565b60008215806120365750508181028183828161203357fe5b04145b611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b6020831061211457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120d7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612176576040519150601f19603f3d011682016040523d82523d6000602084013e61217b565b606091505b50915091508180156121a95750805115806121a957508080602001905160208110156121a657600080fd5b50515b6112f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f5354000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60008182601401101561228857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b81601401835110156122fb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b5001602001516c01000000000000000000000000900490565b61231c61289f565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115612354579091905b506040805180820190915273ffffffffffffffffffffffffffffffffffffffff92831681529116602082015290565b600061238f8383612777565b90503373ffffffffffffffffffffffffffffffffffffffff821614611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000178152925182516000948594938a169392918291908083835b6020831061249057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612453565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146124f2576040519150601f19603f3d011682016040523d82523d6000602084013e6124f7565b606091505b5091509150818015612525575080511580612525575080806020019051602081101561252257600080fd5b50515b6108a857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60608182601f01101561260457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b82828401101561267557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b818301845110156126e757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015290519081900360640190fd5b606082158015612706576040519150600082526020820160405261276e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561273f578051835260209283019201612727565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16106127b957600080fd5b5080516020918201516040805173ffffffffffffffffffffffffffffffffffffffff938416818601529290911682820152805180830382018152606080840183528151918501919091207fff00000000000000000000000000000000000000000000000000000000000000608085015294901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608183015260958201939093527f424896f6cdc5182412012e0779626543e1dc4b12e1c45ee5718ae92f10ad97f260b5808301919091528351808303909101815260d5909101909252815191012090565b604080518082019091526000808252602082015290565b8035611af081613167565b600082601f8301126128d1578081fd5b81356128e46128df826130fb565b6130d7565b8181528460208386010111156128f8578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612923578081fd5b8135611e5381613167565b600080600060608486031215612942578182fd5b833561294d81613167565b925060208401359150604084013561296481613167565b809150509250925092565b600080600080600060a08688031215612986578081fd5b853561299181613167565b94506020860135935060408601356129a881613167565b92506060860135915060808601356129bf81613167565b809150509295509295909350565b60008060008060008060c087890312156129e5578081fd5b86356129f081613167565b95506020870135945060408701359350606087013560ff81168114612a13578182fd5b9598949750929560808101359460a0909101359350915050565b60008060208385031215612a3f578182fd5b823567ffffffffffffffff80821115612a56578384fd5b818501915085601f830112612a69578384fd5b813581811115612a77578485fd5b8660208083028501011115612a8a578485fd5b60209290920196919550909350505050565b60008060408385031215612aae578081fd5b505080516020909101519092909150565b60008060008060608587031215612ad4578182fd5b8435935060208501359250604085013567ffffffffffffffff80821115612af9578384fd5b818701915087601f830112612b0c578384fd5b813581811115612b1a578485fd5b886020828501011115612b2b578485fd5b95989497505060200194505050565b600060208284031215612b4b578081fd5b815167ffffffffffffffff811115612b61578182fd5b8201601f81018413612b71578182fd5b8051612b7f6128df826130fb565b818152856020838501011115612b93578384fd5b612ba482602083016020860161313b565b95945050505050565b600060208284031215612bbe578081fd5b813567ffffffffffffffff80821115612bd5578283fd5b9083019060a08286031215612be8578283fd5b60405160a081018181108382111715612bfd57fe5b604052823582811115612c0e578485fd5b612c1a878286016128c1565b825250612c29602084016128b6565b602082015260408301356040820152606083013560608201526080830135608082015280935050505092915050565b600060e08284031215610eab578081fd5b600060208284031215612c7a578081fd5b813567ffffffffffffffff811115612c90578182fd5b820160a08185031215611e53578182fd5b60006101008284031215610eab578081fd5b600060208284031215612cc4578081fd5b813567ffffffffffffffff80821115612cdb578283fd5b9083019060408286031215612cee578283fd5b604051604081018181108382111715612d0357fe5b604052823582811115612d14578485fd5b612d20878286016128c1565b82525060208301359250612d3383613167565b6020810192909252509392505050565b60008060408385031215612d55578182fd5b823591506020830135612d6781613167565b809150509250929050565b60008060008060808587031215612d87578182fd5b843593506020850135612d9981613167565b9250604085013591506060850135612db081613167565b939692955090935050565b60008151808452612dd381602086016020860161313b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606093841b811682529190921b16601482015260280190565b6000828483379101908152919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152861515604084015285606084015280851660808401525060c060a0830152612ebf60c0830184612dbb565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8088168352861515602084015285604084015280851660608401525060a06080830152612f1260a0830184612dbb565b979650505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015612f8e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612f7c858351612dbb565b94509285019290850190600101612f42565b5092979650505050505050565b600060208252611e536020830184612dbb565b60208082526012908201527f546f6f206d756368207265717565737465640000000000000000000000000000604082015260600190565b60208082526013908201527f546f6f206c6974746c6520726563656976656400000000000000000000000000604082015260600190565b6000602082528251604060208401526130386060840182612dbb565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401528091505092915050565b90815260200190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126130a1578283fd5b83018035915067ffffffffffffffff8211156130bb578283fd5b6020019150368190038213156130d057600080fd5b9250929050565b60405181810167ffffffffffffffff811182821017156130f357fe5b604052919050565b600067ffffffffffffffff82111561310f57fe5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b8381101561315657818101518382015260200161313e565b838111156115955750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461318957600080fd5b5056fea164736f6c6343000706000a000000000000000000000000abe1655110112d0e45ef91e94f8d757e4ddba59c000000000000000000000000acc15dc74880c9944775448304b263d191c6077f000000000000000000000000965a857955d868fd98482e9439b1af297623fb94
Deployed Bytecode
0x6080604052600436106101485760003560e01c8063bc651188116100c0578063db3e219811610074578063e0e189a011610059578063e0e189a01461036d578063f28c049814610380578063f3995c6714610393576101f3565b8063db3e219814610347578063df2ab5bb1461035a576101f3565b8063c2e3140a116100a5578063c2e3140a1461030c578063c45a01551461031f578063c60696ec14610334576101f3565b8063bc651188146102e6578063c04b8d59146102f9576101f3565b806369bc35b211610117578063a4a78f0c116100fc578063a4a78f0c14610286578063ac9650d814610299578063b87d2524146102b9576101f3565b806369bc35b21461025e5780638af3ac8514610271576101f3565b80632c8958f6146101f85780633119049a1461021857806341865270146102435780634659a4941461024b576101f3565b366101f3573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f16146101f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420574e6174697665546f6b656e00000000000000000000000000000000604482015290519081900360640190fd5b005b600080fd5b34801561020457600080fd5b506101f1610213366004612abf565b6103a6565b34801561022457600080fd5b5061022d6104f3565b60405161023a9190612e4f565b60405180910390f35b6101f1610517565b6101f16102593660046129cd565b610529565b6101f161026c366004612d43565b6105e9565b34801561027d57600080fd5b5061022d6107af565b6101f16102943660046129cd565b6107d3565b6102ac6102a7366004612a2d565b6108b0565b60405161023a9190612f1d565b3480156102c557600080fd5b506102d96102d4366004612c58565b610a13565b60405161023a9190613064565b6102d96102f4366004612c58565b610d5a565b6102d9610307366004612bad565b610eb1565b6101f161031a3660046129cd565b611010565b34801561032b57600080fd5b5061022d6110c5565b6101f1610342366004612d72565b6110e9565b6102d9610355366004612ca1565b6112ff565b6101f161036836600461292e565b61147e565b6101f161037b36600461296f565b61159b565b6102d961038e366004612c69565b611701565b6101f16103a13660046129cd565b611835565b60008413806103b55750600083135b6103be57600080fd5b60006103cc82840184612cb3565b90506000806103de83600001516118cd565b9150915061040d7f000000000000000000000000965a857955d868fd98482e9439b1af297623fb9483836118ee565b506000806000891361044e578373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16108861047f565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610895b91509150811561049e57610499848660200151338461190b565b6104e8565b84516104a990611ae9565b156104ce5784516104b990611af5565b85526104c88133600088611b16565b506104e8565b806000819055508293506104e8848660200151338461190b565b505050505050505050565b7f000000000000000000000000965a857955d868fd98482e9439b1af297623fb9481565b4715610527576105273347611ccc565b565b604080517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101879052606481018690526001608482015260ff851660a482015260c4810184905260e48101839052905173ffffffffffffffffffffffffffffffffffffffff881691638fcbaf0c9161010480830192600092919082900301818387803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b50505050505050505050565b60007f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561067257600080fd5b505afa158015610686573d6000803e3d6000fd5b505050506040513d602081101561069c57600080fd5b505190508281101561070f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156107aa577f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f73ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561078857600080fd5b505af115801561079c573d6000803e3d6000fd5b505050506107aa8282611ccc565b505050565b7f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f81565b604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015290517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561086857600080fd5b505afa15801561087c573d6000803e3d6000fd5b505050506040513d602081101561089257600080fd5b505110156108a8576108a8868686868686610529565b505050505050565b60608167ffffffffffffffff811180156108c957600080fd5b506040519080825280602002602001820160405280156108fd57816020015b60608152602001906001900390816108e85790505b50905060005b82811015610a0c576000803086868581811061091b57fe5b905060200281019061092d919061306d565b60405161093b929190612e3f565b600060405180830381855af49150503d8060008114610976576040519150601f19603f3d011682016040523d82523d6000602084013e61097b565b606091505b5091509150816109ea5760448151101561099457600080fd5b600481019050808060200190518101906109ae9190612b3a565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e19190612f9b565b60405180910390fd5b808484815181106109f757fe5b60209081029190910101525050600101610903565b5092915050565b6000816060013580610a23611e1a565b1115610a9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6040805180820190915260009080610aab6020870187612912565b610abb6040880160208901612912565b604051602001610acc929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250905060008073ffffffffffffffffffffffffffffffffffffffff16856040016020810190610b289190612912565b73ffffffffffffffffffffffffffffffffffffffff1614610b5857610b536060860160408701612912565b610b5a565b305b90506000610b6e6040870160208801612912565b73ffffffffffffffffffffffffffffffffffffffff16610b916020880188612912565b73ffffffffffffffffffffffffffffffffffffffff16109050600080610bd2610bbd60208a018a612912565b610bcd60408b0160208c01612912565b611e1e565b73ffffffffffffffffffffffffffffffffffffffff166371334694338686610bfd8d60800135611e5a565b8d60c0016020810190610c109190612912565b73ffffffffffffffffffffffffffffffffffffffff1615610c43578d60c0016020810190610c3e9190612912565b610c69565b88610c625773fffd8963efd1fc6a506488495d951d5263988d25610c69565b6401000276a45b8b604051602001610c7a919061301c565b6040516020818303038152906040526040518763ffffffff1660e01b8152600401610caa96959493929190612e70565b6040805180830381600087803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb9190612a9c565b9150915082610d0a5781610d0c565b805b60000396508760a00135871015610d4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b505050505050919050565b6000816060013580610d6a611e1a565b1115610dd757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b610e6b6080840135610def6060860160408701612912565b610dff60e0870160c08801612912565b6040805180820190915280610e1760208a018a612912565b610e2760408b0160208c01612912565b604051602001610e38929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b91508260a00135821015610eab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b50919050565b6000816040015180610ec1611e1a565b1115610f2e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b335b6000610f3f8560000151611ae9565b9050610f98856060015182610f58578660200151610f5a565b305b60006040518060400160405280610f748b6000015161200c565b81526020018773ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b60608601528015610fb8578451309250610fb190611af5565b8552610fc5565b8460600151935050610fcb565b50610f30565b8360800151831015611009576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b5050919050565b604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051869173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561108557600080fd5b505afa158015611099573d6000803e3d6000fd5b505050506040513d60208110156110af57600080fd5b505110156108a8576108a8868686868686611835565b7f000000000000000000000000abe1655110112d0e45ef91e94f8d757e4ddba59c81565b6000821180156110fa575060648211155b61110357600080fd5b60007f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561118c57600080fd5b505afa1580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b505190508481101561122957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156112f8577f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f73ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156112a257600080fd5b505af11580156112b6573d6000803e3d6000fd5b5050505060006127106112d2858461201b90919063ffffffff16565b816112d957fe5b04905080156112ec576112ec8382611ccc565b6108a885828403611ccc565b5050505050565b600081608001358061130f611e1a565b111561137c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b61141460a08401356113946080860160608701612912565b6113a5610100870160e08801612912565b60405180604001604052808860200160208101906113c39190612912565b6113d060208b018b612912565b6040516020016113e1929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611b16565b91508260c00135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055919050565b60008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d602081101561151157600080fd5b505190508281101561158457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156115955761159584838361203f565b50505050565b6000821180156115ac575060648211155b6115b557600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561161e57600080fd5b505afa158015611632573d6000803e3d6000fd5b505050506040513d602081101561164857600080fd5b50519050848110156116bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156108a85760006127106116d0838661201b565b816116d757fe5b04905080156116eb576116eb87848361203f565b6116f8878683850361203f565b50505050505050565b6000816040013580611711611e1a565b111561177e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6117f160608401356117966040860160208701612912565b60408051808201909152600090806117ae898061306d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525033602090910152611b16565b5060005491508260800135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b604080517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018790526064810186905260ff8516608482015260a4810184905260c48101839052905173ffffffffffffffffffffffffffffffffffffffff88169163d505accf9160e480830192600092919082900301818387803b1580156105c957600080fd5b6000806118da8382612214565b91506118e7836014612214565b9050915091565b6000611903846118fe8585612314565b612383565b949350505050565b7f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156119665750804710155b15611aaf577f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f73ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119d357600080fd5b505af11580156119e7573d6000803e3d6000fd5b50505050507f000000000000000000000000acc15dc74880c9944775448304b263d191c6077f73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611a7d57600080fd5b505af1158015611a91573d6000803e3d6000fd5b505050506040513d6020811015611aa757600080fd5b506115959050565b73ffffffffffffffffffffffffffffffffffffffff8316301415611add57611ad884838361203f565b611595565b611595848484846123b3565b8051603c11155b919050565b6060611b10601480845103846125909092919063ffffffff16565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8416611b37573093505b600080611b4784600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80831690821610600080611b758486611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611b9b8e611e5a565b60000373ffffffffffffffffffffffffffffffffffffffff8d1615611bc0578c611be6565b87611bdf5773fffd8963efd1fc6a506488495d951d5263988d25611be6565b6401000276a45b8c604051602001611bf7919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611c26959493929190612ecb565b6040805180830381600087803b158015611c3f57600080fd5b505af1158015611c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c779190612a9c565b91509150600083611c8c578183600003611c92565b82826000035b909750905073ffffffffffffffffffffffffffffffffffffffff8916611cbe578a8114611cbe57600080fd5b505050505050949350505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040518082805190602001908083835b60208310611d4357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611d06565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611da5576040519150601f19603f3d011682016040523d82523d6000602084013e611daa565b606091505b50509050806107aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354450000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b4290565b6000611e537f000000000000000000000000965a857955d868fd98482e9439b1af297623fb94611e4e8585612314565b612777565b9392505050565b60007f80000000000000000000000000000000000000000000000000000000000000008210611e8857600080fd5b5090565b600073ffffffffffffffffffffffffffffffffffffffff8416611ead573093505b600080611ebd84600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80821690831610600080611eeb8585611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611f118e611e5a565b73ffffffffffffffffffffffffffffffffffffffff8d1615611f33578c611f59565b87611f525773fffd8963efd1fc6a506488495d951d5263988d25611f59565b6401000276a45b8c604051602001611f6a919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611f99959493929190612ecb565b6040805180830381600087803b158015611fb257600080fd5b505af1158015611fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fea9190612a9c565b9150915082611ff95781611ffb565b805b6000039a9950505050505050505050565b6060611b108260006028612590565b60008215806120365750508181028183828161203357fe5b04145b611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b6020831061211457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120d7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612176576040519150601f19603f3d011682016040523d82523d6000602084013e61217b565b606091505b50915091508180156121a95750805115806121a957508080602001905160208110156121a657600080fd5b50515b6112f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f5354000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60008182601401101561228857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b81601401835110156122fb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b5001602001516c01000000000000000000000000900490565b61231c61289f565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115612354579091905b506040805180820190915273ffffffffffffffffffffffffffffffffffffffff92831681529116602082015290565b600061238f8383612777565b90503373ffffffffffffffffffffffffffffffffffffffff821614611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000178152925182516000948594938a169392918291908083835b6020831061249057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612453565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146124f2576040519150601f19603f3d011682016040523d82523d6000602084013e6124f7565b606091505b5091509150818015612525575080511580612525575080806020019051602081101561252257600080fd5b50515b6108a857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60608182601f01101561260457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b82828401101561267557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b818301845110156126e757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015290519081900360640190fd5b606082158015612706576040519150600082526020820160405261276e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561273f578051835260209283019201612727565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16106127b957600080fd5b5080516020918201516040805173ffffffffffffffffffffffffffffffffffffffff938416818601529290911682820152805180830382018152606080840183528151918501919091207fff00000000000000000000000000000000000000000000000000000000000000608085015294901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608183015260958201939093527f424896f6cdc5182412012e0779626543e1dc4b12e1c45ee5718ae92f10ad97f260b5808301919091528351808303909101815260d5909101909252815191012090565b604080518082019091526000808252602082015290565b8035611af081613167565b600082601f8301126128d1578081fd5b81356128e46128df826130fb565b6130d7565b8181528460208386010111156128f8578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612923578081fd5b8135611e5381613167565b600080600060608486031215612942578182fd5b833561294d81613167565b925060208401359150604084013561296481613167565b809150509250925092565b600080600080600060a08688031215612986578081fd5b853561299181613167565b94506020860135935060408601356129a881613167565b92506060860135915060808601356129bf81613167565b809150509295509295909350565b60008060008060008060c087890312156129e5578081fd5b86356129f081613167565b95506020870135945060408701359350606087013560ff81168114612a13578182fd5b9598949750929560808101359460a0909101359350915050565b60008060208385031215612a3f578182fd5b823567ffffffffffffffff80821115612a56578384fd5b818501915085601f830112612a69578384fd5b813581811115612a77578485fd5b8660208083028501011115612a8a578485fd5b60209290920196919550909350505050565b60008060408385031215612aae578081fd5b505080516020909101519092909150565b60008060008060608587031215612ad4578182fd5b8435935060208501359250604085013567ffffffffffffffff80821115612af9578384fd5b818701915087601f830112612b0c578384fd5b813581811115612b1a578485fd5b886020828501011115612b2b578485fd5b95989497505060200194505050565b600060208284031215612b4b578081fd5b815167ffffffffffffffff811115612b61578182fd5b8201601f81018413612b71578182fd5b8051612b7f6128df826130fb565b818152856020838501011115612b93578384fd5b612ba482602083016020860161313b565b95945050505050565b600060208284031215612bbe578081fd5b813567ffffffffffffffff80821115612bd5578283fd5b9083019060a08286031215612be8578283fd5b60405160a081018181108382111715612bfd57fe5b604052823582811115612c0e578485fd5b612c1a878286016128c1565b825250612c29602084016128b6565b602082015260408301356040820152606083013560608201526080830135608082015280935050505092915050565b600060e08284031215610eab578081fd5b600060208284031215612c7a578081fd5b813567ffffffffffffffff811115612c90578182fd5b820160a08185031215611e53578182fd5b60006101008284031215610eab578081fd5b600060208284031215612cc4578081fd5b813567ffffffffffffffff80821115612cdb578283fd5b9083019060408286031215612cee578283fd5b604051604081018181108382111715612d0357fe5b604052823582811115612d14578485fd5b612d20878286016128c1565b82525060208301359250612d3383613167565b6020810192909252509392505050565b60008060408385031215612d55578182fd5b823591506020830135612d6781613167565b809150509250929050565b60008060008060808587031215612d87578182fd5b843593506020850135612d9981613167565b9250604085013591506060850135612db081613167565b939692955090935050565b60008151808452612dd381602086016020860161313b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606093841b811682529190921b16601482015260280190565b6000828483379101908152919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152861515604084015285606084015280851660808401525060c060a0830152612ebf60c0830184612dbb565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8088168352861515602084015285604084015280851660608401525060a06080830152612f1260a0830184612dbb565b979650505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015612f8e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612f7c858351612dbb565b94509285019290850190600101612f42565b5092979650505050505050565b600060208252611e536020830184612dbb565b60208082526012908201527f546f6f206d756368207265717565737465640000000000000000000000000000604082015260600190565b60208082526013908201527f546f6f206c6974746c6520726563656976656400000000000000000000000000604082015260600190565b6000602082528251604060208401526130386060840182612dbb565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401528091505092915050565b90815260200190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126130a1578283fd5b83018035915067ffffffffffffffff8211156130bb578283fd5b6020019150368190038213156130d057600080fd5b9250929050565b60405181810167ffffffffffffffff811182821017156130f357fe5b604052919050565b600067ffffffffffffffff82111561310f57fe5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b8381101561315657818101518382015260200161313e565b838111156115955750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461318957600080fd5b5056fea164736f6c6343000706000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000abe1655110112d0e45ef91e94f8d757e4ddba59c000000000000000000000000acc15dc74880c9944775448304b263d191c6077f000000000000000000000000965a857955d868fd98482e9439b1af297623fb94
-----Decoded View---------------
Arg [0] : _factory (address): 0xabE1655110112D0E45EF91e94f8d757e4ddBA59C
Arg [1] : _WNativeToken (address): 0xAcc15dC74880C9944775448304B263D191c6077F
Arg [2] : _poolDeployer (address): 0x965A857955d868fd98482E9439b1aF297623fb94
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000abe1655110112d0e45ef91e94f8d757e4ddba59c
Arg [1] : 000000000000000000000000acc15dc74880c9944775448304b263d191c6077f
Arg [2] : 000000000000000000000000965a857955d868fd98482e9439b1af297623fb94
Loading...
Loading
Loading...
Loading
OVERVIEW
StellaSwap's Pulsar (concentrated liquidity) router.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.