Eliminate dependence on most uniswap functions
This commit is contained in:
137
lib_sol8/v3-periphery/contracts/libraries/LiquidityAmounts.sol
Normal file
137
lib_sol8/v3-periphery/contracts/libraries/LiquidityAmounts.sol
Normal file
@@ -0,0 +1,137 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
import '@uniswap/v3-core/contracts/libraries/FullMath.sol';
|
||||
import '@uniswap/v3-core/contracts/libraries/FixedPoint96.sol';
|
||||
|
||||
/// @title Liquidity amount functions
|
||||
/// @notice Provides functions for computing liquidity amounts from token amounts and prices
|
||||
library LiquidityAmounts {
|
||||
/// @notice Downcasts uint256 to uint128
|
||||
/// @param x The uint258 to be downcasted
|
||||
/// @return y The passed value, downcasted to uint128
|
||||
function toUint128(uint256 x) private pure returns (uint128 y) {
|
||||
require((y = uint128(x)) == x);
|
||||
}
|
||||
|
||||
/// @notice Computes the amount of liquidity received for a given amount of token0 and price range
|
||||
/// @dev Calculates amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower))
|
||||
/// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
|
||||
/// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
|
||||
/// @param amount0 The amount0 being sent in
|
||||
/// @return liquidity The amount of returned liquidity
|
||||
function getLiquidityForAmount0(
|
||||
uint160 sqrtRatioAX96,
|
||||
uint160 sqrtRatioBX96,
|
||||
uint256 amount0
|
||||
) internal pure returns (uint128 liquidity) {
|
||||
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
||||
uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96);
|
||||
return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96));
|
||||
}
|
||||
|
||||
/// @notice Computes the amount of liquidity received for a given amount of token1 and price range
|
||||
/// @dev Calculates amount1 / (sqrt(upper) - sqrt(lower)).
|
||||
/// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
|
||||
/// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
|
||||
/// @param amount1 The amount1 being sent in
|
||||
/// @return liquidity The amount of returned liquidity
|
||||
function getLiquidityForAmount1(
|
||||
uint160 sqrtRatioAX96,
|
||||
uint160 sqrtRatioBX96,
|
||||
uint256 amount1
|
||||
) internal pure returns (uint128 liquidity) {
|
||||
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
||||
return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96));
|
||||
}
|
||||
|
||||
/// @notice Computes the maximum amount of liquidity received for a given amount of token0, token1, the current
|
||||
/// pool prices and the prices at the tick boundaries
|
||||
/// @param sqrtRatioX96 A sqrt price representing the current pool prices
|
||||
/// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
|
||||
/// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
|
||||
/// @param amount0 The amount of token0 being sent in
|
||||
/// @param amount1 The amount of token1 being sent in
|
||||
/// @return liquidity The maximum amount of liquidity received
|
||||
function getLiquidityForAmounts(
|
||||
uint160 sqrtRatioX96,
|
||||
uint160 sqrtRatioAX96,
|
||||
uint160 sqrtRatioBX96,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
) internal pure returns (uint128 liquidity) {
|
||||
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
||||
|
||||
if (sqrtRatioX96 <= sqrtRatioAX96) {
|
||||
liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);
|
||||
} else if (sqrtRatioX96 < sqrtRatioBX96) {
|
||||
uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);
|
||||
uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);
|
||||
|
||||
liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;
|
||||
} else {
|
||||
liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Computes the amount of token0 for a given amount of liquidity and a price range
|
||||
/// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
|
||||
/// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
|
||||
/// @param liquidity The liquidity being valued
|
||||
/// @return amount0 The amount of token0
|
||||
function getAmount0ForLiquidity(
|
||||
uint160 sqrtRatioAX96,
|
||||
uint160 sqrtRatioBX96,
|
||||
uint128 liquidity
|
||||
) internal pure returns (uint256 amount0) {
|
||||
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
||||
|
||||
return
|
||||
FullMath.mulDiv(
|
||||
uint256(liquidity) << FixedPoint96.RESOLUTION,
|
||||
sqrtRatioBX96 - sqrtRatioAX96,
|
||||
sqrtRatioBX96
|
||||
) / sqrtRatioAX96;
|
||||
}
|
||||
|
||||
/// @notice Computes the amount of token1 for a given amount of liquidity and a price range
|
||||
/// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
|
||||
/// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
|
||||
/// @param liquidity The liquidity being valued
|
||||
/// @return amount1 The amount of token1
|
||||
function getAmount1ForLiquidity(
|
||||
uint160 sqrtRatioAX96,
|
||||
uint160 sqrtRatioBX96,
|
||||
uint128 liquidity
|
||||
) internal pure returns (uint256 amount1) {
|
||||
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
||||
|
||||
return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96);
|
||||
}
|
||||
|
||||
/// @notice Computes the token0 and token1 value for a given amount of liquidity, the current
|
||||
/// pool prices and the prices at the tick boundaries
|
||||
/// @param sqrtRatioX96 A sqrt price representing the current pool prices
|
||||
/// @param sqrtRatioAX96 A sqrt price representing the first tick boundary
|
||||
/// @param sqrtRatioBX96 A sqrt price representing the second tick boundary
|
||||
/// @param liquidity The liquidity being valued
|
||||
/// @return amount0 The amount of token0
|
||||
/// @return amount1 The amount of token1
|
||||
function getAmountsForLiquidity(
|
||||
uint160 sqrtRatioX96,
|
||||
uint160 sqrtRatioAX96,
|
||||
uint160 sqrtRatioBX96,
|
||||
uint128 liquidity
|
||||
) internal pure returns (uint256 amount0, uint256 amount1) {
|
||||
if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
||||
|
||||
if (sqrtRatioX96 <= sqrtRatioAX96) {
|
||||
amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
|
||||
} else if (sqrtRatioX96 < sqrtRatioBX96) {
|
||||
amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);
|
||||
amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);
|
||||
} else {
|
||||
amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
lib_sol8/v3-periphery/contracts/libraries/PoolAddress.sol
Normal file
48
lib_sol8/v3-periphery/contracts/libraries/PoolAddress.sol
Normal file
@@ -0,0 +1,48 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.5.0;
|
||||
|
||||
/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee
|
||||
library PoolAddress {
|
||||
bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
|
||||
|
||||
/// @notice The identifying key of the pool
|
||||
struct PoolKey {
|
||||
address token0;
|
||||
address token1;
|
||||
uint24 fee;
|
||||
}
|
||||
|
||||
/// @notice Returns PoolKey: the ordered tokens with the matched fee levels
|
||||
/// @param tokenA The first token of a pool, unsorted
|
||||
/// @param tokenB The second token of a pool, unsorted
|
||||
/// @param fee The fee level of the pool
|
||||
/// @return Poolkey The pool details with ordered token0 and token1 assignments
|
||||
function getPoolKey(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint24 fee
|
||||
) internal pure returns (PoolKey memory) {
|
||||
if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
|
||||
return PoolKey({token0: tokenA, token1: tokenB, fee: fee});
|
||||
}
|
||||
|
||||
/// @notice Deterministically computes the pool address given the factory and PoolKey
|
||||
/// @param factory The Uniswap V3 factory contract address
|
||||
/// @param key The PoolKey
|
||||
/// @return pool The contract address of the V3 pool
|
||||
function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
|
||||
require(key.token0 < key.token1);
|
||||
pool = address(
|
||||
uint256(
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
hex'ff',
|
||||
factory,
|
||||
keccak256(abi.encode(key.token0, key.token1, key.fee)),
|
||||
POOL_INIT_CODE_HASH
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
60
lib_sol8/v3-periphery/contracts/libraries/TransferHelper.sol
Normal file
60
lib_sol8/v3-periphery/contracts/libraries/TransferHelper.sol
Normal file
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity >=0.6.0;
|
||||
|
||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
|
||||
library TransferHelper {
|
||||
/// @notice Transfers tokens from the targeted address to the given destination
|
||||
/// @notice Errors with 'STF' if transfer fails
|
||||
/// @param token The contract address of the token to be transferred
|
||||
/// @param from The originating address from which the tokens will be transferred
|
||||
/// @param to The destination address of the transfer
|
||||
/// @param value The amount to be transferred
|
||||
function safeTransferFrom(
|
||||
address token,
|
||||
address from,
|
||||
address to,
|
||||
uint256 value
|
||||
) internal {
|
||||
(bool success, bytes memory data) =
|
||||
token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
|
||||
require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
|
||||
}
|
||||
|
||||
/// @notice Transfers tokens from msg.sender to a recipient
|
||||
/// @dev Errors with ST if transfer fails
|
||||
/// @param token The contract address of the token which will be transferred
|
||||
/// @param to The recipient of the transfer
|
||||
/// @param value The value of the transfer
|
||||
function safeTransfer(
|
||||
address token,
|
||||
address to,
|
||||
uint256 value
|
||||
) internal {
|
||||
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
|
||||
require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
|
||||
}
|
||||
|
||||
/// @notice Approves the stipulated contract to spend the given allowance in the given token
|
||||
/// @dev Errors with 'SA' if transfer fails
|
||||
/// @param token The contract address of the token to be approved
|
||||
/// @param to The target of the approval
|
||||
/// @param value The amount of the given token the target will be allowed to spend
|
||||
function safeApprove(
|
||||
address token,
|
||||
address to,
|
||||
uint256 value
|
||||
) internal {
|
||||
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
|
||||
require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');
|
||||
}
|
||||
|
||||
/// @notice Transfers ETH to the recipient address
|
||||
/// @dev Fails with `STE`
|
||||
/// @param to The destination of the transfer
|
||||
/// @param value The value to be transferred
|
||||
function safeTransferETH(address to, uint256 value) internal {
|
||||
(bool success, ) = to.call{value: value}(new bytes(0));
|
||||
require(success, 'STE');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user