// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@permit2/src/interfaces/IAllowanceTransfer.sol"; error TokenTransfer__AddressZero(); contract TokenTransfer { using SafeERC20 for IERC20; IAllowanceTransfer public immutable permit2; enum TransferType { // Assume funds are in the TychoRouter - transfer into the pool TRANSFER_TO_PROTOCOL, // Assume funds are in msg.sender's wallet - transferFrom into the pool TRANSFER_FROM_TO_PROTOCOL, // Assume funds are in msg.sender's wallet - permit2TransferFrom into the pool TRANSFER_PERMIT2_TO_PROTOCOL, // Assume funds are in msg.sender's wallet - but the pool requires it to be // in the router contract when calling swap - transferFrom into the router // contract TRANSFER_FROM_TO_ROUTER, // Assume funds are in msg.sender's wallet - but the pool requires it to be // in the router contract when calling swap - transferFrom into the router // contract using permit2 TRANSFER_PERMIT2_TO_ROUTER, // Assume funds have already been transferred into the pool. Do nothing. NONE } constructor(address _permit2) { if (_permit2 == address(0)) { revert TokenTransfer__AddressZero(); } permit2 = IAllowanceTransfer(_permit2); } function _transfer( address tokenIn, address sender, address receiver, uint256 amount, TransferType transferType ) internal { if (transferType == TransferType.TRANSFER_TO_PROTOCOL) { if (tokenIn == address(0)) { payable(receiver).transfer(amount); } else { IERC20(tokenIn).safeTransfer(receiver, amount); } } else if (transferType == TransferType.TRANSFER_FROM_TO_PROTOCOL) { // slither-disable-next-line arbitrary-send-erc20 IERC20(tokenIn).safeTransferFrom(sender, receiver, amount); } else if (transferType == TransferType.TRANSFER_PERMIT2_TO_PROTOCOL) { // Permit2.permit is already called from the TychoRouter permit2.transferFrom(sender, receiver, uint160(amount), tokenIn); } else if (transferType == TransferType.TRANSFER_FROM_TO_ROUTER) { // slither-disable-next-line arbitrary-send-erc20 IERC20(tokenIn).safeTransferFrom(sender, address(this), amount); } else if (transferType == TransferType.TRANSFER_PERMIT2_TO_ROUTER) { // Permit2.permit is already called from the TychoRouter permit2.transferFrom( sender, address(this), uint160(amount), tokenIn ); } } }