fix: Fix tests (not there yet)

Took 58 minutes
This commit is contained in:
Diana Carvalho
2025-05-16 17:57:29 +01:00
parent eeebd51114
commit d4244a7089
23 changed files with 417 additions and 300 deletions

View File

@@ -4,6 +4,7 @@ pragma solidity ^0.8.26;
import "@interfaces/IExecutor.sol"; import "@interfaces/IExecutor.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@permit2/src/interfaces/IAllowanceTransfer.sol"; import "@permit2/src/interfaces/IAllowanceTransfer.sol";
import "@openzeppelin/contracts/utils/Address.sol";
error RestrictTransferFrom__AddressZero(); error RestrictTransferFrom__AddressZero();
error RestrictTransferFrom__ExceededTransferFromAllowance(); error RestrictTransferFrom__ExceededTransferFromAllowance();
@@ -57,10 +58,10 @@ contract RestrictTransferFrom {
) internal { ) internal {
assembly { assembly {
tstore(_TOKEN_IN_SLOT, tokenIn) tstore(_TOKEN_IN_SLOT, tokenIn)
tstore(_AMOUNT_IN_SLOT, amountIn) tstore(_AMOUNT_ALLOWED_SLOT, amountIn)
tstore(_IS_PERMIT2_SLOT, isPermit2) tstore(_IS_PERMIT2_SLOT, isPermit2)
tstore(_SENDER_SLOT, caller()) tstore(_SENDER_SLOT, caller())
tstore(_IS_TRANSFER_EXECUTED_SLOT, false) tstore(_AMOUNT_SPENT_SLOT, 0)
} }
} }
@@ -71,18 +72,20 @@ contract RestrictTransferFrom {
address tokenIn, address tokenIn,
uint256 amount uint256 amount
) internal { ) internal {
if (transferType == TransferType.TransferFrom){ if (transferType == TransferType.TransferFrom) {
bool isPermit2; bool isPermit2;
address sender; address sender;
bool isTransferExecuted; bool isTransferExecuted;
uint256 amountSpent;
uint256 amountAllowed;
assembly { assembly {
tokenIn := tload(_TOKEN_IN_SLOT) tokenIn := tload(_TOKEN_IN_SLOT)
amountPermitted := tload(_AMOUNT_IN_SLOT) amountAllowed := tload(_AMOUNT_ALLOWED_SLOT)
isPermit2 := tload(_IS_PERMIT2_SLOT) isPermit2 := tload(_IS_PERMIT2_SLOT)
sender := tload(_SENDER_SLOT) sender := tload(_SENDER_SLOT)
amountSpent := tload(_IS_TRANSFER_EXECUTED_SLOT) amountSpent := tload(_AMOUNT_SPENT_SLOT)
} }
if (amount + amountSpent > amountPermitted) { if (amount + amountSpent > amountAllowed) {
revert RestrictTransferFrom__ExceededTransferFromAllowance(); revert RestrictTransferFrom__ExceededTransferFromAllowance();
} }
assembly { assembly {

View File

@@ -71,7 +71,7 @@ contract TychoRouter is
Dispatcher, Dispatcher,
Pausable, Pausable,
ReentrancyGuard, ReentrancyGuard,
RestrictTransferFrom RestrictTransferFrom
{ {
IWETH private immutable _weth; IWETH private immutable _weth;
@@ -93,7 +93,9 @@ RestrictTransferFrom
address indexed token, uint256 amount, address indexed receiver address indexed token, uint256 amount, address indexed receiver
); );
constructor(address _permit2, address weth) RestrictTransferFrom(_permit2) { constructor(address _permit2, address weth)
RestrictTransferFrom(_permit2)
{
if (_permit2 == address(0) || weth == address(0)) { if (_permit2 == address(0) || weth == address(0)) {
revert TychoRouter__AddressZero(); revert TychoRouter__AddressZero();
} }
@@ -121,8 +123,6 @@ RestrictTransferFrom
* @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver. * @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver.
* @param nTokens The total number of tokens involved in the swap graph (used to initialize arrays for internal calculations). * @param nTokens The total number of tokens involved in the swap graph (used to initialize arrays for internal calculations).
* @param receiver The address to receive the output tokens. * @param receiver The address to receive the output tokens.
* @param transferFromNeeded If true, the contract will transfer the input token from the caller to the router.
* Otherwise, assume funds are already in router or will be transferred later by the executors (This is the case for executors with callback).
* @param swaps Encoded swap graph data containing details of each swap. * @param swaps Encoded swap graph data containing details of each swap.
* *
* @return amountOut The total amount of the output token received by the receiver. * @return amountOut The total amount of the output token received by the receiver.
@@ -136,14 +136,11 @@ RestrictTransferFrom
bool unwrapEth, bool unwrapEth,
uint256 nTokens, uint256 nTokens,
address receiver, address receiver,
bool transferFromNeeded,
bytes calldata swaps bytes calldata swaps
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) { ) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver); uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
_tstoreTransferFromInfo(tokenIn, amountIn, false); _tstoreTransferFromInfo(tokenIn, amountIn, false);
if (transferFromNeeded) {
_transfer(address(this));
}
return _splitSwapChecked( return _splitSwapChecked(
amountIn, amountIn,
tokenIn, tokenIn,
@@ -178,8 +175,6 @@ RestrictTransferFrom
* @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver. * @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver.
* @param nTokens The total number of tokens involved in the swap graph (used to initialize arrays for internal calculations). * @param nTokens The total number of tokens involved in the swap graph (used to initialize arrays for internal calculations).
* @param receiver The address to receive the output tokens. * @param receiver The address to receive the output tokens.
* @param transferFromNeeded If true, the contract will transfer the input token from the caller to the router.
* Otherwise, assume funds are already in router or will be transferred later by the executors (This is the case for executors with callback).
* @param permitSingle A Permit2 structure containing token approval details for the input token. Ignored if `wrapEth` is true. * @param permitSingle A Permit2 structure containing token approval details for the input token. Ignored if `wrapEth` is true.
* @param signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true. * @param signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true.
* @param swaps Encoded swap graph data containing details of each swap. * @param swaps Encoded swap graph data containing details of each swap.
@@ -195,7 +190,6 @@ RestrictTransferFrom
bool unwrapEth, bool unwrapEth,
uint256 nTokens, uint256 nTokens,
address receiver, address receiver,
bool transferFromNeeded,
IAllowanceTransfer.PermitSingle calldata permitSingle, IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata signature, bytes calldata signature,
bytes calldata swaps bytes calldata swaps
@@ -206,9 +200,6 @@ RestrictTransferFrom
permit2.permit(msg.sender, permitSingle, signature); permit2.permit(msg.sender, permitSingle, signature);
} }
_tstoreTransferFromInfo(tokenIn, amountIn, true); _tstoreTransferFromInfo(tokenIn, amountIn, true);
if (transferFromNeeded) {
_transfer(address(this));
}
return _splitSwapChecked( return _splitSwapChecked(
amountIn, amountIn,
@@ -242,9 +233,6 @@ RestrictTransferFrom
* @param wrapEth If true, wraps the input token (native ETH) into WETH. * @param wrapEth If true, wraps the input token (native ETH) into WETH.
* @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver. * @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver.
* @param receiver The address to receive the output tokens. * @param receiver The address to receive the output tokens.
* @param transferFromNeeded If true, the contract will transfer the input token from the caller to the tokenInReceiver.
* Otherwise, assume funds are already in router or will be transferred later by the executors (This is the case for executors with callback).
* @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromNeeded` is true.
* @param swaps Encoded swap graph data containing details of each swap. * @param swaps Encoded swap graph data containing details of each swap.
* *
* @return amountOut The total amount of the output token received by the receiver. * @return amountOut The total amount of the output token received by the receiver.
@@ -257,15 +245,11 @@ RestrictTransferFrom
bool wrapEth, bool wrapEth,
bool unwrapEth, bool unwrapEth,
address receiver, address receiver,
bool transferFromNeeded,
address tokenInReceiver,
bytes calldata swaps bytes calldata swaps
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) { ) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver); uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
_tstoreTransferFromInfo(tokenIn, amountIn, false); _tstoreTransferFromInfo(tokenIn, amountIn, false);
if (transferFromNeeded) {
_transfer(tokenInReceiver);
}
return _sequentialSwapChecked( return _sequentialSwapChecked(
amountIn, amountIn,
tokenIn, tokenIn,
@@ -297,8 +281,6 @@ RestrictTransferFrom
* @param wrapEth If true, wraps the input token (native ETH) into WETH. * @param wrapEth If true, wraps the input token (native ETH) into WETH.
* @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver. * @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver.
* @param receiver The address to receive the output tokens. * @param receiver The address to receive the output tokens.
* @param transferFromNeeded If true, the contract will transfer the input token from the caller to the tokenInReceiver.
* Otherwise, assume funds are already in router or will be transferred later by the executors (This is the case for executors with callback). * @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromNeeded` is true.
* @param permitSingle A Permit2 structure containing token approval details for the input token. Ignored if `wrapEth` is true. * @param permitSingle A Permit2 structure containing token approval details for the input token. Ignored if `wrapEth` is true.
* @param signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true. * @param signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true.
* @param swaps Encoded swap graph data containing details of each swap. * @param swaps Encoded swap graph data containing details of each swap.
@@ -313,8 +295,6 @@ RestrictTransferFrom
bool wrapEth, bool wrapEth,
bool unwrapEth, bool unwrapEth,
address receiver, address receiver,
bool transferFromNeeded,
address tokenInReceiver,
IAllowanceTransfer.PermitSingle calldata permitSingle, IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata signature, bytes calldata signature,
bytes calldata swaps bytes calldata swaps
@@ -326,9 +306,7 @@ RestrictTransferFrom
} }
_tstoreTransferFromInfo(tokenIn, amountIn, true); _tstoreTransferFromInfo(tokenIn, amountIn, true);
if (transferFromNeeded) {
_transfer(tokenInReceiver);
}
return _sequentialSwapChecked( return _sequentialSwapChecked(
amountIn, amountIn,
tokenIn, tokenIn,
@@ -358,8 +336,6 @@ RestrictTransferFrom
* @param wrapEth If true, wraps the input token (native ETH) into WETH. * @param wrapEth If true, wraps the input token (native ETH) into WETH.
* @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver. * @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver.
* @param receiver The address to receive the output tokens. * @param receiver The address to receive the output tokens.
* @param transferFromNeeded If true, the contract will transfer the input token from the caller to the tokenInReceiver.
* Otherwise, assume funds are already in router or will be transferred later by the executors (This is the case for executors with callback). * @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromNeeded` is true.
* @param swapData Encoded swap details. * @param swapData Encoded swap details.
* *
* @return amountOut The total amount of the output token received by the receiver. * @return amountOut The total amount of the output token received by the receiver.
@@ -372,15 +348,11 @@ RestrictTransferFrom
bool wrapEth, bool wrapEth,
bool unwrapEth, bool unwrapEth,
address receiver, address receiver,
bool transferFromNeeded,
address tokenInReceiver,
bytes calldata swapData bytes calldata swapData
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) { ) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver); uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
_tstoreTransferFromInfo(tokenIn, amountIn, false); _tstoreTransferFromInfo(tokenIn, amountIn, false);
if (transferFromNeeded) {
_transfer(tokenInReceiver);
}
return _singleSwap( return _singleSwap(
amountIn, amountIn,
tokenIn, tokenIn,
@@ -412,8 +384,6 @@ RestrictTransferFrom
* @param wrapEth If true, wraps the input token (native ETH) into WETH. * @param wrapEth If true, wraps the input token (native ETH) into WETH.
* @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver. * @param unwrapEth If true, unwraps the resulting WETH into native ETH and sends it to the receiver.
* @param receiver The address to receive the output tokens. * @param receiver The address to receive the output tokens.
* @param transferFromNeeded If true, the contract will transfer the input token from the caller to the tokenInReceiver.
* Otherwise, assume funds are already in router or will be transferred later by the executors (This is the case for executors with callback). * @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromNeeded` is true.
* @param permitSingle A Permit2 structure containing token approval details for the input token. Ignored if `wrapEth` is true. * @param permitSingle A Permit2 structure containing token approval details for the input token. Ignored if `wrapEth` is true.
* @param signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true. * @param signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true.
* @param swapData Encoded swap details. * @param swapData Encoded swap details.
@@ -428,8 +398,6 @@ RestrictTransferFrom
bool wrapEth, bool wrapEth,
bool unwrapEth, bool unwrapEth,
address receiver, address receiver,
bool transferFromNeeded,
address tokenInReceiver,
IAllowanceTransfer.PermitSingle calldata permitSingle, IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata signature, bytes calldata signature,
bytes calldata swapData bytes calldata swapData
@@ -440,9 +408,7 @@ RestrictTransferFrom
permit2.permit(msg.sender, permitSingle, signature); permit2.permit(msg.sender, permitSingle, signature);
} }
_tstoreTransferFromInfo(tokenIn, amountIn, true); _tstoreTransferFromInfo(tokenIn, amountIn, true);
if (transferFromNeeded) {
_transfer(tokenInReceiver);
}
return _singleSwap( return _singleSwap(
amountIn, amountIn,
tokenIn, tokenIn,

View File

@@ -12,7 +12,7 @@ import {IAsset} from "@balancer-labs/v2-interfaces/contracts/vault/IAsset.sol";
import {IVault} from "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol"; import {IVault} from "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol";
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol"; import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
error BalancerV2Executor__InvalidDataLength(); error BalancerV2Executor__InvalidDataLength();
contract BalancerV2Executor is IExecutor, RestrictTransferFrom { contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
@@ -36,7 +36,7 @@ contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
TransferType transferType TransferType transferType
) = _decodeData(data); ) = _decodeData(data);
_transfer(address(this), transferType, tokenIn, givenAmount); _transfer(address(this), transferType, address(tokenIn), givenAmount);
if (approvalNeeded) { if (approvalNeeded) {
// slither-disable-next-line unused-return // slither-disable-next-line unused-return
@@ -73,7 +73,8 @@ contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
IERC20 tokenOut, IERC20 tokenOut,
bytes32 poolId, bytes32 poolId,
address receiver, address receiver,
bool approvalNeeded bool approvalNeeded,
TransferType transferType
) )
{ {
if (data.length != 93) { if (data.length != 93) {
@@ -85,5 +86,6 @@ contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
poolId = bytes32(data[40:72]); poolId = bytes32(data[40:72]);
receiver = address(bytes20(data[72:92])); receiver = address(bytes20(data[72:92]));
approvalNeeded = data[92] != 0; approvalNeeded = data[92] != 0;
transferType = TransferType(uint8(data[93]));
} }
} }

View File

@@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/Address.sol";
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol"; import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
error CurveExecutor__AddressZero(); error CurveExecutor__AddressZero();
error CurveExecutor__InvalidDataLength(); error CurveExecutor__InvalidDataLength();
interface CryptoPool { interface CryptoPool {
@@ -40,7 +40,9 @@ contract CurveExecutor is IExecutor, RestrictTransferFrom {
address public immutable nativeToken; address public immutable nativeToken;
constructor(address _nativeToken, address _permit2) RestrictTransferFrom(_permit2) { constructor(address _nativeToken, address _permit2)
RestrictTransferFrom(_permit2)
{
if (_nativeToken == address(0)) { if (_nativeToken == address(0)) {
revert CurveExecutor__AddressZero(); revert CurveExecutor__AddressZero();
} }

View File

@@ -11,7 +11,7 @@ import {SafeTransferLib} from "@solady/utils/SafeTransferLib.sol";
import {LibBytes} from "@solady/utils/LibBytes.sol"; import {LibBytes} from "@solady/utils/LibBytes.sol";
import {Config, EkuboPoolKey} from "@ekubo/types/poolKey.sol"; import {Config, EkuboPoolKey} from "@ekubo/types/poolKey.sol";
import {MAX_SQRT_RATIO, MIN_SQRT_RATIO} from "@ekubo/types/sqrtRatio.sol"; import {MAX_SQRT_RATIO, MIN_SQRT_RATIO} from "@ekubo/types/sqrtRatio.sol";
import "../RestrictTransferFrom.sol"; import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/Address.sol";
contract EkuboExecutor is contract EkuboExecutor is
@@ -19,7 +19,7 @@ contract EkuboExecutor is
ILocker, ILocker,
IPayer, IPayer,
ICallback, ICallback,
RestrictTransferFrom RestrictTransferFrom
{ {
error EkuboExecutor__InvalidDataLength(); error EkuboExecutor__InvalidDataLength();
error EkuboExecutor__CoreOnly(); error EkuboExecutor__CoreOnly();
@@ -166,11 +166,9 @@ RestrictTransferFrom
return nextAmountIn; return nextAmountIn;
} }
function _pay( function _pay(address token, uint128 amount, TransferType transferType)
address token, internal
uint128 amount, {
TransferType transferType
) internal {
address target = address(core); address target = address(core);
if (token == NATIVE_TOKEN_ADDRESS) { if (token == NATIVE_TOKEN_ADDRESS) {
@@ -198,7 +196,7 @@ RestrictTransferFrom
address token = address(bytes20(payData[12:32])); // This arg is abi-encoded address token = address(bytes20(payData[12:32])); // This arg is abi-encoded
uint128 amount = uint128(bytes16(payData[32:48])); uint128 amount = uint128(bytes16(payData[32:48]));
TransferType transferType = TransferType(uint8(payData[48])); TransferType transferType = TransferType(uint8(payData[48]));
_transfer(core, transferType, token, amount); _transfer(address(core), transferType, token, amount);
} }
// To receive withdrawals from Core // To receive withdrawals from Core

View File

@@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/Address.sol";
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol"; import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
error MaverickV2Executor__InvalidDataLength(); error MaverickV2Executor__InvalidDataLength();
error MaverickV2Executor__InvalidTarget(); error MaverickV2Executor__InvalidTarget();
error MaverickV2Executor__InvalidFactory(); error MaverickV2Executor__InvalidFactory();
@@ -15,7 +15,9 @@ contract MaverickV2Executor is IExecutor, RestrictTransferFrom {
address public immutable factory; address public immutable factory;
constructor(address _factory, address _permit2) RestrictTransferFrom(_permit2) { constructor(address _factory, address _permit2)
RestrictTransferFrom(_permit2)
{
if (_factory == address(0)) { if (_factory == address(0)) {
revert MaverickV2Executor__InvalidFactory(); revert MaverickV2Executor__InvalidFactory();
} }
@@ -48,7 +50,7 @@ contract MaverickV2Executor is IExecutor, RestrictTransferFrom {
tickLimit: tickLimit tickLimit: tickLimit
}); });
_transfer(target, transferType, tokenIn, givenAmount); _transfer(target, transferType, address(tokenIn), givenAmount);
// slither-disable-next-line unused-return // slither-disable-next-line unused-return
(, calculatedAmount) = pool.swap(receiver, swapParams, ""); (, calculatedAmount) = pool.swap(receiver, swapParams, "");

View File

@@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@uniswap-v2/contracts/interfaces/IUniswapV2Pair.sol"; import "@uniswap-v2/contracts/interfaces/IUniswapV2Pair.sol";
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol"; import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
error UniswapV2Executor__InvalidDataLength(); error UniswapV2Executor__InvalidDataLength();
error UniswapV2Executor__InvalidTarget(); error UniswapV2Executor__InvalidTarget();
error UniswapV2Executor__InvalidFactory(); error UniswapV2Executor__InvalidFactory();
error UniswapV2Executor__InvalidInitCode(); error UniswapV2Executor__InvalidInitCode();
@@ -78,7 +78,7 @@ contract UniswapV2Executor is IExecutor, RestrictTransferFrom {
address target, address target,
address receiver, address receiver,
bool zeroForOne, bool zeroForOne,
TransferType transferType, TransferType transferType
) )
{ {
if (data.length != 62) { if (data.length != 62) {

View File

@@ -51,7 +51,7 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
address receiver, address receiver,
address target, address target,
bool zeroForOne, bool zeroForOne,
uint8 transferType TransferType transferType
) = _decodeData(data); ) = _decodeData(data);
_verifyPairAddress(tokenIn, tokenOut, fee, target); _verifyPairAddress(tokenIn, tokenOut, fee, target);
@@ -60,9 +60,8 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
int256 amount1; int256 amount1;
IUniswapV3Pool pool = IUniswapV3Pool(target); IUniswapV3Pool pool = IUniswapV3Pool(target);
bytes memory callbackData = _makeV3CallbackData( bytes memory callbackData =
tokenIn, tokenOut, fee, transferType _makeV3CallbackData(tokenIn, tokenOut, fee, transferType);
);
{ {
(amount0, amount1) = pool.swap( (amount0, amount1) = pool.swap(
@@ -98,7 +97,7 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
abi.decode(msgData[4:68], (int256, int256)); abi.decode(msgData[4:68], (int256, int256));
address tokenIn = address(bytes20(msgData[132:152])); address tokenIn = address(bytes20(msgData[132:152]));
bool transferType = TransferType(uint8(msgData[175])); TransferType transferType = TransferType(uint8(msgData[175]));
verifyCallback(msgData[132:]); verifyCallback(msgData[132:]);
@@ -136,7 +135,7 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
address receiver, address receiver,
address target, address target,
bool zeroForOne, bool zeroForOne,
uint8 transferType TransferType transferType
) )
{ {
if (data.length != 85) { if (data.length != 85) {
@@ -148,18 +147,16 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
receiver = address(bytes20(data[43:63])); receiver = address(bytes20(data[43:63]));
target = address(bytes20(data[63:83])); target = address(bytes20(data[63:83]));
zeroForOne = uint8(data[83]) > 0; zeroForOne = uint8(data[83]) > 0;
transferType = uint8(data[84]); transferType = TransferType(uint8(data[84]));
} }
function _makeV3CallbackData( function _makeV3CallbackData(
address tokenIn, address tokenIn,
address tokenOut, address tokenOut,
uint24 fee, uint24 fee,
uint8 transferType TransferType transferType
) internal pure returns (bytes memory) { ) internal pure returns (bytes memory) {
return abi.encodePacked( return abi.encodePacked(tokenIn, tokenOut, fee, uint8(transferType));
tokenIn, tokenOut, fee, transferType
);
} }
function _verifyPairAddress( function _verifyPairAddress(

View File

@@ -399,7 +399,7 @@ RestrictTransferFrom
_transfer( _transfer(
address(poolManager), address(poolManager),
transferType, transferType,
address(currency), Currency.unwrap(currency),
amount amount
); );
// slither-disable-next-line unused-return // slither-disable-next-line unused-return

View File

@@ -26,8 +26,7 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
USDE_ADDR, USDE_ADDR,
USDT_ADDR, USDT_ADDR,
true, true,
true, // permit2 transferFrom to protocol RestrictTransferFrom.TransferType.TransferFrom,
false, // transfer to protocol
ALICE, ALICE,
pools pools
); );
@@ -43,8 +42,6 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
false,
address(0),
permitSingle, permitSingle,
signature, signature,
swap swap
@@ -77,8 +74,7 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
USDE_ADDR, USDE_ADDR,
WBTC_ADDR, WBTC_ADDR,
true, true,
true, // transferFrom to protocol RestrictTransferFrom.TransferType.TransferFrom,
false, // transfer to protocol
ALICE, ALICE,
pools pools
); );
@@ -89,16 +85,7 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(USDE_ADDR).approve(tychoRouterAddr, amountIn); IERC20(USDE_ADDR).approve(tychoRouterAddr, amountIn);
tychoRouter.singleSwap( tychoRouter.singleSwap(
amountIn, amountIn, USDE_ADDR, WBTC_ADDR, 118280, false, false, ALICE, swap
USDE_ADDR,
WBTC_ADDR,
118280,
false,
false,
ALICE,
false,
address(0),
swap
); );
assertEq(IERC20(WBTC_ADDR).balanceOf(ALICE), 118281); assertEq(IERC20(WBTC_ADDR).balanceOf(ALICE), 118281);
@@ -277,8 +264,7 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
ALICE, ALICE,
DAI_WETH_USV3, DAI_WETH_USV3,
zeroForOne, zeroForOne,
true, // permit2 transferFrom to protocol RestrictTransferFrom.TransferType.TransferFrom
false // transfer to protocol
); );
bytes memory swap = bytes memory swap =
encodeSingleSwap(address(usv3Executor), protocolData); encodeSingleSwap(address(usv3Executor), protocolData);
@@ -291,8 +277,6 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
false,
address(0),
permitSingle, permitSingle,
signature, signature,
swap swap

View File

@@ -22,7 +22,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
WETH_DAI_POOL, WETH_DAI_POOL,
DAI_USDC_POOL, // receiver (direct to next pool) DAI_USDC_POOL, // receiver (direct to next pool)
false, false,
false // transfer to protocol from router RestrictTransferFrom.TransferType.None // transfer to protocol from router
) )
); );
@@ -34,7 +34,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
DAI_USDC_POOL, DAI_USDC_POOL,
ALICE, ALICE,
true, true,
false // transfer to protocol from router RestrictTransferFrom.TransferType.None // transfer to protocol from router
) )
); );
return swaps; return swaps;
@@ -60,8 +60,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
permitSingle, permitSingle,
signature, signature,
pleEncode(swaps) pleEncode(swaps)
@@ -89,8 +87,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
pleEncode(swaps) pleEncode(swaps)
); );
@@ -117,8 +113,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
pleEncode(swaps) pleEncode(swaps)
); );
} }
@@ -141,8 +135,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
pleEncode(swaps) pleEncode(swaps)
); );
} }
@@ -177,8 +169,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
permitSingle, permitSingle,
signature, signature,
pleEncode(swaps) pleEncode(swaps)
@@ -208,14 +198,24 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
swaps[0] = encodeSequentialSwap( swaps[0] = encodeSequentialSwap(
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap( encodeUniswapV2Swap(
WETH_ADDR, WETH_DAI_POOL, DAI_USDC_POOL, false, true WETH_ADDR,
WETH_DAI_POOL,
DAI_USDC_POOL,
false,
RestrictTransferFrom.TransferType.Transfer
) )
); );
// DAI -> USDC // DAI -> USDC
swaps[1] = encodeSequentialSwap( swaps[1] = encodeSequentialSwap(
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, ALICE, true, false) encodeUniswapV2Swap(
DAI_ADDR,
DAI_USDC_POOL,
ALICE,
true,
RestrictTransferFrom.TransferType.None
)
); );
uint256 amountOut = tychoRouter.sequentialSwapPermit2{value: amountIn}( uint256 amountOut = tychoRouter.sequentialSwapPermit2{value: amountIn}(
@@ -226,8 +226,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
true, true,
false, false,
ALICE, ALICE,
false,
address(0),
emptyPermitSingle, emptyPermitSingle,
"", "",
pleEncode(swaps) pleEncode(swaps)
@@ -260,7 +258,11 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
swaps[0] = encodeSequentialSwap( swaps[0] = encodeSequentialSwap(
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap( encodeUniswapV2Swap(
USDC_ADDR, DAI_USDC_POOL, tychoRouterAddr, false, false USDC_ADDR,
DAI_USDC_POOL,
tychoRouterAddr,
false,
RestrictTransferFrom.TransferType.TransferFrom
) )
); );
@@ -268,7 +270,11 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
swaps[1] = encodeSequentialSwap( swaps[1] = encodeSequentialSwap(
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap( encodeUniswapV2Swap(
DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true, true DAI_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
true,
RestrictTransferFrom.TransferType.Transfer
) )
); );
@@ -280,8 +286,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
false, false,
true, true,
ALICE, ALICE,
true,
DAI_USDC_POOL,
permitSingle, permitSingle,
signature, signature,
pleEncode(swaps) pleEncode(swaps)
@@ -307,8 +311,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3, USDC_WETH_USV3,
true, true,
false, RestrictTransferFrom.TransferType.Transfer
true
); );
bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap( bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap(
@@ -317,8 +320,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3_2, USDC_WETH_USV3_2,
false, false,
false, // permit2 transferFrom to protocol RestrictTransferFrom.TransferType.Transfer
true // transfer to protocol
); );
bytes[] memory swaps = new bytes[](2); bytes[] memory swaps = new bytes[](2);

View File

@@ -26,7 +26,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
WETH_DAI_POOL, WETH_DAI_POOL,
ALICE, ALICE,
false, false,
false // funds already in WETH_DAI_POOL, no transfer necessary RestrictTransferFrom.TransferType.None // funds already in WETH_DAI_POOL, no transfer necessary
); );
bytes memory swap = bytes memory swap =
@@ -40,8 +40,6 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true, // transferFrom to WETH_DAI_POOL
WETH_DAI_POOL, // receiver of input tokens
permitSingle, permitSingle,
signature, signature,
swap swap
@@ -69,7 +67,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
WETH_DAI_POOL, WETH_DAI_POOL,
ALICE, ALICE,
false, false,
false // funds already in WETH_DAI_POOL, no transfer necessary RestrictTransferFrom.TransferType.None // funds already in WETH_DAI_POOL, no transfer necessary
); );
bytes memory swap = bytes memory swap =
@@ -84,8 +82,6 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
swap swap
); );
@@ -107,24 +103,20 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(address(tychoRouterAddr), amountIn); IERC20(WETH_ADDR).approve(address(tychoRouterAddr), amountIn);
bytes memory protocolData = bytes memory protocolData = encodeUniswapV2Swap(
encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false, false); WETH_ADDR,
WETH_DAI_POOL,
ALICE,
false,
RestrictTransferFrom.TransferType.None
);
bytes memory swap = bytes memory swap =
encodeSingleSwap(address(usv2Executor), protocolData); encodeSingleSwap(address(usv2Executor), protocolData);
vm.expectRevert(TychoRouter__UndefinedMinAmountOut.selector); vm.expectRevert(TychoRouter__UndefinedMinAmountOut.selector);
tychoRouter.singleSwap( tychoRouter.singleSwap(
amountIn, amountIn, WETH_ADDR, DAI_ADDR, 0, false, false, ALICE, swap
WETH_ADDR,
DAI_ADDR,
0,
false,
false,
ALICE,
true,
WETH_DAI_POOL,
swap
); );
} }
@@ -142,7 +134,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
WETH_DAI_POOL, WETH_DAI_POOL,
ALICE, ALICE,
false, false,
false // funds already in WETH_DAI_POOL, no transfer necessary RestrictTransferFrom.TransferType.None // funds already in WETH_DAI_POOL, no transfer necessary
); );
bytes memory swap = bytes memory swap =
@@ -158,8 +150,6 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
swap swap
); );
} }
@@ -179,7 +169,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
WETH_DAI_POOL, WETH_DAI_POOL,
ALICE, ALICE,
false, false,
false // funds already in WETH_DAI_POOL, no transfer necessary RestrictTransferFrom.TransferType.None // funds already in WETH_DAI_POOL, no transfer necessary
); );
bytes memory swap = bytes memory swap =
@@ -202,8 +192,6 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
false, false,
false, false,
ALICE, ALICE,
true,
WETH_DAI_POOL,
swap swap
); );
} }
@@ -225,8 +213,13 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
sigDeadline: 0 sigDeadline: 0
}); });
bytes memory protocolData = bytes memory protocolData = encodeUniswapV2Swap(
encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false, true); WETH_ADDR,
WETH_DAI_POOL,
ALICE,
false,
RestrictTransferFrom.TransferType.None
);
bytes memory swap = bytes memory swap =
encodeSingleSwap(address(usv2Executor), protocolData); encodeSingleSwap(address(usv2Executor), protocolData);
@@ -239,8 +232,6 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
true, true,
false, false,
ALICE, ALICE,
false,
tychoRouterAddr,
emptyPermitSingle, emptyPermitSingle,
"", "",
swap swap
@@ -266,7 +257,11 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
) = handlePermit2Approval(DAI_ADDR, tychoRouterAddr, amountIn); ) = handlePermit2Approval(DAI_ADDR, tychoRouterAddr, amountIn);
bytes memory protocolData = encodeUniswapV2Swap( bytes memory protocolData = encodeUniswapV2Swap(
DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true, false DAI_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
true,
RestrictTransferFrom.TransferType.None
); );
bytes memory swap = bytes memory swap =
@@ -280,8 +275,6 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
false, false,
true, true,
ALICE, ALICE,
true, // transferFrom to WETH_DAI_POOL
WETH_DAI_POOL, // receiver of input tokens
permitSingle, permitSingle,
signature, signature,
swap swap

View File

@@ -23,7 +23,11 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
(0xffffff * 60) / 100, // 60% (0xffffff * 60) / 100, // 60%
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap( encodeUniswapV2Swap(
WETH_ADDR, WETH_WBTC_POOL, tychoRouterAddr, false, true WETH_ADDR,
WETH_WBTC_POOL,
tychoRouterAddr,
false,
RestrictTransferFrom.TransferType.Transfer
) )
); );
// WBTC -> USDC // WBTC -> USDC
@@ -32,7 +36,13 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
uint8(2), uint8(2),
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap(WBTC_ADDR, USDC_WBTC_POOL, ALICE, true, true) encodeUniswapV2Swap(
WBTC_ADDR,
USDC_WBTC_POOL,
ALICE,
true,
RestrictTransferFrom.TransferType.Transfer
)
); );
// WETH -> DAI // WETH -> DAI
swaps[2] = encodeSplitSwap( swaps[2] = encodeSplitSwap(
@@ -41,7 +51,11 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap( encodeUniswapV2Swap(
WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false, true WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
false,
RestrictTransferFrom.TransferType.Transfer
) )
); );
@@ -51,7 +65,13 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
uint8(2), uint8(2),
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, ALICE, true, true) encodeUniswapV2Swap(
DAI_ADDR,
DAI_USDC_POOL,
ALICE,
true,
RestrictTransferFrom.TransferType.Transfer
)
); );
return swaps; return swaps;
@@ -95,7 +115,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
false, false,
4, 4,
ALICE, ALICE,
true,
permitSingle, permitSingle,
signature, signature,
pleEncode(swaps) pleEncode(swaps)
@@ -125,7 +144,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
false, false,
4, 4,
ALICE, ALICE,
true,
pleEncode(swaps) pleEncode(swaps)
); );
@@ -154,7 +172,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
false, false,
4, 4,
ALICE, ALICE,
true,
pleEncode(swaps) pleEncode(swaps)
); );
vm.stopPrank(); vm.stopPrank();
@@ -180,7 +197,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
false, false,
2, 2,
ALICE, ALICE,
true,
pleEncode(swaps) pleEncode(swaps)
); );
@@ -218,7 +234,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
false, false,
4, 4,
ALICE, ALICE,
true,
permitSingle, permitSingle,
signature, signature,
pleEncode(swaps) pleEncode(swaps)
@@ -245,8 +260,13 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
spender: address(0), spender: address(0),
sigDeadline: 0 sigDeadline: 0
}); });
bytes memory protocolData = bytes memory protocolData = encodeUniswapV2Swap(
encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false, true); WETH_ADDR,
WETH_DAI_POOL,
ALICE,
false,
RestrictTransferFrom.TransferType.Transfer
);
bytes memory swap = encodeSplitSwap( bytes memory swap = encodeSplitSwap(
uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
@@ -263,7 +283,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
false, false,
2, 2,
ALICE, ALICE,
false,
emptyPermitSingle, emptyPermitSingle,
"", "",
pleEncode(swaps) pleEncode(swaps)
@@ -291,7 +310,11 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
) = handlePermit2Approval(DAI_ADDR, tychoRouterAddr, amountIn); ) = handlePermit2Approval(DAI_ADDR, tychoRouterAddr, amountIn);
bytes memory protocolData = encodeUniswapV2Swap( bytes memory protocolData = encodeUniswapV2Swap(
DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true, true DAI_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
true,
RestrictTransferFrom.TransferType.Transfer
); );
bytes memory swap = encodeSplitSwap( bytes memory swap = encodeSplitSwap(
@@ -309,7 +332,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
true, true,
2, 2,
ALICE, ALICE,
true,
permitSingle, permitSingle,
signature, signature,
pleEncode(swaps) pleEncode(swaps)
@@ -349,8 +371,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3, USDC_WETH_USV3,
true, true,
false, // transferFrom swapper required RestrictTransferFrom.TransferType.Transfer
true // transfer from tycho router to protocol
); );
bytes memory usdcWethV3Pool2ZeroOneData = encodeUniswapV3Swap( bytes memory usdcWethV3Pool2ZeroOneData = encodeUniswapV3Swap(
@@ -359,8 +380,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3_2, USDC_WETH_USV3_2,
true, true,
false, // transferFrom swapper required RestrictTransferFrom.TransferType.Transfer
true // transfer from tycho router to protocol
); );
bytes memory wethUsdcV2OneZeroData = encodeUniswapV2Swap( bytes memory wethUsdcV2OneZeroData = encodeUniswapV2Swap(
@@ -368,7 +388,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
USDC_WETH_USV2, USDC_WETH_USV2,
tychoRouterAddr, tychoRouterAddr,
false, false,
true // transfer from tycho router to protocol RestrictTransferFrom.TransferType.Transfer
); );
bytes[] memory swaps = new bytes[](3); bytes[] memory swaps = new bytes[](3);
@@ -424,8 +444,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3, USDC_WETH_USV3,
true, true,
true, // transferFrom swapper required RestrictTransferFrom.TransferType.Transfer
false // transfer from tycho router to protocol
); );
bytes memory usdcWethV3Pool2ZeroOneData = encodeUniswapV3Swap( bytes memory usdcWethV3Pool2ZeroOneData = encodeUniswapV3Swap(
@@ -434,8 +453,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3_2, USDC_WETH_USV3_2,
true, true,
true, // transferFrom swapper required RestrictTransferFrom.TransferType.Transfer
false // transfer from tycho router to protocol
); );
bytes[] memory swaps = new bytes[](2); bytes[] memory swaps = new bytes[](2);
@@ -465,7 +483,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
false, false,
2, 2,
ALICE, ALICE,
false,
pleEncode(swaps) pleEncode(swaps)
); );
vm.stopPrank(); vm.stopPrank();
@@ -488,7 +505,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
USDC_WETH_USV2, USDC_WETH_USV2,
tychoRouterAddr, tychoRouterAddr,
true, true,
true // transfer required RestrictTransferFrom.TransferType.Transfer
); );
bytes memory usdcWethV3Pool1OneZeroData = encodeUniswapV3Swap( bytes memory usdcWethV3Pool1OneZeroData = encodeUniswapV3Swap(
@@ -497,8 +514,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3, USDC_WETH_USV3,
false, false,
false, // transferFrom required RestrictTransferFrom.TransferType.Transfer
true // transfer required
); );
bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap( bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap(
@@ -507,8 +523,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouterAddr, tychoRouterAddr,
USDC_WETH_USV3_2, USDC_WETH_USV3_2,
false, false,
false, // transferFrom required RestrictTransferFrom.TransferType.Transfer
true // transfer required
); );
bytes[] memory swaps = new bytes[](3); bytes[] memory swaps = new bytes[](3);
@@ -547,7 +562,11 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
deal(BASE_USDC, tychoRouterAddr, amountIn); deal(BASE_USDC, tychoRouterAddr, amountIn);
bytes memory protocolData = encodeUniswapV2Swap( bytes memory protocolData = encodeUniswapV2Swap(
BASE_USDC, USDC_MAG7_POOL, tychoRouterAddr, true, true BASE_USDC,
USDC_MAG7_POOL,
tychoRouterAddr,
true,
RestrictTransferFrom.TransferType.Transfer
); );
bytes memory swap = encodeSplitSwap( bytes memory swap = encodeSplitSwap(

View File

@@ -185,11 +185,10 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
address target, address target,
address receiver, address receiver,
bool zero2one, bool zero2one,
bool transferNeeded RestrictTransferFrom.TransferType transferType
) internal pure returns (bytes memory) { ) internal pure returns (bytes memory) {
return abi.encodePacked( return
tokenIn, target, receiver, zero2one, transferNeeded abi.encodePacked(tokenIn, target, receiver, zero2one, transferType);
);
} }
function encodeUniswapV3Swap( function encodeUniswapV3Swap(
@@ -198,8 +197,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
address receiver, address receiver,
address target, address target,
bool zero2one, bool zero2one,
bool transferFromNeeded, RestrictTransferFrom.TransferType transferType
bool transferNeeded
) internal view returns (bytes memory) { ) internal view returns (bytes memory) {
IUniswapV3Pool pool = IUniswapV3Pool(target); IUniswapV3Pool pool = IUniswapV3Pool(target);
return abi.encodePacked( return abi.encodePacked(
@@ -209,8 +207,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
receiver, receiver,
target, target,
zero2one, zero2one,
transferFromNeeded, transferType
transferNeeded
); );
} }
} }

View File

@@ -16,7 +16,8 @@ contract BalancerV2ExecutorExposed is BalancerV2Executor {
IERC20 tokenOut, IERC20 tokenOut,
bytes32 poolId, bytes32 poolId,
address receiver, address receiver,
bool needsApproval bool needsApproval,
TransferType transferType
) )
{ {
return _decodeData(data); return _decodeData(data);
@@ -40,7 +41,12 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
function testDecodeParams() public view { function testDecodeParams() public view {
bytes memory params = abi.encodePacked( bytes memory params = abi.encodePacked(
WETH_ADDR, BAL_ADDR, WETH_BAL_POOL_ID, address(2), true WETH_ADDR,
BAL_ADDR,
WETH_BAL_POOL_ID,
address(2),
true,
RestrictTransferFrom.TransferType.None
); );
( (
@@ -48,7 +54,8 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
IERC20 tokenOut, IERC20 tokenOut,
bytes32 poolId, bytes32 poolId,
address receiver, address receiver,
bool needsApproval bool needsApproval,
RestrictTransferFrom.TransferType transferType
) = balancerV2Exposed.decodeParams(params); ) = balancerV2Exposed.decodeParams(params);
assertEq(address(tokenIn), WETH_ADDR); assertEq(address(tokenIn), WETH_ADDR);
@@ -56,6 +63,9 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
assertEq(poolId, WETH_BAL_POOL_ID); assertEq(poolId, WETH_BAL_POOL_ID);
assertEq(receiver, address(2)); assertEq(receiver, address(2));
assertEq(needsApproval, true); assertEq(needsApproval, true);
assertEq(
uint8(transferType), uint8(RestrictTransferFrom.TransferType.None)
);
} }
function testDecodeParamsInvalidDataLength() public { function testDecodeParamsInvalidDataLength() public {
@@ -89,7 +99,8 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
IERC20 tokenOut, IERC20 tokenOut,
bytes32 poolId, bytes32 poolId,
address receiver, address receiver,
bool needsApproval bool needsApproval,
RestrictTransferFrom.TransferType transferType
) = balancerV2Exposed.decodeParams(protocolData); ) = balancerV2Exposed.decodeParams(protocolData);
assertEq(address(tokenIn), WETH_ADDR); assertEq(address(tokenIn), WETH_ADDR);
@@ -97,6 +108,9 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
assertEq(poolId, WETH_BAL_POOL_ID); assertEq(poolId, WETH_BAL_POOL_ID);
assertEq(receiver, BOB); assertEq(receiver, BOB);
assertEq(needsApproval, true); assertEq(needsApproval, true);
assertEq(
uint8(transferType), uint8(RestrictTransferFrom.TransferType.None)
);
} }
function testSwapIntegration() public { function testSwapIntegration() public {

View File

@@ -37,6 +37,7 @@ contract CurveExecutorExposed is CurveExecutor {
int128 i, int128 i,
int128 j, int128 j,
bool tokenApprovalNeeded, bool tokenApprovalNeeded,
RestrictTransferFrom.TransferType transferType,
address receiver address receiver
) )
{ {
@@ -67,6 +68,7 @@ contract CurveExecutorTest is Test, Constants {
uint8(2), uint8(2),
uint8(0), uint8(0),
true, true,
RestrictTransferFrom.TransferType.None,
ALICE ALICE
); );
@@ -78,6 +80,7 @@ contract CurveExecutorTest is Test, Constants {
int128 i, int128 i,
int128 j, int128 j,
bool tokenApprovalNeeded, bool tokenApprovalNeeded,
RestrictTransferFrom.TransferType transferType,
address receiver address receiver
) = curveExecutorExposed.decodeData(data); ) = curveExecutorExposed.decodeData(data);
@@ -88,6 +91,9 @@ contract CurveExecutorTest is Test, Constants {
assertEq(i, 2); assertEq(i, 2);
assertEq(j, 0); assertEq(j, 0);
assertEq(tokenApprovalNeeded, true); assertEq(tokenApprovalNeeded, true);
assertEq(
uint8(transferType), uint8(RestrictTransferFrom.TransferType.None)
);
assertEq(receiver, ALICE); assertEq(receiver, ALICE);
} }
@@ -96,7 +102,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(DAI_ADDR, address(curveExecutorExposed), amountIn); deal(DAI_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(DAI_ADDR, USDC_ADDR, TRIPOOL, 1, ALICE); bytes memory data = _getData(
DAI_ADDR,
USDC_ADDR,
TRIPOOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -109,8 +122,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(address(curveExecutorExposed), amountIn); deal(address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(ETH_ADDR_FOR_CURVE, STETH_ADDR, STETH_POOL, 1, ALICE); ETH_ADDR_FOR_CURVE,
STETH_ADDR,
STETH_POOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -126,8 +145,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(WETH_ADDR, address(curveExecutorExposed), amountIn); deal(WETH_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(WETH_ADDR, WBTC_ADDR, TRICRYPTO2_POOL, 3, ALICE); WETH_ADDR,
WBTC_ADDR,
TRICRYPTO2_POOL,
3,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -140,7 +165,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 100 * 10 ** 6; uint256 amountIn = 100 * 10 ** 6;
deal(USDC_ADDR, address(curveExecutorExposed), amountIn); deal(USDC_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(USDC_ADDR, SUSD_ADDR, SUSD_POOL, 1, ALICE); bytes memory data = _getData(
USDC_ADDR,
SUSD_ADDR,
SUSD_POOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -153,8 +185,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(FRAX_ADDR, address(curveExecutorExposed), amountIn); deal(FRAX_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(FRAX_ADDR, USDC_ADDR, FRAX_USDC_POOL, 1, ALICE); FRAX_ADDR,
USDC_ADDR,
FRAX_USDC_POOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -167,8 +205,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 100 * 10 ** 6; uint256 amountIn = 100 * 10 ** 6;
deal(USDC_ADDR, address(curveExecutorExposed), amountIn); deal(USDC_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(USDC_ADDR, USDE_ADDR, USDE_USDC_POOL, 1, ALICE); USDC_ADDR,
USDE_ADDR,
USDE_USDC_POOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -181,8 +225,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 100 * 10 ** 6; uint256 amountIn = 100 * 10 ** 6;
deal(DOLA_ADDR, address(curveExecutorExposed), amountIn); deal(DOLA_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(DOLA_ADDR, FRAXPYUSD_POOL, DOLA_FRAXPYUSD_POOL, 1, ALICE); DOLA_ADDR,
FRAXPYUSD_POOL,
DOLA_FRAXPYUSD_POOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -196,8 +246,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 initialBalance = address(ALICE).balance; // this address already has some ETH assigned to it uint256 initialBalance = address(ALICE).balance; // this address already has some ETH assigned to it
deal(XYO_ADDR, address(curveExecutorExposed), amountIn); deal(XYO_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(XYO_ADDR, ETH_ADDR_FOR_CURVE, ETH_XYO_POOL, 2, ALICE); XYO_ADDR,
ETH_ADDR_FOR_CURVE,
ETH_XYO_POOL,
2,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -210,8 +266,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1000 ether; uint256 amountIn = 1000 ether;
deal(BSGG_ADDR, address(curveExecutorExposed), amountIn); deal(BSGG_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(BSGG_ADDR, USDT_ADDR, BSGG_USDT_POOL, 2, ALICE); BSGG_ADDR,
USDT_ADDR,
BSGG_USDT_POOL,
2,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -224,8 +286,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(WETH_ADDR, address(curveExecutorExposed), amountIn); deal(WETH_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(WETH_ADDR, USDC_ADDR, TRICRYPTO_POOL, 2, ALICE); WETH_ADDR,
USDC_ADDR,
TRICRYPTO_POOL,
2,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -238,8 +306,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(UWU_ADDR, address(curveExecutorExposed), amountIn); deal(UWU_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(UWU_ADDR, WETH_ADDR, UWU_WETH_POOL, 2, ALICE); UWU_ADDR,
WETH_ADDR,
UWU_WETH_POOL,
2,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -252,8 +326,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(USDT_ADDR, address(curveExecutorExposed), amountIn); deal(USDT_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(USDT_ADDR, CRVUSD_ADDR, CRVUSD_USDT_POOL, 1, ALICE); USDT_ADDR,
CRVUSD_ADDR,
CRVUSD_USDT_POOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -266,8 +346,14 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 100 * 10 ** 9; // 9 decimals uint256 amountIn = 100 * 10 ** 9; // 9 decimals
deal(WTAO_ADDR, address(curveExecutorExposed), amountIn); deal(WTAO_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = bytes memory data = _getData(
_getData(WTAO_ADDR, WSTTAO_ADDR, WSTTAO_WTAO_POOL, 1, ALICE); WTAO_ADDR,
WSTTAO_ADDR,
WSTTAO_WTAO_POOL,
1,
ALICE,
RestrictTransferFrom.TransferType.None
);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data); uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -280,7 +366,8 @@ contract CurveExecutorTest is Test, Constants {
address tokenOut, address tokenOut,
address pool, address pool,
uint8 poolType, uint8 poolType,
address receiver address receiver,
RestrictTransferFrom.TransferType transferType
) internal view returns (bytes memory data) { ) internal view returns (bytes memory data) {
(int128 i, int128 j) = _getIndexes(tokenIn, tokenOut, pool); (int128 i, int128 j) = _getIndexes(tokenIn, tokenOut, pool);
data = abi.encodePacked( data = abi.encodePacked(
@@ -291,6 +378,7 @@ contract CurveExecutorTest is Test, Constants {
uint8(uint256(uint128(i))), uint8(uint256(uint128(i))),
uint8(uint256(uint128(j))), uint8(uint256(uint128(j))),
true, true,
transferType,
receiver receiver
); );
} }

View File

@@ -3,7 +3,7 @@ pragma solidity ^0.8.26;
import "../TestUtils.sol"; import "../TestUtils.sol";
import {Constants} from "../Constants.sol"; import {Constants} from "../Constants.sol";
import {EkuboExecutor} from "@src/executors/EkuboExecutor.sol"; import "@src/executors/EkuboExecutor.sol";
import {ICore} from "@ekubo/interfaces/ICore.sol"; import {ICore} from "@ekubo/interfaces/ICore.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {NATIVE_TOKEN_ADDRESS} from "@ekubo/math/constants.sol"; import {NATIVE_TOKEN_ADDRESS} from "@ekubo/math/constants.sol";
@@ -45,8 +45,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
uint256 usdcBalanceBeforeExecutor = USDC.balanceOf(address(executor)); uint256 usdcBalanceBeforeExecutor = USDC.balanceOf(address(executor));
bytes memory data = abi.encodePacked( bytes memory data = abi.encodePacked(
false, // transferFromNeeded (transfer user to core) uint8(RestrictTransferFrom.TransferType.Transfer), // transfer type (transfer from executor to core)
true, // transferNeeded (transfer from executor to core)
address(executor), // receiver address(executor), // receiver
NATIVE_TOKEN_ADDRESS, // tokenIn NATIVE_TOKEN_ADDRESS, // tokenIn
USDC_ADDR, // tokenOut USDC_ADDR, // tokenOut
@@ -83,8 +82,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
uint256 ethBalanceBeforeExecutor = address(executor).balance; uint256 ethBalanceBeforeExecutor = address(executor).balance;
bytes memory data = abi.encodePacked( bytes memory data = abi.encodePacked(
false, // transferFromNeeded (transfer user to core) uint8(RestrictTransferFrom.TransferType.Transfer), // transferNeeded (transfer from executor to core)
true, // transferNeeded (transfer from executor to core)
address(executor), // receiver address(executor), // receiver
USDC_ADDR, // tokenIn USDC_ADDR, // tokenIn
NATIVE_TOKEN_ADDRESS, // tokenOut NATIVE_TOKEN_ADDRESS, // tokenOut
@@ -142,8 +140,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
// Same test case as in swap_encoder::tests::ekubo::test_encode_swap_multi // Same test case as in swap_encoder::tests::ekubo::test_encode_swap_multi
function testMultiHopSwap() public { function testMultiHopSwap() public {
bytes memory data = abi.encodePacked( bytes memory data = abi.encodePacked(
false, // transferFromNeeded (transfer user to core) uint8(RestrictTransferFrom.TransferType.Transfer), // transferNeeded (transfer from executor to core)
true, // transferNeeded (transfer from executor to core)
address(executor), // receiver address(executor), // receiver
NATIVE_TOKEN_ADDRESS, // tokenIn NATIVE_TOKEN_ADDRESS, // tokenIn
USDC_ADDR, // tokenOut of 1st swap USDC_ADDR, // tokenOut of 1st swap

View File

@@ -17,7 +17,7 @@ contract MaverickV2ExecutorExposed is MaverickV2Executor {
IERC20 tokenIn, IERC20 tokenIn,
address target, address target,
address receiver, address receiver,
bool transferNeeded RestrictTransferFrom.TransferType transferType
) )
{ {
return _decodeData(data); return _decodeData(data);
@@ -39,16 +39,28 @@ contract MaverickV2ExecutorTest is TestUtils, Constants {
} }
function testDecodeParams() public view { function testDecodeParams() public view {
bytes memory params = bytes memory params = abi.encodePacked(
abi.encodePacked(GHO_ADDR, GHO_USDC_POOL, address(2), true); GHO_ADDR,
GHO_USDC_POOL,
address(2),
true,
RestrictTransferFrom.TransferType.Transfer
);
(IERC20 tokenIn, address target, address receiver, bool transferNeeded) (
= maverickV2Exposed.decodeParams(params); IERC20 tokenIn,
address target,
address receiver,
RestrictTransferFrom.TransferType transferType
) = maverickV2Exposed.decodeParams(params);
assertEq(address(tokenIn), GHO_ADDR); assertEq(address(tokenIn), GHO_ADDR);
assertEq(target, GHO_USDC_POOL); assertEq(target, GHO_USDC_POOL);
assertEq(receiver, address(2)); assertEq(receiver, address(2));
assertEq(transferNeeded, true); assertEq(
uint8(transferType),
uint8(RestrictTransferFrom.TransferType.Transfer)
);
} }
function testDecodeParamsInvalidDataLength() public { function testDecodeParamsInvalidDataLength() public {
@@ -61,8 +73,12 @@ contract MaverickV2ExecutorTest is TestUtils, Constants {
function testSwap() public { function testSwap() public {
uint256 amountIn = 10e18; uint256 amountIn = 10e18;
bytes memory protocolData = bytes memory protocolData = abi.encodePacked(
abi.encodePacked(GHO_ADDR, GHO_USDC_POOL, BOB, true); GHO_ADDR,
GHO_USDC_POOL,
BOB,
RestrictTransferFrom.TransferType.Transfer
);
deal(GHO_ADDR, address(maverickV2Exposed), amountIn); deal(GHO_ADDR, address(maverickV2Exposed), amountIn);
uint256 balanceBefore = USDC.balanceOf(BOB); uint256 balanceBefore = USDC.balanceOf(BOB);
@@ -79,13 +95,20 @@ contract MaverickV2ExecutorTest is TestUtils, Constants {
bytes memory protocolData = bytes memory protocolData =
loadCallDataFromFile("test_encode_maverick_v2"); loadCallDataFromFile("test_encode_maverick_v2");
(IERC20 tokenIn, address pool, address receiver, bool transferNeeded) = (
maverickV2Exposed.decodeParams(protocolData); IERC20 tokenIn,
address pool,
address receiver,
RestrictTransferFrom.TransferType transferType
) = maverickV2Exposed.decodeParams(protocolData);
assertEq(address(tokenIn), GHO_ADDR); assertEq(address(tokenIn), GHO_ADDR);
assertEq(pool, GHO_USDC_POOL); assertEq(pool, GHO_USDC_POOL);
assertEq(receiver, BOB); assertEq(receiver, BOB);
assertEq(transferNeeded, true); assertEq(
uint8(transferType),
uint8(RestrictTransferFrom.TransferType.Transfer)
);
} }
function testSwapIntegration() public { function testSwapIntegration() public {

View File

@@ -23,7 +23,7 @@ contract UniswapV2ExecutorExposed is UniswapV2Executor {
address target, address target,
address receiver, address receiver,
bool zeroForOne, bool zeroForOne,
bool transferNeeded RestrictTransferFrom.TransferType transferType
) )
{ {
return _decodeData(data); return _decodeData(data);
@@ -82,22 +82,30 @@ contract UniswapV2ExecutorTest is Constants, Permit2TestHelper, TestUtils {
} }
function testDecodeParams() public view { function testDecodeParams() public view {
bytes memory params = bytes memory params = abi.encodePacked(
abi.encodePacked(WETH_ADDR, address(2), address(3), false, true); WETH_ADDR,
address(2),
address(3),
false,
RestrictTransferFrom.TransferType.Transfer
);
( (
IERC20 tokenIn, IERC20 tokenIn,
address target, address target,
address receiver, address receiver,
bool zeroForOne, bool zeroForOne,
bool transferNeeded RestrictTransferFrom.TransferType transferType
) = uniswapV2Exposed.decodeParams(params); ) = uniswapV2Exposed.decodeParams(params);
assertEq(address(tokenIn), WETH_ADDR); assertEq(address(tokenIn), WETH_ADDR);
assertEq(target, address(2)); assertEq(target, address(2));
assertEq(receiver, address(3)); assertEq(receiver, address(3));
assertEq(zeroForOne, false); assertEq(zeroForOne, false);
assertEq(transferNeeded, true); assertEq(
uint8(transferType),
uint8(RestrictTransferFrom.TransferType.Transfer)
);
} }
function testDecodeParamsInvalidDataLength() public { function testDecodeParamsInvalidDataLength() public {
@@ -148,8 +156,13 @@ contract UniswapV2ExecutorTest is Constants, Permit2TestHelper, TestUtils {
uint256 amountIn = 10 ** 18; uint256 amountIn = 10 ** 18;
uint256 amountOut = 1847751195973566072891; uint256 amountOut = 1847751195973566072891;
bool zeroForOne = false; bool zeroForOne = false;
bytes memory protocolData = bytes memory protocolData = abi.encodePacked(
abi.encodePacked(WETH_ADDR, WETH_DAI_POOL, BOB, zeroForOne, true); WETH_ADDR,
WETH_DAI_POOL,
BOB,
zeroForOne,
RestrictTransferFrom.TransferType.Transfer
);
deal(WETH_ADDR, address(uniswapV2Exposed), amountIn); deal(WETH_ADDR, address(uniswapV2Exposed), amountIn);
uniswapV2Exposed.swap(amountIn, protocolData); uniswapV2Exposed.swap(amountIn, protocolData);
@@ -162,8 +175,13 @@ contract UniswapV2ExecutorTest is Constants, Permit2TestHelper, TestUtils {
uint256 amountIn = 10 ** 18; uint256 amountIn = 10 ** 18;
uint256 amountOut = 1847751195973566072891; uint256 amountOut = 1847751195973566072891;
bool zeroForOne = false; bool zeroForOne = false;
bytes memory protocolData = bytes memory protocolData = abi.encodePacked(
abi.encodePacked(WETH_ADDR, WETH_DAI_POOL, BOB, zeroForOne, false); WETH_ADDR,
WETH_DAI_POOL,
BOB,
zeroForOne,
RestrictTransferFrom.TransferType.None
);
deal(WETH_ADDR, address(this), amountIn); deal(WETH_ADDR, address(this), amountIn);
IERC20(WETH_ADDR).transfer(address(WETH_DAI_POOL), amountIn); IERC20(WETH_ADDR).transfer(address(WETH_DAI_POOL), amountIn);
@@ -175,21 +193,24 @@ contract UniswapV2ExecutorTest is Constants, Permit2TestHelper, TestUtils {
function testDecodeIntegration() public view { function testDecodeIntegration() public view {
bytes memory protocolData = bytes memory protocolData =
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc288e6a0c2ddd26feeb64f039a2c41296fcb3f564000000000000000000000000000000000000000010000"; hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc288e6a0c2ddd26feeb64f039a2c41296fcb3f564000000000000000000000000000000000000000010001";
( (
IERC20 tokenIn, IERC20 tokenIn,
address target, address target,
address receiver, address receiver,
bool zeroForOne, bool zeroForOne,
bool transferNeeded RestrictTransferFrom.TransferType transferType
) = uniswapV2Exposed.decodeParams(protocolData); ) = uniswapV2Exposed.decodeParams(protocolData);
assertEq(address(tokenIn), WETH_ADDR); assertEq(address(tokenIn), WETH_ADDR);
assertEq(target, 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640); assertEq(target, 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640);
assertEq(receiver, 0x0000000000000000000000000000000000000001); assertEq(receiver, 0x0000000000000000000000000000000000000001);
assertEq(zeroForOne, false); assertEq(zeroForOne, false);
assertEq(transferNeeded, false); assertEq(
uint8(transferType),
uint8(RestrictTransferFrom.TransferType.Transfer)
);
} }
function testSwapIntegration() public { function testSwapIntegration() public {
@@ -208,8 +229,13 @@ contract UniswapV2ExecutorTest is Constants, Permit2TestHelper, TestUtils {
uint256 amountIn = 10 ** 18; uint256 amountIn = 10 ** 18;
bool zeroForOne = false; bool zeroForOne = false;
address fakePool = address(new FakeUniswapV2Pool(WETH_ADDR, DAI_ADDR)); address fakePool = address(new FakeUniswapV2Pool(WETH_ADDR, DAI_ADDR));
bytes memory protocolData = bytes memory protocolData = abi.encodePacked(
abi.encodePacked(WETH_ADDR, fakePool, BOB, zeroForOne, true); WETH_ADDR,
fakePool,
BOB,
zeroForOne,
RestrictTransferFrom.TransferType.Transfer
);
deal(WETH_ADDR, address(uniswapV2Exposed), amountIn); deal(WETH_ADDR, address(uniswapV2Exposed), amountIn);
vm.expectRevert(UniswapV2Executor__InvalidTarget.selector); vm.expectRevert(UniswapV2Executor__InvalidTarget.selector);
@@ -223,8 +249,13 @@ contract UniswapV2ExecutorTest is Constants, Permit2TestHelper, TestUtils {
vm.rollFork(26857267); vm.rollFork(26857267);
uint256 amountIn = 10 * 10 ** 6; uint256 amountIn = 10 * 10 ** 6;
bool zeroForOne = true; bool zeroForOne = true;
bytes memory protocolData = bytes memory protocolData = abi.encodePacked(
abi.encodePacked(BASE_USDC, USDC_MAG7_POOL, BOB, zeroForOne, true); BASE_USDC,
USDC_MAG7_POOL,
BOB,
zeroForOne,
RestrictTransferFrom.TransferType.Transfer
);
deal(BASE_USDC, address(uniswapV2Exposed), amountIn); deal(BASE_USDC, address(uniswapV2Exposed), amountIn);

View File

@@ -22,8 +22,7 @@ contract UniswapV3ExecutorExposed is UniswapV3Executor {
address receiver, address receiver,
address target, address target,
bool zeroForOne, bool zeroForOne,
bool transferFromNeeded, RestrictTransferFrom.TransferType transferType
bool transferNeeded
) )
{ {
return _decodeData(data); return _decodeData(data);
@@ -72,8 +71,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
address(2), address(2),
address(3), address(3),
false, false,
false, RestrictTransferFrom.TransferType.Transfer
true
); );
( (
@@ -83,8 +81,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
address receiver, address receiver,
address target, address target,
bool zeroForOne, bool zeroForOne,
bool transferFromNeeded, RestrictTransferFrom.TransferType transferType
bool transferNeeded
) = uniswapV3Exposed.decodeData(data); ) = uniswapV3Exposed.decodeData(data);
assertEq(tokenIn, WETH_ADDR); assertEq(tokenIn, WETH_ADDR);
@@ -93,8 +90,10 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
assertEq(receiver, address(2)); assertEq(receiver, address(2));
assertEq(target, address(3)); assertEq(target, address(3));
assertEq(zeroForOne, false); assertEq(zeroForOne, false);
assertEq(transferFromNeeded, false); assertEq(
assertEq(transferNeeded, true); uint8(transferType),
uint8(RestrictTransferFrom.TransferType.Transfer)
);
} }
function testSwapIntegration() public { function testSwapIntegration() public {
@@ -110,8 +109,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
address(this), address(this),
DAI_WETH_USV3, DAI_WETH_USV3,
zeroForOne, zeroForOne,
false, RestrictTransferFrom.TransferType.Transfer
true
); );
uint256 amountOut = uniswapV3Exposed.swap(amountIn, data); uint256 amountOut = uniswapV3Exposed.swap(amountIn, data);
@@ -149,7 +147,11 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
vm.startPrank(DAI_WETH_USV3); vm.startPrank(DAI_WETH_USV3);
bytes memory protocolData = abi.encodePacked( bytes memory protocolData = abi.encodePacked(
WETH_ADDR, DAI_ADDR, poolFee, false, true, address(uniswapV3Exposed) WETH_ADDR,
DAI_ADDR,
poolFee,
RestrictTransferFrom.TransferType.Transfer,
address(uniswapV3Exposed)
); );
uint256 dataOffset = 3; // some offset uint256 dataOffset = 3; // some offset
uint256 dataLength = protocolData.length; uint256 dataLength = protocolData.length;
@@ -182,8 +184,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
address(this), address(this),
fakePool, fakePool,
zeroForOne, zeroForOne,
false, RestrictTransferFrom.TransferType.Transfer
true
); );
vm.expectRevert(UniswapV3Executor__InvalidTarget.selector); vm.expectRevert(UniswapV3Executor__InvalidTarget.selector);
@@ -196,8 +197,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
address receiver, address receiver,
address target, address target,
bool zero2one, bool zero2one,
bool transferFromNeeded, RestrictTransferFrom.TransferType transferType
bool transferNeeded
) internal view returns (bytes memory) { ) internal view returns (bytes memory) {
IUniswapV3Pool pool = IUniswapV3Pool(target); IUniswapV3Pool pool = IUniswapV3Pool(target);
return abi.encodePacked( return abi.encodePacked(
@@ -207,8 +207,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
receiver, receiver,
target, target,
zero2one, zero2one,
transferFromNeeded, transferType
transferNeeded
); );
} }
} }

View File

@@ -21,8 +21,7 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor {
address tokenIn, address tokenIn,
address tokenOut, address tokenOut,
bool zeroForOne, bool zeroForOne,
bool transferFromNeeded, RestrictTransferFrom.TransferType transferType,
bool transferNeeded,
address receiver, address receiver,
UniswapV4Pool[] memory pools UniswapV4Pool[] memory pools
) )
@@ -53,8 +52,6 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
int24 tickSpacing1 = 60; int24 tickSpacing1 = 60;
uint24 pool2Fee = 1000; uint24 pool2Fee = 1000;
int24 tickSpacing2 = -10; int24 tickSpacing2 = -10;
bool transferFromNeeded = false;
bool transferNeeded = true;
UniswapV4Executor.UniswapV4Pool[] memory pools = UniswapV4Executor.UniswapV4Pool[] memory pools =
new UniswapV4Executor.UniswapV4Pool[](2); new UniswapV4Executor.UniswapV4Pool[](2);
@@ -73,8 +70,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
USDE_ADDR, USDE_ADDR,
USDT_ADDR, USDT_ADDR,
zeroForOne, zeroForOne,
transferFromNeeded, RestrictTransferFrom.TransferType.Transfer,
transferNeeded,
ALICE, ALICE,
pools pools
); );
@@ -83,8 +79,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
address tokenIn, address tokenIn,
address tokenOut, address tokenOut,
bool zeroForOneDecoded, bool zeroForOneDecoded,
bool transferFromNeededDecoded, RestrictTransferFrom.TransferType transferType,
bool transferNeededDecoded,
address receiver, address receiver,
UniswapV4Executor.UniswapV4Pool[] memory decodedPools UniswapV4Executor.UniswapV4Pool[] memory decodedPools
) = uniswapV4Exposed.decodeData(data); ) = uniswapV4Exposed.decodeData(data);
@@ -92,8 +87,10 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
assertEq(tokenIn, USDE_ADDR); assertEq(tokenIn, USDE_ADDR);
assertEq(tokenOut, USDT_ADDR); assertEq(tokenOut, USDT_ADDR);
assertEq(zeroForOneDecoded, zeroForOne); assertEq(zeroForOneDecoded, zeroForOne);
assertEq(transferFromNeededDecoded, transferFromNeeded); assertEq(
assertEq(transferNeededDecoded, transferNeeded); uint8(transferType),
uint8(RestrictTransferFrom.TransferType.Transfer)
);
assertEq(receiver, ALICE); assertEq(receiver, ALICE);
assertEq(decodedPools.length, 2); assertEq(decodedPools.length, 2);
assertEq(decodedPools[0].intermediaryToken, USDT_ADDR); assertEq(decodedPools[0].intermediaryToken, USDT_ADDR);
@@ -120,7 +117,12 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
}); });
bytes memory data = UniswapV4Utils.encodeExactInput( bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDT_ADDR, true, false, true, ALICE, pools USDE_ADDR,
USDT_ADDR,
true,
RestrictTransferFrom.TransferType.Transfer,
ALICE,
pools
); );
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);
@@ -172,7 +174,12 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
}); });
bytes memory data = UniswapV4Utils.encodeExactInput( bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, WBTC_ADDR, true, false, true, ALICE, pools USDE_ADDR,
WBTC_ADDR,
true,
RestrictTransferFrom.TransferType.Transfer,
ALICE,
pools
); );
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);

View File

@@ -8,8 +8,7 @@ library UniswapV4Utils {
address tokenIn, address tokenIn,
address tokenOut, address tokenOut,
bool zeroForOne, bool zeroForOne,
bool transferFromNeeded, RestrictTransferFrom.TransferType transferType,
bool transferNeeded,
address receiver, address receiver,
UniswapV4Executor.UniswapV4Pool[] memory pools UniswapV4Executor.UniswapV4Pool[] memory pools
) public pure returns (bytes memory) { ) public pure returns (bytes memory) {
@@ -25,13 +24,7 @@ library UniswapV4Utils {
} }
return abi.encodePacked( return abi.encodePacked(
tokenIn, tokenIn, tokenOut, zeroForOne, transferType, receiver, encodedPools
tokenOut,
zeroForOne,
transferFromNeeded,
transferNeeded,
receiver,
encodedPools
); );
} }
} }

View File

@@ -575,8 +575,8 @@ impl SwapEncoder for CurveSwapEncoder {
i.to_be_bytes::<1>(), i.to_be_bytes::<1>(),
j.to_be_bytes::<1>(), j.to_be_bytes::<1>(),
approval_needed, approval_needed,
bytes_to_address(&encoding_context.receiver)?,
(encoding_context.transfer as u8).to_be_bytes(), (encoding_context.transfer as u8).to_be_bytes(),
bytes_to_address(&encoding_context.receiver)?,
); );
Ok(args.abi_encode_packed()) Ok(args.abi_encode_packed())
@@ -1386,10 +1386,10 @@ mod tests {
"01", "01",
// approval needed // approval needed
"01", "01",
// receiver,
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
// transfer type None // transfer type None
"02", "02",
// receiver,
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
)) ))
); );
} }
@@ -1456,10 +1456,10 @@ mod tests {
"00", "00",
// approval needed // approval needed
"01", "01",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
// transfer type None // transfer type None
"02", "02",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
)) ))
); );
} }
@@ -1536,10 +1536,10 @@ mod tests {
"01", "01",
// approval needed // approval needed
"01", "01",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
// transfer type None // transfer type None
"02", "02",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
)) ))
); );
} }