├── .env.sample ├── .gitignore ├── README.md ├── contracts ├── Multicall2 │ └── Multicall2.sol ├── NFTDescriptor │ ├── BitMath.sol │ ├── FullMath.sol │ ├── HexStrings.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── IUniswapV3PoolDerivedState.sol │ ├── IUniswapV3PoolEvents.sol │ ├── IUniswapV3PoolImmutables.sol │ ├── IUniswapV3PoolOwnerActions.sol │ ├── IUniswapV3PoolState.sol │ ├── NFTDescriptor.sol │ ├── NFTSVG.sol │ ├── SafeMath.sol │ ├── SignedSafeMath.sol │ ├── Strings.sol │ ├── TickMath.sol │ └── base64.sol ├── NonfungiblePositionManager │ ├── Address.sol │ ├── BlockTimestamp.sol │ ├── CallbackValidation.sol │ ├── ChainId.sol │ ├── Context.sol │ ├── ERC165.sol │ ├── ERC721.sol │ ├── ERC721Permit.sol │ ├── EnumerableMap.sol │ ├── EnumerableSet.sol │ ├── FixedPoint128.sol │ ├── FixedPoint96.sol │ ├── FullMath.sol │ ├── IERC1271.sol │ ├── IERC165.sol │ ├── IERC20.sol │ ├── IERC20Permit.sol │ ├── IERC20PermitAllowed.sol │ ├── IERC721.sol │ ├── IERC721Enumerable.sol │ ├── IERC721Metadata.sol │ ├── IERC721Permit.sol │ ├── IERC721Receiver.sol │ ├── IMulticall.sol │ ├── INonfungiblePositionManager.sol │ ├── INonfungibleTokenPositionDescriptor.sol │ ├── IPeripheryImmutableState.sol │ ├── IPeripheryPayments.sol │ ├── IPoolInitializer.sol │ ├── ISelfPermit.sol │ ├── IUniswapV3Factory.sol │ ├── IUniswapV3MintCallback.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── IUniswapV3PoolDerivedState.sol │ ├── IUniswapV3PoolEvents.sol │ ├── IUniswapV3PoolImmutables.sol │ ├── IUniswapV3PoolOwnerActions.sol │ ├── IUniswapV3PoolState.sol │ ├── IWETH9.sol │ ├── LiquidityAmounts.sol │ ├── LiquidityManagement.sol │ ├── Multicall.sol │ ├── NonfungiblePositionManager.sol │ ├── PeripheryImmutableState.sol │ ├── PeripheryPayments.sol │ ├── PeripheryValidation.sol │ ├── PoolAddress.sol │ ├── PoolInitializer.sol │ ├── PositionKey.sol │ ├── SafeMath.sol │ ├── SelfPermit.sol │ ├── Strings.sol │ ├── TickMath.sol │ └── TransferHelper.sol ├── NonfungibleTokenPositionDescriptor │ ├── AddressStringUtil.sol │ ├── BitMath.sol │ ├── ChainId.sol │ ├── FullMath.sol │ ├── HexStrings.sol │ ├── IERC165.sol │ ├── IERC20.sol │ ├── IERC20Metadata.sol │ ├── IERC721.sol │ ├── IERC721Enumerable.sol │ ├── IERC721Metadata.sol │ ├── IERC721Permit.sol │ ├── INonfungiblePositionManager.sol │ ├── INonfungibleTokenPositionDescriptor.sol │ ├── IPeripheryImmutableState.sol │ ├── IPeripheryPayments.sol │ ├── IPoolInitializer.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── IUniswapV3PoolDerivedState.sol │ ├── IUniswapV3PoolEvents.sol │ ├── IUniswapV3PoolImmutables.sol │ ├── IUniswapV3PoolOwnerActions.sol │ ├── IUniswapV3PoolState.sol │ ├── NFTDescriptor.sol │ ├── NFTSVG.sol │ ├── NonfungibleTokenPositionDescriptor.sol │ ├── PoolAddress.sol │ ├── SafeERC20Namer.sol │ ├── SafeMath.sol │ ├── SignedSafeMath.sol │ ├── Strings.sol │ ├── TickMath.sol │ ├── TokenRatioSortOrder.sol │ └── base64.sol ├── ProxyAdmin │ ├── Address.sol │ ├── Context.sol │ ├── Ownable.sol │ ├── Proxy.sol │ ├── ProxyAdmin.sol │ ├── TransparentUpgradeableProxy.sol │ └── UpgradeableProxy.sol ├── Quoter │ ├── BytesLib.sol │ ├── CallbackValidation.sol │ ├── IPeripheryImmutableState.sol │ ├── IQuoter.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── IUniswapV3PoolDerivedState.sol │ ├── IUniswapV3PoolEvents.sol │ ├── IUniswapV3PoolImmutables.sol │ ├── IUniswapV3PoolOwnerActions.sol │ ├── IUniswapV3PoolState.sol │ ├── IUniswapV3SwapCallback.sol │ ├── Path.sol │ ├── PeripheryImmutableState.sol │ ├── PoolAddress.sol │ ├── Quoter.sol │ ├── SafeCast.sol │ └── TickMath.sol ├── SwapRouter │ ├── BlockTimestamp.sol │ ├── BytesLib.sol │ ├── CallbackValidation.sol │ ├── IERC20.sol │ ├── IERC20Permit.sol │ ├── IERC20PermitAllowed.sol │ ├── IMulticall.sol │ ├── IPeripheryImmutableState.sol │ ├── IPeripheryPayments.sol │ ├── IPeripheryPaymentsWithFee.sol │ ├── ISelfPermit.sol │ ├── ISwapRouter.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── IUniswapV3PoolDerivedState.sol │ ├── IUniswapV3PoolEvents.sol │ ├── IUniswapV3PoolImmutables.sol │ ├── IUniswapV3PoolOwnerActions.sol │ ├── IUniswapV3PoolState.sol │ ├── IUniswapV3SwapCallback.sol │ ├── IWETH9.sol │ ├── LowGasSafeMath.sol │ ├── Multicall.sol │ ├── Path.sol │ ├── PeripheryImmutableState.sol │ ├── PeripheryPayments.sol │ ├── PeripheryPaymentsWithFee.sol │ ├── PeripheryValidation.sol │ ├── PoolAddress.sol │ ├── SafeCast.sol │ ├── SelfPermit.sol │ ├── SwapRouter.sol │ ├── TickMath.sol │ └── TransferHelper.sol ├── TickLens │ ├── ITickLens.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── IUniswapV3PoolDerivedState.sol │ ├── IUniswapV3PoolEvents.sol │ ├── IUniswapV3PoolImmutables.sol │ ├── IUniswapV3PoolOwnerActions.sol │ ├── IUniswapV3PoolState.sol │ └── TickLens.sol ├── TransparentUpgradeableProxy │ ├── Address.sol │ ├── Context.sol │ ├── Ownable.sol │ ├── Proxy.sol │ ├── ProxyAdmin.sol │ ├── TransparentUpgradeableProxy.sol │ └── UpgradeableProxy.sol ├── UniswapV3Factory │ └── UniswapV3Factory_Output.sol ├── V2Core │ ├── Factory.sol │ └── Router02.sol ├── V3Migrator │ ├── IERC165.sol │ ├── IERC20.sol │ ├── IERC20Permit.sol │ ├── IERC20PermitAllowed.sol │ ├── IERC721.sol │ ├── IERC721Enumerable.sol │ ├── IERC721Metadata.sol │ ├── IERC721Permit.sol │ ├── IMulticall.sol │ ├── INonfungiblePositionManager.sol │ ├── IPeripheryImmutableState.sol │ ├── IPeripheryPayments.sol │ ├── IPoolInitializer.sol │ ├── ISelfPermit.sol │ ├── IUniswapV2Pair.sol │ ├── IUniswapV3Factory.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── IUniswapV3PoolDerivedState.sol │ ├── IUniswapV3PoolEvents.sol │ ├── IUniswapV3PoolImmutables.sol │ ├── IUniswapV3PoolOwnerActions.sol │ ├── IUniswapV3PoolState.sol │ ├── IV3Migrator.sol │ ├── IWETH9.sol │ ├── LowGasSafeMath.sol │ ├── Multicall.sol │ ├── PeripheryImmutableState.sol │ ├── PoolAddress.sol │ ├── PoolInitializer.sol │ ├── SelfPermit.sol │ ├── TransferHelper.sol │ └── V3Migrator.sol └── WETH9 │ └── WETH9.sol ├── deployments └── hardhat │ ├── NFTDescriptor.json │ ├── NonfungiblePositionManager.json │ ├── NonfungibleTokenPositionDescriptor.json │ ├── ProxyAdmin.json │ ├── Quoter.json │ ├── SwapRouter.json │ ├── TickLens.json │ ├── TransparentUpgradeableProxy.json │ ├── UniswapV2Factory.json │ ├── UniswapV2Router02.json │ ├── UniswapV3Factory.json │ ├── V3Migrator.json │ └── WETH9.json ├── hardhat.config.ts ├── package-lock.json ├── package.json ├── script ├── deployTool.ts └── network.ts ├── tsconfig.json └── uniswapV3.md /.env.sample: -------------------------------------------------------------------------------- 1 | MNEMONIC='' 2 | INFURA_API_KEY='' 3 | ETHERSCAN_APIKEY='' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | artifacts/ 2 | cache/ 3 | crytic-export/ 4 | node_modules/ 5 | typechain/ 6 | .env 7 | .env.development -------------------------------------------------------------------------------- /contracts/NFTDescriptor/HexStrings.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity =0.7.6; 3 | 4 | library HexStrings { 5 | bytes16 internal constant ALPHABET = '0123456789abcdef'; 6 | 7 | /// @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. 8 | /// @dev Credit to Open Zeppelin under MIT license https://github.com/OpenZeppelin/openzeppelin-contracts/blob/243adff49ce1700e0ecb99fe522fb16cff1d1ddc/contracts/utils/Strings.sol#L55 9 | function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 10 | bytes memory buffer = new bytes(2 * length + 2); 11 | buffer[0] = '0'; 12 | buffer[1] = 'x'; 13 | for (uint256 i = 2 * length + 1; i > 1; --i) { 14 | buffer[i] = ALPHABET[value & 0xf]; 15 | value >>= 4; 16 | } 17 | require(value == 0, 'Strings: hex length insufficient'); 18 | return string(buffer); 19 | } 20 | 21 | function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) { 22 | bytes memory buffer = new bytes(2 * length); 23 | for (uint256 i = buffer.length; i > 0; i--) { 24 | buffer[i - 1] = ALPHABET[value & 0xf]; 25 | value >>= 4; 26 | } 27 | return string(buffer); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/NFTDescriptor/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IUniswapV3PoolImmutables.sol'; 5 | import './IUniswapV3PoolState.sol'; 6 | import './IUniswapV3PoolDerivedState.sol'; 7 | import './IUniswapV3PoolActions.sol'; 8 | import './IUniswapV3PoolOwnerActions.sol'; 9 | import './IUniswapV3PoolEvents.sol'; 10 | 11 | /// @title The interface for a Uniswap V3 Pool 12 | /// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform 13 | /// to the ERC20 specification 14 | /// @dev The pool interface is broken up into many smaller pieces 15 | interface IUniswapV3Pool is 16 | IUniswapV3PoolImmutables, 17 | IUniswapV3PoolState, 18 | IUniswapV3PoolDerivedState, 19 | IUniswapV3PoolActions, 20 | IUniswapV3PoolOwnerActions, 21 | IUniswapV3PoolEvents 22 | { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /contracts/NFTDescriptor/IUniswapV3PoolDerivedState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that is not stored 5 | /// @notice Contains view functions to provide information about the pool that is computed rather than stored on the 6 | /// blockchain. The functions here may have variable gas costs. 7 | interface IUniswapV3PoolDerivedState { 8 | /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp 9 | /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing 10 | /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, 11 | /// you must call it with secondsAgos = [3600, 0]. 12 | /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in 13 | /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. 14 | /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned 15 | /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp 16 | /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block 17 | /// timestamp 18 | function observe(uint32[] calldata secondsAgos) 19 | external 20 | view 21 | returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); 22 | 23 | /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range 24 | /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. 25 | /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first 26 | /// snapshot is taken and the second snapshot is taken. 27 | /// @param tickLower The lower tick of the range 28 | /// @param tickUpper The upper tick of the range 29 | /// @return tickCumulativeInside The snapshot of the tick accumulator for the range 30 | /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range 31 | /// @return secondsInside The snapshot of seconds per liquidity for the range 32 | function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) 33 | external 34 | view 35 | returns ( 36 | int56 tickCumulativeInside, 37 | uint160 secondsPerLiquidityInsideX128, 38 | uint32 secondsInside 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/NFTDescriptor/IUniswapV3PoolImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that never changes 5 | /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values 6 | interface IUniswapV3PoolImmutables { 7 | /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface 8 | /// @return The contract address 9 | function factory() external view returns (address); 10 | 11 | /// @notice The first of the two tokens of the pool, sorted by address 12 | /// @return The token contract address 13 | function token0() external view returns (address); 14 | 15 | /// @notice The second of the two tokens of the pool, sorted by address 16 | /// @return The token contract address 17 | function token1() external view returns (address); 18 | 19 | /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 20 | /// @return The fee 21 | function fee() external view returns (uint24); 22 | 23 | /// @notice The pool tick spacing 24 | /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive 25 | /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... 26 | /// This value is an int24 to avoid casting even though it is always positive. 27 | /// @return The tick spacing 28 | function tickSpacing() external view returns (int24); 29 | 30 | /// @notice The maximum amount of position liquidity that can use any tick in the range 31 | /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and 32 | /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool 33 | /// @return The max amount of liquidity per tick 34 | function maxLiquidityPerTick() external view returns (uint128); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/NFTDescriptor/IUniswapV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Permissioned pool actions 5 | /// @notice Contains pool methods that may only be called by the factory owner 6 | interface IUniswapV3PoolOwnerActions { 7 | /// @notice Set the denominator of the protocol's % share of the fees 8 | /// @param feeProtocol0 new protocol fee for token0 of the pool 9 | /// @param feeProtocol1 new protocol fee for token1 of the pool 10 | function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; 11 | 12 | /// @notice Collect the protocol fee accrued to the pool 13 | /// @param recipient The address to which collected protocol fees should be sent 14 | /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 15 | /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 16 | /// @return amount0 The protocol fee collected in token0 17 | /// @return amount1 The protocol fee collected in token1 18 | function collectProtocol( 19 | address recipient, 20 | uint128 amount0Requested, 21 | uint128 amount1Requested 22 | ) external returns (uint128 amount0, uint128 amount1); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/NFTDescriptor/Strings.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev String operations. 7 | */ 8 | library Strings { 9 | /** 10 | * @dev Converts a `uint256` to its ASCII `string` representation. 11 | */ 12 | function toString(uint256 value) internal pure returns (string memory) { 13 | // Inspired by OraclizeAPI's implementation - MIT licence 14 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 15 | 16 | if (value == 0) { 17 | return "0"; 18 | } 19 | uint256 temp = value; 20 | uint256 digits; 21 | while (temp != 0) { 22 | digits++; 23 | temp /= 10; 24 | } 25 | bytes memory buffer = new bytes(digits); 26 | uint256 index = digits - 1; 27 | temp = value; 28 | while (temp != 0) { 29 | buffer[index--] = bytes1(uint8(48 + temp % 10)); 30 | temp /= 10; 31 | } 32 | return string(buffer); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/NFTDescriptor/base64.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | /// @title Base64 5 | /// @author Brecht Devos - 6 | /// @notice Provides a function for encoding some bytes in base64 7 | library Base64 { 8 | string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 9 | 10 | function encode(bytes memory data) internal pure returns (string memory) { 11 | if (data.length == 0) return ''; 12 | 13 | // load the table into memory 14 | string memory table = TABLE; 15 | 16 | // multiply by 4/3 rounded up 17 | uint256 encodedLen = 4 * ((data.length + 2) / 3); 18 | 19 | // add some extra buffer at the end required for the writing 20 | string memory result = new string(encodedLen + 32); 21 | 22 | assembly { 23 | // set the actual output length 24 | mstore(result, encodedLen) 25 | 26 | // prepare the lookup table 27 | let tablePtr := add(table, 1) 28 | 29 | // input ptr 30 | let dataPtr := data 31 | let endPtr := add(dataPtr, mload(data)) 32 | 33 | // result ptr, jump over length 34 | let resultPtr := add(result, 32) 35 | 36 | // run over the input, 3 bytes at a time 37 | for {} lt(dataPtr, endPtr) {} 38 | { 39 | dataPtr := add(dataPtr, 3) 40 | 41 | // read 3 bytes 42 | let input := mload(dataPtr) 43 | 44 | // write 4 characters 45 | mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))) 46 | resultPtr := add(resultPtr, 1) 47 | mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))) 48 | resultPtr := add(resultPtr, 1) 49 | mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F))))) 50 | resultPtr := add(resultPtr, 1) 51 | mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F))))) 52 | resultPtr := add(resultPtr, 1) 53 | } 54 | 55 | // padding with '=' 56 | switch mod(mload(data), 3) 57 | case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } 58 | case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } 59 | } 60 | 61 | return result; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/BlockTimestamp.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | /// @title Function for getting block timestamp 5 | /// @dev Base contract that is overridden for tests 6 | abstract contract BlockTimestamp { 7 | /// @dev Method that exists purely to be overridden for tests 8 | /// @return The current block timestamp 9 | function _blockTimestamp() internal view virtual returns (uint256) { 10 | return block.timestamp; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/CallbackValidation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IUniswapV3Pool.sol'; 5 | import './PoolAddress.sol'; 6 | 7 | /// @notice Provides validation for callbacks from Uniswap V3 Pools 8 | library CallbackValidation { 9 | /// @notice Returns the address of a valid Uniswap V3 Pool 10 | /// @param factory The contract address of the Uniswap V3 factory 11 | /// @param tokenA The contract address of either token0 or token1 12 | /// @param tokenB The contract address of the other token 13 | /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip 14 | /// @return pool The V3 pool contract address 15 | function verifyCallback( 16 | address factory, 17 | address tokenA, 18 | address tokenB, 19 | uint24 fee 20 | ) internal view returns (IUniswapV3Pool pool) { 21 | return verifyCallback(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee)); 22 | } 23 | 24 | /// @notice Returns the address of a valid Uniswap V3 Pool 25 | /// @param factory The contract address of the Uniswap V3 factory 26 | /// @param poolKey The identifying key of the V3 pool 27 | /// @return pool The V3 pool contract address 28 | function verifyCallback(address factory, PoolAddress.PoolKey memory poolKey) 29 | internal 30 | view 31 | returns (IUniswapV3Pool pool) 32 | { 33 | pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); 34 | require(msg.sender == address(pool)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/ChainId.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.0; 3 | 4 | /// @title Function for getting the current chain ID 5 | library ChainId { 6 | /// @dev Gets the current chain ID 7 | /// @return chainId The current chain ID 8 | function get() internal pure returns (uint256 chainId) { 9 | assembly { 10 | chainId := chainid() 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with GSN meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address payable) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes memory) { 21 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 22 | return msg.data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/ERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./IERC165.sol"; 6 | 7 | /** 8 | * @dev Implementation of the {IERC165} interface. 9 | * 10 | * Contracts may inherit from this and call {_registerInterface} to declare 11 | * their support of an interface. 12 | */ 13 | abstract contract ERC165 is IERC165 { 14 | /* 15 | * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 16 | */ 17 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; 18 | 19 | /** 20 | * @dev Mapping of interface ids to whether or not it's supported. 21 | */ 22 | mapping(bytes4 => bool) private _supportedInterfaces; 23 | 24 | constructor () { 25 | // Derived contracts need only register support for their own interfaces, 26 | // we register support for ERC165 itself here 27 | _registerInterface(_INTERFACE_ID_ERC165); 28 | } 29 | 30 | /** 31 | * @dev See {IERC165-supportsInterface}. 32 | * 33 | * Time complexity O(1), guaranteed to always use less than 30 000 gas. 34 | */ 35 | function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 36 | return _supportedInterfaces[interfaceId]; 37 | } 38 | 39 | /** 40 | * @dev Registers the contract as an implementer of the interface defined by 41 | * `interfaceId`. Support of the actual ERC165 interface is automatic and 42 | * registering its interface id is not required. 43 | * 44 | * See {IERC165-supportsInterface}. 45 | * 46 | * Requirements: 47 | * 48 | * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). 49 | */ 50 | function _registerInterface(bytes4 interfaceId) internal virtual { 51 | require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); 52 | _supportedInterfaces[interfaceId] = true; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/FixedPoint128.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.4.0; 3 | 4 | /// @title FixedPoint128 5 | /// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) 6 | library FixedPoint128 { 7 | uint256 internal constant Q128 = 0x100000000000000000000000000000000; 8 | } 9 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/FixedPoint96.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.4.0; 3 | 4 | /// @title FixedPoint96 5 | /// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) 6 | /// @dev Used in SqrtPriceMath.sol 7 | library FixedPoint96 { 8 | uint8 internal constant RESOLUTION = 96; 9 | uint256 internal constant Q96 = 0x1000000000000000000000000; 10 | } 11 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC1271.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Interface for verifying contract-based account signatures 5 | /// @notice Interface that verifies provided signature for the data 6 | /// @dev Interface defined by EIP-1271 7 | interface IERC1271 { 8 | /// @notice Returns whether the provided signature is valid for the provided data 9 | /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes. 10 | /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5). 11 | /// MUST allow external calls. 12 | /// @param hash Hash of the data to be signed 13 | /// @param signature Signature byte array associated with _data 14 | /// @return magicValue The bytes4 magic value 0x1626ba7e 15 | function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev Interface of the ERC165 standard, as defined in the 7 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 8 | * 9 | * Implementers can declare support of contract interfaces, which can then be 10 | * queried by others ({ERC165Checker}). 11 | * 12 | * For an implementation, see {ERC165}. 13 | */ 14 | interface IERC165 { 15 | /** 16 | * @dev Returns true if this contract implements the interface defined by 17 | * `interfaceId`. See the corresponding 18 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 19 | * to learn more about how these ids are created. 20 | * 21 | * This function call must use less than 30 000 gas. 22 | */ 23 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 standard as defined in the EIP. 7 | */ 8 | interface IERC20 { 9 | /** 10 | * @dev Returns the amount of tokens in existence. 11 | */ 12 | function totalSupply() external view returns (uint256); 13 | 14 | /** 15 | * @dev Returns the amount of tokens owned by `account`. 16 | */ 17 | function balanceOf(address account) external view returns (uint256); 18 | 19 | /** 20 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 21 | * 22 | * Returns a boolean value indicating whether the operation succeeded. 23 | * 24 | * Emits a {Transfer} event. 25 | */ 26 | function transfer(address recipient, uint256 amount) external returns (bool); 27 | 28 | /** 29 | * @dev Returns the remaining number of tokens that `spender` will be 30 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 31 | * zero by default. 32 | * 33 | * This value changes when {approve} or {transferFrom} are called. 34 | */ 35 | function allowance(address owner, address spender) external view returns (uint256); 36 | 37 | /** 38 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 39 | * 40 | * Returns a boolean value indicating whether the operation succeeded. 41 | * 42 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 43 | * that someone may use both the old and the new allowance by unfortunate 44 | * transaction ordering. One possible solution to mitigate this race 45 | * condition is to first reduce the spender's allowance to 0 and set the 46 | * desired value afterwards: 47 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 48 | * 49 | * Emits an {Approval} event. 50 | */ 51 | function approve(address spender, uint256 amount) external returns (bool); 52 | 53 | /** 54 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 55 | * allowance mechanism. `amount` is then deducted from the caller's 56 | * allowance. 57 | * 58 | * Returns a boolean value indicating whether the operation succeeded. 59 | * 60 | * Emits a {Transfer} event. 61 | */ 62 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 63 | 64 | /** 65 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 66 | * another (`to`). 67 | * 68 | * Note that `value` may be zero. 69 | */ 70 | event Transfer(address indexed from, address indexed to, uint256 value); 71 | 72 | /** 73 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 74 | * a call to {approve}. `value` is the new allowance. 75 | */ 76 | event Approval(address indexed owner, address indexed spender, uint256 value); 77 | } 78 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC20Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in 7 | * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. 8 | * 9 | * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by 10 | * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't 11 | * need to send a transaction, and thus is not required to hold Ether at all. 12 | */ 13 | interface IERC20Permit { 14 | /** 15 | * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens, 16 | * given `owner`'s signed approval. 17 | * 18 | * IMPORTANT: The same issues {IERC20-approve} has related to transaction 19 | * ordering also apply here. 20 | * 21 | * Emits an {Approval} event. 22 | * 23 | * Requirements: 24 | * 25 | * - `spender` cannot be the zero address. 26 | * - `deadline` must be a timestamp in the future. 27 | * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` 28 | * over the EIP712-formatted function arguments. 29 | * - the signature must use ``owner``'s current nonce (see {nonces}). 30 | * 31 | * For more information on the signature format, see the 32 | * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP 33 | * section]. 34 | */ 35 | function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; 36 | 37 | /** 38 | * @dev Returns the current nonce for `owner`. This value must be 39 | * included whenever a signature is generated for {permit}. 40 | * 41 | * Every successful call to {permit} increases ``owner``'s nonce by one. This 42 | * prevents a signature from being used multiple times. 43 | */ 44 | function nonces(address owner) external view returns (uint256); 45 | 46 | /** 47 | * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}. 48 | */ 49 | // solhint-disable-next-line func-name-mixedcase 50 | function DOMAIN_SEPARATOR() external view returns (bytes32); 51 | } 52 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC20PermitAllowed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Interface for permit 5 | /// @notice Interface used by DAI/CHAI for permit 6 | interface IERC20PermitAllowed { 7 | /// @notice Approve the spender to spend some tokens via the holder signature 8 | /// @dev This is the permit interface used by DAI and CHAI 9 | /// @param holder The address of the token holder, the token owner 10 | /// @param spender The address of the token spender 11 | /// @param nonce The holder's nonce, increases at each call to permit 12 | /// @param expiry The timestamp at which the permit is no longer valid 13 | /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0 14 | /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` 15 | /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` 16 | /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` 17 | function permit( 18 | address holder, 19 | address spender, 20 | uint256 nonce, 21 | uint256 expiry, 22 | bool allowed, 23 | uint8 v, 24 | bytes32 r, 25 | bytes32 s 26 | ) external; 27 | } 28 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC721Enumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./IERC721.sol"; 6 | 7 | /** 8 | * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension 9 | * @dev See https://eips.ethereum.org/EIPS/eip-721 10 | */ 11 | interface IERC721Enumerable is IERC721 { 12 | 13 | /** 14 | * @dev Returns the total amount of tokens stored by the contract. 15 | */ 16 | function totalSupply() external view returns (uint256); 17 | 18 | /** 19 | * @dev Returns a token ID owned by `owner` at a given `index` of its token list. 20 | * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. 21 | */ 22 | function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); 23 | 24 | /** 25 | * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. 26 | * Use along with {totalSupply} to enumerate all tokens. 27 | */ 28 | function tokenByIndex(uint256 index) external view returns (uint256); 29 | } 30 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC721Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./IERC721.sol"; 6 | 7 | /** 8 | * @title ERC-721 Non-Fungible Token Standard, optional metadata extension 9 | * @dev See https://eips.ethereum.org/EIPS/eip-721 10 | */ 11 | interface IERC721Metadata is IERC721 { 12 | 13 | /** 14 | * @dev Returns the token collection name. 15 | */ 16 | function name() external view returns (string memory); 17 | 18 | /** 19 | * @dev Returns the token collection symbol. 20 | */ 21 | function symbol() external view returns (string memory); 22 | 23 | /** 24 | * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. 25 | */ 26 | function tokenURI(uint256 tokenId) external view returns (string memory); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC721Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | import './IERC721.sol'; 5 | 6 | /// @title ERC721 with permit 7 | /// @notice Extension to ERC721 that includes a permit function for signature based approvals 8 | interface IERC721Permit is IERC721 { 9 | /// @notice The permit typehash used in the permit signature 10 | /// @return The typehash for the permit 11 | function PERMIT_TYPEHASH() external pure returns (bytes32); 12 | 13 | /// @notice The domain separator used in the permit signature 14 | /// @return The domain seperator used in encoding of permit signature 15 | function DOMAIN_SEPARATOR() external view returns (bytes32); 16 | 17 | /// @notice Approve of a specific token ID for spending by spender via signature 18 | /// @param spender The account that is being approved 19 | /// @param tokenId The ID of the token that is being approved for spending 20 | /// @param deadline The deadline timestamp by which the call must be mined for the approve to work 21 | /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` 22 | /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` 23 | /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` 24 | function permit( 25 | address spender, 26 | uint256 tokenId, 27 | uint256 deadline, 28 | uint8 v, 29 | bytes32 r, 30 | bytes32 s 31 | ) external payable; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IERC721Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @title ERC721 token receiver interface 7 | * @dev Interface for any contract that wants to support safeTransfers 8 | * from ERC721 asset contracts. 9 | */ 10 | interface IERC721Receiver { 11 | /** 12 | * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} 13 | * by `operator` from `from`, this function is called. 14 | * 15 | * It must return its Solidity selector to confirm the token transfer. 16 | * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. 17 | * 18 | * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. 19 | */ 20 | function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); 21 | } 22 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IMulticall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Multicall interface 6 | /// @notice Enables calling multiple methods in a single call to the contract 7 | interface IMulticall { 8 | /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed 9 | /// @dev The `msg.value` should not be trusted for any method callable from multicall. 10 | /// @param data The encoded function data for each of the calls to make to this contract 11 | /// @return results The results from each of the calls passed in via data 12 | function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/INonfungibleTokenPositionDescriptor.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './INonfungiblePositionManager.sol'; 5 | 6 | /// @title Describes position NFT tokens via URI 7 | interface INonfungibleTokenPositionDescriptor { 8 | /// @notice Produces the URI describing a particular token ID for a position manager 9 | /// @dev Note this URI may be a data: URI with the JSON contents directly inlined 10 | /// @param positionManager The position manager for which to describe the token 11 | /// @param tokenId The ID of the token for which to produce a description, which may not be valid 12 | /// @return The URI of the ERC721-compliant metadata 13 | function tokenURI(INonfungiblePositionManager positionManager, uint256 tokenId) 14 | external 15 | view 16 | returns (string memory); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IPeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Immutable state 5 | /// @notice Functions that return immutable state of the router 6 | interface IPeripheryImmutableState { 7 | /// @return Returns the address of the Uniswap V3 factory 8 | function factory() external view returns (address); 9 | 10 | /// @return Returns the address of WETH9 11 | function WETH9() external view returns (address); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IPeripheryPayments.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | /// @title Periphery Payments 5 | /// @notice Functions to ease deposits and withdrawals of ETH 6 | interface IPeripheryPayments { 7 | /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. 8 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. 9 | /// @param amountMinimum The minimum amount of WETH9 to unwrap 10 | /// @param recipient The address receiving ETH 11 | function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; 12 | 13 | /// @notice Refunds any ETH balance held by this contract to the `msg.sender` 14 | /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps 15 | /// that use ether for the input amount 16 | function refundETH() external payable; 17 | 18 | /// @notice Transfers the full amount of a token held by this contract to recipient 19 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users 20 | /// @param token The contract address of the token which will be transferred to `recipient` 21 | /// @param amountMinimum The minimum amount of token required for a transfer 22 | /// @param recipient The destination address of the token 23 | function sweepToken( 24 | address token, 25 | uint256 amountMinimum, 26 | address recipient 27 | ) external payable; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IPoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Creates and initializes V3 Pools 6 | /// @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that 7 | /// require the pool to exist. 8 | interface IPoolInitializer { 9 | /// @notice Creates a new pool if it does not exist, then initializes if not initialized 10 | /// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool 11 | /// @param token0 The contract address of token0 of the pool 12 | /// @param token1 The contract address of token1 of the pool 13 | /// @param fee The fee amount of the v3 pool for the specified token pair 14 | /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value 15 | /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary 16 | function createAndInitializePoolIfNecessary( 17 | address token0, 18 | address token1, 19 | uint24 fee, 20 | uint160 sqrtPriceX96 21 | ) external payable returns (address pool); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IUniswapV3MintCallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Callback for IUniswapV3PoolActions#mint 5 | /// @notice Any contract that calls IUniswapV3PoolActions#mint must implement this interface 6 | interface IUniswapV3MintCallback { 7 | /// @notice Called to `msg.sender` after minting liquidity to a position from IUniswapV3Pool#mint. 8 | /// @dev In the implementation you must pay the pool tokens owed for the minted liquidity. 9 | /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. 10 | /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity 11 | /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity 12 | /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#mint call 13 | function uniswapV3MintCallback( 14 | uint256 amount0Owed, 15 | uint256 amount1Owed, 16 | bytes calldata data 17 | ) external; 18 | } 19 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IUniswapV3PoolImmutables.sol'; 5 | import './IUniswapV3PoolState.sol'; 6 | import './IUniswapV3PoolDerivedState.sol'; 7 | import './IUniswapV3PoolActions.sol'; 8 | import './IUniswapV3PoolOwnerActions.sol'; 9 | import './IUniswapV3PoolEvents.sol'; 10 | 11 | /// @title The interface for a Uniswap V3 Pool 12 | /// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform 13 | /// to the ERC20 specification 14 | /// @dev The pool interface is broken up into many smaller pieces 15 | interface IUniswapV3Pool is 16 | IUniswapV3PoolImmutables, 17 | IUniswapV3PoolState, 18 | IUniswapV3PoolDerivedState, 19 | IUniswapV3PoolActions, 20 | IUniswapV3PoolOwnerActions, 21 | IUniswapV3PoolEvents 22 | { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IUniswapV3PoolDerivedState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that is not stored 5 | /// @notice Contains view functions to provide information about the pool that is computed rather than stored on the 6 | /// blockchain. The functions here may have variable gas costs. 7 | interface IUniswapV3PoolDerivedState { 8 | /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp 9 | /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing 10 | /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, 11 | /// you must call it with secondsAgos = [3600, 0]. 12 | /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in 13 | /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. 14 | /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned 15 | /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp 16 | /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block 17 | /// timestamp 18 | function observe(uint32[] calldata secondsAgos) 19 | external 20 | view 21 | returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); 22 | 23 | /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range 24 | /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. 25 | /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first 26 | /// snapshot is taken and the second snapshot is taken. 27 | /// @param tickLower The lower tick of the range 28 | /// @param tickUpper The upper tick of the range 29 | /// @return tickCumulativeInside The snapshot of the tick accumulator for the range 30 | /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range 31 | /// @return secondsInside The snapshot of seconds per liquidity for the range 32 | function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) 33 | external 34 | view 35 | returns ( 36 | int56 tickCumulativeInside, 37 | uint160 secondsPerLiquidityInsideX128, 38 | uint32 secondsInside 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IUniswapV3PoolImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that never changes 5 | /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values 6 | interface IUniswapV3PoolImmutables { 7 | /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface 8 | /// @return The contract address 9 | function factory() external view returns (address); 10 | 11 | /// @notice The first of the two tokens of the pool, sorted by address 12 | /// @return The token contract address 13 | function token0() external view returns (address); 14 | 15 | /// @notice The second of the two tokens of the pool, sorted by address 16 | /// @return The token contract address 17 | function token1() external view returns (address); 18 | 19 | /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 20 | /// @return The fee 21 | function fee() external view returns (uint24); 22 | 23 | /// @notice The pool tick spacing 24 | /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive 25 | /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... 26 | /// This value is an int24 to avoid casting even though it is always positive. 27 | /// @return The tick spacing 28 | function tickSpacing() external view returns (int24); 29 | 30 | /// @notice The maximum amount of position liquidity that can use any tick in the range 31 | /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and 32 | /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool 33 | /// @return The max amount of liquidity per tick 34 | function maxLiquidityPerTick() external view returns (uint128); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IUniswapV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Permissioned pool actions 5 | /// @notice Contains pool methods that may only be called by the factory owner 6 | interface IUniswapV3PoolOwnerActions { 7 | /// @notice Set the denominator of the protocol's % share of the fees 8 | /// @param feeProtocol0 new protocol fee for token0 of the pool 9 | /// @param feeProtocol1 new protocol fee for token1 of the pool 10 | function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; 11 | 12 | /// @notice Collect the protocol fee accrued to the pool 13 | /// @param recipient The address to which collected protocol fees should be sent 14 | /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 15 | /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 16 | /// @return amount0 The protocol fee collected in token0 17 | /// @return amount1 The protocol fee collected in token1 18 | function collectProtocol( 19 | address recipient, 20 | uint128 amount0Requested, 21 | uint128 amount1Requested 22 | ) external returns (uint128 amount0, uint128 amount1); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/IWETH9.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IERC20.sol'; 5 | 6 | /// @title Interface for WETH9 7 | interface IWETH9 is IERC20 { 8 | /// @notice Deposit ether to get wrapped ether 9 | function deposit() external payable; 10 | 11 | /// @notice Withdraw wrapped ether to get ether 12 | function withdraw(uint256) external; 13 | } 14 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/Multicall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | pragma abicoder v2; 4 | 5 | import './IMulticall.sol'; 6 | 7 | /// @title Multicall 8 | /// @notice Enables calling multiple methods in a single call to the contract 9 | abstract contract Multicall is IMulticall { 10 | /// @inheritdoc IMulticall 11 | function multicall(bytes[] calldata data) external payable override returns (bytes[] memory results) { 12 | results = new bytes[](data.length); 13 | for (uint256 i = 0; i < data.length; i++) { 14 | (bool success, bytes memory result) = address(this).delegatecall(data[i]); 15 | 16 | if (!success) { 17 | // Next 5 lines from https://ethereum.stackexchange.com/a/83577 18 | if (result.length < 68) revert(); 19 | assembly { 20 | result := add(result, 0x04) 21 | } 22 | revert(abi.decode(result, (string))); 23 | } 24 | 25 | results[i] = result; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/PeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IPeripheryImmutableState.sol'; 5 | 6 | /// @title Immutable state 7 | /// @notice Immutable state used by periphery contracts 8 | abstract contract PeripheryImmutableState is IPeripheryImmutableState { 9 | /// @inheritdoc IPeripheryImmutableState 10 | address public immutable override factory; 11 | /// @inheritdoc IPeripheryImmutableState 12 | address public immutable override WETH9; 13 | 14 | constructor(address _factory, address _WETH9) { 15 | factory = _factory; 16 | WETH9 = _WETH9; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/PeripheryPayments.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | import './IERC20.sol'; 5 | 6 | import './IPeripheryPayments.sol'; 7 | import './IWETH9.sol'; 8 | 9 | import './TransferHelper.sol'; 10 | 11 | import './PeripheryImmutableState.sol'; 12 | 13 | abstract contract PeripheryPayments is IPeripheryPayments, PeripheryImmutableState { 14 | receive() external payable { 15 | require(msg.sender == WETH9, 'Not WETH9'); 16 | } 17 | 18 | /// @inheritdoc IPeripheryPayments 19 | function unwrapWETH9(uint256 amountMinimum, address recipient) external payable override { 20 | uint256 balanceWETH9 = IWETH9(WETH9).balanceOf(address(this)); 21 | require(balanceWETH9 >= amountMinimum, 'Insufficient WETH9'); 22 | 23 | if (balanceWETH9 > 0) { 24 | IWETH9(WETH9).withdraw(balanceWETH9); 25 | TransferHelper.safeTransferETH(recipient, balanceWETH9); 26 | } 27 | } 28 | 29 | /// @inheritdoc IPeripheryPayments 30 | function sweepToken( 31 | address token, 32 | uint256 amountMinimum, 33 | address recipient 34 | ) external payable override { 35 | uint256 balanceToken = IERC20(token).balanceOf(address(this)); 36 | require(balanceToken >= amountMinimum, 'Insufficient token'); 37 | 38 | if (balanceToken > 0) { 39 | TransferHelper.safeTransfer(token, recipient, balanceToken); 40 | } 41 | } 42 | 43 | /// @inheritdoc IPeripheryPayments 44 | function refundETH() external payable override { 45 | if (address(this).balance > 0) TransferHelper.safeTransferETH(msg.sender, address(this).balance); 46 | } 47 | 48 | /// @param token The token to pay 49 | /// @param payer The entity that must pay 50 | /// @param recipient The entity that will receive payment 51 | /// @param value The amount to pay 52 | function pay( 53 | address token, 54 | address payer, 55 | address recipient, 56 | uint256 value 57 | ) internal { 58 | if (token == WETH9 && address(this).balance >= value) { 59 | // pay with WETH9 60 | IWETH9(WETH9).deposit{value: value}(); // wrap only what is needed to pay 61 | IWETH9(WETH9).transfer(recipient, value); 62 | } else if (payer == address(this)) { 63 | // pay with tokens already in the contract (for the exact input multihop case) 64 | TransferHelper.safeTransfer(token, recipient, value); 65 | } else { 66 | // pull payment 67 | TransferHelper.safeTransferFrom(token, payer, recipient, value); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/PeripheryValidation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './BlockTimestamp.sol'; 5 | 6 | abstract contract PeripheryValidation is BlockTimestamp { 7 | modifier checkDeadline(uint256 deadline) { 8 | require(_blockTimestamp() <= deadline, 'Transaction too old'); 9 | _; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/PoolAddress.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Provides functions for deriving a pool address from the factory, tokens, and the fee 5 | library PoolAddress { 6 | bytes32 internal constant POOL_INIT_CODE_HASH = 0xd70958ebfff5a99884d37fb1ba60083c838125942b9ab042cf8d49a7929bb9d0; 7 | 8 | /// @notice The identifying key of the pool 9 | struct PoolKey { 10 | address token0; 11 | address token1; 12 | uint24 fee; 13 | } 14 | 15 | /// @notice Returns PoolKey: the ordered tokens with the matched fee levels 16 | /// @param tokenA The first token of a pool, unsorted 17 | /// @param tokenB The second token of a pool, unsorted 18 | /// @param fee The fee level of the pool 19 | /// @return Poolkey The pool details with ordered token0 and token1 assignments 20 | function getPoolKey( 21 | address tokenA, 22 | address tokenB, 23 | uint24 fee 24 | ) internal pure returns (PoolKey memory) { 25 | if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); 26 | return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); 27 | } 28 | 29 | /// @notice Deterministically computes the pool address given the factory and PoolKey 30 | /// @param factory The Uniswap V3 factory contract address 31 | /// @param key The PoolKey 32 | /// @return pool The contract address of the V3 pool 33 | function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { 34 | require(key.token0 < key.token1); 35 | pool = address( 36 | uint256( 37 | keccak256( 38 | abi.encodePacked( 39 | hex'ff', 40 | factory, 41 | keccak256(abi.encode(key.token0, key.token1, key.fee)), 42 | POOL_INIT_CODE_HASH 43 | ) 44 | ) 45 | ) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/PoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IUniswapV3Factory.sol'; 5 | import './IUniswapV3Pool.sol'; 6 | 7 | import './PeripheryImmutableState.sol'; 8 | import './IPoolInitializer.sol'; 9 | 10 | /// @title Creates and initializes V3 Pools 11 | abstract contract PoolInitializer is IPoolInitializer, PeripheryImmutableState { 12 | /// @inheritdoc IPoolInitializer 13 | function createAndInitializePoolIfNecessary( 14 | address token0, 15 | address token1, 16 | uint24 fee, 17 | uint160 sqrtPriceX96 18 | ) external payable override returns (address pool) { 19 | require(token0 < token1); 20 | pool = IUniswapV3Factory(factory).getPool(token0, token1, fee); 21 | 22 | if (pool == address(0)) { 23 | pool = IUniswapV3Factory(factory).createPool(token0, token1, fee); 24 | IUniswapV3Pool(pool).initialize(sqrtPriceX96); 25 | } else { 26 | (uint160 sqrtPriceX96Existing, , , , , , ) = IUniswapV3Pool(pool).slot0(); 27 | if (sqrtPriceX96Existing == 0) { 28 | IUniswapV3Pool(pool).initialize(sqrtPriceX96); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/PositionKey.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | library PositionKey { 5 | /// @dev Returns the key of the position in the core library 6 | function compute( 7 | address owner, 8 | int24 tickLower, 9 | int24 tickUpper 10 | ) internal pure returns (bytes32) { 11 | return keccak256(abi.encodePacked(owner, tickLower, tickUpper)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/SelfPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IERC20.sol'; 5 | import './IERC20Permit.sol'; 6 | 7 | import './ISelfPermit.sol'; 8 | import './IERC20PermitAllowed.sol'; 9 | 10 | /// @title Self Permit 11 | /// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route 12 | /// @dev These functions are expected to be embedded in multicalls to allow EOAs to approve a contract and call a function 13 | /// that requires an approval in a single transaction. 14 | abstract contract SelfPermit is ISelfPermit { 15 | /// @inheritdoc ISelfPermit 16 | function selfPermit( 17 | address token, 18 | uint256 value, 19 | uint256 deadline, 20 | uint8 v, 21 | bytes32 r, 22 | bytes32 s 23 | ) public payable override { 24 | IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s); 25 | } 26 | 27 | /// @inheritdoc ISelfPermit 28 | function selfPermitIfNecessary( 29 | address token, 30 | uint256 value, 31 | uint256 deadline, 32 | uint8 v, 33 | bytes32 r, 34 | bytes32 s 35 | ) external payable override { 36 | if (IERC20(token).allowance(msg.sender, address(this)) < value) selfPermit(token, value, deadline, v, r, s); 37 | } 38 | 39 | /// @inheritdoc ISelfPermit 40 | function selfPermitAllowed( 41 | address token, 42 | uint256 nonce, 43 | uint256 expiry, 44 | uint8 v, 45 | bytes32 r, 46 | bytes32 s 47 | ) public payable override { 48 | IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s); 49 | } 50 | 51 | /// @inheritdoc ISelfPermit 52 | function selfPermitAllowedIfNecessary( 53 | address token, 54 | uint256 nonce, 55 | uint256 expiry, 56 | uint8 v, 57 | bytes32 r, 58 | bytes32 s 59 | ) external payable override { 60 | if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) 61 | selfPermitAllowed(token, nonce, expiry, v, r, s); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/Strings.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev String operations. 7 | */ 8 | library Strings { 9 | /** 10 | * @dev Converts a `uint256` to its ASCII `string` representation. 11 | */ 12 | function toString(uint256 value) internal pure returns (string memory) { 13 | // Inspired by OraclizeAPI's implementation - MIT licence 14 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 15 | 16 | if (value == 0) { 17 | return "0"; 18 | } 19 | uint256 temp = value; 20 | uint256 digits; 21 | while (temp != 0) { 22 | digits++; 23 | temp /= 10; 24 | } 25 | bytes memory buffer = new bytes(digits); 26 | uint256 index = digits - 1; 27 | temp = value; 28 | while (temp != 0) { 29 | buffer[index--] = bytes1(uint8(48 + temp % 10)); 30 | temp /= 10; 31 | } 32 | return string(buffer); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/NonfungiblePositionManager/TransferHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.6.0; 3 | 4 | import './IERC20.sol'; 5 | 6 | library TransferHelper { 7 | /// @notice Transfers tokens from the targeted address to the given destination 8 | /// @notice Errors with 'STF' if transfer fails 9 | /// @param token The contract address of the token to be transferred 10 | /// @param from The originating address from which the tokens will be transferred 11 | /// @param to The destination address of the transfer 12 | /// @param value The amount to be transferred 13 | function safeTransferFrom( 14 | address token, 15 | address from, 16 | address to, 17 | uint256 value 18 | ) internal { 19 | (bool success, bytes memory data) = 20 | token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); 21 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); 22 | } 23 | 24 | /// @notice Transfers tokens from msg.sender to a recipient 25 | /// @dev Errors with ST if transfer fails 26 | /// @param token The contract address of the token which will be transferred 27 | /// @param to The recipient of the transfer 28 | /// @param value The value of the transfer 29 | function safeTransfer( 30 | address token, 31 | address to, 32 | uint256 value 33 | ) internal { 34 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); 35 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); 36 | } 37 | 38 | /// @notice Approves the stipulated contract to spend the given allowance in the given token 39 | /// @dev Errors with 'SA' if transfer fails 40 | /// @param token The contract address of the token to be approved 41 | /// @param to The target of the approval 42 | /// @param value The amount of the given token the target will be allowed to spend 43 | function safeApprove( 44 | address token, 45 | address to, 46 | uint256 value 47 | ) internal { 48 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); 49 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); 50 | } 51 | 52 | /// @notice Transfers ETH to the recipient address 53 | /// @dev Fails with `STE` 54 | /// @param to The destination of the transfer 55 | /// @param value The value to be transferred 56 | function safeTransferETH(address to, uint256 value) internal { 57 | (bool success, ) = to.call{value: value}(new bytes(0)); 58 | require(success, 'STE'); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/AddressStringUtil.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | library AddressStringUtil { 6 | // converts an address to the uppercase hex string, extracting only len bytes (up to 20, multiple of 2) 7 | function toAsciiString(address addr, uint256 len) internal pure returns (string memory) { 8 | require(len % 2 == 0 && len > 0 && len <= 40, 'AddressStringUtil: INVALID_LEN'); 9 | 10 | bytes memory s = new bytes(len); 11 | uint256 addrNum = uint256(addr); 12 | for (uint256 i = 0; i < len / 2; i++) { 13 | // shift right and truncate all but the least significant byte to extract the byte at position 19-i 14 | uint8 b = uint8(addrNum >> (8 * (19 - i))); 15 | // first hex character is the most significant 4 bits 16 | uint8 hi = b >> 4; 17 | // second hex character is the least significant 4 bits 18 | uint8 lo = b - (hi << 4); 19 | s[2 * i] = char(hi); 20 | s[2 * i + 1] = char(lo); 21 | } 22 | return string(s); 23 | } 24 | 25 | // hi and lo are only 4 bits and between 0 and 16 26 | // this method converts those values to the unicode/ascii code point for the hex representation 27 | // uses upper case for the characters 28 | function char(uint8 b) private pure returns (bytes1 c) { 29 | if (b < 10) { 30 | return bytes1(b + 0x30); 31 | } else { 32 | return bytes1(b + 0x37); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/ChainId.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.0; 3 | 4 | /// @title Function for getting the current chain ID 5 | library ChainId { 6 | /// @dev Gets the current chain ID 7 | /// @return chainId The current chain ID 8 | function get() internal pure returns (uint256 chainId) { 9 | assembly { 10 | chainId := chainid() 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/HexStrings.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity =0.7.6; 3 | 4 | library HexStrings { 5 | bytes16 internal constant ALPHABET = '0123456789abcdef'; 6 | 7 | /// @notice Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. 8 | /// @dev Credit to Open Zeppelin under MIT license https://github.com/OpenZeppelin/openzeppelin-contracts/blob/243adff49ce1700e0ecb99fe522fb16cff1d1ddc/contracts/utils/Strings.sol#L55 9 | function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 10 | bytes memory buffer = new bytes(2 * length + 2); 11 | buffer[0] = '0'; 12 | buffer[1] = 'x'; 13 | for (uint256 i = 2 * length + 1; i > 1; --i) { 14 | buffer[i] = ALPHABET[value & 0xf]; 15 | value >>= 4; 16 | } 17 | require(value == 0, 'Strings: hex length insufficient'); 18 | return string(buffer); 19 | } 20 | 21 | function toHexStringNoPrefix(uint256 value, uint256 length) internal pure returns (string memory) { 22 | bytes memory buffer = new bytes(2 * length); 23 | for (uint256 i = buffer.length; i > 0; i--) { 24 | buffer[i - 1] = ALPHABET[value & 0xf]; 25 | value >>= 4; 26 | } 27 | return string(buffer); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev Interface of the ERC165 standard, as defined in the 7 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 8 | * 9 | * Implementers can declare support of contract interfaces, which can then be 10 | * queried by others ({ERC165Checker}). 11 | * 12 | * For an implementation, see {ERC165}. 13 | */ 14 | interface IERC165 { 15 | /** 16 | * @dev Returns true if this contract implements the interface defined by 17 | * `interfaceId`. See the corresponding 18 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 19 | * to learn more about how these ids are created. 20 | * 21 | * This function call must use less than 30 000 gas. 22 | */ 23 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 standard as defined in the EIP. 7 | */ 8 | interface IERC20 { 9 | /** 10 | * @dev Returns the amount of tokens in existence. 11 | */ 12 | function totalSupply() external view returns (uint256); 13 | 14 | /** 15 | * @dev Returns the amount of tokens owned by `account`. 16 | */ 17 | function balanceOf(address account) external view returns (uint256); 18 | 19 | /** 20 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 21 | * 22 | * Returns a boolean value indicating whether the operation succeeded. 23 | * 24 | * Emits a {Transfer} event. 25 | */ 26 | function transfer(address recipient, uint256 amount) external returns (bool); 27 | 28 | /** 29 | * @dev Returns the remaining number of tokens that `spender` will be 30 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 31 | * zero by default. 32 | * 33 | * This value changes when {approve} or {transferFrom} are called. 34 | */ 35 | function allowance(address owner, address spender) external view returns (uint256); 36 | 37 | /** 38 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 39 | * 40 | * Returns a boolean value indicating whether the operation succeeded. 41 | * 42 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 43 | * that someone may use both the old and the new allowance by unfortunate 44 | * transaction ordering. One possible solution to mitigate this race 45 | * condition is to first reduce the spender's allowance to 0 and set the 46 | * desired value afterwards: 47 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 48 | * 49 | * Emits an {Approval} event. 50 | */ 51 | function approve(address spender, uint256 amount) external returns (bool); 52 | 53 | /** 54 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 55 | * allowance mechanism. `amount` is then deducted from the caller's 56 | * allowance. 57 | * 58 | * Returns a boolean value indicating whether the operation succeeded. 59 | * 60 | * Emits a {Transfer} event. 61 | */ 62 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 63 | 64 | /** 65 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 66 | * another (`to`). 67 | * 68 | * Note that `value` may be zero. 69 | */ 70 | event Transfer(address indexed from, address indexed to, uint256 value); 71 | 72 | /** 73 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 74 | * a call to {approve}. `value` is the new allowance. 75 | */ 76 | event Approval(address indexed owner, address indexed spender, uint256 value); 77 | } 78 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IERC20Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.7.0; 3 | 4 | import './IERC20.sol'; 5 | 6 | /// @title IERC20Metadata 7 | /// @title Interface for ERC20 Metadata 8 | /// @notice Extension to IERC20 that includes token metadata 9 | interface IERC20Metadata is IERC20 { 10 | /// @return The name of the token 11 | function name() external view returns (string memory); 12 | 13 | /// @return The symbol of the token 14 | function symbol() external view returns (string memory); 15 | 16 | /// @return The number of decimal places the token has 17 | function decimals() external view returns (uint8); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IERC721Enumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./IERC721.sol"; 6 | 7 | /** 8 | * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension 9 | * @dev See https://eips.ethereum.org/EIPS/eip-721 10 | */ 11 | interface IERC721Enumerable is IERC721 { 12 | 13 | /** 14 | * @dev Returns the total amount of tokens stored by the contract. 15 | */ 16 | function totalSupply() external view returns (uint256); 17 | 18 | /** 19 | * @dev Returns a token ID owned by `owner` at a given `index` of its token list. 20 | * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. 21 | */ 22 | function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); 23 | 24 | /** 25 | * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. 26 | * Use along with {totalSupply} to enumerate all tokens. 27 | */ 28 | function tokenByIndex(uint256 index) external view returns (uint256); 29 | } 30 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IERC721Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./IERC721.sol"; 6 | 7 | /** 8 | * @title ERC-721 Non-Fungible Token Standard, optional metadata extension 9 | * @dev See https://eips.ethereum.org/EIPS/eip-721 10 | */ 11 | interface IERC721Metadata is IERC721 { 12 | 13 | /** 14 | * @dev Returns the token collection name. 15 | */ 16 | function name() external view returns (string memory); 17 | 18 | /** 19 | * @dev Returns the token collection symbol. 20 | */ 21 | function symbol() external view returns (string memory); 22 | 23 | /** 24 | * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. 25 | */ 26 | function tokenURI(uint256 tokenId) external view returns (string memory); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IERC721Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | import './IERC721.sol'; 5 | 6 | /// @title ERC721 with permit 7 | /// @notice Extension to ERC721 that includes a permit function for signature based approvals 8 | interface IERC721Permit is IERC721 { 9 | /// @notice The permit typehash used in the permit signature 10 | /// @return The typehash for the permit 11 | function PERMIT_TYPEHASH() external pure returns (bytes32); 12 | 13 | /// @notice The domain separator used in the permit signature 14 | /// @return The domain seperator used in encoding of permit signature 15 | function DOMAIN_SEPARATOR() external view returns (bytes32); 16 | 17 | /// @notice Approve of a specific token ID for spending by spender via signature 18 | /// @param spender The account that is being approved 19 | /// @param tokenId The ID of the token that is being approved for spending 20 | /// @param deadline The deadline timestamp by which the call must be mined for the approve to work 21 | /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` 22 | /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` 23 | /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` 24 | function permit( 25 | address spender, 26 | uint256 tokenId, 27 | uint256 deadline, 28 | uint8 v, 29 | bytes32 r, 30 | bytes32 s 31 | ) external payable; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/INonfungibleTokenPositionDescriptor.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './INonfungiblePositionManager.sol'; 5 | 6 | /// @title Describes position NFT tokens via URI 7 | interface INonfungibleTokenPositionDescriptor { 8 | /// @notice Produces the URI describing a particular token ID for a position manager 9 | /// @dev Note this URI may be a data: URI with the JSON contents directly inlined 10 | /// @param positionManager The position manager for which to describe the token 11 | /// @param tokenId The ID of the token for which to produce a description, which may not be valid 12 | /// @return The URI of the ERC721-compliant metadata 13 | function tokenURI(INonfungiblePositionManager positionManager, uint256 tokenId) 14 | external 15 | view 16 | returns (string memory); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IPeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Immutable state 5 | /// @notice Functions that return immutable state of the router 6 | interface IPeripheryImmutableState { 7 | /// @return Returns the address of the Uniswap V3 factory 8 | function factory() external view returns (address); 9 | 10 | /// @return Returns the address of WETH9 11 | function WETH9() external view returns (address); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IPeripheryPayments.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | /// @title Periphery Payments 5 | /// @notice Functions to ease deposits and withdrawals of ETH 6 | interface IPeripheryPayments { 7 | /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. 8 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. 9 | /// @param amountMinimum The minimum amount of WETH9 to unwrap 10 | /// @param recipient The address receiving ETH 11 | function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; 12 | 13 | /// @notice Refunds any ETH balance held by this contract to the `msg.sender` 14 | /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps 15 | /// that use ether for the input amount 16 | function refundETH() external payable; 17 | 18 | /// @notice Transfers the full amount of a token held by this contract to recipient 19 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users 20 | /// @param token The contract address of the token which will be transferred to `recipient` 21 | /// @param amountMinimum The minimum amount of token required for a transfer 22 | /// @param recipient The destination address of the token 23 | function sweepToken( 24 | address token, 25 | uint256 amountMinimum, 26 | address recipient 27 | ) external payable; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IPoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Creates and initializes V3 Pools 6 | /// @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that 7 | /// require the pool to exist. 8 | interface IPoolInitializer { 9 | /// @notice Creates a new pool if it does not exist, then initializes if not initialized 10 | /// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool 11 | /// @param token0 The contract address of token0 of the pool 12 | /// @param token1 The contract address of token1 of the pool 13 | /// @param fee The fee amount of the v3 pool for the specified token pair 14 | /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value 15 | /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary 16 | function createAndInitializePoolIfNecessary( 17 | address token0, 18 | address token1, 19 | uint24 fee, 20 | uint160 sqrtPriceX96 21 | ) external payable returns (address pool); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IUniswapV3PoolImmutables.sol'; 5 | import './IUniswapV3PoolState.sol'; 6 | import './IUniswapV3PoolDerivedState.sol'; 7 | import './IUniswapV3PoolActions.sol'; 8 | import './IUniswapV3PoolOwnerActions.sol'; 9 | import './IUniswapV3PoolEvents.sol'; 10 | 11 | /// @title The interface for a Uniswap V3 Pool 12 | /// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform 13 | /// to the ERC20 specification 14 | /// @dev The pool interface is broken up into many smaller pieces 15 | interface IUniswapV3Pool is 16 | IUniswapV3PoolImmutables, 17 | IUniswapV3PoolState, 18 | IUniswapV3PoolDerivedState, 19 | IUniswapV3PoolActions, 20 | IUniswapV3PoolOwnerActions, 21 | IUniswapV3PoolEvents 22 | { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IUniswapV3PoolDerivedState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that is not stored 5 | /// @notice Contains view functions to provide information about the pool that is computed rather than stored on the 6 | /// blockchain. The functions here may have variable gas costs. 7 | interface IUniswapV3PoolDerivedState { 8 | /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp 9 | /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing 10 | /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, 11 | /// you must call it with secondsAgos = [3600, 0]. 12 | /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in 13 | /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. 14 | /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned 15 | /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp 16 | /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block 17 | /// timestamp 18 | function observe(uint32[] calldata secondsAgos) 19 | external 20 | view 21 | returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); 22 | 23 | /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range 24 | /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. 25 | /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first 26 | /// snapshot is taken and the second snapshot is taken. 27 | /// @param tickLower The lower tick of the range 28 | /// @param tickUpper The upper tick of the range 29 | /// @return tickCumulativeInside The snapshot of the tick accumulator for the range 30 | /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range 31 | /// @return secondsInside The snapshot of seconds per liquidity for the range 32 | function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) 33 | external 34 | view 35 | returns ( 36 | int56 tickCumulativeInside, 37 | uint160 secondsPerLiquidityInsideX128, 38 | uint32 secondsInside 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IUniswapV3PoolImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that never changes 5 | /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values 6 | interface IUniswapV3PoolImmutables { 7 | /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface 8 | /// @return The contract address 9 | function factory() external view returns (address); 10 | 11 | /// @notice The first of the two tokens of the pool, sorted by address 12 | /// @return The token contract address 13 | function token0() external view returns (address); 14 | 15 | /// @notice The second of the two tokens of the pool, sorted by address 16 | /// @return The token contract address 17 | function token1() external view returns (address); 18 | 19 | /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 20 | /// @return The fee 21 | function fee() external view returns (uint24); 22 | 23 | /// @notice The pool tick spacing 24 | /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive 25 | /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... 26 | /// This value is an int24 to avoid casting even though it is always positive. 27 | /// @return The tick spacing 28 | function tickSpacing() external view returns (int24); 29 | 30 | /// @notice The maximum amount of position liquidity that can use any tick in the range 31 | /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and 32 | /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool 33 | /// @return The max amount of liquidity per tick 34 | function maxLiquidityPerTick() external view returns (uint128); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/IUniswapV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Permissioned pool actions 5 | /// @notice Contains pool methods that may only be called by the factory owner 6 | interface IUniswapV3PoolOwnerActions { 7 | /// @notice Set the denominator of the protocol's % share of the fees 8 | /// @param feeProtocol0 new protocol fee for token0 of the pool 9 | /// @param feeProtocol1 new protocol fee for token1 of the pool 10 | function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; 11 | 12 | /// @notice Collect the protocol fee accrued to the pool 13 | /// @param recipient The address to which collected protocol fees should be sent 14 | /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 15 | /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 16 | /// @return amount0 The protocol fee collected in token0 17 | /// @return amount1 The protocol fee collected in token1 18 | function collectProtocol( 19 | address recipient, 20 | uint128 amount0Requested, 21 | uint128 amount1Requested 22 | ) external returns (uint128 amount0, uint128 amount1); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/PoolAddress.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Provides functions for deriving a pool address from the factory, tokens, and the fee 5 | library PoolAddress { 6 | bytes32 internal constant POOL_INIT_CODE_HASH = 0xd70958ebfff5a99884d37fb1ba60083c838125942b9ab042cf8d49a7929bb9d0; 7 | 8 | /// @notice The identifying key of the pool 9 | struct PoolKey { 10 | address token0; 11 | address token1; 12 | uint24 fee; 13 | } 14 | 15 | /// @notice Returns PoolKey: the ordered tokens with the matched fee levels 16 | /// @param tokenA The first token of a pool, unsorted 17 | /// @param tokenB The second token of a pool, unsorted 18 | /// @param fee The fee level of the pool 19 | /// @return Poolkey The pool details with ordered token0 and token1 assignments 20 | function getPoolKey( 21 | address tokenA, 22 | address tokenB, 23 | uint24 fee 24 | ) internal pure returns (PoolKey memory) { 25 | if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); 26 | return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); 27 | } 28 | 29 | /// @notice Deterministically computes the pool address given the factory and PoolKey 30 | /// @param factory The Uniswap V3 factory contract address 31 | /// @param key The PoolKey 32 | /// @return pool The contract address of the V3 pool 33 | function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { 34 | require(key.token0 < key.token1); 35 | pool = address( 36 | uint256( 37 | keccak256( 38 | abi.encodePacked( 39 | hex'ff', 40 | factory, 41 | keccak256(abi.encode(key.token0, key.token1, key.fee)), 42 | POOL_INIT_CODE_HASH 43 | ) 44 | ) 45 | ) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/Strings.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev String operations. 7 | */ 8 | library Strings { 9 | /** 10 | * @dev Converts a `uint256` to its ASCII `string` representation. 11 | */ 12 | function toString(uint256 value) internal pure returns (string memory) { 13 | // Inspired by OraclizeAPI's implementation - MIT licence 14 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 15 | 16 | if (value == 0) { 17 | return "0"; 18 | } 19 | uint256 temp = value; 20 | uint256 digits; 21 | while (temp != 0) { 22 | digits++; 23 | temp /= 10; 24 | } 25 | bytes memory buffer = new bytes(digits); 26 | uint256 index = digits - 1; 27 | temp = value; 28 | while (temp != 0) { 29 | buffer[index--] = bytes1(uint8(48 + temp % 10)); 30 | temp /= 10; 31 | } 32 | return string(buffer); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/TokenRatioSortOrder.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity =0.7.6; 3 | 4 | library TokenRatioSortOrder { 5 | int256 constant NUMERATOR_MOST = 300; 6 | int256 constant NUMERATOR_MORE = 200; 7 | int256 constant NUMERATOR = 100; 8 | 9 | int256 constant DENOMINATOR_MOST = -300; 10 | int256 constant DENOMINATOR_MORE = -200; 11 | int256 constant DENOMINATOR = -100; 12 | } 13 | -------------------------------------------------------------------------------- /contracts/NonfungibleTokenPositionDescriptor/base64.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | /// @title Base64 5 | /// @author Brecht Devos - 6 | /// @notice Provides a function for encoding some bytes in base64 7 | library Base64 { 8 | string internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 9 | 10 | function encode(bytes memory data) internal pure returns (string memory) { 11 | if (data.length == 0) return ''; 12 | 13 | // load the table into memory 14 | string memory table = TABLE; 15 | 16 | // multiply by 4/3 rounded up 17 | uint256 encodedLen = 4 * ((data.length + 2) / 3); 18 | 19 | // add some extra buffer at the end required for the writing 20 | string memory result = new string(encodedLen + 32); 21 | 22 | assembly { 23 | // set the actual output length 24 | mstore(result, encodedLen) 25 | 26 | // prepare the lookup table 27 | let tablePtr := add(table, 1) 28 | 29 | // input ptr 30 | let dataPtr := data 31 | let endPtr := add(dataPtr, mload(data)) 32 | 33 | // result ptr, jump over length 34 | let resultPtr := add(result, 32) 35 | 36 | // run over the input, 3 bytes at a time 37 | for {} lt(dataPtr, endPtr) {} 38 | { 39 | dataPtr := add(dataPtr, 3) 40 | 41 | // read 3 bytes 42 | let input := mload(dataPtr) 43 | 44 | // write 4 characters 45 | mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))) 46 | resultPtr := add(resultPtr, 1) 47 | mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))) 48 | resultPtr := add(resultPtr, 1) 49 | mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F))))) 50 | resultPtr := add(resultPtr, 1) 51 | mstore(resultPtr, shl(248, mload(add(tablePtr, and( input, 0x3F))))) 52 | resultPtr := add(resultPtr, 1) 53 | } 54 | 55 | // padding with '=' 56 | switch mod(mload(data), 3) 57 | case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } 58 | case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } 59 | } 60 | 61 | return result; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/ProxyAdmin/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with GSN meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address payable) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes memory) { 21 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 22 | return msg.data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/ProxyAdmin/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./Context.sol"; 6 | 7 | /** 8 | * @dev Contract module which provides a basic access control mechanism, where 9 | * there is an account (an owner) that can be granted exclusive access to 10 | * specific functions. 11 | * 12 | * By default, the owner account will be the one that deploys the contract. This 13 | * can later be changed with {transferOwnership}. 14 | * 15 | * This module is used through inheritance. It will make available the modifier 16 | * `onlyOwner`, which can be applied to your functions to restrict their use to 17 | * the owner. 18 | */ 19 | abstract contract Ownable is Context { 20 | address private _owner; 21 | 22 | event OwnershipTransferred( 23 | address indexed previousOwner, 24 | address indexed newOwner 25 | ); 26 | 27 | /** 28 | * @dev Initializes the contract setting the deployer as the initial owner. 29 | */ 30 | constructor() { 31 | address msgSender = _msgSender(); 32 | _owner = msgSender; 33 | emit OwnershipTransferred(address(0), msgSender); 34 | } 35 | 36 | /** 37 | * @dev Returns the address of the current owner. 38 | */ 39 | function owner() public view virtual returns (address) { 40 | return _owner; 41 | } 42 | 43 | /** 44 | * @dev Throws if called by any account other than the owner. 45 | */ 46 | modifier onlyOwner() { 47 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 48 | _; 49 | } 50 | 51 | /** 52 | * @dev Leaves the contract without owner. It will not be possible to call 53 | * `onlyOwner` functions anymore. Can only be called by the current owner. 54 | * 55 | * NOTE: Renouncing ownership will leave the contract without an owner, 56 | * thereby removing any functionality that is only available to the owner. 57 | */ 58 | function renounceOwnership() public virtual onlyOwner { 59 | emit OwnershipTransferred(_owner, address(0)); 60 | _owner = address(0); 61 | } 62 | 63 | /** 64 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 65 | * Can only be called by the current owner. 66 | */ 67 | function transferOwnership(address newOwner) public virtual onlyOwner { 68 | require( 69 | newOwner != address(0), 70 | "Ownable: new owner is the zero address" 71 | ); 72 | emit OwnershipTransferred(_owner, newOwner); 73 | _owner = newOwner; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /contracts/Quoter/CallbackValidation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IUniswapV3Pool.sol'; 5 | import './PoolAddress.sol'; 6 | 7 | /// @notice Provides validation for callbacks from Uniswap V3 Pools 8 | library CallbackValidation { 9 | /// @notice Returns the address of a valid Uniswap V3 Pool 10 | /// @param factory The contract address of the Uniswap V3 factory 11 | /// @param tokenA The contract address of either token0 or token1 12 | /// @param tokenB The contract address of the other token 13 | /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip 14 | /// @return pool The V3 pool contract address 15 | function verifyCallback( 16 | address factory, 17 | address tokenA, 18 | address tokenB, 19 | uint24 fee 20 | ) internal view returns (IUniswapV3Pool pool) { 21 | return verifyCallback(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee)); 22 | } 23 | 24 | /// @notice Returns the address of a valid Uniswap V3 Pool 25 | /// @param factory The contract address of the Uniswap V3 factory 26 | /// @param poolKey The identifying key of the V3 pool 27 | /// @return pool The V3 pool contract address 28 | function verifyCallback(address factory, PoolAddress.PoolKey memory poolKey) 29 | internal 30 | view 31 | returns (IUniswapV3Pool pool) 32 | { 33 | pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); 34 | require(msg.sender == address(pool)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contracts/Quoter/IPeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Immutable state 5 | /// @notice Functions that return immutable state of the router 6 | interface IPeripheryImmutableState { 7 | /// @return Returns the address of the Uniswap V3 factory 8 | function factory() external view returns (address); 9 | 10 | /// @return Returns the address of WETH9 11 | function WETH9() external view returns (address); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/Quoter/IQuoter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Quoter Interface 6 | /// @notice Supports quoting the calculated amounts from exact input or exact output swaps 7 | /// @dev These functions are not marked view because they rely on calling non-view functions and reverting 8 | /// to compute the result. They are also not gas efficient and should not be called on-chain. 9 | interface IQuoter { 10 | /// @notice Returns the amount out received for a given exact input swap without executing the swap 11 | /// @param path The path of the swap, i.e. each token pair and the pool fee 12 | /// @param amountIn The amount of the first token to swap 13 | /// @return amountOut The amount of the last token that would be received 14 | function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut); 15 | 16 | /// @notice Returns the amount out received for a given exact input but for a swap of a single pool 17 | /// @param tokenIn The token being swapped in 18 | /// @param tokenOut The token being swapped out 19 | /// @param fee The fee of the token pool to consider for the pair 20 | /// @param amountIn The desired input amount 21 | /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap 22 | /// @return amountOut The amount of `tokenOut` that would be received 23 | function quoteExactInputSingle( 24 | address tokenIn, 25 | address tokenOut, 26 | uint24 fee, 27 | uint256 amountIn, 28 | uint160 sqrtPriceLimitX96 29 | ) external returns (uint256 amountOut); 30 | 31 | /// @notice Returns the amount in required for a given exact output swap without executing the swap 32 | /// @param path The path of the swap, i.e. each token pair and the pool fee 33 | /// @param amountOut The amount of the last token to receive 34 | /// @return amountIn The amount of first token required to be paid 35 | function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn); 36 | 37 | /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool 38 | /// @param tokenIn The token being swapped in 39 | /// @param tokenOut The token being swapped out 40 | /// @param fee The fee of the token pool to consider for the pair 41 | /// @param amountOut The desired output amount 42 | /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap 43 | /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` 44 | function quoteExactOutputSingle( 45 | address tokenIn, 46 | address tokenOut, 47 | uint24 fee, 48 | uint256 amountOut, 49 | uint160 sqrtPriceLimitX96 50 | ) external returns (uint256 amountIn); 51 | } 52 | -------------------------------------------------------------------------------- /contracts/Quoter/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IUniswapV3PoolImmutables.sol'; 5 | import './IUniswapV3PoolState.sol'; 6 | import './IUniswapV3PoolDerivedState.sol'; 7 | import './IUniswapV3PoolActions.sol'; 8 | import './IUniswapV3PoolOwnerActions.sol'; 9 | import './IUniswapV3PoolEvents.sol'; 10 | 11 | /// @title The interface for a Uniswap V3 Pool 12 | /// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform 13 | /// to the ERC20 specification 14 | /// @dev The pool interface is broken up into many smaller pieces 15 | interface IUniswapV3Pool is 16 | IUniswapV3PoolImmutables, 17 | IUniswapV3PoolState, 18 | IUniswapV3PoolDerivedState, 19 | IUniswapV3PoolActions, 20 | IUniswapV3PoolOwnerActions, 21 | IUniswapV3PoolEvents 22 | { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /contracts/Quoter/IUniswapV3PoolDerivedState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that is not stored 5 | /// @notice Contains view functions to provide information about the pool that is computed rather than stored on the 6 | /// blockchain. The functions here may have variable gas costs. 7 | interface IUniswapV3PoolDerivedState { 8 | /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp 9 | /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing 10 | /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, 11 | /// you must call it with secondsAgos = [3600, 0]. 12 | /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in 13 | /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. 14 | /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned 15 | /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp 16 | /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block 17 | /// timestamp 18 | function observe(uint32[] calldata secondsAgos) 19 | external 20 | view 21 | returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); 22 | 23 | /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range 24 | /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. 25 | /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first 26 | /// snapshot is taken and the second snapshot is taken. 27 | /// @param tickLower The lower tick of the range 28 | /// @param tickUpper The upper tick of the range 29 | /// @return tickCumulativeInside The snapshot of the tick accumulator for the range 30 | /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range 31 | /// @return secondsInside The snapshot of seconds per liquidity for the range 32 | function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) 33 | external 34 | view 35 | returns ( 36 | int56 tickCumulativeInside, 37 | uint160 secondsPerLiquidityInsideX128, 38 | uint32 secondsInside 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/Quoter/IUniswapV3PoolImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that never changes 5 | /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values 6 | interface IUniswapV3PoolImmutables { 7 | /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface 8 | /// @return The contract address 9 | function factory() external view returns (address); 10 | 11 | /// @notice The first of the two tokens of the pool, sorted by address 12 | /// @return The token contract address 13 | function token0() external view returns (address); 14 | 15 | /// @notice The second of the two tokens of the pool, sorted by address 16 | /// @return The token contract address 17 | function token1() external view returns (address); 18 | 19 | /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 20 | /// @return The fee 21 | function fee() external view returns (uint24); 22 | 23 | /// @notice The pool tick spacing 24 | /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive 25 | /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... 26 | /// This value is an int24 to avoid casting even though it is always positive. 27 | /// @return The tick spacing 28 | function tickSpacing() external view returns (int24); 29 | 30 | /// @notice The maximum amount of position liquidity that can use any tick in the range 31 | /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and 32 | /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool 33 | /// @return The max amount of liquidity per tick 34 | function maxLiquidityPerTick() external view returns (uint128); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/Quoter/IUniswapV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Permissioned pool actions 5 | /// @notice Contains pool methods that may only be called by the factory owner 6 | interface IUniswapV3PoolOwnerActions { 7 | /// @notice Set the denominator of the protocol's % share of the fees 8 | /// @param feeProtocol0 new protocol fee for token0 of the pool 9 | /// @param feeProtocol1 new protocol fee for token1 of the pool 10 | function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; 11 | 12 | /// @notice Collect the protocol fee accrued to the pool 13 | /// @param recipient The address to which collected protocol fees should be sent 14 | /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 15 | /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 16 | /// @return amount0 The protocol fee collected in token0 17 | /// @return amount1 The protocol fee collected in token1 18 | function collectProtocol( 19 | address recipient, 20 | uint128 amount0Requested, 21 | uint128 amount1Requested 22 | ) external returns (uint128 amount0, uint128 amount1); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/Quoter/IUniswapV3SwapCallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Callback for IUniswapV3PoolActions#swap 5 | /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface 6 | interface IUniswapV3SwapCallback { 7 | /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. 8 | /// @dev In the implementation you must pay the pool tokens owed for the swap. 9 | /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. 10 | /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. 11 | /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by 12 | /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. 13 | /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by 14 | /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. 15 | /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call 16 | function uniswapV3SwapCallback( 17 | int256 amount0Delta, 18 | int256 amount1Delta, 19 | bytes calldata data 20 | ) external; 21 | } 22 | -------------------------------------------------------------------------------- /contracts/Quoter/Path.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.6.0; 3 | 4 | import './BytesLib.sol'; 5 | 6 | /// @title Functions for manipulating path data for multihop swaps 7 | library Path { 8 | using BytesLib for bytes; 9 | 10 | /// @dev The length of the bytes encoded address 11 | uint256 private constant ADDR_SIZE = 20; 12 | /// @dev The length of the bytes encoded fee 13 | uint256 private constant FEE_SIZE = 3; 14 | 15 | /// @dev The offset of a single token address and pool fee 16 | uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE; 17 | /// @dev The offset of an encoded pool key 18 | uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; 19 | /// @dev The minimum length of an encoding that contains 2 or more pools 20 | uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; 21 | 22 | /// @notice Returns true iff the path contains two or more pools 23 | /// @param path The encoded swap path 24 | /// @return True if path contains two or more pools, otherwise false 25 | function hasMultiplePools(bytes memory path) internal pure returns (bool) { 26 | return path.length >= MULTIPLE_POOLS_MIN_LENGTH; 27 | } 28 | 29 | /// @notice Decodes the first pool in path 30 | /// @param path The bytes encoded swap path 31 | /// @return tokenA The first token of the given pool 32 | /// @return tokenB The second token of the given pool 33 | /// @return fee The fee level of the pool 34 | function decodeFirstPool(bytes memory path) 35 | internal 36 | pure 37 | returns ( 38 | address tokenA, 39 | address tokenB, 40 | uint24 fee 41 | ) 42 | { 43 | tokenA = path.toAddress(0); 44 | fee = path.toUint24(ADDR_SIZE); 45 | tokenB = path.toAddress(NEXT_OFFSET); 46 | } 47 | 48 | /// @notice Gets the segment corresponding to the first pool in the path 49 | /// @param path The bytes encoded swap path 50 | /// @return The segment containing all data necessary to target the first pool in the path 51 | function getFirstPool(bytes memory path) internal pure returns (bytes memory) { 52 | return path.slice(0, POP_OFFSET); 53 | } 54 | 55 | /// @notice Skips a token + fee element from the buffer and returns the remainder 56 | /// @param path The swap path 57 | /// @return The remaining token + fee elements in the path 58 | function skipToken(bytes memory path) internal pure returns (bytes memory) { 59 | return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/Quoter/PeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IPeripheryImmutableState.sol'; 5 | 6 | /// @title Immutable state 7 | /// @notice Immutable state used by periphery contracts 8 | abstract contract PeripheryImmutableState is IPeripheryImmutableState { 9 | /// @inheritdoc IPeripheryImmutableState 10 | address public immutable override factory; 11 | /// @inheritdoc IPeripheryImmutableState 12 | address public immutable override WETH9; 13 | 14 | constructor(address _factory, address _WETH9) { 15 | factory = _factory; 16 | WETH9 = _WETH9; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/Quoter/PoolAddress.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Provides functions for deriving a pool address from the factory, tokens, and the fee 5 | library PoolAddress { 6 | bytes32 internal constant POOL_INIT_CODE_HASH = 0xd70958ebfff5a99884d37fb1ba60083c838125942b9ab042cf8d49a7929bb9d0; 7 | 8 | /// @notice The identifying key of the pool 9 | struct PoolKey { 10 | address token0; 11 | address token1; 12 | uint24 fee; 13 | } 14 | 15 | /// @notice Returns PoolKey: the ordered tokens with the matched fee levels 16 | /// @param tokenA The first token of a pool, unsorted 17 | /// @param tokenB The second token of a pool, unsorted 18 | /// @param fee The fee level of the pool 19 | /// @return Poolkey The pool details with ordered token0 and token1 assignments 20 | function getPoolKey( 21 | address tokenA, 22 | address tokenB, 23 | uint24 fee 24 | ) internal pure returns (PoolKey memory) { 25 | if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); 26 | return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); 27 | } 28 | 29 | /// @notice Deterministically computes the pool address given the factory and PoolKey 30 | /// @param factory The Uniswap V3 factory contract address 31 | /// @param key The PoolKey 32 | /// @return pool The contract address of the V3 pool 33 | function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { 34 | require(key.token0 < key.token1); 35 | pool = address( 36 | uint256( 37 | keccak256( 38 | abi.encodePacked( 39 | hex'ff', 40 | factory, 41 | keccak256(abi.encode(key.token0, key.token1, key.fee)), 42 | POOL_INIT_CODE_HASH 43 | ) 44 | ) 45 | ) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/Quoter/SafeCast.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Safe casting methods 5 | /// @notice Contains methods for safely casting between types 6 | library SafeCast { 7 | /// @notice Cast a uint256 to a uint160, revert on overflow 8 | /// @param y The uint256 to be downcasted 9 | /// @return z The downcasted integer, now type uint160 10 | function toUint160(uint256 y) internal pure returns (uint160 z) { 11 | require((z = uint160(y)) == y); 12 | } 13 | 14 | /// @notice Cast a int256 to a int128, revert on overflow or underflow 15 | /// @param y The int256 to be downcasted 16 | /// @return z The downcasted integer, now type int128 17 | function toInt128(int256 y) internal pure returns (int128 z) { 18 | require((z = int128(y)) == y); 19 | } 20 | 21 | /// @notice Cast a uint256 to a int256, revert on overflow 22 | /// @param y The uint256 to be casted 23 | /// @return z The casted integer, now type int256 24 | function toInt256(uint256 y) internal pure returns (int256 z) { 25 | require(y < 2**255); 26 | z = int256(y); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/SwapRouter/BlockTimestamp.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | /// @title Function for getting block timestamp 5 | /// @dev Base contract that is overridden for tests 6 | abstract contract BlockTimestamp { 7 | /// @dev Method that exists purely to be overridden for tests 8 | /// @return The current block timestamp 9 | function _blockTimestamp() internal view virtual returns (uint256) { 10 | return block.timestamp; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/SwapRouter/CallbackValidation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IUniswapV3Pool.sol'; 5 | import './PoolAddress.sol'; 6 | 7 | /// @notice Provides validation for callbacks from Uniswap V3 Pools 8 | library CallbackValidation { 9 | /// @notice Returns the address of a valid Uniswap V3 Pool 10 | /// @param factory The contract address of the Uniswap V3 factory 11 | /// @param tokenA The contract address of either token0 or token1 12 | /// @param tokenB The contract address of the other token 13 | /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip 14 | /// @return pool The V3 pool contract address 15 | function verifyCallback( 16 | address factory, 17 | address tokenA, 18 | address tokenB, 19 | uint24 fee 20 | ) internal view returns (IUniswapV3Pool pool) { 21 | return verifyCallback(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee)); 22 | } 23 | 24 | /// @notice Returns the address of a valid Uniswap V3 Pool 25 | /// @param factory The contract address of the Uniswap V3 factory 26 | /// @param poolKey The identifying key of the V3 pool 27 | /// @return pool The V3 pool contract address 28 | function verifyCallback(address factory, PoolAddress.PoolKey memory poolKey) 29 | internal 30 | view 31 | returns (IUniswapV3Pool pool) 32 | { 33 | pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); 34 | require(msg.sender == address(pool)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 standard as defined in the EIP. 7 | */ 8 | interface IERC20 { 9 | /** 10 | * @dev Returns the amount of tokens in existence. 11 | */ 12 | function totalSupply() external view returns (uint256); 13 | 14 | /** 15 | * @dev Returns the amount of tokens owned by `account`. 16 | */ 17 | function balanceOf(address account) external view returns (uint256); 18 | 19 | /** 20 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 21 | * 22 | * Returns a boolean value indicating whether the operation succeeded. 23 | * 24 | * Emits a {Transfer} event. 25 | */ 26 | function transfer(address recipient, uint256 amount) external returns (bool); 27 | 28 | /** 29 | * @dev Returns the remaining number of tokens that `spender` will be 30 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 31 | * zero by default. 32 | * 33 | * This value changes when {approve} or {transferFrom} are called. 34 | */ 35 | function allowance(address owner, address spender) external view returns (uint256); 36 | 37 | /** 38 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 39 | * 40 | * Returns a boolean value indicating whether the operation succeeded. 41 | * 42 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 43 | * that someone may use both the old and the new allowance by unfortunate 44 | * transaction ordering. One possible solution to mitigate this race 45 | * condition is to first reduce the spender's allowance to 0 and set the 46 | * desired value afterwards: 47 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 48 | * 49 | * Emits an {Approval} event. 50 | */ 51 | function approve(address spender, uint256 amount) external returns (bool); 52 | 53 | /** 54 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 55 | * allowance mechanism. `amount` is then deducted from the caller's 56 | * allowance. 57 | * 58 | * Returns a boolean value indicating whether the operation succeeded. 59 | * 60 | * Emits a {Transfer} event. 61 | */ 62 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 63 | 64 | /** 65 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 66 | * another (`to`). 67 | * 68 | * Note that `value` may be zero. 69 | */ 70 | event Transfer(address indexed from, address indexed to, uint256 value); 71 | 72 | /** 73 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 74 | * a call to {approve}. `value` is the new allowance. 75 | */ 76 | event Approval(address indexed owner, address indexed spender, uint256 value); 77 | } 78 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IERC20Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in 7 | * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. 8 | * 9 | * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by 10 | * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't 11 | * need to send a transaction, and thus is not required to hold Ether at all. 12 | */ 13 | interface IERC20Permit { 14 | /** 15 | * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens, 16 | * given `owner`'s signed approval. 17 | * 18 | * IMPORTANT: The same issues {IERC20-approve} has related to transaction 19 | * ordering also apply here. 20 | * 21 | * Emits an {Approval} event. 22 | * 23 | * Requirements: 24 | * 25 | * - `spender` cannot be the zero address. 26 | * - `deadline` must be a timestamp in the future. 27 | * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` 28 | * over the EIP712-formatted function arguments. 29 | * - the signature must use ``owner``'s current nonce (see {nonces}). 30 | * 31 | * For more information on the signature format, see the 32 | * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP 33 | * section]. 34 | */ 35 | function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; 36 | 37 | /** 38 | * @dev Returns the current nonce for `owner`. This value must be 39 | * included whenever a signature is generated for {permit}. 40 | * 41 | * Every successful call to {permit} increases ``owner``'s nonce by one. This 42 | * prevents a signature from being used multiple times. 43 | */ 44 | function nonces(address owner) external view returns (uint256); 45 | 46 | /** 47 | * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}. 48 | */ 49 | // solhint-disable-next-line func-name-mixedcase 50 | function DOMAIN_SEPARATOR() external view returns (bytes32); 51 | } 52 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IERC20PermitAllowed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Interface for permit 5 | /// @notice Interface used by DAI/CHAI for permit 6 | interface IERC20PermitAllowed { 7 | /// @notice Approve the spender to spend some tokens via the holder signature 8 | /// @dev This is the permit interface used by DAI and CHAI 9 | /// @param holder The address of the token holder, the token owner 10 | /// @param spender The address of the token spender 11 | /// @param nonce The holder's nonce, increases at each call to permit 12 | /// @param expiry The timestamp at which the permit is no longer valid 13 | /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0 14 | /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` 15 | /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` 16 | /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` 17 | function permit( 18 | address holder, 19 | address spender, 20 | uint256 nonce, 21 | uint256 expiry, 22 | bool allowed, 23 | uint8 v, 24 | bytes32 r, 25 | bytes32 s 26 | ) external; 27 | } 28 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IMulticall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Multicall interface 6 | /// @notice Enables calling multiple methods in a single call to the contract 7 | interface IMulticall { 8 | /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed 9 | /// @dev The `msg.value` should not be trusted for any method callable from multicall. 10 | /// @param data The encoded function data for each of the calls to make to this contract 11 | /// @return results The results from each of the calls passed in via data 12 | function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IPeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Immutable state 5 | /// @notice Functions that return immutable state of the router 6 | interface IPeripheryImmutableState { 7 | /// @return Returns the address of the Uniswap V3 factory 8 | function factory() external view returns (address); 9 | 10 | /// @return Returns the address of WETH9 11 | function WETH9() external view returns (address); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IPeripheryPayments.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | /// @title Periphery Payments 5 | /// @notice Functions to ease deposits and withdrawals of ETH 6 | interface IPeripheryPayments { 7 | /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. 8 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. 9 | /// @param amountMinimum The minimum amount of WETH9 to unwrap 10 | /// @param recipient The address receiving ETH 11 | function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; 12 | 13 | /// @notice Refunds any ETH balance held by this contract to the `msg.sender` 14 | /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps 15 | /// that use ether for the input amount 16 | function refundETH() external payable; 17 | 18 | /// @notice Transfers the full amount of a token held by this contract to recipient 19 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users 20 | /// @param token The contract address of the token which will be transferred to `recipient` 21 | /// @param amountMinimum The minimum amount of token required for a transfer 22 | /// @param recipient The destination address of the token 23 | function sweepToken( 24 | address token, 25 | uint256 amountMinimum, 26 | address recipient 27 | ) external payable; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IPeripheryPaymentsWithFee.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | import './IPeripheryPayments.sol'; 5 | 6 | /// @title Periphery Payments 7 | /// @notice Functions to ease deposits and withdrawals of ETH 8 | interface IPeripheryPaymentsWithFee is IPeripheryPayments { 9 | /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH, with a percentage between 10 | /// 0 (exclusive), and 1 (inclusive) going to feeRecipient 11 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. 12 | function unwrapWETH9WithFee( 13 | uint256 amountMinimum, 14 | address recipient, 15 | uint256 feeBips, 16 | address feeRecipient 17 | ) external payable; 18 | 19 | /// @notice Transfers the full amount of a token held by this contract to recipient, with a percentage between 20 | /// 0 (exclusive) and 1 (inclusive) going to feeRecipient 21 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users 22 | function sweepTokenWithFee( 23 | address token, 24 | uint256 amountMinimum, 25 | address recipient, 26 | uint256 feeBips, 27 | address feeRecipient 28 | ) external payable; 29 | } 30 | -------------------------------------------------------------------------------- /contracts/SwapRouter/ISwapRouter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | import './IUniswapV3SwapCallback.sol'; 6 | 7 | /// @title Router token swapping functionality 8 | /// @notice Functions for swapping tokens via Uniswap V3 9 | interface ISwapRouter is IUniswapV3SwapCallback { 10 | struct ExactInputSingleParams { 11 | address tokenIn; 12 | address tokenOut; 13 | uint24 fee; 14 | address recipient; 15 | uint256 deadline; 16 | uint256 amountIn; 17 | uint256 amountOutMinimum; 18 | uint160 sqrtPriceLimitX96; 19 | } 20 | 21 | /// @notice Swaps `amountIn` of one token for as much as possible of another token 22 | /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata 23 | /// @return amountOut The amount of the received token 24 | function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); 25 | 26 | struct ExactInputParams { 27 | bytes path; 28 | address recipient; 29 | uint256 deadline; 30 | uint256 amountIn; 31 | uint256 amountOutMinimum; 32 | } 33 | 34 | /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path 35 | /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata 36 | /// @return amountOut The amount of the received token 37 | function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); 38 | 39 | struct ExactOutputSingleParams { 40 | address tokenIn; 41 | address tokenOut; 42 | uint24 fee; 43 | address recipient; 44 | uint256 deadline; 45 | uint256 amountOut; 46 | uint256 amountInMaximum; 47 | uint160 sqrtPriceLimitX96; 48 | } 49 | 50 | /// @notice Swaps as little as possible of one token for `amountOut` of another token 51 | /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata 52 | /// @return amountIn The amount of the input token 53 | function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); 54 | 55 | struct ExactOutputParams { 56 | bytes path; 57 | address recipient; 58 | uint256 deadline; 59 | uint256 amountOut; 60 | uint256 amountInMaximum; 61 | } 62 | 63 | /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) 64 | /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata 65 | /// @return amountIn The amount of the input token 66 | function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); 67 | } 68 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IUniswapV3PoolImmutables.sol'; 5 | import './IUniswapV3PoolState.sol'; 6 | import './IUniswapV3PoolDerivedState.sol'; 7 | import './IUniswapV3PoolActions.sol'; 8 | import './IUniswapV3PoolOwnerActions.sol'; 9 | import './IUniswapV3PoolEvents.sol'; 10 | 11 | /// @title The interface for a Uniswap V3 Pool 12 | /// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform 13 | /// to the ERC20 specification 14 | /// @dev The pool interface is broken up into many smaller pieces 15 | interface IUniswapV3Pool is 16 | IUniswapV3PoolImmutables, 17 | IUniswapV3PoolState, 18 | IUniswapV3PoolDerivedState, 19 | IUniswapV3PoolActions, 20 | IUniswapV3PoolOwnerActions, 21 | IUniswapV3PoolEvents 22 | { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IUniswapV3PoolDerivedState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that is not stored 5 | /// @notice Contains view functions to provide information about the pool that is computed rather than stored on the 6 | /// blockchain. The functions here may have variable gas costs. 7 | interface IUniswapV3PoolDerivedState { 8 | /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp 9 | /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing 10 | /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, 11 | /// you must call it with secondsAgos = [3600, 0]. 12 | /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in 13 | /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. 14 | /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned 15 | /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp 16 | /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block 17 | /// timestamp 18 | function observe(uint32[] calldata secondsAgos) 19 | external 20 | view 21 | returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); 22 | 23 | /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range 24 | /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. 25 | /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first 26 | /// snapshot is taken and the second snapshot is taken. 27 | /// @param tickLower The lower tick of the range 28 | /// @param tickUpper The upper tick of the range 29 | /// @return tickCumulativeInside The snapshot of the tick accumulator for the range 30 | /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range 31 | /// @return secondsInside The snapshot of seconds per liquidity for the range 32 | function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) 33 | external 34 | view 35 | returns ( 36 | int56 tickCumulativeInside, 37 | uint160 secondsPerLiquidityInsideX128, 38 | uint32 secondsInside 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IUniswapV3PoolImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that never changes 5 | /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values 6 | interface IUniswapV3PoolImmutables { 7 | /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface 8 | /// @return The contract address 9 | function factory() external view returns (address); 10 | 11 | /// @notice The first of the two tokens of the pool, sorted by address 12 | /// @return The token contract address 13 | function token0() external view returns (address); 14 | 15 | /// @notice The second of the two tokens of the pool, sorted by address 16 | /// @return The token contract address 17 | function token1() external view returns (address); 18 | 19 | /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 20 | /// @return The fee 21 | function fee() external view returns (uint24); 22 | 23 | /// @notice The pool tick spacing 24 | /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive 25 | /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... 26 | /// This value is an int24 to avoid casting even though it is always positive. 27 | /// @return The tick spacing 28 | function tickSpacing() external view returns (int24); 29 | 30 | /// @notice The maximum amount of position liquidity that can use any tick in the range 31 | /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and 32 | /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool 33 | /// @return The max amount of liquidity per tick 34 | function maxLiquidityPerTick() external view returns (uint128); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IUniswapV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Permissioned pool actions 5 | /// @notice Contains pool methods that may only be called by the factory owner 6 | interface IUniswapV3PoolOwnerActions { 7 | /// @notice Set the denominator of the protocol's % share of the fees 8 | /// @param feeProtocol0 new protocol fee for token0 of the pool 9 | /// @param feeProtocol1 new protocol fee for token1 of the pool 10 | function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; 11 | 12 | /// @notice Collect the protocol fee accrued to the pool 13 | /// @param recipient The address to which collected protocol fees should be sent 14 | /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 15 | /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 16 | /// @return amount0 The protocol fee collected in token0 17 | /// @return amount1 The protocol fee collected in token1 18 | function collectProtocol( 19 | address recipient, 20 | uint128 amount0Requested, 21 | uint128 amount1Requested 22 | ) external returns (uint128 amount0, uint128 amount1); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IUniswapV3SwapCallback.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Callback for IUniswapV3PoolActions#swap 5 | /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface 6 | interface IUniswapV3SwapCallback { 7 | /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. 8 | /// @dev In the implementation you must pay the pool tokens owed for the swap. 9 | /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. 10 | /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. 11 | /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by 12 | /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. 13 | /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by 14 | /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. 15 | /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call 16 | function uniswapV3SwapCallback( 17 | int256 amount0Delta, 18 | int256 amount1Delta, 19 | bytes calldata data 20 | ) external; 21 | } 22 | -------------------------------------------------------------------------------- /contracts/SwapRouter/IWETH9.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IERC20.sol'; 5 | 6 | /// @title Interface for WETH9 7 | interface IWETH9 is IERC20 { 8 | /// @notice Deposit ether to get wrapped ether 9 | function deposit() external payable; 10 | 11 | /// @notice Withdraw wrapped ether to get ether 12 | function withdraw(uint256) external; 13 | } 14 | -------------------------------------------------------------------------------- /contracts/SwapRouter/LowGasSafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.0; 3 | 4 | /// @title Optimized overflow and underflow safe math operations 5 | /// @notice Contains methods for doing math operations that revert on overflow or underflow for minimal gas cost 6 | library LowGasSafeMath { 7 | /// @notice Returns x + y, reverts if sum overflows uint256 8 | /// @param x The augend 9 | /// @param y The addend 10 | /// @return z The sum of x and y 11 | function add(uint256 x, uint256 y) internal pure returns (uint256 z) { 12 | require((z = x + y) >= x); 13 | } 14 | 15 | /// @notice Returns x - y, reverts if underflows 16 | /// @param x The minuend 17 | /// @param y The subtrahend 18 | /// @return z The difference of x and y 19 | function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { 20 | require((z = x - y) <= x); 21 | } 22 | 23 | /// @notice Returns x * y, reverts if overflows 24 | /// @param x The multiplicand 25 | /// @param y The multiplier 26 | /// @return z The product of x and y 27 | function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { 28 | require(x == 0 || (z = x * y) / x == y); 29 | } 30 | 31 | /// @notice Returns x + y, reverts if overflows or underflows 32 | /// @param x The augend 33 | /// @param y The addend 34 | /// @return z The sum of x and y 35 | function add(int256 x, int256 y) internal pure returns (int256 z) { 36 | require((z = x + y) >= x == (y >= 0)); 37 | } 38 | 39 | /// @notice Returns x - y, reverts if overflows or underflows 40 | /// @param x The minuend 41 | /// @param y The subtrahend 42 | /// @return z The difference of x and y 43 | function sub(int256 x, int256 y) internal pure returns (int256 z) { 44 | require((z = x - y) <= x == (y >= 0)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/SwapRouter/Multicall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | pragma abicoder v2; 4 | 5 | import './IMulticall.sol'; 6 | 7 | /// @title Multicall 8 | /// @notice Enables calling multiple methods in a single call to the contract 9 | abstract contract Multicall is IMulticall { 10 | /// @inheritdoc IMulticall 11 | function multicall(bytes[] calldata data) external payable override returns (bytes[] memory results) { 12 | results = new bytes[](data.length); 13 | for (uint256 i = 0; i < data.length; i++) { 14 | (bool success, bytes memory result) = address(this).delegatecall(data[i]); 15 | 16 | if (!success) { 17 | // Next 5 lines from https://ethereum.stackexchange.com/a/83577 18 | if (result.length < 68) revert(); 19 | assembly { 20 | result := add(result, 0x04) 21 | } 22 | revert(abi.decode(result, (string))); 23 | } 24 | 25 | results[i] = result; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/SwapRouter/Path.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.6.0; 3 | 4 | import './BytesLib.sol'; 5 | 6 | /// @title Functions for manipulating path data for multihop swaps 7 | library Path { 8 | using BytesLib for bytes; 9 | 10 | /// @dev The length of the bytes encoded address 11 | uint256 private constant ADDR_SIZE = 20; 12 | /// @dev The length of the bytes encoded fee 13 | uint256 private constant FEE_SIZE = 3; 14 | 15 | /// @dev The offset of a single token address and pool fee 16 | uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE; 17 | /// @dev The offset of an encoded pool key 18 | uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; 19 | /// @dev The minimum length of an encoding that contains 2 or more pools 20 | uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; 21 | 22 | /// @notice Returns true iff the path contains two or more pools 23 | /// @param path The encoded swap path 24 | /// @return True if path contains two or more pools, otherwise false 25 | function hasMultiplePools(bytes memory path) internal pure returns (bool) { 26 | return path.length >= MULTIPLE_POOLS_MIN_LENGTH; 27 | } 28 | 29 | /// @notice Decodes the first pool in path 30 | /// @param path The bytes encoded swap path 31 | /// @return tokenA The first token of the given pool 32 | /// @return tokenB The second token of the given pool 33 | /// @return fee The fee level of the pool 34 | function decodeFirstPool(bytes memory path) 35 | internal 36 | pure 37 | returns ( 38 | address tokenA, 39 | address tokenB, 40 | uint24 fee 41 | ) 42 | { 43 | tokenA = path.toAddress(0); 44 | fee = path.toUint24(ADDR_SIZE); 45 | tokenB = path.toAddress(NEXT_OFFSET); 46 | } 47 | 48 | /// @notice Gets the segment corresponding to the first pool in the path 49 | /// @param path The bytes encoded swap path 50 | /// @return The segment containing all data necessary to target the first pool in the path 51 | function getFirstPool(bytes memory path) internal pure returns (bytes memory) { 52 | return path.slice(0, POP_OFFSET); 53 | } 54 | 55 | /// @notice Skips a token + fee element from the buffer and returns the remainder 56 | /// @param path The swap path 57 | /// @return The remaining token + fee elements in the path 58 | function skipToken(bytes memory path) internal pure returns (bytes memory) { 59 | return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/SwapRouter/PeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IPeripheryImmutableState.sol'; 5 | 6 | /// @title Immutable state 7 | /// @notice Immutable state used by periphery contracts 8 | abstract contract PeripheryImmutableState is IPeripheryImmutableState { 9 | /// @inheritdoc IPeripheryImmutableState 10 | address public immutable override factory; 11 | /// @inheritdoc IPeripheryImmutableState 12 | address public immutable override WETH9; 13 | 14 | constructor(address _factory, address _WETH9) { 15 | factory = _factory; 16 | WETH9 = _WETH9; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/SwapRouter/PeripheryPayments.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | import './IERC20.sol'; 5 | 6 | import './IPeripheryPayments.sol'; 7 | import './IWETH9.sol'; 8 | 9 | import './TransferHelper.sol'; 10 | 11 | import './PeripheryImmutableState.sol'; 12 | 13 | abstract contract PeripheryPayments is IPeripheryPayments, PeripheryImmutableState { 14 | receive() external payable { 15 | require(msg.sender == WETH9, 'Not WETH9'); 16 | } 17 | 18 | /// @inheritdoc IPeripheryPayments 19 | function unwrapWETH9(uint256 amountMinimum, address recipient) external payable override { 20 | uint256 balanceWETH9 = IWETH9(WETH9).balanceOf(address(this)); 21 | require(balanceWETH9 >= amountMinimum, 'Insufficient WETH9'); 22 | 23 | if (balanceWETH9 > 0) { 24 | IWETH9(WETH9).withdraw(balanceWETH9); 25 | TransferHelper.safeTransferETH(recipient, balanceWETH9); 26 | } 27 | } 28 | 29 | /// @inheritdoc IPeripheryPayments 30 | function sweepToken( 31 | address token, 32 | uint256 amountMinimum, 33 | address recipient 34 | ) external payable override { 35 | uint256 balanceToken = IERC20(token).balanceOf(address(this)); 36 | require(balanceToken >= amountMinimum, 'Insufficient token'); 37 | 38 | if (balanceToken > 0) { 39 | TransferHelper.safeTransfer(token, recipient, balanceToken); 40 | } 41 | } 42 | 43 | /// @inheritdoc IPeripheryPayments 44 | function refundETH() external payable override { 45 | if (address(this).balance > 0) TransferHelper.safeTransferETH(msg.sender, address(this).balance); 46 | } 47 | 48 | /// @param token The token to pay 49 | /// @param payer The entity that must pay 50 | /// @param recipient The entity that will receive payment 51 | /// @param value The amount to pay 52 | function pay( 53 | address token, 54 | address payer, 55 | address recipient, 56 | uint256 value 57 | ) internal { 58 | if (token == WETH9 && address(this).balance >= value) { 59 | // pay with WETH9 60 | IWETH9(WETH9).deposit{value: value}(); // wrap only what is needed to pay 61 | IWETH9(WETH9).transfer(recipient, value); 62 | } else if (payer == address(this)) { 63 | // pay with tokens already in the contract (for the exact input multihop case) 64 | TransferHelper.safeTransfer(token, recipient, value); 65 | } else { 66 | // pull payment 67 | TransferHelper.safeTransferFrom(token, payer, recipient, value); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /contracts/SwapRouter/PeripheryPaymentsWithFee.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | import './IERC20.sol'; 5 | import './LowGasSafeMath.sol'; 6 | 7 | import './PeripheryPayments.sol'; 8 | import './IPeripheryPaymentsWithFee.sol'; 9 | 10 | import './IWETH9.sol'; 11 | import './TransferHelper.sol'; 12 | 13 | abstract contract PeripheryPaymentsWithFee is PeripheryPayments, IPeripheryPaymentsWithFee { 14 | using LowGasSafeMath for uint256; 15 | 16 | /// @inheritdoc IPeripheryPaymentsWithFee 17 | function unwrapWETH9WithFee( 18 | uint256 amountMinimum, 19 | address recipient, 20 | uint256 feeBips, 21 | address feeRecipient 22 | ) public payable override { 23 | require(feeBips > 0 && feeBips <= 100); 24 | 25 | uint256 balanceWETH9 = IWETH9(WETH9).balanceOf(address(this)); 26 | require(balanceWETH9 >= amountMinimum, 'Insufficient WETH9'); 27 | 28 | if (balanceWETH9 > 0) { 29 | IWETH9(WETH9).withdraw(balanceWETH9); 30 | uint256 feeAmount = balanceWETH9.mul(feeBips) / 10_000; 31 | if (feeAmount > 0) TransferHelper.safeTransferETH(feeRecipient, feeAmount); 32 | TransferHelper.safeTransferETH(recipient, balanceWETH9 - feeAmount); 33 | } 34 | } 35 | 36 | /// @inheritdoc IPeripheryPaymentsWithFee 37 | function sweepTokenWithFee( 38 | address token, 39 | uint256 amountMinimum, 40 | address recipient, 41 | uint256 feeBips, 42 | address feeRecipient 43 | ) public payable override { 44 | require(feeBips > 0 && feeBips <= 100); 45 | 46 | uint256 balanceToken = IERC20(token).balanceOf(address(this)); 47 | require(balanceToken >= amountMinimum, 'Insufficient token'); 48 | 49 | if (balanceToken > 0) { 50 | uint256 feeAmount = balanceToken.mul(feeBips) / 10_000; 51 | if (feeAmount > 0) TransferHelper.safeTransfer(token, feeRecipient, feeAmount); 52 | TransferHelper.safeTransfer(token, recipient, balanceToken - feeAmount); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /contracts/SwapRouter/PeripheryValidation.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './BlockTimestamp.sol'; 5 | 6 | abstract contract PeripheryValidation is BlockTimestamp { 7 | modifier checkDeadline(uint256 deadline) { 8 | require(_blockTimestamp() <= deadline, 'Transaction too old'); 9 | _; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/SwapRouter/PoolAddress.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Provides functions for deriving a pool address from the factory, tokens, and the fee 5 | library PoolAddress { 6 | bytes32 internal constant POOL_INIT_CODE_HASH = 0xd70958ebfff5a99884d37fb1ba60083c838125942b9ab042cf8d49a7929bb9d0; 7 | 8 | /// @notice The identifying key of the pool 9 | struct PoolKey { 10 | address token0; 11 | address token1; 12 | uint24 fee; 13 | } 14 | 15 | /// @notice Returns PoolKey: the ordered tokens with the matched fee levels 16 | /// @param tokenA The first token of a pool, unsorted 17 | /// @param tokenB The second token of a pool, unsorted 18 | /// @param fee The fee level of the pool 19 | /// @return Poolkey The pool details with ordered token0 and token1 assignments 20 | function getPoolKey( 21 | address tokenA, 22 | address tokenB, 23 | uint24 fee 24 | ) internal pure returns (PoolKey memory) { 25 | if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); 26 | return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); 27 | } 28 | 29 | /// @notice Deterministically computes the pool address given the factory and PoolKey 30 | /// @param factory The Uniswap V3 factory contract address 31 | /// @param key The PoolKey 32 | /// @return pool The contract address of the V3 pool 33 | function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { 34 | require(key.token0 < key.token1); 35 | pool = address( 36 | uint256( 37 | keccak256( 38 | abi.encodePacked( 39 | hex'ff', 40 | factory, 41 | keccak256(abi.encode(key.token0, key.token1, key.fee)), 42 | POOL_INIT_CODE_HASH 43 | ) 44 | ) 45 | ) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/SwapRouter/SafeCast.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Safe casting methods 5 | /// @notice Contains methods for safely casting between types 6 | library SafeCast { 7 | /// @notice Cast a uint256 to a uint160, revert on overflow 8 | /// @param y The uint256 to be downcasted 9 | /// @return z The downcasted integer, now type uint160 10 | function toUint160(uint256 y) internal pure returns (uint160 z) { 11 | require((z = uint160(y)) == y); 12 | } 13 | 14 | /// @notice Cast a int256 to a int128, revert on overflow or underflow 15 | /// @param y The int256 to be downcasted 16 | /// @return z The downcasted integer, now type int128 17 | function toInt128(int256 y) internal pure returns (int128 z) { 18 | require((z = int128(y)) == y); 19 | } 20 | 21 | /// @notice Cast a uint256 to a int256, revert on overflow 22 | /// @param y The uint256 to be casted 23 | /// @return z The casted integer, now type int256 24 | function toInt256(uint256 y) internal pure returns (int256 z) { 25 | require(y < 2**255); 26 | z = int256(y); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/SwapRouter/SelfPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IERC20.sol'; 5 | import './IERC20Permit.sol'; 6 | 7 | import './ISelfPermit.sol'; 8 | import './IERC20PermitAllowed.sol'; 9 | 10 | /// @title Self Permit 11 | /// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route 12 | /// @dev These functions are expected to be embedded in multicalls to allow EOAs to approve a contract and call a function 13 | /// that requires an approval in a single transaction. 14 | abstract contract SelfPermit is ISelfPermit { 15 | /// @inheritdoc ISelfPermit 16 | function selfPermit( 17 | address token, 18 | uint256 value, 19 | uint256 deadline, 20 | uint8 v, 21 | bytes32 r, 22 | bytes32 s 23 | ) public payable override { 24 | IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s); 25 | } 26 | 27 | /// @inheritdoc ISelfPermit 28 | function selfPermitIfNecessary( 29 | address token, 30 | uint256 value, 31 | uint256 deadline, 32 | uint8 v, 33 | bytes32 r, 34 | bytes32 s 35 | ) external payable override { 36 | if (IERC20(token).allowance(msg.sender, address(this)) < value) selfPermit(token, value, deadline, v, r, s); 37 | } 38 | 39 | /// @inheritdoc ISelfPermit 40 | function selfPermitAllowed( 41 | address token, 42 | uint256 nonce, 43 | uint256 expiry, 44 | uint8 v, 45 | bytes32 r, 46 | bytes32 s 47 | ) public payable override { 48 | IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s); 49 | } 50 | 51 | /// @inheritdoc ISelfPermit 52 | function selfPermitAllowedIfNecessary( 53 | address token, 54 | uint256 nonce, 55 | uint256 expiry, 56 | uint8 v, 57 | bytes32 r, 58 | bytes32 s 59 | ) external payable override { 60 | if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) 61 | selfPermitAllowed(token, nonce, expiry, v, r, s); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/SwapRouter/TransferHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.6.0; 3 | 4 | import './IERC20.sol'; 5 | 6 | library TransferHelper { 7 | /// @notice Transfers tokens from the targeted address to the given destination 8 | /// @notice Errors with 'STF' if transfer fails 9 | /// @param token The contract address of the token to be transferred 10 | /// @param from The originating address from which the tokens will be transferred 11 | /// @param to The destination address of the transfer 12 | /// @param value The amount to be transferred 13 | function safeTransferFrom( 14 | address token, 15 | address from, 16 | address to, 17 | uint256 value 18 | ) internal { 19 | (bool success, bytes memory data) = 20 | token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); 21 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); 22 | } 23 | 24 | /// @notice Transfers tokens from msg.sender to a recipient 25 | /// @dev Errors with ST if transfer fails 26 | /// @param token The contract address of the token which will be transferred 27 | /// @param to The recipient of the transfer 28 | /// @param value The value of the transfer 29 | function safeTransfer( 30 | address token, 31 | address to, 32 | uint256 value 33 | ) internal { 34 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); 35 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); 36 | } 37 | 38 | /// @notice Approves the stipulated contract to spend the given allowance in the given token 39 | /// @dev Errors with 'SA' if transfer fails 40 | /// @param token The contract address of the token to be approved 41 | /// @param to The target of the approval 42 | /// @param value The amount of the given token the target will be allowed to spend 43 | function safeApprove( 44 | address token, 45 | address to, 46 | uint256 value 47 | ) internal { 48 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); 49 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); 50 | } 51 | 52 | /// @notice Transfers ETH to the recipient address 53 | /// @dev Fails with `STE` 54 | /// @param to The destination of the transfer 55 | /// @param value The value to be transferred 56 | function safeTransferETH(address to, uint256 value) internal { 57 | (bool success, ) = to.call{value: value}(new bytes(0)); 58 | require(success, 'STE'); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /contracts/TickLens/ITickLens.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Tick Lens 6 | /// @notice Provides functions for fetching chunks of tick data for a pool 7 | /// @dev This avoids the waterfall of fetching the tick bitmap, parsing the bitmap to know which ticks to fetch, and 8 | /// then sending additional multicalls to fetch the tick data 9 | interface ITickLens { 10 | struct PopulatedTick { 11 | int24 tick; 12 | int128 liquidityNet; 13 | uint128 liquidityGross; 14 | } 15 | 16 | /// @notice Get all the tick data for the populated ticks from a word of the tick bitmap of a pool 17 | /// @param pool The address of the pool for which to fetch populated tick data 18 | /// @param tickBitmapIndex The index of the word in the tick bitmap for which to parse the bitmap and 19 | /// fetch all the populated ticks 20 | /// @return populatedTicks An array of tick data for the given word in the tick bitmap 21 | function getPopulatedTicksInWord(address pool, int16 tickBitmapIndex) 22 | external 23 | view 24 | returns (PopulatedTick[] memory populatedTicks); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/TickLens/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IUniswapV3PoolImmutables.sol'; 5 | import './IUniswapV3PoolState.sol'; 6 | import './IUniswapV3PoolDerivedState.sol'; 7 | import './IUniswapV3PoolActions.sol'; 8 | import './IUniswapV3PoolOwnerActions.sol'; 9 | import './IUniswapV3PoolEvents.sol'; 10 | 11 | /// @title The interface for a Uniswap V3 Pool 12 | /// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform 13 | /// to the ERC20 specification 14 | /// @dev The pool interface is broken up into many smaller pieces 15 | interface IUniswapV3Pool is 16 | IUniswapV3PoolImmutables, 17 | IUniswapV3PoolState, 18 | IUniswapV3PoolDerivedState, 19 | IUniswapV3PoolActions, 20 | IUniswapV3PoolOwnerActions, 21 | IUniswapV3PoolEvents 22 | { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /contracts/TickLens/IUniswapV3PoolDerivedState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that is not stored 5 | /// @notice Contains view functions to provide information about the pool that is computed rather than stored on the 6 | /// blockchain. The functions here may have variable gas costs. 7 | interface IUniswapV3PoolDerivedState { 8 | /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp 9 | /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing 10 | /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, 11 | /// you must call it with secondsAgos = [3600, 0]. 12 | /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in 13 | /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. 14 | /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned 15 | /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp 16 | /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block 17 | /// timestamp 18 | function observe(uint32[] calldata secondsAgos) 19 | external 20 | view 21 | returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); 22 | 23 | /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range 24 | /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. 25 | /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first 26 | /// snapshot is taken and the second snapshot is taken. 27 | /// @param tickLower The lower tick of the range 28 | /// @param tickUpper The upper tick of the range 29 | /// @return tickCumulativeInside The snapshot of the tick accumulator for the range 30 | /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range 31 | /// @return secondsInside The snapshot of seconds per liquidity for the range 32 | function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) 33 | external 34 | view 35 | returns ( 36 | int56 tickCumulativeInside, 37 | uint160 secondsPerLiquidityInsideX128, 38 | uint32 secondsInside 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/TickLens/IUniswapV3PoolImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that never changes 5 | /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values 6 | interface IUniswapV3PoolImmutables { 7 | /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface 8 | /// @return The contract address 9 | function factory() external view returns (address); 10 | 11 | /// @notice The first of the two tokens of the pool, sorted by address 12 | /// @return The token contract address 13 | function token0() external view returns (address); 14 | 15 | /// @notice The second of the two tokens of the pool, sorted by address 16 | /// @return The token contract address 17 | function token1() external view returns (address); 18 | 19 | /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 20 | /// @return The fee 21 | function fee() external view returns (uint24); 22 | 23 | /// @notice The pool tick spacing 24 | /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive 25 | /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... 26 | /// This value is an int24 to avoid casting even though it is always positive. 27 | /// @return The tick spacing 28 | function tickSpacing() external view returns (int24); 29 | 30 | /// @notice The maximum amount of position liquidity that can use any tick in the range 31 | /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and 32 | /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool 33 | /// @return The max amount of liquidity per tick 34 | function maxLiquidityPerTick() external view returns (uint128); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/TickLens/IUniswapV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Permissioned pool actions 5 | /// @notice Contains pool methods that may only be called by the factory owner 6 | interface IUniswapV3PoolOwnerActions { 7 | /// @notice Set the denominator of the protocol's % share of the fees 8 | /// @param feeProtocol0 new protocol fee for token0 of the pool 9 | /// @param feeProtocol1 new protocol fee for token1 of the pool 10 | function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; 11 | 12 | /// @notice Collect the protocol fee accrued to the pool 13 | /// @param recipient The address to which collected protocol fees should be sent 14 | /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 15 | /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 16 | /// @return amount0 The protocol fee collected in token0 17 | /// @return amount1 The protocol fee collected in token1 18 | function collectProtocol( 19 | address recipient, 20 | uint128 amount0Requested, 21 | uint128 amount1Requested 22 | ) external returns (uint128 amount0, uint128 amount1); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/TickLens/TickLens.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | pragma abicoder v2; 4 | 5 | import './IUniswapV3Pool.sol'; 6 | import './ITickLens.sol'; 7 | 8 | /// @title Tick Lens contract 9 | contract TickLens is ITickLens { 10 | /// @inheritdoc ITickLens 11 | function getPopulatedTicksInWord(address pool, int16 tickBitmapIndex) 12 | public 13 | view 14 | override 15 | returns (PopulatedTick[] memory populatedTicks) 16 | { 17 | // fetch bitmap 18 | uint256 bitmap = IUniswapV3Pool(pool).tickBitmap(tickBitmapIndex); 19 | 20 | // calculate the number of populated ticks 21 | uint256 numberOfPopulatedTicks; 22 | for (uint256 i = 0; i < 256; i++) { 23 | if (bitmap & (1 << i) > 0) numberOfPopulatedTicks++; 24 | } 25 | 26 | // fetch populated tick data 27 | int24 tickSpacing = IUniswapV3Pool(pool).tickSpacing(); 28 | populatedTicks = new PopulatedTick[](numberOfPopulatedTicks); 29 | for (uint256 i = 0; i < 256; i++) { 30 | if (bitmap & (1 << i) > 0) { 31 | int24 populatedTick = ((int24(tickBitmapIndex) << 8) + int24(i)) * tickSpacing; 32 | (uint128 liquidityGross, int128 liquidityNet, , , , , , ) = IUniswapV3Pool(pool).ticks(populatedTick); 33 | populatedTicks[--numberOfPopulatedTicks] = PopulatedTick({ 34 | tick: populatedTick, 35 | liquidityNet: liquidityNet, 36 | liquidityGross: liquidityGross 37 | }); 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /contracts/TransparentUpgradeableProxy/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with GSN meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address payable) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes memory) { 21 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 22 | return msg.data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/TransparentUpgradeableProxy/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./Context.sol"; 6 | 7 | /** 8 | * @dev Contract module which provides a basic access control mechanism, where 9 | * there is an account (an owner) that can be granted exclusive access to 10 | * specific functions. 11 | * 12 | * By default, the owner account will be the one that deploys the contract. This 13 | * can later be changed with {transferOwnership}. 14 | * 15 | * This module is used through inheritance. It will make available the modifier 16 | * `onlyOwner`, which can be applied to your functions to restrict their use to 17 | * the owner. 18 | */ 19 | abstract contract Ownable is Context { 20 | address private _owner; 21 | 22 | event OwnershipTransferred( 23 | address indexed previousOwner, 24 | address indexed newOwner 25 | ); 26 | 27 | /** 28 | * @dev Initializes the contract setting the deployer as the initial owner. 29 | */ 30 | constructor() { 31 | address msgSender = _msgSender(); 32 | _owner = msgSender; 33 | emit OwnershipTransferred(address(0), msgSender); 34 | } 35 | 36 | /** 37 | * @dev Returns the address of the current owner. 38 | */ 39 | function owner() public view virtual returns (address) { 40 | return _owner; 41 | } 42 | 43 | /** 44 | * @dev Throws if called by any account other than the owner. 45 | */ 46 | modifier onlyOwner() { 47 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 48 | _; 49 | } 50 | 51 | /** 52 | * @dev Leaves the contract without owner. It will not be possible to call 53 | * `onlyOwner` functions anymore. Can only be called by the current owner. 54 | * 55 | * NOTE: Renouncing ownership will leave the contract without an owner, 56 | * thereby removing any functionality that is only available to the owner. 57 | */ 58 | function renounceOwnership() public virtual onlyOwner { 59 | emit OwnershipTransferred(_owner, address(0)); 60 | _owner = address(0); 61 | } 62 | 63 | /** 64 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 65 | * Can only be called by the current owner. 66 | */ 67 | function transferOwnership(address newOwner) public virtual onlyOwner { 68 | require( 69 | newOwner != address(0), 70 | "Ownable: new owner is the zero address" 71 | ); 72 | emit OwnershipTransferred(_owner, newOwner); 73 | _owner = newOwner; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev Interface of the ERC165 standard, as defined in the 7 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 8 | * 9 | * Implementers can declare support of contract interfaces, which can then be 10 | * queried by others ({ERC165Checker}). 11 | * 12 | * For an implementation, see {ERC165}. 13 | */ 14 | interface IERC165 { 15 | /** 16 | * @dev Returns true if this contract implements the interface defined by 17 | * `interfaceId`. See the corresponding 18 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 19 | * to learn more about how these ids are created. 20 | * 21 | * This function call must use less than 30 000 gas. 22 | */ 23 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 24 | } 25 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 standard as defined in the EIP. 7 | */ 8 | interface IERC20 { 9 | /** 10 | * @dev Returns the amount of tokens in existence. 11 | */ 12 | function totalSupply() external view returns (uint256); 13 | 14 | /** 15 | * @dev Returns the amount of tokens owned by `account`. 16 | */ 17 | function balanceOf(address account) external view returns (uint256); 18 | 19 | /** 20 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 21 | * 22 | * Returns a boolean value indicating whether the operation succeeded. 23 | * 24 | * Emits a {Transfer} event. 25 | */ 26 | function transfer(address recipient, uint256 amount) external returns (bool); 27 | 28 | /** 29 | * @dev Returns the remaining number of tokens that `spender` will be 30 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 31 | * zero by default. 32 | * 33 | * This value changes when {approve} or {transferFrom} are called. 34 | */ 35 | function allowance(address owner, address spender) external view returns (uint256); 36 | 37 | /** 38 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 39 | * 40 | * Returns a boolean value indicating whether the operation succeeded. 41 | * 42 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 43 | * that someone may use both the old and the new allowance by unfortunate 44 | * transaction ordering. One possible solution to mitigate this race 45 | * condition is to first reduce the spender's allowance to 0 and set the 46 | * desired value afterwards: 47 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 48 | * 49 | * Emits an {Approval} event. 50 | */ 51 | function approve(address spender, uint256 amount) external returns (bool); 52 | 53 | /** 54 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 55 | * allowance mechanism. `amount` is then deducted from the caller's 56 | * allowance. 57 | * 58 | * Returns a boolean value indicating whether the operation succeeded. 59 | * 60 | * Emits a {Transfer} event. 61 | */ 62 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 63 | 64 | /** 65 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 66 | * another (`to`). 67 | * 68 | * Note that `value` may be zero. 69 | */ 70 | event Transfer(address indexed from, address indexed to, uint256 value); 71 | 72 | /** 73 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 74 | * a call to {approve}. `value` is the new allowance. 75 | */ 76 | event Approval(address indexed owner, address indexed spender, uint256 value); 77 | } 78 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IERC20Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /** 6 | * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in 7 | * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. 8 | * 9 | * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by 10 | * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't 11 | * need to send a transaction, and thus is not required to hold Ether at all. 12 | */ 13 | interface IERC20Permit { 14 | /** 15 | * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens, 16 | * given `owner`'s signed approval. 17 | * 18 | * IMPORTANT: The same issues {IERC20-approve} has related to transaction 19 | * ordering also apply here. 20 | * 21 | * Emits an {Approval} event. 22 | * 23 | * Requirements: 24 | * 25 | * - `spender` cannot be the zero address. 26 | * - `deadline` must be a timestamp in the future. 27 | * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` 28 | * over the EIP712-formatted function arguments. 29 | * - the signature must use ``owner``'s current nonce (see {nonces}). 30 | * 31 | * For more information on the signature format, see the 32 | * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP 33 | * section]. 34 | */ 35 | function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; 36 | 37 | /** 38 | * @dev Returns the current nonce for `owner`. This value must be 39 | * included whenever a signature is generated for {permit}. 40 | * 41 | * Every successful call to {permit} increases ``owner``'s nonce by one. This 42 | * prevents a signature from being used multiple times. 43 | */ 44 | function nonces(address owner) external view returns (uint256); 45 | 46 | /** 47 | * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}. 48 | */ 49 | // solhint-disable-next-line func-name-mixedcase 50 | function DOMAIN_SEPARATOR() external view returns (bytes32); 51 | } 52 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IERC20PermitAllowed.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Interface for permit 5 | /// @notice Interface used by DAI/CHAI for permit 6 | interface IERC20PermitAllowed { 7 | /// @notice Approve the spender to spend some tokens via the holder signature 8 | /// @dev This is the permit interface used by DAI and CHAI 9 | /// @param holder The address of the token holder, the token owner 10 | /// @param spender The address of the token spender 11 | /// @param nonce The holder's nonce, increases at each call to permit 12 | /// @param expiry The timestamp at which the permit is no longer valid 13 | /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0 14 | /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` 15 | /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` 16 | /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` 17 | function permit( 18 | address holder, 19 | address spender, 20 | uint256 nonce, 21 | uint256 expiry, 22 | bool allowed, 23 | uint8 v, 24 | bytes32 r, 25 | bytes32 s 26 | ) external; 27 | } 28 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IERC721Enumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./IERC721.sol"; 6 | 7 | /** 8 | * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension 9 | * @dev See https://eips.ethereum.org/EIPS/eip-721 10 | */ 11 | interface IERC721Enumerable is IERC721 { 12 | 13 | /** 14 | * @dev Returns the total amount of tokens stored by the contract. 15 | */ 16 | function totalSupply() external view returns (uint256); 17 | 18 | /** 19 | * @dev Returns a token ID owned by `owner` at a given `index` of its token list. 20 | * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. 21 | */ 22 | function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); 23 | 24 | /** 25 | * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. 26 | * Use along with {totalSupply} to enumerate all tokens. 27 | */ 28 | function tokenByIndex(uint256 index) external view returns (uint256); 29 | } 30 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IERC721Metadata.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.7.0; 4 | 5 | import "./IERC721.sol"; 6 | 7 | /** 8 | * @title ERC-721 Non-Fungible Token Standard, optional metadata extension 9 | * @dev See https://eips.ethereum.org/EIPS/eip-721 10 | */ 11 | interface IERC721Metadata is IERC721 { 12 | 13 | /** 14 | * @dev Returns the token collection name. 15 | */ 16 | function name() external view returns (string memory); 17 | 18 | /** 19 | * @dev Returns the token collection symbol. 20 | */ 21 | function symbol() external view returns (string memory); 22 | 23 | /** 24 | * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. 25 | */ 26 | function tokenURI(uint256 tokenId) external view returns (string memory); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IERC721Permit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | import './IERC721.sol'; 5 | 6 | /// @title ERC721 with permit 7 | /// @notice Extension to ERC721 that includes a permit function for signature based approvals 8 | interface IERC721Permit is IERC721 { 9 | /// @notice The permit typehash used in the permit signature 10 | /// @return The typehash for the permit 11 | function PERMIT_TYPEHASH() external pure returns (bytes32); 12 | 13 | /// @notice The domain separator used in the permit signature 14 | /// @return The domain seperator used in encoding of permit signature 15 | function DOMAIN_SEPARATOR() external view returns (bytes32); 16 | 17 | /// @notice Approve of a specific token ID for spending by spender via signature 18 | /// @param spender The account that is being approved 19 | /// @param tokenId The ID of the token that is being approved for spending 20 | /// @param deadline The deadline timestamp by which the call must be mined for the approve to work 21 | /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` 22 | /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` 23 | /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` 24 | function permit( 25 | address spender, 26 | uint256 tokenId, 27 | uint256 deadline, 28 | uint8 v, 29 | bytes32 r, 30 | bytes32 s 31 | ) external payable; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IMulticall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Multicall interface 6 | /// @notice Enables calling multiple methods in a single call to the contract 7 | interface IMulticall { 8 | /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed 9 | /// @dev The `msg.value` should not be trusted for any method callable from multicall. 10 | /// @param data The encoded function data for each of the calls to make to this contract 11 | /// @return results The results from each of the calls passed in via data 12 | function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IPeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Immutable state 5 | /// @notice Functions that return immutable state of the router 6 | interface IPeripheryImmutableState { 7 | /// @return Returns the address of the Uniswap V3 factory 8 | function factory() external view returns (address); 9 | 10 | /// @return Returns the address of WETH9 11 | function WETH9() external view returns (address); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IPeripheryPayments.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | 4 | /// @title Periphery Payments 5 | /// @notice Functions to ease deposits and withdrawals of ETH 6 | interface IPeripheryPayments { 7 | /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. 8 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. 9 | /// @param amountMinimum The minimum amount of WETH9 to unwrap 10 | /// @param recipient The address receiving ETH 11 | function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; 12 | 13 | /// @notice Refunds any ETH balance held by this contract to the `msg.sender` 14 | /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps 15 | /// that use ether for the input amount 16 | function refundETH() external payable; 17 | 18 | /// @notice Transfers the full amount of a token held by this contract to recipient 19 | /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users 20 | /// @param token The contract address of the token which will be transferred to `recipient` 21 | /// @param amountMinimum The minimum amount of token required for a transfer 22 | /// @param recipient The destination address of the token 23 | function sweepToken( 24 | address token, 25 | uint256 amountMinimum, 26 | address recipient 27 | ) external payable; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IPoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | /// @title Creates and initializes V3 Pools 6 | /// @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that 7 | /// require the pool to exist. 8 | interface IPoolInitializer { 9 | /// @notice Creates a new pool if it does not exist, then initializes if not initialized 10 | /// @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool 11 | /// @param token0 The contract address of token0 of the pool 12 | /// @param token1 The contract address of token1 of the pool 13 | /// @param fee The fee amount of the v3 pool for the specified token pair 14 | /// @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value 15 | /// @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary 16 | function createAndInitializePoolIfNecessary( 17 | address token0, 18 | address token1, 19 | uint24 fee, 20 | uint160 sqrtPriceX96 21 | ) external payable returns (address pool); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IUniswapV2Pair.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IUniswapV2Pair { 4 | event Approval(address indexed owner, address indexed spender, uint value); 5 | event Transfer(address indexed from, address indexed to, uint value); 6 | 7 | function name() external pure returns (string memory); 8 | function symbol() external pure returns (string memory); 9 | function decimals() external pure returns (uint8); 10 | function totalSupply() external view returns (uint); 11 | function balanceOf(address owner) external view returns (uint); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | 14 | function approve(address spender, uint value) external returns (bool); 15 | function transfer(address to, uint value) external returns (bool); 16 | function transferFrom(address from, address to, uint value) external returns (bool); 17 | 18 | function DOMAIN_SEPARATOR() external view returns (bytes32); 19 | function PERMIT_TYPEHASH() external pure returns (bytes32); 20 | function nonces(address owner) external view returns (uint); 21 | 22 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 23 | 24 | event Mint(address indexed sender, uint amount0, uint amount1); 25 | event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); 26 | event Swap( 27 | address indexed sender, 28 | uint amount0In, 29 | uint amount1In, 30 | uint amount0Out, 31 | uint amount1Out, 32 | address indexed to 33 | ); 34 | event Sync(uint112 reserve0, uint112 reserve1); 35 | 36 | function MINIMUM_LIQUIDITY() external pure returns (uint); 37 | function factory() external view returns (address); 38 | function token0() external view returns (address); 39 | function token1() external view returns (address); 40 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 41 | function price0CumulativeLast() external view returns (uint); 42 | function price1CumulativeLast() external view returns (uint); 43 | function kLast() external view returns (uint); 44 | 45 | function mint(address to) external returns (uint liquidity); 46 | function burn(address to) external returns (uint amount0, uint amount1); 47 | function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; 48 | function skim(address to) external; 49 | function sync() external; 50 | 51 | function initialize(address, address) external; 52 | } 53 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IUniswapV3PoolImmutables.sol'; 5 | import './IUniswapV3PoolState.sol'; 6 | import './IUniswapV3PoolDerivedState.sol'; 7 | import './IUniswapV3PoolActions.sol'; 8 | import './IUniswapV3PoolOwnerActions.sol'; 9 | import './IUniswapV3PoolEvents.sol'; 10 | 11 | /// @title The interface for a Uniswap V3 Pool 12 | /// @notice A Uniswap pool facilitates swapping and automated market making between any two assets that strictly conform 13 | /// to the ERC20 specification 14 | /// @dev The pool interface is broken up into many smaller pieces 15 | interface IUniswapV3Pool is 16 | IUniswapV3PoolImmutables, 17 | IUniswapV3PoolState, 18 | IUniswapV3PoolDerivedState, 19 | IUniswapV3PoolActions, 20 | IUniswapV3PoolOwnerActions, 21 | IUniswapV3PoolEvents 22 | { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IUniswapV3PoolDerivedState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that is not stored 5 | /// @notice Contains view functions to provide information about the pool that is computed rather than stored on the 6 | /// blockchain. The functions here may have variable gas costs. 7 | interface IUniswapV3PoolDerivedState { 8 | /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp 9 | /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing 10 | /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, 11 | /// you must call it with secondsAgos = [3600, 0]. 12 | /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in 13 | /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. 14 | /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned 15 | /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp 16 | /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block 17 | /// timestamp 18 | function observe(uint32[] calldata secondsAgos) 19 | external 20 | view 21 | returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s); 22 | 23 | /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range 24 | /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. 25 | /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first 26 | /// snapshot is taken and the second snapshot is taken. 27 | /// @param tickLower The lower tick of the range 28 | /// @param tickUpper The upper tick of the range 29 | /// @return tickCumulativeInside The snapshot of the tick accumulator for the range 30 | /// @return secondsPerLiquidityInsideX128 The snapshot of seconds per liquidity for the range 31 | /// @return secondsInside The snapshot of seconds per liquidity for the range 32 | function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) 33 | external 34 | view 35 | returns ( 36 | int56 tickCumulativeInside, 37 | uint160 secondsPerLiquidityInsideX128, 38 | uint32 secondsInside 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IUniswapV3PoolImmutables.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Pool state that never changes 5 | /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values 6 | interface IUniswapV3PoolImmutables { 7 | /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface 8 | /// @return The contract address 9 | function factory() external view returns (address); 10 | 11 | /// @notice The first of the two tokens of the pool, sorted by address 12 | /// @return The token contract address 13 | function token0() external view returns (address); 14 | 15 | /// @notice The second of the two tokens of the pool, sorted by address 16 | /// @return The token contract address 17 | function token1() external view returns (address); 18 | 19 | /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 20 | /// @return The fee 21 | function fee() external view returns (uint24); 22 | 23 | /// @notice The pool tick spacing 24 | /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive 25 | /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... 26 | /// This value is an int24 to avoid casting even though it is always positive. 27 | /// @return The tick spacing 28 | function tickSpacing() external view returns (int24); 29 | 30 | /// @notice The maximum amount of position liquidity that can use any tick in the range 31 | /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and 32 | /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool 33 | /// @return The max amount of liquidity per tick 34 | function maxLiquidityPerTick() external view returns (uint128); 35 | } 36 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IUniswapV3PoolOwnerActions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Permissioned pool actions 5 | /// @notice Contains pool methods that may only be called by the factory owner 6 | interface IUniswapV3PoolOwnerActions { 7 | /// @notice Set the denominator of the protocol's % share of the fees 8 | /// @param feeProtocol0 new protocol fee for token0 of the pool 9 | /// @param feeProtocol1 new protocol fee for token1 of the pool 10 | function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) external; 11 | 12 | /// @notice Collect the protocol fee accrued to the pool 13 | /// @param recipient The address to which collected protocol fees should be sent 14 | /// @param amount0Requested The maximum amount of token0 to send, can be 0 to collect fees in only token1 15 | /// @param amount1Requested The maximum amount of token1 to send, can be 0 to collect fees in only token0 16 | /// @return amount0 The protocol fee collected in token0 17 | /// @return amount1 The protocol fee collected in token1 18 | function collectProtocol( 19 | address recipient, 20 | uint128 amount0Requested, 21 | uint128 amount1Requested 22 | ) external returns (uint128 amount0, uint128 amount1); 23 | } 24 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IV3Migrator.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.5; 3 | pragma abicoder v2; 4 | 5 | import './IMulticall.sol'; 6 | import './ISelfPermit.sol'; 7 | import './IPoolInitializer.sol'; 8 | 9 | /// @title V3 Migrator 10 | /// @notice Enables migration of liqudity from Uniswap v2-compatible pairs into Uniswap v3 pools 11 | interface IV3Migrator is IMulticall, ISelfPermit, IPoolInitializer { 12 | struct MigrateParams { 13 | address pair; // the Uniswap v2-compatible pair 14 | uint256 liquidityToMigrate; // expected to be balanceOf(msg.sender) 15 | uint8 percentageToMigrate; // represented as a numerator over 100 16 | address token0; 17 | address token1; 18 | uint24 fee; 19 | int24 tickLower; 20 | int24 tickUpper; 21 | uint256 amount0Min; // must be discounted by percentageToMigrate 22 | uint256 amount1Min; // must be discounted by percentageToMigrate 23 | address recipient; 24 | uint256 deadline; 25 | bool refundAsETH; 26 | } 27 | 28 | /// @notice Migrates liquidity to v3 by burning v2 liquidity and minting a new position for v3 29 | /// @dev Slippage protection is enforced via `amount{0,1}Min`, which should be a discount of the expected values of 30 | /// the maximum amount of v3 liquidity that the v2 liquidity can get. For the special case of migrating to an 31 | /// out-of-range position, `amount{0,1}Min` may be set to 0, enforcing that the position remains out of range 32 | /// @param params The params necessary to migrate v2 liquidity, encoded as `MigrateParams` in calldata 33 | function migrate(MigrateParams calldata params) external; 34 | } 35 | -------------------------------------------------------------------------------- /contracts/V3Migrator/IWETH9.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IERC20.sol'; 5 | 6 | /// @title Interface for WETH9 7 | interface IWETH9 is IERC20 { 8 | /// @notice Deposit ether to get wrapped ether 9 | function deposit() external payable; 10 | 11 | /// @notice Withdraw wrapped ether to get ether 12 | function withdraw(uint256) external; 13 | } 14 | -------------------------------------------------------------------------------- /contracts/V3Migrator/LowGasSafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.7.0; 3 | 4 | /// @title Optimized overflow and underflow safe math operations 5 | /// @notice Contains methods for doing math operations that revert on overflow or underflow for minimal gas cost 6 | library LowGasSafeMath { 7 | /// @notice Returns x + y, reverts if sum overflows uint256 8 | /// @param x The augend 9 | /// @param y The addend 10 | /// @return z The sum of x and y 11 | function add(uint256 x, uint256 y) internal pure returns (uint256 z) { 12 | require((z = x + y) >= x); 13 | } 14 | 15 | /// @notice Returns x - y, reverts if underflows 16 | /// @param x The minuend 17 | /// @param y The subtrahend 18 | /// @return z The difference of x and y 19 | function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { 20 | require((z = x - y) <= x); 21 | } 22 | 23 | /// @notice Returns x * y, reverts if overflows 24 | /// @param x The multiplicand 25 | /// @param y The multiplier 26 | /// @return z The product of x and y 27 | function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { 28 | require(x == 0 || (z = x * y) / x == y); 29 | } 30 | 31 | /// @notice Returns x + y, reverts if overflows or underflows 32 | /// @param x The augend 33 | /// @param y The addend 34 | /// @return z The sum of x and y 35 | function add(int256 x, int256 y) internal pure returns (int256 z) { 36 | require((z = x + y) >= x == (y >= 0)); 37 | } 38 | 39 | /// @notice Returns x - y, reverts if overflows or underflows 40 | /// @param x The minuend 41 | /// @param y The subtrahend 42 | /// @return z The difference of x and y 43 | function sub(int256 x, int256 y) internal pure returns (int256 z) { 44 | require((z = x - y) <= x == (y >= 0)); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/V3Migrator/Multicall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | pragma abicoder v2; 4 | 5 | import './IMulticall.sol'; 6 | 7 | /// @title Multicall 8 | /// @notice Enables calling multiple methods in a single call to the contract 9 | abstract contract Multicall is IMulticall { 10 | /// @inheritdoc IMulticall 11 | function multicall(bytes[] calldata data) external payable override returns (bytes[] memory results) { 12 | results = new bytes[](data.length); 13 | for (uint256 i = 0; i < data.length; i++) { 14 | (bool success, bytes memory result) = address(this).delegatecall(data[i]); 15 | 16 | if (!success) { 17 | // Next 5 lines from https://ethereum.stackexchange.com/a/83577 18 | if (result.length < 68) revert(); 19 | assembly { 20 | result := add(result, 0x04) 21 | } 22 | revert(abi.decode(result, (string))); 23 | } 24 | 25 | results[i] = result; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/V3Migrator/PeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IPeripheryImmutableState.sol'; 5 | 6 | /// @title Immutable state 7 | /// @notice Immutable state used by periphery contracts 8 | abstract contract PeripheryImmutableState is IPeripheryImmutableState { 9 | /// @inheritdoc IPeripheryImmutableState 10 | address public immutable override factory; 11 | /// @inheritdoc IPeripheryImmutableState 12 | address public immutable override WETH9; 13 | 14 | constructor(address _factory, address _WETH9) { 15 | factory = _factory; 16 | WETH9 = _WETH9; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/V3Migrator/PoolAddress.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Provides functions for deriving a pool address from the factory, tokens, and the fee 5 | library PoolAddress { 6 | bytes32 internal constant POOL_INIT_CODE_HASH = 0xd70958ebfff5a99884d37fb1ba60083c838125942b9ab042cf8d49a7929bb9d0; 7 | 8 | /// @notice The identifying key of the pool 9 | struct PoolKey { 10 | address token0; 11 | address token1; 12 | uint24 fee; 13 | } 14 | 15 | /// @notice Returns PoolKey: the ordered tokens with the matched fee levels 16 | /// @param tokenA The first token of a pool, unsorted 17 | /// @param tokenB The second token of a pool, unsorted 18 | /// @param fee The fee level of the pool 19 | /// @return Poolkey The pool details with ordered token0 and token1 assignments 20 | function getPoolKey( 21 | address tokenA, 22 | address tokenB, 23 | uint24 fee 24 | ) internal pure returns (PoolKey memory) { 25 | if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); 26 | return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); 27 | } 28 | 29 | /// @notice Deterministically computes the pool address given the factory and PoolKey 30 | /// @param factory The Uniswap V3 factory contract address 31 | /// @param key The PoolKey 32 | /// @return pool The contract address of the V3 pool 33 | function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { 34 | require(key.token0 < key.token1); 35 | pool = address( 36 | uint256( 37 | keccak256( 38 | abi.encodePacked( 39 | hex'ff', 40 | factory, 41 | keccak256(abi.encode(key.token0, key.token1, key.fee)), 42 | POOL_INIT_CODE_HASH 43 | ) 44 | ) 45 | ) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/V3Migrator/PoolInitializer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity =0.7.6; 3 | 4 | import './IUniswapV3Factory.sol'; 5 | import './IUniswapV3Pool.sol'; 6 | 7 | import './PeripheryImmutableState.sol'; 8 | import './IPoolInitializer.sol'; 9 | 10 | /// @title Creates and initializes V3 Pools 11 | abstract contract PoolInitializer is IPoolInitializer, PeripheryImmutableState { 12 | /// @inheritdoc IPoolInitializer 13 | function createAndInitializePoolIfNecessary( 14 | address token0, 15 | address token1, 16 | uint24 fee, 17 | uint160 sqrtPriceX96 18 | ) external payable override returns (address pool) { 19 | require(token0 < token1); 20 | pool = IUniswapV3Factory(factory).getPool(token0, token1, fee); 21 | 22 | if (pool == address(0)) { 23 | pool = IUniswapV3Factory(factory).createPool(token0, token1, fee); 24 | IUniswapV3Pool(pool).initialize(sqrtPriceX96); 25 | } else { 26 | (uint160 sqrtPriceX96Existing, , , , , , ) = IUniswapV3Pool(pool).slot0(); 27 | if (sqrtPriceX96Existing == 0) { 28 | IUniswapV3Pool(pool).initialize(sqrtPriceX96); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contracts/V3Migrator/SelfPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import './IERC20.sol'; 5 | import './IERC20Permit.sol'; 6 | 7 | import './ISelfPermit.sol'; 8 | import './IERC20PermitAllowed.sol'; 9 | 10 | /// @title Self Permit 11 | /// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route 12 | /// @dev These functions are expected to be embedded in multicalls to allow EOAs to approve a contract and call a function 13 | /// that requires an approval in a single transaction. 14 | abstract contract SelfPermit is ISelfPermit { 15 | /// @inheritdoc ISelfPermit 16 | function selfPermit( 17 | address token, 18 | uint256 value, 19 | uint256 deadline, 20 | uint8 v, 21 | bytes32 r, 22 | bytes32 s 23 | ) public payable override { 24 | IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s); 25 | } 26 | 27 | /// @inheritdoc ISelfPermit 28 | function selfPermitIfNecessary( 29 | address token, 30 | uint256 value, 31 | uint256 deadline, 32 | uint8 v, 33 | bytes32 r, 34 | bytes32 s 35 | ) external payable override { 36 | if (IERC20(token).allowance(msg.sender, address(this)) < value) selfPermit(token, value, deadline, v, r, s); 37 | } 38 | 39 | /// @inheritdoc ISelfPermit 40 | function selfPermitAllowed( 41 | address token, 42 | uint256 nonce, 43 | uint256 expiry, 44 | uint8 v, 45 | bytes32 r, 46 | bytes32 s 47 | ) public payable override { 48 | IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s); 49 | } 50 | 51 | /// @inheritdoc ISelfPermit 52 | function selfPermitAllowedIfNecessary( 53 | address token, 54 | uint256 nonce, 55 | uint256 expiry, 56 | uint8 v, 57 | bytes32 r, 58 | bytes32 s 59 | ) external payable override { 60 | if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) 61 | selfPermitAllowed(token, nonce, expiry, v, r, s); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/V3Migrator/TransferHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.6.0; 3 | 4 | import './IERC20.sol'; 5 | 6 | library TransferHelper { 7 | /// @notice Transfers tokens from the targeted address to the given destination 8 | /// @notice Errors with 'STF' if transfer fails 9 | /// @param token The contract address of the token to be transferred 10 | /// @param from The originating address from which the tokens will be transferred 11 | /// @param to The destination address of the transfer 12 | /// @param value The amount to be transferred 13 | function safeTransferFrom( 14 | address token, 15 | address from, 16 | address to, 17 | uint256 value 18 | ) internal { 19 | (bool success, bytes memory data) = 20 | token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); 21 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); 22 | } 23 | 24 | /// @notice Transfers tokens from msg.sender to a recipient 25 | /// @dev Errors with ST if transfer fails 26 | /// @param token The contract address of the token which will be transferred 27 | /// @param to The recipient of the transfer 28 | /// @param value The value of the transfer 29 | function safeTransfer( 30 | address token, 31 | address to, 32 | uint256 value 33 | ) internal { 34 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); 35 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); 36 | } 37 | 38 | /// @notice Approves the stipulated contract to spend the given allowance in the given token 39 | /// @dev Errors with 'SA' if transfer fails 40 | /// @param token The contract address of the token to be approved 41 | /// @param to The target of the approval 42 | /// @param value The amount of the given token the target will be allowed to spend 43 | function safeApprove( 44 | address token, 45 | address to, 46 | uint256 value 47 | ) internal { 48 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); 49 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); 50 | } 51 | 52 | /// @notice Transfers ETH to the recipient address 53 | /// @dev Fails with `STE` 54 | /// @param to The destination of the transfer 55 | /// @param value The value to be transferred 56 | function safeTransferETH(address to, uint256 value) internal { 57 | (bool success, ) = to.call{value: value}(new bytes(0)); 58 | require(success, 'STE'); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /deployments/hardhat/NFTDescriptor.json: -------------------------------------------------------------------------------- 1 | {"address":"0x856E06a26e32A03932f7a408bA1B296a212239c7","constructorArguments":[],"libraries":{},"contract":"contracts/NFTDescriptor/NFTDescriptor.sol:NFTDescriptor"} -------------------------------------------------------------------------------- /deployments/hardhat/NonfungiblePositionManager.json: -------------------------------------------------------------------------------- 1 | {"address":"0x91CA6F77Bd05dc47bfA313341f891E0a1724892F","constructorArguments":["0x99926d145D79567d2F07007e2095A3c1570e6D5e","0x99926d145D79567d2F07007e2095A3c1570e6D5e","0x0C4CCda8e0eCeB0ef3B2477f9bF6751CF52Be7b9"],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/NonfungibleTokenPositionDescriptor.json: -------------------------------------------------------------------------------- 1 | {"address":"0x0b2e287309A8728A01C6Ec8683349E524e103b25","constructorArguments":["0x99926d145D79567d2F07007e2095A3c1570e6D5e","ETH"],"libraries":{"contracts/NonfungibleTokenPositionDescriptor/NFTDescriptor.sol:NFTDescriptor":"0x856E06a26e32A03932f7a408bA1B296a212239c7"}} -------------------------------------------------------------------------------- /deployments/hardhat/ProxyAdmin.json: -------------------------------------------------------------------------------- 1 | {"address":"0xf825d15BD7E70a9fc5F87C339a6F464Ec6cf80da","constructorArguments":[],"libraries":{},"contract":"contracts/ProxyAdmin/ProxyAdmin.sol:ProxyAdmin"} -------------------------------------------------------------------------------- /deployments/hardhat/Quoter.json: -------------------------------------------------------------------------------- 1 | {"address":"0x2e07978f213A9823333dC5121D79379e7b4dfb15","constructorArguments":["0x99926d145D79567d2F07007e2095A3c1570e6D5e","0x99926d145D79567d2F07007e2095A3c1570e6D5e"],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/SwapRouter.json: -------------------------------------------------------------------------------- 1 | {"address":"0xb78AAc38F1dc8E4aA244A196085011d7931E087d","constructorArguments":["0x99926d145D79567d2F07007e2095A3c1570e6D5e","0x99926d145D79567d2F07007e2095A3c1570e6D5e"],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/TickLens.json: -------------------------------------------------------------------------------- 1 | {"address":"0x0872B14C6fc1dF9b9070ECbEd22547627d012A58","constructorArguments":[],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/TransparentUpgradeableProxy.json: -------------------------------------------------------------------------------- 1 | {"address":"0x0C4CCda8e0eCeB0ef3B2477f9bF6751CF52Be7b9","constructorArguments":["0x0b2e287309A8728A01C6Ec8683349E524e103b25","0xf825d15BD7E70a9fc5F87C339a6F464Ec6cf80da","0x"],"libraries":{},"contract":"contracts/TransparentUpgradeableProxy/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy"} -------------------------------------------------------------------------------- /deployments/hardhat/UniswapV2Factory.json: -------------------------------------------------------------------------------- 1 | {"address":"0x0872B14C6fc1dF9b9070ECbEd22547627d012A58","constructorArguments":["0x1381C573b97Bf393A81fA42760DD21E109d8092B"],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/UniswapV2Router02.json: -------------------------------------------------------------------------------- 1 | {"address":"0x2e07978f213A9823333dC5121D79379e7b4dfb15","constructorArguments":["0x0872B14C6fc1dF9b9070ECbEd22547627d012A58","0x99926d145D79567d2F07007e2095A3c1570e6D5e"],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/UniswapV3Factory.json: -------------------------------------------------------------------------------- 1 | {"address":"0x99926d145D79567d2F07007e2095A3c1570e6D5e","constructorArguments":[],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/V3Migrator.json: -------------------------------------------------------------------------------- 1 | {"address":"0xAFfe8B72a29A28999a472a056374d8B8607e4347","constructorArguments":["0x99926d145D79567d2F07007e2095A3c1570e6D5e","0x99926d145D79567d2F07007e2095A3c1570e6D5e","0x91CA6F77Bd05dc47bfA313341f891E0a1724892F"],"libraries":{}} -------------------------------------------------------------------------------- /deployments/hardhat/WETH9.json: -------------------------------------------------------------------------------- 1 | {"address":"0x99926d145D79567d2F07007e2095A3c1570e6D5e","constructorArguments":[],"libraries":{}} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-uniswap-v3", 3 | "version": "1.0.0", 4 | "description": "Uniswap 合约部署方案", 5 | "license": "GPL-2.0-or-later", 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "homepage": "https://uniswap.org", 10 | "keywords": [ 11 | "uniswap", 12 | "periphery", 13 | "v3" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/Uniswap/uniswap-v3-periphery" 18 | }, 19 | "files": [ 20 | "contracts/base", 21 | "contracts/interfaces", 22 | "contracts/libraries", 23 | "artifacts/contracts/**/*.json", 24 | "!artifacts/contracts/**/*.dbg.json", 25 | "!artifacts/contracts/test/**/*", 26 | "!artifacts/contracts/base/**/*" 27 | ], 28 | "engines": { 29 | "node": ">=10" 30 | }, 31 | "dependencies": { 32 | "hardhat-gas-reporter": "^1.0.4" 33 | }, 34 | "devDependencies": { 35 | "@nomiclabs/hardhat-ethers": "^2.0.2", 36 | "@nomiclabs/hardhat-etherscan": "^2.1.1", 37 | "@nomiclabs/hardhat-waffle": "^2.0.1", 38 | "@typechain/ethers-v5": "^4.0.0", 39 | "@types/chai": "^4.2.6", 40 | "@types/mocha": "^5.2.7", 41 | "chai": "^4.2.0", 42 | "decimal.js": "^10.2.1", 43 | "dotenv": "^10.0.0", 44 | "ethereum-waffle": "^3.0.2", 45 | "ethers": "^5.0.8", 46 | "hardhat": "^2.2.0", 47 | "hardhat-typechain": "^0.3.5", 48 | "mocha": "^6.2.2", 49 | "mocha-chai-jest-snapshot": "^1.1.0", 50 | "prettier": "^2.0.5", 51 | "prettier-plugin-solidity": "^1.0.0-alpha.59", 52 | "solhint": "^3.2.1", 53 | "solhint-plugin-prettier": "^0.0.5", 54 | "ts-generator": "^0.1.1", 55 | "ts-node": "^8.5.4", 56 | "typechain": "^4.0.0", 57 | "typescript": "^3.7.3" 58 | }, 59 | "scripts": { 60 | "compile": "hardhat compile", 61 | "test": "hardhat test", 62 | "deploy": "hardhat deploy" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "strict": true, 6 | "esModuleInterop": true, 7 | "outDir": "dist", 8 | "typeRoots": ["./typechain", "./node_modules/@types"], 9 | "types": ["@nomiclabs/hardhat-ethers", "@nomiclabs/hardhat-waffle"] 10 | }, 11 | "include": ["./test"], 12 | "files": ["./hardhat.config.ts"] 13 | } 14 | --------------------------------------------------------------------------------