fix: Fix tests (not there yet)
Took 58 minutes
This commit is contained in:
@@ -4,6 +4,7 @@ pragma solidity ^0.8.26;
|
||||
import "@interfaces/IExecutor.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "@permit2/src/interfaces/IAllowanceTransfer.sol";
|
||||
import "@openzeppelin/contracts/utils/Address.sol";
|
||||
|
||||
error RestrictTransferFrom__AddressZero();
|
||||
error RestrictTransferFrom__ExceededTransferFromAllowance();
|
||||
@@ -57,10 +58,10 @@ contract RestrictTransferFrom {
|
||||
) internal {
|
||||
assembly {
|
||||
tstore(_TOKEN_IN_SLOT, tokenIn)
|
||||
tstore(_AMOUNT_IN_SLOT, amountIn)
|
||||
tstore(_AMOUNT_ALLOWED_SLOT, amountIn)
|
||||
tstore(_IS_PERMIT2_SLOT, isPermit2)
|
||||
tstore(_SENDER_SLOT, caller())
|
||||
tstore(_IS_TRANSFER_EXECUTED_SLOT, false)
|
||||
tstore(_AMOUNT_SPENT_SLOT, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,18 +72,20 @@ contract RestrictTransferFrom {
|
||||
address tokenIn,
|
||||
uint256 amount
|
||||
) internal {
|
||||
if (transferType == TransferType.TransferFrom){
|
||||
if (transferType == TransferType.TransferFrom) {
|
||||
bool isPermit2;
|
||||
address sender;
|
||||
bool isTransferExecuted;
|
||||
uint256 amountSpent;
|
||||
uint256 amountAllowed;
|
||||
assembly {
|
||||
tokenIn := tload(_TOKEN_IN_SLOT)
|
||||
amountPermitted := tload(_AMOUNT_IN_SLOT)
|
||||
amountAllowed := tload(_AMOUNT_ALLOWED_SLOT)
|
||||
isPermit2 := tload(_IS_PERMIT2_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();
|
||||
}
|
||||
assembly {
|
||||
|
||||
@@ -71,7 +71,7 @@ contract TychoRouter is
|
||||
Dispatcher,
|
||||
Pausable,
|
||||
ReentrancyGuard,
|
||||
RestrictTransferFrom
|
||||
RestrictTransferFrom
|
||||
{
|
||||
IWETH private immutable _weth;
|
||||
|
||||
@@ -93,7 +93,9 @@ RestrictTransferFrom
|
||||
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)) {
|
||||
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 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 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.
|
||||
*
|
||||
* @return amountOut The total amount of the output token received by the receiver.
|
||||
@@ -136,14 +136,11 @@ RestrictTransferFrom
|
||||
bool unwrapEth,
|
||||
uint256 nTokens,
|
||||
address receiver,
|
||||
bool transferFromNeeded,
|
||||
bytes calldata swaps
|
||||
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
|
||||
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
|
||||
_tstoreTransferFromInfo(tokenIn, amountIn, false);
|
||||
if (transferFromNeeded) {
|
||||
_transfer(address(this));
|
||||
}
|
||||
|
||||
return _splitSwapChecked(
|
||||
amountIn,
|
||||
tokenIn,
|
||||
@@ -178,8 +175,6 @@ RestrictTransferFrom
|
||||
* @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 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 signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true.
|
||||
* @param swaps Encoded swap graph data containing details of each swap.
|
||||
@@ -195,7 +190,6 @@ RestrictTransferFrom
|
||||
bool unwrapEth,
|
||||
uint256 nTokens,
|
||||
address receiver,
|
||||
bool transferFromNeeded,
|
||||
IAllowanceTransfer.PermitSingle calldata permitSingle,
|
||||
bytes calldata signature,
|
||||
bytes calldata swaps
|
||||
@@ -206,9 +200,6 @@ RestrictTransferFrom
|
||||
permit2.permit(msg.sender, permitSingle, signature);
|
||||
}
|
||||
_tstoreTransferFromInfo(tokenIn, amountIn, true);
|
||||
if (transferFromNeeded) {
|
||||
_transfer(address(this));
|
||||
}
|
||||
|
||||
return _splitSwapChecked(
|
||||
amountIn,
|
||||
@@ -242,9 +233,6 @@ RestrictTransferFrom
|
||||
* @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 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.
|
||||
*
|
||||
* @return amountOut The total amount of the output token received by the receiver.
|
||||
@@ -257,15 +245,11 @@ RestrictTransferFrom
|
||||
bool wrapEth,
|
||||
bool unwrapEth,
|
||||
address receiver,
|
||||
bool transferFromNeeded,
|
||||
address tokenInReceiver,
|
||||
bytes calldata swaps
|
||||
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
|
||||
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
|
||||
_tstoreTransferFromInfo(tokenIn, amountIn, false);
|
||||
if (transferFromNeeded) {
|
||||
_transfer(tokenInReceiver);
|
||||
}
|
||||
|
||||
return _sequentialSwapChecked(
|
||||
amountIn,
|
||||
tokenIn,
|
||||
@@ -297,8 +281,6 @@ RestrictTransferFrom
|
||||
* @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 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 signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true.
|
||||
* @param swaps Encoded swap graph data containing details of each swap.
|
||||
@@ -313,8 +295,6 @@ RestrictTransferFrom
|
||||
bool wrapEth,
|
||||
bool unwrapEth,
|
||||
address receiver,
|
||||
bool transferFromNeeded,
|
||||
address tokenInReceiver,
|
||||
IAllowanceTransfer.PermitSingle calldata permitSingle,
|
||||
bytes calldata signature,
|
||||
bytes calldata swaps
|
||||
@@ -326,9 +306,7 @@ RestrictTransferFrom
|
||||
}
|
||||
|
||||
_tstoreTransferFromInfo(tokenIn, amountIn, true);
|
||||
if (transferFromNeeded) {
|
||||
_transfer(tokenInReceiver);
|
||||
}
|
||||
|
||||
return _sequentialSwapChecked(
|
||||
amountIn,
|
||||
tokenIn,
|
||||
@@ -358,8 +336,6 @@ RestrictTransferFrom
|
||||
* @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 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.
|
||||
*
|
||||
* @return amountOut The total amount of the output token received by the receiver.
|
||||
@@ -372,15 +348,11 @@ RestrictTransferFrom
|
||||
bool wrapEth,
|
||||
bool unwrapEth,
|
||||
address receiver,
|
||||
bool transferFromNeeded,
|
||||
address tokenInReceiver,
|
||||
bytes calldata swapData
|
||||
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
|
||||
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
|
||||
_tstoreTransferFromInfo(tokenIn, amountIn, false);
|
||||
if (transferFromNeeded) {
|
||||
_transfer(tokenInReceiver);
|
||||
}
|
||||
|
||||
return _singleSwap(
|
||||
amountIn,
|
||||
tokenIn,
|
||||
@@ -412,8 +384,6 @@ RestrictTransferFrom
|
||||
* @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 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 signature A valid signature authorizing the Permit2 approval. Ignored if `wrapEth` is true.
|
||||
* @param swapData Encoded swap details.
|
||||
@@ -428,8 +398,6 @@ RestrictTransferFrom
|
||||
bool wrapEth,
|
||||
bool unwrapEth,
|
||||
address receiver,
|
||||
bool transferFromNeeded,
|
||||
address tokenInReceiver,
|
||||
IAllowanceTransfer.PermitSingle calldata permitSingle,
|
||||
bytes calldata signature,
|
||||
bytes calldata swapData
|
||||
@@ -440,9 +408,7 @@ RestrictTransferFrom
|
||||
permit2.permit(msg.sender, permitSingle, signature);
|
||||
}
|
||||
_tstoreTransferFromInfo(tokenIn, amountIn, true);
|
||||
if (transferFromNeeded) {
|
||||
_transfer(tokenInReceiver);
|
||||
}
|
||||
|
||||
return _singleSwap(
|
||||
amountIn,
|
||||
tokenIn,
|
||||
|
||||
@@ -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 {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
|
||||
|
||||
error BalancerV2Executor__InvalidDataLength();
|
||||
error BalancerV2Executor__InvalidDataLength();
|
||||
|
||||
contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
|
||||
using SafeERC20 for IERC20;
|
||||
@@ -36,7 +36,7 @@ contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
|
||||
TransferType transferType
|
||||
) = _decodeData(data);
|
||||
|
||||
_transfer(address(this), transferType, tokenIn, givenAmount);
|
||||
_transfer(address(this), transferType, address(tokenIn), givenAmount);
|
||||
|
||||
if (approvalNeeded) {
|
||||
// slither-disable-next-line unused-return
|
||||
@@ -73,7 +73,8 @@ contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
|
||||
IERC20 tokenOut,
|
||||
bytes32 poolId,
|
||||
address receiver,
|
||||
bool approvalNeeded
|
||||
bool approvalNeeded,
|
||||
TransferType transferType
|
||||
)
|
||||
{
|
||||
if (data.length != 93) {
|
||||
@@ -85,5 +86,6 @@ contract BalancerV2Executor is IExecutor, RestrictTransferFrom {
|
||||
poolId = bytes32(data[40:72]);
|
||||
receiver = address(bytes20(data[72:92]));
|
||||
approvalNeeded = data[92] != 0;
|
||||
transferType = TransferType(uint8(data[93]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "@openzeppelin/contracts/utils/Address.sol";
|
||||
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
|
||||
|
||||
error CurveExecutor__AddressZero();
|
||||
error CurveExecutor__AddressZero();
|
||||
error CurveExecutor__InvalidDataLength();
|
||||
|
||||
interface CryptoPool {
|
||||
@@ -40,7 +40,9 @@ contract CurveExecutor is IExecutor, RestrictTransferFrom {
|
||||
|
||||
address public immutable nativeToken;
|
||||
|
||||
constructor(address _nativeToken, address _permit2) RestrictTransferFrom(_permit2) {
|
||||
constructor(address _nativeToken, address _permit2)
|
||||
RestrictTransferFrom(_permit2)
|
||||
{
|
||||
if (_nativeToken == address(0)) {
|
||||
revert CurveExecutor__AddressZero();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {SafeTransferLib} from "@solady/utils/SafeTransferLib.sol";
|
||||
import {LibBytes} from "@solady/utils/LibBytes.sol";
|
||||
import {Config, EkuboPoolKey} from "@ekubo/types/poolKey.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";
|
||||
|
||||
contract EkuboExecutor is
|
||||
@@ -19,7 +19,7 @@ contract EkuboExecutor is
|
||||
ILocker,
|
||||
IPayer,
|
||||
ICallback,
|
||||
RestrictTransferFrom
|
||||
RestrictTransferFrom
|
||||
{
|
||||
error EkuboExecutor__InvalidDataLength();
|
||||
error EkuboExecutor__CoreOnly();
|
||||
@@ -166,11 +166,9 @@ RestrictTransferFrom
|
||||
return nextAmountIn;
|
||||
}
|
||||
|
||||
function _pay(
|
||||
address token,
|
||||
uint128 amount,
|
||||
TransferType transferType
|
||||
) internal {
|
||||
function _pay(address token, uint128 amount, TransferType transferType)
|
||||
internal
|
||||
{
|
||||
address target = address(core);
|
||||
|
||||
if (token == NATIVE_TOKEN_ADDRESS) {
|
||||
@@ -198,7 +196,7 @@ RestrictTransferFrom
|
||||
address token = address(bytes20(payData[12:32])); // This arg is abi-encoded
|
||||
uint128 amount = uint128(bytes16(payData[32:48]));
|
||||
TransferType transferType = TransferType(uint8(payData[48]));
|
||||
_transfer(core, transferType, token, amount);
|
||||
_transfer(address(core), transferType, token, amount);
|
||||
}
|
||||
|
||||
// To receive withdrawals from Core
|
||||
|
||||
@@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "@openzeppelin/contracts/utils/Address.sol";
|
||||
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
|
||||
|
||||
error MaverickV2Executor__InvalidDataLength();
|
||||
error MaverickV2Executor__InvalidDataLength();
|
||||
error MaverickV2Executor__InvalidTarget();
|
||||
error MaverickV2Executor__InvalidFactory();
|
||||
|
||||
@@ -15,7 +15,9 @@ contract MaverickV2Executor is IExecutor, RestrictTransferFrom {
|
||||
|
||||
address public immutable factory;
|
||||
|
||||
constructor(address _factory, address _permit2) RestrictTransferFrom(_permit2) {
|
||||
constructor(address _factory, address _permit2)
|
||||
RestrictTransferFrom(_permit2)
|
||||
{
|
||||
if (_factory == address(0)) {
|
||||
revert MaverickV2Executor__InvalidFactory();
|
||||
}
|
||||
@@ -48,7 +50,7 @@ contract MaverickV2Executor is IExecutor, RestrictTransferFrom {
|
||||
tickLimit: tickLimit
|
||||
});
|
||||
|
||||
_transfer(target, transferType, tokenIn, givenAmount);
|
||||
_transfer(target, transferType, address(tokenIn), givenAmount);
|
||||
|
||||
// slither-disable-next-line unused-return
|
||||
(, calculatedAmount) = pool.swap(receiver, swapParams, "");
|
||||
|
||||
@@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "@uniswap-v2/contracts/interfaces/IUniswapV2Pair.sol";
|
||||
import {RestrictTransferFrom} from "../RestrictTransferFrom.sol";
|
||||
|
||||
error UniswapV2Executor__InvalidDataLength();
|
||||
error UniswapV2Executor__InvalidDataLength();
|
||||
error UniswapV2Executor__InvalidTarget();
|
||||
error UniswapV2Executor__InvalidFactory();
|
||||
error UniswapV2Executor__InvalidInitCode();
|
||||
@@ -78,7 +78,7 @@ contract UniswapV2Executor is IExecutor, RestrictTransferFrom {
|
||||
address target,
|
||||
address receiver,
|
||||
bool zeroForOne,
|
||||
TransferType transferType,
|
||||
TransferType transferType
|
||||
)
|
||||
{
|
||||
if (data.length != 62) {
|
||||
|
||||
@@ -51,7 +51,7 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
|
||||
address receiver,
|
||||
address target,
|
||||
bool zeroForOne,
|
||||
uint8 transferType
|
||||
TransferType transferType
|
||||
) = _decodeData(data);
|
||||
|
||||
_verifyPairAddress(tokenIn, tokenOut, fee, target);
|
||||
@@ -60,9 +60,8 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
|
||||
int256 amount1;
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(target);
|
||||
|
||||
bytes memory callbackData = _makeV3CallbackData(
|
||||
tokenIn, tokenOut, fee, transferType
|
||||
);
|
||||
bytes memory callbackData =
|
||||
_makeV3CallbackData(tokenIn, tokenOut, fee, transferType);
|
||||
|
||||
{
|
||||
(amount0, amount1) = pool.swap(
|
||||
@@ -98,7 +97,7 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
|
||||
abi.decode(msgData[4:68], (int256, int256));
|
||||
|
||||
address tokenIn = address(bytes20(msgData[132:152]));
|
||||
bool transferType = TransferType(uint8(msgData[175]));
|
||||
TransferType transferType = TransferType(uint8(msgData[175]));
|
||||
|
||||
verifyCallback(msgData[132:]);
|
||||
|
||||
@@ -136,7 +135,7 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
|
||||
address receiver,
|
||||
address target,
|
||||
bool zeroForOne,
|
||||
uint8 transferType
|
||||
TransferType transferType
|
||||
)
|
||||
{
|
||||
if (data.length != 85) {
|
||||
@@ -148,18 +147,16 @@ contract UniswapV3Executor is IExecutor, ICallback, RestrictTransferFrom {
|
||||
receiver = address(bytes20(data[43:63]));
|
||||
target = address(bytes20(data[63:83]));
|
||||
zeroForOne = uint8(data[83]) > 0;
|
||||
transferType = uint8(data[84]);
|
||||
transferType = TransferType(uint8(data[84]));
|
||||
}
|
||||
|
||||
function _makeV3CallbackData(
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
uint24 fee,
|
||||
uint8 transferType
|
||||
TransferType transferType
|
||||
) internal pure returns (bytes memory) {
|
||||
return abi.encodePacked(
|
||||
tokenIn, tokenOut, fee, transferType
|
||||
);
|
||||
return abi.encodePacked(tokenIn, tokenOut, fee, uint8(transferType));
|
||||
}
|
||||
|
||||
function _verifyPairAddress(
|
||||
|
||||
@@ -399,7 +399,7 @@ RestrictTransferFrom
|
||||
_transfer(
|
||||
address(poolManager),
|
||||
transferType,
|
||||
address(currency),
|
||||
Currency.unwrap(currency),
|
||||
amount
|
||||
);
|
||||
// slither-disable-next-line unused-return
|
||||
|
||||
Reference in New Issue
Block a user