Source Code
Overview
S Balance
S Value
$0.00Latest 25 from a total of 2,915 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Multicall | 50241879 | 105 days ago | IN | 0 S | 0.01654774 | ||||
| Multicall | 41187371 | 176 days ago | IN | 0 S | 0.01521113 | ||||
| Multicall | 38423124 | 194 days ago | IN | 0 S | 0.01489622 | ||||
| Multicall | 36635498 | 208 days ago | IN | 0.1 S | 0.0169916 | ||||
| Multicall | 36630777 | 208 days ago | IN | 3 S | 0.01447607 | ||||
| Multicall | 36611686 | 208 days ago | IN | 0 S | 0.01739125 | ||||
| Multicall | 36611279 | 208 days ago | IN | 2 S | 0.0184184 | ||||
| Multicall | 36606850 | 208 days ago | IN | 1 S | 0.01821735 | ||||
| Multicall | 36553693 | 208 days ago | IN | 25 S | 0.0245132 | ||||
| Multicall | 36549121 | 208 days ago | IN | 0.5 S | 0.01567968 | ||||
| Multicall | 36508224 | 209 days ago | IN | 0.001 S | 0.01746459 | ||||
| Multicall | 36451436 | 209 days ago | IN | 1 S | 0.01565683 | ||||
| Multicall | 36391078 | 209 days ago | IN | 15 S | 0.02901595 | ||||
| Multicall | 36376222 | 210 days ago | IN | 0.2 S | 0.02011896 | ||||
| Multicall | 36197897 | 211 days ago | IN | 0.1 S | 0.02068486 | ||||
| Multicall | 35975317 | 212 days ago | IN | 0 S | 0.0246239 | ||||
| Multicall | 35974961 | 212 days ago | IN | 0.1 S | 0.01949112 | ||||
| Multicall | 35969443 | 212 days ago | IN | 10 S | 0.02335544 | ||||
| Multicall | 35956653 | 212 days ago | IN | 0.1 S | 0.01700451 | ||||
| Multicall | 35549332 | 215 days ago | IN | 2 S | 0.02315682 | ||||
| Multicall | 35549064 | 215 days ago | IN | 1 S | 0.01775546 | ||||
| Multicall | 35517067 | 215 days ago | IN | 0.001 S | 0.01542713 | ||||
| Multicall | 35474738 | 215 days ago | IN | 11 S | 0.02582115 | ||||
| Multicall | 35401040 | 216 days ago | IN | 2 S | 0.01701998 | ||||
| Multicall | 35182131 | 217 days ago | IN | 4 S | 0.01900313 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 50241879 | 105 days ago | 0.01976925 S | ||||
| 50241879 | 105 days ago | 0.01976925 S | ||||
| 41187371 | 176 days ago | 17.15768572 S | ||||
| 41187371 | 176 days ago | 17.15768572 S | ||||
| 38423124 | 194 days ago | 3.06674548 S | ||||
| 38423124 | 194 days ago | 3.06674548 S | ||||
| 36635498 | 208 days ago | 0.1 S | ||||
| 36630777 | 208 days ago | 3 S | ||||
| 36611686 | 208 days ago | 1.99091411 S | ||||
| 36611686 | 208 days ago | 1.99091411 S | ||||
| 36611279 | 208 days ago | 2 S | ||||
| 36606850 | 208 days ago | 1 S | ||||
| 36553693 | 208 days ago | 25 S | ||||
| 36549121 | 208 days ago | 0.5 S | ||||
| 36508224 | 209 days ago | 0.001 S | ||||
| 36451436 | 209 days ago | 1 S | ||||
| 36391078 | 209 days ago | 15 S | ||||
| 36376222 | 210 days ago | 0.2 S | ||||
| 36197897 | 211 days ago | 0.1 S | ||||
| 35975317 | 212 days ago | 4.96829215 S | ||||
| 35975317 | 212 days ago | 4.96829215 S | ||||
| 35974961 | 212 days ago | 0.1 S | ||||
| 35969443 | 212 days ago | 10 S | ||||
| 35956653 | 212 days ago | 0.1 S | ||||
| 35549332 | 215 days ago | 2 S |
Cross-Chain Transactions
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/v1.9-directional-fee-core/contracts/libraries/SafeCast.sol';
import '@cryptoalgebra/v1.9-directional-fee-core/contracts/libraries/TickMath.sol';
import '@cryptoalgebra/v1.9-directional-fee-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(bool zto, AdaptiveFee.Configuration feeConfig);
/**
* @notice Returns data belonging to a certain timepoint
* @param index The index of timepoint in the array
* @dev There is more convenient function to fetch a timepoint: getTimepoints(). Which requires not an index but seconds
* @return initialized Whether the timepoint has been initialized and the values are safe to use,
* blockTimestamp The timestamp of the observation,
* tickCumulative The tick multiplied by seconds elapsed for the life of the pool as of the timepoint timestamp,
* secondsPerLiquidityCumulative The seconds per in range liquidity for the life of the pool as of the timepoint timestamp,
* volatilityCumulative Cumulative standard deviation for the life of the pool as of the timepoint timestamp,
* averageTick Time-weighted average tick,
* volumePerLiquidityCumulative Cumulative swap volume per liquidity for the life of the pool as of the timepoint timestamp
*/
function timepoints(uint256 index)
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(bool zto, 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 feeZto The fee for ZtO swaps in hundredths of a bip, i.e. 1e-6
/// @return feeOtz The fee for OtZ swaps in hundredths of a bip, i.e. 1e-6
function getFees(
uint32 time,
int24 tick,
uint16 index,
uint128 liquidity
) external view returns (uint16 feeZto, uint16 feeOtz);
}// 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 the tick spacing changes
* @param newTickSpacing The updated value of the new tick spacing
*/
event TickSpacing(int24 newTickSpacing);
/**
* @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 feeZto The value of the token fee for zto swaps
* @param feeOtz The value of the token fee for otz swaps
*/
event Fee(uint16 feeZto, uint16 feeOtz);
/**
* @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 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 Set the new tick spacing values. Only factory owner
/// @param newTickSpacing The new tick spacing value
function setTickSpacing(int24 newTickSpacing) external;
/**
* @notice Sets an active incentive
* @param virtualPoolAddress The address of a virtual pool associated with the incentive
*/
function setIncentive(address virtualPoolAddress) external;
/**
* @notice Sets new lock time for added liquidity
* @param newLiquidityCooldown The time in seconds
*/
function setLiquidityCooldown(uint32 newLiquidityCooldown) external;
}// 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 feeZto The last pool fee value for ZtO swaps in hundredths of a bip, i.e. 1e-6;
* Returns feeOtz The last pool fee value for OtZ swaps in hundredths of a bip, i.e. 1e-6;
* Returns timepointIndex The index of the last written timepoint;
* Returns communityFeeToken0 The community fee percentage of the swap fee in thousandths (1e-3) for token0;
* Returns communityFeeToken1 The community fee percentage of the swap fee in thousandths (1e-3) for token1;
* Returns unlocked Whether the pool is currently locked to reentrancy;
*/
function globalState()
external
view
returns (
uint160 price,
int24 tick,
uint16 feeZto,
uint16 feeOtz,
uint16 timepointIndex,
uint8 communityFeeToken0,
uint8 communityFeeToken1,
bool unlocked
);
/**
* @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool
* @dev This value can overflow the uint256
*/
function totalFeeGrowth0Token() external view returns (uint256);
/**
* @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);
/**
* @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);
}// 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 MAX_TICK_SPACING = 500;
// max(uint128) / (MAX_TICK - MIN_TICK)
uint128 internal constant MAX_LIQUIDITY_PER_TICK = 191757638537527648490752896198553;
uint32 internal constant MAX_LIQUIDITY_COOLDOWN = 1 days;
uint8 internal constant MAX_COMMUNITY_FEE = 250;
uint256 internal constant COMMUNITY_FEE_DENOMINATOR = 1000;
}// 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) public 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) public 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) public 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/v1.9-directional-fee-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/v1.9-directional-fee-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/v1.9-directional-fee-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 = 0x6c1bebd370ba84753516bc1393c0d0a6c645856da55f5393ac8ab3d6dbc861d3;
/// @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
Contract ABI
API[{"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
60e06040526000196000553480156200001757600080fd5b50604051620032c8380380620032c88339810160408190526200003a916200007e565b6001600160601b0319606093841b811660805290831b811660a052911b1660c052620000c7565b80516001600160a01b03811681146200007957600080fd5b919050565b60008060006060848603121562000093578283fd5b6200009e8462000061565b9250620000ae6020850162000061565b9150620000be6040850162000061565b90509250925092565b60805160601c60a05160601c60c05160601c6131996200012f6000398061016552806105ed528061071752806107b152806111075280611231528061190d528061196d52806119ee5250806103e752806104f55280611e255250806110c752506131996000f3fe6080604052600436106101485760003560e01c8063bc651188116100c0578063db3e219811610074578063e0e189a011610059578063e0e189a01461036d578063f28c049814610380578063f3995c6714610393576101f3565b8063db3e219814610347578063df2ab5bb1461035a576101f3565b8063c2e3140a116100a5578063c2e3140a1461030c578063c45a01551461031f578063c60696ec14610334576101f3565b8063bc651188146102e6578063c04b8d59146102f9576101f3565b806369bc35b211610117578063a4a78f0c116100fc578063a4a78f0c14610286578063ac9650d814610299578063b87d2524146102b9576101f3565b806369bc35b21461025e5780638af3ac8514610271576101f3565b80632c8958f6146101f85780633119049a1461021857806341865270146102435780634659a4941461024b576101f3565b366101f3573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420574e6174697665546f6b656e00000000000000000000000000000000604482015290519081900360640190fd5b005b600080fd5b34801561020457600080fd5b506101f1610213366004612abf565b6103a6565b34801561022457600080fd5b5061022d6104f3565b60405161023a9190612e4f565b60405180910390f35b6101f1610517565b6101f16102593660046129cd565b610529565b6101f161026c366004612d43565b6105e9565b34801561027d57600080fd5b5061022d6107af565b6101f16102943660046129cd565b6107d3565b6102ac6102a7366004612a2d565b6108b0565b60405161023a9190612f1d565b3480156102c557600080fd5b506102d96102d4366004612c58565b610a13565b60405161023a9190613064565b6102d96102f4366004612c58565b610d5a565b6102d9610307366004612bad565b610eb1565b6101f161031a3660046129cd565b611010565b34801561032b57600080fd5b5061022d6110c5565b6101f1610342366004612d72565b6110e9565b6102d9610355366004612ca1565b6112ff565b6101f161036836600461292e565b61147e565b6101f161037b36600461296f565b61159b565b6102d961038e366004612c69565b611701565b6101f16103a13660046129cd565b611835565b60008413806103b55750600083135b6103be57600080fd5b60006103cc82840184612cb3565b90506000806103de83600001516118cd565b9150915061040d7f000000000000000000000000000000000000000000000000000000000000000083836118ee565b506000806000891361044e578373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16108861047f565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610895b91509150811561049e57610499848660200151338461190b565b6104e8565b84516104a990611ae9565b156104ce5784516104b990611af5565b85526104c88133600088611b16565b506104e8565b806000819055508293506104e8848660200151338461190b565b505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b4715610527576105273347611ccc565b565b604080517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101879052606481018690526001608482015260ff851660a482015260c4810184905260e48101839052905173ffffffffffffffffffffffffffffffffffffffff881691638fcbaf0c9161010480830192600092919082900301818387803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561067257600080fd5b505afa158015610686573d6000803e3d6000fd5b505050506040513d602081101561069c57600080fd5b505190508281101561070f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156107aa577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561078857600080fd5b505af115801561079c573d6000803e3d6000fd5b505050506107aa8282611ccc565b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015290517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561086857600080fd5b505afa15801561087c573d6000803e3d6000fd5b505050506040513d602081101561089257600080fd5b505110156108a8576108a8868686868686610529565b505050505050565b60608167ffffffffffffffff811180156108c957600080fd5b506040519080825280602002602001820160405280156108fd57816020015b60608152602001906001900390816108e85790505b50905060005b82811015610a0c576000803086868581811061091b57fe5b905060200281019061092d919061306d565b60405161093b929190612e3f565b600060405180830381855af49150503d8060008114610976576040519150601f19603f3d011682016040523d82523d6000602084013e61097b565b606091505b5091509150816109ea5760448151101561099457600080fd5b600481019050808060200190518101906109ae9190612b3a565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e19190612f9b565b60405180910390fd5b808484815181106109f757fe5b60209081029190910101525050600101610903565b5092915050565b6000816060013580610a23611e1a565b1115610a9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6040805180820190915260009080610aab6020870187612912565b610abb6040880160208901612912565b604051602001610acc929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250905060008073ffffffffffffffffffffffffffffffffffffffff16856040016020810190610b289190612912565b73ffffffffffffffffffffffffffffffffffffffff1614610b5857610b536060860160408701612912565b610b5a565b305b90506000610b6e6040870160208801612912565b73ffffffffffffffffffffffffffffffffffffffff16610b916020880188612912565b73ffffffffffffffffffffffffffffffffffffffff16109050600080610bd2610bbd60208a018a612912565b610bcd60408b0160208c01612912565b611e1e565b73ffffffffffffffffffffffffffffffffffffffff166371334694338686610bfd8d60800135611e5a565b8d60c0016020810190610c109190612912565b73ffffffffffffffffffffffffffffffffffffffff1615610c43578d60c0016020810190610c3e9190612912565b610c69565b88610c625773fffd8963efd1fc6a506488495d951d5263988d25610c69565b6401000276a45b8b604051602001610c7a919061301c565b6040516020818303038152906040526040518763ffffffff1660e01b8152600401610caa96959493929190612e70565b6040805180830381600087803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb9190612a9c565b9150915082610d0a5781610d0c565b805b60000396508760a00135871015610d4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b505050505050919050565b6000816060013580610d6a611e1a565b1115610dd757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b610e6b6080840135610def6060860160408701612912565b610dff60e0870160c08801612912565b6040805180820190915280610e1760208a018a612912565b610e2760408b0160208c01612912565b604051602001610e38929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b91508260a00135821015610eab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b50919050565b6000816040015180610ec1611e1a565b1115610f2e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b335b6000610f3f8560000151611ae9565b9050610f98856060015182610f58578660200151610f5a565b305b60006040518060400160405280610f748b6000015161200c565b81526020018773ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b60608601528015610fb8578451309250610fb190611af5565b8552610fc5565b8460600151935050610fcb565b50610f30565b8360800151831015611009576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b5050919050565b604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051869173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561108557600080fd5b505afa158015611099573d6000803e3d6000fd5b505050506040513d60208110156110af57600080fd5b505110156108a8576108a8868686868686611835565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000821180156110fa575060648211155b61110357600080fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561118c57600080fd5b505afa1580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b505190508481101561122957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156112f8577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156112a257600080fd5b505af11580156112b6573d6000803e3d6000fd5b5050505060006127106112d2858461201b90919063ffffffff16565b816112d957fe5b04905080156112ec576112ec8382611ccc565b6108a885828403611ccc565b5050505050565b600081608001358061130f611e1a565b111561137c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b61141460a08401356113946080860160608701612912565b6113a5610100870160e08801612912565b60405180604001604052808860200160208101906113c39190612912565b6113d060208b018b612912565b6040516020016113e1929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611b16565b91508260c00135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055919050565b60008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d602081101561151157600080fd5b505190508281101561158457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156115955761159584838361203f565b50505050565b6000821180156115ac575060648211155b6115b557600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561161e57600080fd5b505afa158015611632573d6000803e3d6000fd5b505050506040513d602081101561164857600080fd5b50519050848110156116bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156108a85760006127106116d0838661201b565b816116d757fe5b04905080156116eb576116eb87848361203f565b6116f8878683850361203f565b50505050505050565b6000816040013580611711611e1a565b111561177e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6117f160608401356117966040860160208701612912565b60408051808201909152600090806117ae898061306d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525033602090910152611b16565b5060005491508260800135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b604080517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018790526064810186905260ff8516608482015260a4810184905260c48101839052905173ffffffffffffffffffffffffffffffffffffffff88169163d505accf9160e480830192600092919082900301818387803b1580156105c957600080fd5b6000806118da8382612214565b91506118e7836014612214565b9050915091565b6000611903846118fe8585612314565b612383565b949350505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156119665750804710155b15611aaf577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119d357600080fd5b505af11580156119e7573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611a7d57600080fd5b505af1158015611a91573d6000803e3d6000fd5b505050506040513d6020811015611aa757600080fd5b506115959050565b73ffffffffffffffffffffffffffffffffffffffff8316301415611add57611ad884838361203f565b611595565b611595848484846123b3565b8051603c11155b919050565b6060611b10601480845103846125909092919063ffffffff16565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8416611b37573093505b600080611b4784600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80831690821610600080611b758486611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611b9b8e611e5a565b60000373ffffffffffffffffffffffffffffffffffffffff8d1615611bc0578c611be6565b87611bdf5773fffd8963efd1fc6a506488495d951d5263988d25611be6565b6401000276a45b8c604051602001611bf7919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611c26959493929190612ecb565b6040805180830381600087803b158015611c3f57600080fd5b505af1158015611c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c779190612a9c565b91509150600083611c8c578183600003611c92565b82826000035b909750905073ffffffffffffffffffffffffffffffffffffffff8916611cbe578a8114611cbe57600080fd5b505050505050949350505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040518082805190602001908083835b60208310611d4357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611d06565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611da5576040519150601f19603f3d011682016040523d82523d6000602084013e611daa565b606091505b50509050806107aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354450000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b4290565b6000611e537f0000000000000000000000000000000000000000000000000000000000000000611e4e8585612314565b612777565b9392505050565b60007f80000000000000000000000000000000000000000000000000000000000000008210611e8857600080fd5b5090565b600073ffffffffffffffffffffffffffffffffffffffff8416611ead573093505b600080611ebd84600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80821690831610600080611eeb8585611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611f118e611e5a565b73ffffffffffffffffffffffffffffffffffffffff8d1615611f33578c611f59565b87611f525773fffd8963efd1fc6a506488495d951d5263988d25611f59565b6401000276a45b8c604051602001611f6a919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611f99959493929190612ecb565b6040805180830381600087803b158015611fb257600080fd5b505af1158015611fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fea9190612a9c565b9150915082611ff95781611ffb565b805b6000039a9950505050505050505050565b6060611b108260006028612590565b60008215806120365750508181028183828161203357fe5b04145b611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b6020831061211457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120d7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612176576040519150601f19603f3d011682016040523d82523d6000602084013e61217b565b606091505b50915091508180156121a95750805115806121a957508080602001905160208110156121a657600080fd5b50515b6112f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f5354000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60008182601401101561228857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b81601401835110156122fb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b5001602001516c01000000000000000000000000900490565b61231c61289f565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115612354579091905b506040805180820190915273ffffffffffffffffffffffffffffffffffffffff92831681529116602082015290565b600061238f8383612777565b90503373ffffffffffffffffffffffffffffffffffffffff821614611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000178152925182516000948594938a169392918291908083835b6020831061249057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612453565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146124f2576040519150601f19603f3d011682016040523d82523d6000602084013e6124f7565b606091505b5091509150818015612525575080511580612525575080806020019051602081101561252257600080fd5b50515b6108a857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60608182601f01101561260457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b82828401101561267557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b818301845110156126e757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015290519081900360640190fd5b606082158015612706576040519150600082526020820160405261276e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561273f578051835260209283019201612727565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16106127b957600080fd5b5080516020918201516040805173ffffffffffffffffffffffffffffffffffffffff938416818601529290911682820152805180830382018152606080840183528151918501919091207fff00000000000000000000000000000000000000000000000000000000000000608085015294901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608183015260958201939093527f6c1bebd370ba84753516bc1393c0d0a6c645856da55f5393ac8ab3d6dbc861d360b5808301919091528351808303909101815260d5909101909252815191012090565b604080518082019091526000808252602082015290565b8035611af081613167565b600082601f8301126128d1578081fd5b81356128e46128df826130fb565b6130d7565b8181528460208386010111156128f8578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612923578081fd5b8135611e5381613167565b600080600060608486031215612942578182fd5b833561294d81613167565b925060208401359150604084013561296481613167565b809150509250925092565b600080600080600060a08688031215612986578081fd5b853561299181613167565b94506020860135935060408601356129a881613167565b92506060860135915060808601356129bf81613167565b809150509295509295909350565b60008060008060008060c087890312156129e5578081fd5b86356129f081613167565b95506020870135945060408701359350606087013560ff81168114612a13578182fd5b9598949750929560808101359460a0909101359350915050565b60008060208385031215612a3f578182fd5b823567ffffffffffffffff80821115612a56578384fd5b818501915085601f830112612a69578384fd5b813581811115612a77578485fd5b8660208083028501011115612a8a578485fd5b60209290920196919550909350505050565b60008060408385031215612aae578081fd5b505080516020909101519092909150565b60008060008060608587031215612ad4578182fd5b8435935060208501359250604085013567ffffffffffffffff80821115612af9578384fd5b818701915087601f830112612b0c578384fd5b813581811115612b1a578485fd5b886020828501011115612b2b578485fd5b95989497505060200194505050565b600060208284031215612b4b578081fd5b815167ffffffffffffffff811115612b61578182fd5b8201601f81018413612b71578182fd5b8051612b7f6128df826130fb565b818152856020838501011115612b93578384fd5b612ba482602083016020860161313b565b95945050505050565b600060208284031215612bbe578081fd5b813567ffffffffffffffff80821115612bd5578283fd5b9083019060a08286031215612be8578283fd5b60405160a081018181108382111715612bfd57fe5b604052823582811115612c0e578485fd5b612c1a878286016128c1565b825250612c29602084016128b6565b602082015260408301356040820152606083013560608201526080830135608082015280935050505092915050565b600060e08284031215610eab578081fd5b600060208284031215612c7a578081fd5b813567ffffffffffffffff811115612c90578182fd5b820160a08185031215611e53578182fd5b60006101008284031215610eab578081fd5b600060208284031215612cc4578081fd5b813567ffffffffffffffff80821115612cdb578283fd5b9083019060408286031215612cee578283fd5b604051604081018181108382111715612d0357fe5b604052823582811115612d14578485fd5b612d20878286016128c1565b82525060208301359250612d3383613167565b6020810192909252509392505050565b60008060408385031215612d55578182fd5b823591506020830135612d6781613167565b809150509250929050565b60008060008060808587031215612d87578182fd5b843593506020850135612d9981613167565b9250604085013591506060850135612db081613167565b939692955090935050565b60008151808452612dd381602086016020860161313b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606093841b811682529190921b16601482015260280190565b6000828483379101908152919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152861515604084015285606084015280851660808401525060c060a0830152612ebf60c0830184612dbb565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8088168352861515602084015285604084015280851660608401525060a06080830152612f1260a0830184612dbb565b979650505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015612f8e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612f7c858351612dbb565b94509285019290850190600101612f42565b5092979650505050505050565b600060208252611e536020830184612dbb565b60208082526012908201527f546f6f206d756368207265717565737465640000000000000000000000000000604082015260600190565b60208082526013908201527f546f6f206c6974746c6520726563656976656400000000000000000000000000604082015260600190565b6000602082528251604060208401526130386060840182612dbb565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401528091505092915050565b90815260200190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126130a1578283fd5b83018035915067ffffffffffffffff8211156130bb578283fd5b6020019150368190038213156130d057600080fd5b9250929050565b60405181810167ffffffffffffffff811182821017156130f357fe5b604052919050565b600067ffffffffffffffff82111561310f57fe5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b8381101561315657818101518382015260200161313e565b838111156115955750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461318957600080fd5b5056fea164736f6c6343000706000a000000000000000000000000b4aad9bc2a12eab13736e8ac24fa91e2610e42e4000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000020697daff6cd042074ad8afc795e0e23a4f35f34
Deployed Bytecode
0x6080604052600436106101485760003560e01c8063bc651188116100c0578063db3e219811610074578063e0e189a011610059578063e0e189a01461036d578063f28c049814610380578063f3995c6714610393576101f3565b8063db3e219814610347578063df2ab5bb1461035a576101f3565b8063c2e3140a116100a5578063c2e3140a1461030c578063c45a01551461031f578063c60696ec14610334576101f3565b8063bc651188146102e6578063c04b8d59146102f9576101f3565b806369bc35b211610117578063a4a78f0c116100fc578063a4a78f0c14610286578063ac9650d814610299578063b87d2524146102b9576101f3565b806369bc35b21461025e5780638af3ac8514610271576101f3565b80632c8958f6146101f85780633119049a1461021857806341865270146102435780634659a4941461024b576101f3565b366101f3573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3816146101f157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4e6f7420574e6174697665546f6b656e00000000000000000000000000000000604482015290519081900360640190fd5b005b600080fd5b34801561020457600080fd5b506101f1610213366004612abf565b6103a6565b34801561022457600080fd5b5061022d6104f3565b60405161023a9190612e4f565b60405180910390f35b6101f1610517565b6101f16102593660046129cd565b610529565b6101f161026c366004612d43565b6105e9565b34801561027d57600080fd5b5061022d6107af565b6101f16102943660046129cd565b6107d3565b6102ac6102a7366004612a2d565b6108b0565b60405161023a9190612f1d565b3480156102c557600080fd5b506102d96102d4366004612c58565b610a13565b60405161023a9190613064565b6102d96102f4366004612c58565b610d5a565b6102d9610307366004612bad565b610eb1565b6101f161031a3660046129cd565b611010565b34801561032b57600080fd5b5061022d6110c5565b6101f1610342366004612d72565b6110e9565b6102d9610355366004612ca1565b6112ff565b6101f161036836600461292e565b61147e565b6101f161037b36600461296f565b61159b565b6102d961038e366004612c69565b611701565b6101f16103a13660046129cd565b611835565b60008413806103b55750600083135b6103be57600080fd5b60006103cc82840184612cb3565b90506000806103de83600001516118cd565b9150915061040d7f00000000000000000000000020697daff6cd042074ad8afc795e0e23a4f35f3483836118ee565b506000806000891361044e578373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16108861047f565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610895b91509150811561049e57610499848660200151338461190b565b6104e8565b84516104a990611ae9565b156104ce5784516104b990611af5565b85526104c88133600088611b16565b506104e8565b806000819055508293506104e8848660200151338461190b565b505050505050505050565b7f00000000000000000000000020697daff6cd042074ad8afc795e0e23a4f35f3481565b4715610527576105273347611ccc565b565b604080517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101879052606481018690526001608482015260ff851660a482015260c4810184905260e48101839052905173ffffffffffffffffffffffffffffffffffffffff881691638fcbaf0c9161010480830192600092919082900301818387803b1580156105c957600080fd5b505af11580156105dd573d6000803e3d6000fd5b50505050505050505050565b60007f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561067257600080fd5b505afa158015610686573d6000803e3d6000fd5b505050506040513d602081101561069c57600080fd5b505190508281101561070f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156107aa577f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3873ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561078857600080fd5b505af115801561079c573d6000803e3d6000fd5b505050506107aa8282611ccc565b505050565b7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3881565b604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015290517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561086857600080fd5b505afa15801561087c573d6000803e3d6000fd5b505050506040513d602081101561089257600080fd5b505110156108a8576108a8868686868686610529565b505050505050565b60608167ffffffffffffffff811180156108c957600080fd5b506040519080825280602002602001820160405280156108fd57816020015b60608152602001906001900390816108e85790505b50905060005b82811015610a0c576000803086868581811061091b57fe5b905060200281019061092d919061306d565b60405161093b929190612e3f565b600060405180830381855af49150503d8060008114610976576040519150601f19603f3d011682016040523d82523d6000602084013e61097b565b606091505b5091509150816109ea5760448151101561099457600080fd5b600481019050808060200190518101906109ae9190612b3a565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e19190612f9b565b60405180910390fd5b808484815181106109f757fe5b60209081029190910101525050600101610903565b5092915050565b6000816060013580610a23611e1a565b1115610a9057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6040805180820190915260009080610aab6020870187612912565b610abb6040880160208901612912565b604051602001610acc929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250905060008073ffffffffffffffffffffffffffffffffffffffff16856040016020810190610b289190612912565b73ffffffffffffffffffffffffffffffffffffffff1614610b5857610b536060860160408701612912565b610b5a565b305b90506000610b6e6040870160208801612912565b73ffffffffffffffffffffffffffffffffffffffff16610b916020880188612912565b73ffffffffffffffffffffffffffffffffffffffff16109050600080610bd2610bbd60208a018a612912565b610bcd60408b0160208c01612912565b611e1e565b73ffffffffffffffffffffffffffffffffffffffff166371334694338686610bfd8d60800135611e5a565b8d60c0016020810190610c109190612912565b73ffffffffffffffffffffffffffffffffffffffff1615610c43578d60c0016020810190610c3e9190612912565b610c69565b88610c625773fffd8963efd1fc6a506488495d951d5263988d25610c69565b6401000276a45b8b604051602001610c7a919061301c565b6040516020818303038152906040526040518763ffffffff1660e01b8152600401610caa96959493929190612e70565b6040805180830381600087803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb9190612a9c565b9150915082610d0a5781610d0c565b805b60000396508760a00135871015610d4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b505050505050919050565b6000816060013580610d6a611e1a565b1115610dd757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b610e6b6080840135610def6060860160408701612912565b610dff60e0870160c08801612912565b6040805180820190915280610e1760208a018a612912565b610e2760408b0160208c01612912565b604051602001610e38929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b91508260a00135821015610eab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b50919050565b6000816040015180610ec1611e1a565b1115610f2e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b335b6000610f3f8560000151611ae9565b9050610f98856060015182610f58578660200151610f5a565b305b60006040518060400160405280610f748b6000015161200c565b81526020018773ffffffffffffffffffffffffffffffffffffffff16815250611e8c565b60608601528015610fb8578451309250610fb190611af5565b8552610fc5565b8460600151935050610fcb565b50610f30565b8360800151831015611009576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fe5565b5050919050565b604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051869173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b15801561108557600080fd5b505afa158015611099573d6000803e3d6000fd5b505050506040513d60208110156110af57600080fd5b505110156108a8576108a8868686868686611835565b7f000000000000000000000000b4aad9bc2a12eab13736e8ac24fa91e2610e42e481565b6000821180156110fa575060648211155b61110357600080fd5b60007f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561118c57600080fd5b505afa1580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b505190508481101561122957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e73756666696369656e7420574e6174697665546f6b656e00000000000000604482015290519081900360640190fd5b80156112f8577f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3873ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156112a257600080fd5b505af11580156112b6573d6000803e3d6000fd5b5050505060006127106112d2858461201b90919063ffffffff16565b816112d957fe5b04905080156112ec576112ec8382611ccc565b6108a885828403611ccc565b5050505050565b600081608001358061130f611e1a565b111561137c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b61141460a08401356113946080860160608701612912565b6113a5610100870160e08801612912565b60405180604001604052808860200160208101906113c39190612912565b6113d060208b018b612912565b6040516020016113e1929190612e05565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611b16565b91508260c00135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055919050565b60008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d602081101561151157600080fd5b505190508281101561158457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156115955761159584838361203f565b50505050565b6000821180156115ac575060648211155b6115b557600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561161e57600080fd5b505afa158015611632573d6000803e3d6000fd5b505050506040513d602081101561164857600080fd5b50519050848110156116bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156108a85760006127106116d0838661201b565b816116d757fe5b04905080156116eb576116eb87848361203f565b6116f8878683850361203f565b50505050505050565b6000816040013580611711611e1a565b111561177e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6117f160608401356117966040860160208701612912565b60408051808201909152600090806117ae898061306d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525033602090910152611b16565b5060005491508260800135821115611454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e190612fae565b604080517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018790526064810186905260ff8516608482015260a4810184905260c48101839052905173ffffffffffffffffffffffffffffffffffffffff88169163d505accf9160e480830192600092919082900301818387803b1580156105c957600080fd5b6000806118da8382612214565b91506118e7836014612214565b9050915091565b6000611903846118fe8585612314565b612383565b949350505050565b7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3873ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156119665750804710155b15611aaf577f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3873ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119d357600080fd5b505af11580156119e7573d6000803e3d6000fd5b50505050507f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3873ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611a7d57600080fd5b505af1158015611a91573d6000803e3d6000fd5b505050506040513d6020811015611aa757600080fd5b506115959050565b73ffffffffffffffffffffffffffffffffffffffff8316301415611add57611ad884838361203f565b611595565b611595848484846123b3565b8051603c11155b919050565b6060611b10601480845103846125909092919063ffffffff16565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff8416611b37573093505b600080611b4784600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80831690821610600080611b758486611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611b9b8e611e5a565b60000373ffffffffffffffffffffffffffffffffffffffff8d1615611bc0578c611be6565b87611bdf5773fffd8963efd1fc6a506488495d951d5263988d25611be6565b6401000276a45b8c604051602001611bf7919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611c26959493929190612ecb565b6040805180830381600087803b158015611c3f57600080fd5b505af1158015611c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c779190612a9c565b91509150600083611c8c578183600003611c92565b82826000035b909750905073ffffffffffffffffffffffffffffffffffffffff8916611cbe578a8114611cbe57600080fd5b505050505050949350505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040518082805190602001908083835b60208310611d4357805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611d06565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611da5576040519150601f19603f3d011682016040523d82523d6000602084013e611daa565b606091505b50509050806107aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354450000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b4290565b6000611e537f00000000000000000000000020697daff6cd042074ad8afc795e0e23a4f35f34611e4e8585612314565b612777565b9392505050565b60007f80000000000000000000000000000000000000000000000000000000000000008210611e8857600080fd5b5090565b600073ffffffffffffffffffffffffffffffffffffffff8416611ead573093505b600080611ebd84600001516118cd565b909250905073ffffffffffffffffffffffffffffffffffffffff80821690831610600080611eeb8585611e1e565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088a85611f118e611e5a565b73ffffffffffffffffffffffffffffffffffffffff8d1615611f33578c611f59565b87611f525773fffd8963efd1fc6a506488495d951d5263988d25611f59565b6401000276a45b8c604051602001611f6a919061301c565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611f99959493929190612ecb565b6040805180830381600087803b158015611fb257600080fd5b505af1158015611fc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fea9190612a9c565b9150915082611ff95781611ffb565b805b6000039a9950505050505050505050565b6060611b108260006028612590565b60008215806120365750508181028183828161203357fe5b04145b611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b6020831061211457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016120d7565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612176576040519150601f19603f3d011682016040523d82523d6000602084013e61217b565b606091505b50915091508180156121a95750805115806121a957508080602001905160208110156121a657600080fd5b50515b6112f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f5354000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60008182601401101561228857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b81601401835110156122fb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b5001602001516c01000000000000000000000000900490565b61231c61289f565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161115612354579091905b506040805180820190915273ffffffffffffffffffffffffffffffffffffffff92831681529116602082015290565b600061238f8383612777565b90503373ffffffffffffffffffffffffffffffffffffffff821614611b1057600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000178152925182516000948594938a169392918291908083835b6020831061249057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612453565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146124f2576040519150601f19603f3d011682016040523d82523d6000602084013e6124f7565b606091505b5091509150818015612525575080511580612525575080806020019051602081101561252257600080fd5b50515b6108a857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60608182601f01101561260457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b82828401101561267557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b818301845110156126e757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015290519081900360640190fd5b606082158015612706576040519150600082526020820160405261276e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561273f578051835260209283019201612727565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16106127b957600080fd5b5080516020918201516040805173ffffffffffffffffffffffffffffffffffffffff938416818601529290911682820152805180830382018152606080840183528151918501919091207fff00000000000000000000000000000000000000000000000000000000000000608085015294901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608183015260958201939093527f6c1bebd370ba84753516bc1393c0d0a6c645856da55f5393ac8ab3d6dbc861d360b5808301919091528351808303909101815260d5909101909252815191012090565b604080518082019091526000808252602082015290565b8035611af081613167565b600082601f8301126128d1578081fd5b81356128e46128df826130fb565b6130d7565b8181528460208386010111156128f8578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612923578081fd5b8135611e5381613167565b600080600060608486031215612942578182fd5b833561294d81613167565b925060208401359150604084013561296481613167565b809150509250925092565b600080600080600060a08688031215612986578081fd5b853561299181613167565b94506020860135935060408601356129a881613167565b92506060860135915060808601356129bf81613167565b809150509295509295909350565b60008060008060008060c087890312156129e5578081fd5b86356129f081613167565b95506020870135945060408701359350606087013560ff81168114612a13578182fd5b9598949750929560808101359460a0909101359350915050565b60008060208385031215612a3f578182fd5b823567ffffffffffffffff80821115612a56578384fd5b818501915085601f830112612a69578384fd5b813581811115612a77578485fd5b8660208083028501011115612a8a578485fd5b60209290920196919550909350505050565b60008060408385031215612aae578081fd5b505080516020909101519092909150565b60008060008060608587031215612ad4578182fd5b8435935060208501359250604085013567ffffffffffffffff80821115612af9578384fd5b818701915087601f830112612b0c578384fd5b813581811115612b1a578485fd5b886020828501011115612b2b578485fd5b95989497505060200194505050565b600060208284031215612b4b578081fd5b815167ffffffffffffffff811115612b61578182fd5b8201601f81018413612b71578182fd5b8051612b7f6128df826130fb565b818152856020838501011115612b93578384fd5b612ba482602083016020860161313b565b95945050505050565b600060208284031215612bbe578081fd5b813567ffffffffffffffff80821115612bd5578283fd5b9083019060a08286031215612be8578283fd5b60405160a081018181108382111715612bfd57fe5b604052823582811115612c0e578485fd5b612c1a878286016128c1565b825250612c29602084016128b6565b602082015260408301356040820152606083013560608201526080830135608082015280935050505092915050565b600060e08284031215610eab578081fd5b600060208284031215612c7a578081fd5b813567ffffffffffffffff811115612c90578182fd5b820160a08185031215611e53578182fd5b60006101008284031215610eab578081fd5b600060208284031215612cc4578081fd5b813567ffffffffffffffff80821115612cdb578283fd5b9083019060408286031215612cee578283fd5b604051604081018181108382111715612d0357fe5b604052823582811115612d14578485fd5b612d20878286016128c1565b82525060208301359250612d3383613167565b6020810192909252509392505050565b60008060408385031215612d55578182fd5b823591506020830135612d6781613167565b809150509250929050565b60008060008060808587031215612d87578182fd5b843593506020850135612d9981613167565b9250604085013591506060850135612db081613167565b939692955090935050565b60008151808452612dd381602086016020860161313b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606093841b811682529190921b16601482015260280190565b6000828483379101908152919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152861515604084015285606084015280851660808401525060c060a0830152612ebf60c0830184612dbb565b98975050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8088168352861515602084015285604084015280851660608401525060a06080830152612f1260a0830184612dbb565b979650505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015612f8e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612f7c858351612dbb565b94509285019290850190600101612f42565b5092979650505050505050565b600060208252611e536020830184612dbb565b60208082526012908201527f546f6f206d756368207265717565737465640000000000000000000000000000604082015260600190565b60208082526013908201527f546f6f206c6974746c6520726563656976656400000000000000000000000000604082015260600190565b6000602082528251604060208401526130386060840182612dbb565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401528091505092915050565b90815260200190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126130a1578283fd5b83018035915067ffffffffffffffff8211156130bb578283fd5b6020019150368190038213156130d057600080fd5b9250929050565b60405181810167ffffffffffffffff811182821017156130f357fe5b604052919050565b600067ffffffffffffffff82111561310f57fe5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b8381101561315657818101518382015260200161313e565b838111156115955750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461318957600080fd5b5056fea164736f6c6343000706000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b4aad9bc2a12eab13736e8ac24fa91e2610e42e4000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000020697daff6cd042074ad8afc795e0e23a4f35f34
-----Decoded View---------------
Arg [0] : _factory (address): 0xB4AaD9bc2a12eAB13736E8AC24FA91E2610e42E4
Arg [1] : _WNativeToken (address): 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
Arg [2] : _poolDeployer (address): 0x20697Daff6cD042074ad8aFc795e0e23a4F35F34
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000b4aad9bc2a12eab13736e8ac24fa91e2610e42e4
Arg [1] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Arg [2] : 00000000000000000000000020697daff6cd042074ad8afc795e0e23a4f35f34
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.