Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode router params calldata #230

Merged
merged 7 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134624
134171
Original file line number Diff line number Diff line change
@@ -1 +1 @@
127419
126966
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_Bytecode.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7256
6942
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
120842
120501
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
120037
119696
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_oneForZero.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
128909
128568
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn1Hop_zeroForOne.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
135739
135398
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn2Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
187091
186897
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn2Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
179026
178832
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn3Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
238470
238421
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactIn3Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
230429
230380
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactInputSingle.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134624
134171
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactInputSingle_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
119727
119274
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactInputSingle_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
118900
118447
Original file line number Diff line number Diff line change
@@ -1 +1 @@
126645
126298
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut1Hop_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
120878
120531
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut1Hop_oneForZero.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
129750
129403
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut1Hop_zeroForOne.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134551
134204
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut2Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
186512
186306
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut2Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
183407
183201
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut3Hops.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
238515
238448
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut3Hops_nativeIn.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
235434
235367
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOut3Hops_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
229667
229600
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOutputSingle.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
133428
132975
Original file line number Diff line number Diff line change
@@ -1 +1 @@
125522
125069
2 changes: 1 addition & 1 deletion .forge-snapshots/V4Router_ExactOutputSingle_nativeOut.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
119813
119360
26 changes: 15 additions & 11 deletions src/V4Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
// swap actions and payment actions in different blocks for gas efficiency
if (action < Actions.SETTLE) {
if (action == Actions.SWAP_EXACT_IN) {
_swapExactInput(abi.decode(params, (IV4Router.ExactInputParams)));
IV4Router.ExactInputParams calldata swapParams = params.decodeSwapExactInParams();
_swapExactInput(swapParams);
} else if (action == Actions.SWAP_EXACT_IN_SINGLE) {
_swapExactInputSingle(abi.decode(params, (IV4Router.ExactInputSingleParams)));
IV4Router.ExactInputSingleParams calldata swapParams = params.decodeSwapExactInSingleParams();
_swapExactInputSingle(swapParams);
} else if (action == Actions.SWAP_EXACT_OUT) {
_swapExactOutput(abi.decode(params, (IV4Router.ExactOutputParams)));
IV4Router.ExactOutputParams calldata swapParams = params.decodeSwapExactOutParams();
_swapExactOutput(swapParams);
} else if (action == Actions.SWAP_EXACT_OUT_SINGLE) {
_swapExactOutputSingle(abi.decode(params, (IV4Router.ExactOutputSingleParams)));
IV4Router.ExactOutputSingleParams calldata swapParams = params.decodeSwapExactOutSingleParams();
_swapExactOutputSingle(swapParams);
} else {
revert UnsupportedAction(action);
}
Expand All @@ -62,7 +66,7 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
}
}

function _swapExactInputSingle(IV4Router.ExactInputSingleParams memory params) private {
function _swapExactInputSingle(IV4Router.ExactInputSingleParams calldata params) private {
uint128 amountOut = _swap(
params.poolKey,
params.zeroForOne,
Expand All @@ -73,14 +77,14 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
if (amountOut < params.amountOutMinimum) revert TooLittleReceived();
}

function _swapExactInput(IV4Router.ExactInputParams memory params) private {
function _swapExactInput(IV4Router.ExactInputParams calldata params) private {
unchecked {
// Caching for gas savings
uint256 pathLength = params.path.length;
uint128 amountOut;
uint128 amountIn = params.amountIn;
Currency currencyIn = params.currencyIn;
PathKey memory pathKey;
PathKey calldata pathKey;

for (uint256 i = 0; i < pathLength; i++) {
pathKey = params.path[i];
Expand All @@ -96,7 +100,7 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
}
}

function _swapExactOutputSingle(IV4Router.ExactOutputSingleParams memory params) private {
function _swapExactOutputSingle(IV4Router.ExactOutputSingleParams calldata params) private {
uint128 amountIn = (
-_swap(
params.poolKey,
Expand All @@ -109,14 +113,14 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
if (amountIn > params.amountInMaximum) revert TooMuchRequested();
}

function _swapExactOutput(IV4Router.ExactOutputParams memory params) private {
function _swapExactOutput(IV4Router.ExactOutputParams calldata params) private {
unchecked {
// Caching for gas savings
uint256 pathLength = params.path.length;
uint128 amountIn;
uint128 amountOut = params.amountOut;
Currency currencyOut = params.currencyOut;
PathKey memory pathKey;
PathKey calldata pathKey;

for (uint256 i = pathLength; i > 0; i--) {
pathKey = params.path[i - 1];
Expand All @@ -136,7 +140,7 @@ abstract contract V4Router is IV4Router, BaseActionsRouter, DeltaResolver {
bool zeroForOne,
int256 amountSpecified,
uint160 sqrtPriceLimitX96,
bytes memory hookData
bytes calldata hookData
) private returns (int128 reciprocalAmount) {
unchecked {
BalanceDelta delta = poolManager.swap(
Expand Down
10 changes: 5 additions & 5 deletions src/lens/Quoter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ contract Quoter is IQuoter, SafeCallback {
}

/// @dev quote an ExactInput swap along a path of tokens, then revert with the result
function _quoteExactInput(QuoteExactParams memory params) public selfOnly returns (bytes memory) {
function _quoteExactInput(QuoteExactParams calldata params) public selfOnly returns (bytes memory) {
uint256 pathLength = params.path.length;

QuoteResult memory result = QuoteResult({
Expand Down Expand Up @@ -198,7 +198,7 @@ contract Quoter is IQuoter, SafeCallback {
}

/// @dev quote an ExactInput swap on a pool, then revert with the result
function _quoteExactInputSingle(QuoteExactSingleParams memory params) public selfOnly returns (bytes memory) {
function _quoteExactInputSingle(QuoteExactSingleParams calldata params) public selfOnly returns (bytes memory) {
(, int24 tickBefore,,) = poolManager.getSlot0(params.poolKey.toId());

(BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap(
Expand All @@ -223,7 +223,7 @@ contract Quoter is IQuoter, SafeCallback {
}

/// @dev quote an ExactOutput swap along a path of tokens, then revert with the result
function _quoteExactOutput(QuoteExactParams memory params) public selfOnly returns (bytes memory) {
function _quoteExactOutput(QuoteExactParams calldata params) public selfOnly returns (bytes memory) {
uint256 pathLength = params.path.length;

QuoteResult memory result = QuoteResult({
Expand Down Expand Up @@ -269,7 +269,7 @@ contract Quoter is IQuoter, SafeCallback {
}

/// @dev quote an ExactOutput swap on a pool, then revert with the result
function _quoteExactOutputSingle(QuoteExactSingleParams memory params) public selfOnly returns (bytes memory) {
function _quoteExactOutputSingle(QuoteExactSingleParams calldata params) public selfOnly returns (bytes memory) {
// if no price limit has been specified, cache the output amount for comparison in the swap callback
if (params.sqrtPriceLimitX96 == 0) amountOutCached = params.exactAmount;

Expand Down Expand Up @@ -303,7 +303,7 @@ contract Quoter is IQuoter, SafeCallback {
bool zeroForOne,
int256 amountSpecified,
uint160 sqrtPriceLimitX96,
bytes memory hookData
bytes calldata hookData
) private returns (BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) {
deltas = poolManager.swap(
poolKey,
Expand Down
49 changes: 49 additions & 0 deletions src/libraries/CalldataDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.0;

import {PositionConfig} from "./PositionConfig.sol";
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
import {IV4Router} from "../interfaces/IV4Router.sol";

/// @title Library for abi decoding in calldata
library CalldataDecoder {
Expand Down Expand Up @@ -110,6 +111,54 @@ library CalldataDecoder {
hookData = params.toBytes(10);
}

/// @dev equivalent to: abi.decode(params, (IV4Router.ExactInputParams))
function decodeSwapExactInParams(bytes calldata params)
internal
pure
returns (IV4Router.ExactInputParams calldata swapParams)
{
// ExactInputParams is a variable length struct so we just have to look up its location
assembly ("memory-safe") {
swapParams := add(params.offset, calldataload(params.offset))
}
}

/// @dev equivalent to: abi.decode(params, (IV4Router.ExactInputSingleParams))
function decodeSwapExactInSingleParams(bytes calldata params)
internal
pure
returns (IV4Router.ExactInputSingleParams calldata swapParams)
{
// ExactInputSingleParams is a variable length struct so we just have to look up its location
assembly ("memory-safe") {
swapParams := add(params.offset, calldataload(params.offset))
}
}

/// @dev equivalent to: abi.decode(params, (IV4Router.ExactOutputParams))
function decodeSwapExactOutParams(bytes calldata params)
internal
pure
returns (IV4Router.ExactOutputParams calldata swapParams)
{
// ExactOutputParams is a variable length struct so we just have to look up its location
assembly ("memory-safe") {
swapParams := add(params.offset, calldataload(params.offset))
}
}

/// @dev equivalent to: abi.decode(params, (IV4Router.ExactInputSingleParams))
function decodeSwapExactOutSingleParams(bytes calldata params)
internal
pure
returns (IV4Router.ExactOutputSingleParams calldata swapParams)
{
// ExactOutputSingleParams is a variable length struct so we just have to look up its location
assembly ("memory-safe") {
swapParams := add(params.offset, calldataload(params.offset))
}
}

/// @dev equivalent to: abi.decode(params, (Currency)) in calldata
function decodeCurrency(bytes calldata params) internal pure returns (Currency currency) {
assembly ("memory-safe") {
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/PathKey.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct PathKey {
}

library PathKeyLib {
function getPoolAndSwapDirection(PathKey memory params, Currency currencyIn)
function getPoolAndSwapDirection(PathKey calldata params, Currency currencyIn)
internal
pure
returns (PoolKey memory poolKey, bool zeroForOne)
Expand Down
Loading
Loading