Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function _createPosition2(PoolKey calldata key, uint160 sqrtRatioX96, uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint128 liquidity) internal {
- // Calculate amounts of each token
- // I can't use LiquidityAmounts.getAmountsForLiquidity because the function does not exist in the v4
- // library. See below links, there is a discrepency between the source and the documentation:
- // https://docs.uniswap.org/contracts/v4/reference/core/libraries/liquidity-amounts
- // https://github.com/Uniswap/v4-periphery/blob/main/src/libraries/LiquidityAmounts.sol
- // In any case, I included my own implementation in my utils contract:
- // http://etherscan.io/address/0xC97B6F6DC641C0f59c724657B91569aF00C28B7D
- // It's based on the UniswapV3 code so I'm pretty sure it works fine.
- (uint256 amount0, uint256 amount1) = utils.getAmountsForLiquidity(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, liquidity);
- // This function reverts if the amounts of the tokens are less than amount0 and amount1 by the end of the call
- // From this, we can be sure that we have enough of the tokens, assuming that amount0 and amount1 are correct
- obtainTokens(Currency.unwrap(key.currency0), Currency.unwrap(key.currency1), amount0, amount1);
- // Grant allowance to the position manager
- if (Currency.unwrap(key.currency0) != address(0)) permit2.approve(Currency.unwrap(key.currency0), address(v4PositionManager), uint160(amount0), 0);
- permit2.approve(Currency.unwrap(key.currency1), address(v4PositionManager), uint160(amount1), 0);
- // Based on code from:
- // https://docs.uniswap.org/contracts/v4/quickstart/manage-liquidity/mint-position
- // https://docs.uniswap.org/contracts/v4/guides/position-manager
- bytes memory actions = abi.encodePacked(
- uint8(Actions.MINT_POSITION),
- uint8(Actions.SETTLE_PAIR)
- );
- bytes[] memory params = new bytes[](2);
- unchecked {
- params[0] = abi.encode(
- key,
- (TickMath.getTickAtSqrtPrice(sqrtRatioAX96) / key.tickSpacing) * key.tickSpacing,
- (TickMath.getTickAtSqrtPrice(sqrtRatioBX96) / key.tickSpacing) * key.tickSpacing,
- (liquidity * 1015) >> 10, // reduces the inserted liquidity a bit, just in case we barely don't have enough
- amount0,
- amount1,
- address(this),
- abi.encode(address(this))
- );
- }
- params[1] = abi.encode(key.currency0, key.currency1);
- unchecked {
- uint256 deadline = block.timestamp + 60;
- uint256 valueToPass = key.currency0.isAddressZero() ? amount0 : 0;
- // Our revert happens inside this call, apparently before SETTLE_PAIR is ever reached:
- v4PositionManager.modifyLiquidities{value: valueToPass}(abi.encode(actions, params), deadline);
- }
- }
Advertisement