diff --git a/src/V4Router.sol b/src/V4Router.sol index 8e25953de..12b7a6e6f 100644 --- a/src/V4Router.sol +++ b/src/V4Router.sol @@ -74,6 +74,10 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver { (Currency currency, address recipient, uint256 bips) = params.decodeCurrencyAddressAndUint256(); _take(currency, _mapRecipient(recipient), _getFullCredit(currency).calculatePortion(bips)); return; + } else if (action == Actions.SWAP_EXACT_IN_RAW) { + (PoolKey memory poolKey, SwapParams memory swapParams, bytes memory hookData) = params.decodeSwapExactInRawParams(); + _rawSwap(poolKey, swapParams, hookData); + return; } } revert UnsupportedAction(action); @@ -153,6 +157,22 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver { } } + function _rawSwap(PoolKey memory poolKey, SwapParams memory swapParams, bytes memory hookData) + private + returns (int128 reciprocalAmount) + { + // for protection of exactOut swaps, sqrtPriceLimit is not exposed as a feature in this contract + unchecked { + BalanceDelta delta = poolManager.swap( + poolKey, + swapParams, + hookData + ); + + reciprocalAmount = (swapParams.amountSpecified < 0) ? delta.amount1() : delta.amount0(); + } + } + function _swap(PoolKey memory poolKey, bool zeroForOne, int256 amountSpecified, bytes calldata hookData) private returns (int128 reciprocalAmount) diff --git a/src/libraries/Actions.sol b/src/libraries/Actions.sol index a33c4e87d..edc4ac1ec 100644 --- a/src/libraries/Actions.sol +++ b/src/libraries/Actions.sol @@ -46,4 +46,6 @@ library Actions { // note this is not supported in the position manager or router uint256 internal constant MINT_6909 = 0x17; uint256 internal constant BURN_6909 = 0x18; + + uint256 internal constant SWAP_EXACT_IN_RAW = 0x19; } diff --git a/src/libraries/CalldataDecoder.sol b/src/libraries/CalldataDecoder.sol index 496852bdc..aa824806e 100644 --- a/src/libraries/CalldataDecoder.sol +++ b/src/libraries/CalldataDecoder.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IV4Router} from "../interfaces/IV4Router.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; +import {SwapParams} from "@uniswap/v4-core/src/types/PoolOperation.sol"; /// @title Library for abi decoding in calldata library CalldataDecoder { @@ -388,4 +389,13 @@ library CalldataDecoder { } } } + + /// @dev equivalent to: abi.decode(params, (IV4Router.ExactInputWithLimitParams)) + function decodeSwapExactInRawParams(bytes calldata params) + internal + pure + returns (PoolKey memory poolKey, SwapParams memory swapParams, bytes memory hookData) + { + (poolKey, swapParams, hookData) = abi.decode(params, (PoolKey, SwapParams, bytes)); + } }