feat: Support new transfer logic in all executors

TODO:
- Fix failing tests
- Remove permit2 from initialization of contracts
This commit is contained in:
TAMARA LIPOWSKI
2025-05-14 20:42:19 -04:00
parent 0f9af65846
commit 27dfde3118
22 changed files with 378 additions and 462 deletions

View File

@@ -122,6 +122,8 @@ contract TychoRouter is
* @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 transferFromRequired If true, the contract will transfer the input token from the caller to the receiver. Otherwise, assume funds are already in router.
* @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromRequired` 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.
@@ -135,9 +137,14 @@ contract TychoRouter is
bool unwrapEth,
uint256 nTokens,
address receiver,
bool transferFromRequired,
address tokenInReceiver,
bytes calldata swaps
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
tstoreTransferFromInfo(tokenIn, amountIn, false, msg.sender);
if (transferFromRequired) {
_transfer(tokenInReceiver);
}
return _splitSwapChecked(
amountIn,
tokenIn,
@@ -173,6 +180,8 @@ contract TychoRouter is
* @param receiver The address to receive the output tokens.
* @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 transferFromRequired If true, the contract will transfer the input token from the caller to the receiver. Otherwise, assume funds are already in router.
* @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromRequired` 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.
@@ -188,14 +197,18 @@ contract TychoRouter is
address receiver,
IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata signature,
bool transferFromRequired,
address tokenInReceiver,
bytes calldata swaps
) external payable whenNotPaused nonReentrant returns (uint256 amountOut) {
// For native ETH, assume funds already in our router. Else, handle approval.
if (tokenIn != address(0)) {
permit2.permit(msg.sender, permitSingle, signature);
}
tstoreTransferFromInfo(tokenIn, amountIn, true, msg.sender);
if (transferFromRequired) {
_transfer(tokenInReceiver);
}
return _splitSwapChecked(
amountIn,
@@ -228,6 +241,8 @@ contract TychoRouter is
* @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 transferFromRequired If true, the contract will transfer the input token from the caller to the receiver. Otherwise, assume funds are already in router.
* @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromRequired` 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.
@@ -240,9 +255,14 @@ contract TychoRouter is
bool wrapEth,
bool unwrapEth,
address receiver,
bool transferFromRequired,
address tokenInReceiver,
bytes calldata swaps
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
tstoreTransferFromInfo(tokenIn, amountIn, false, msg.sender);
if (transferFromRequired) {
_transfer(tokenInReceiver);
}
return _sequentialSwapChecked(
amountIn,
tokenIn,
@@ -275,6 +295,8 @@ contract TychoRouter is
* @param receiver The address to receive the output tokens.
* @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 transferFromRequired If true, the contract will transfer the input token from the caller to the receiver. Otherwise, assume funds are already in router.
* @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromRequired` 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.
@@ -289,6 +311,8 @@ contract TychoRouter is
address receiver,
IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata signature,
bool transferFromRequired,
address tokenInReceiver,
bytes calldata swaps
) external payable whenNotPaused nonReentrant returns (uint256 amountOut) {
// For native ETH, assume funds already in our router. Else, handle approval.
@@ -297,6 +321,9 @@ contract TychoRouter is
}
tstoreTransferFromInfo(tokenIn, amountIn, true, msg.sender);
if (transferFromRequired) {
_transfer(tokenInReceiver);
}
return _sequentialSwapChecked(
amountIn,
tokenIn,
@@ -325,6 +352,8 @@ contract TychoRouter is
* @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 transferFromRequired If true, the contract will transfer the input token from the caller to the receiver. Otherwise, assume funds are already in router.
* @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromRequired` is true.
* @param swapData Encoded swap details.
*
* @return amountOut The total amount of the output token received by the receiver.
@@ -337,13 +366,13 @@ contract TychoRouter is
bool wrapEth,
bool unwrapEth,
address receiver,
bool inTransferNeeded,
address fundsReceiver,
bool transferFromRequired,
address tokenInReceiver,
bytes calldata swapData
) public payable whenNotPaused nonReentrant returns (uint256 amountOut) {
tstoreTransferFromInfo(tokenIn, amountIn, false, msg.sender);
if (inTransferNeeded) {
_transfer(fundsReceiver);
if (transferFromRequired) {
_transfer(tokenInReceiver);
}
return _singleSwap(
amountIn,
@@ -377,6 +406,8 @@ contract TychoRouter is
* @param receiver The address to receive the output tokens.
* @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 transferFromRequired If true, the contract will transfer the input token from the caller to the receiver. Otherwise, assume funds are already in router.
* @param tokenInReceiver The address to receive the input tokens. This is used when `transferFromRequired` is true.
* @param swapData Encoded swap details.
*
* @return amountOut The total amount of the output token received by the receiver.
@@ -391,6 +422,8 @@ contract TychoRouter is
address receiver,
IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata signature,
bool transferFromRequired,
address tokenInReceiver,
bytes calldata swapData
) external payable whenNotPaused nonReentrant returns (uint256 amountOut) {
// For native ETH, assume funds already in our router. Else, handle approval.
@@ -398,6 +431,9 @@ contract TychoRouter is
permit2.permit(msg.sender, permitSingle, signature);
}
tstoreTransferFromInfo(tokenIn, amountIn, true, msg.sender);
if (transferFromRequired) {
_transfer(tokenInReceiver);
}
return _singleSwap(
amountIn,
tokenIn,