feat: add back uniswapV3SwapCallback in router
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
pragma solidity ^0.8.26;
|
pragma solidity ^0.8.26;
|
||||||
|
|
||||||
import "@interfaces/IExecutor.sol";
|
import "@interfaces/IExecutor.sol";
|
||||||
|
import "forge-std/console.sol";
|
||||||
|
|
||||||
error ExecutionDispatcher__UnapprovedExecutor();
|
error ExecutionDispatcher__UnapprovedExecutor();
|
||||||
error ExecutionDispatcher__NonContractExecutor();
|
error ExecutionDispatcher__NonContractExecutor();
|
||||||
@@ -80,19 +81,25 @@ contract ExecutionDispatcher {
|
|||||||
calculatedAmount = abi.decode(result, (uint256));
|
calculatedAmount = abi.decode(result, (uint256));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _handleCallback(bytes calldata data) internal {
|
function _handleCallback(bytes4 selector, bytes memory data) internal {
|
||||||
// Take last 20 bytes (excluding the final byte)
|
// Access the last 20 bytes of the bytes memory data using assembly
|
||||||
address executor =
|
address executor;
|
||||||
address(bytes20(data[data.length - 21:data.length - 1]));
|
// slither-disable-next-line assembly
|
||||||
|
assembly {
|
||||||
|
let pos := sub(add(add(data, 0x20), mload(data)), 20)
|
||||||
|
executor := mload(pos)
|
||||||
|
executor := shr(96, executor)
|
||||||
|
}
|
||||||
|
|
||||||
if (!executors[executor]) {
|
if (!executors[executor]) {
|
||||||
revert ExecutionDispatcher__UnapprovedExecutor();
|
revert ExecutionDispatcher__UnapprovedExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selector =
|
||||||
|
selector == bytes4(0) ? IExecutor.handleCallback.selector : selector;
|
||||||
// slither-disable-next-line controlled-delegatecall,low-level-calls
|
// slither-disable-next-line controlled-delegatecall,low-level-calls
|
||||||
(bool success, bytes memory result) = executor.delegatecall(
|
(bool success, bytes memory result) =
|
||||||
abi.encodeWithSelector(IExecutor.handleCallback.selector, data)
|
executor.delegatecall(abi.encodeWithSelector(selector, data));
|
||||||
);
|
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
revert(
|
revert(
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import "./ExecutionDispatcher.sol";
|
|||||||
import {LibSwap} from "../lib/LibSwap.sol";
|
import {LibSwap} from "../lib/LibSwap.sol";
|
||||||
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
||||||
import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol";
|
import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol";
|
||||||
|
import "forge-std/console.sol";
|
||||||
|
|
||||||
error TychoRouter__WithdrawalFailed();
|
error TychoRouter__WithdrawalFailed();
|
||||||
error TychoRouter__AddressZero();
|
error TychoRouter__AddressZero();
|
||||||
@@ -228,9 +229,10 @@ contract TychoRouter is
|
|||||||
* This function will static call a verifier contract and should revert if the
|
* This function will static call a verifier contract and should revert if the
|
||||||
* caller is not a pool.
|
* caller is not a pool.
|
||||||
*/
|
*/
|
||||||
fallback() external {
|
// fallback() external {
|
||||||
_handleCallback(msg.data);
|
// bytes4 selector = bytes4(msg.data[:4]);
|
||||||
}
|
// _handleCallback(selector, msg.data[4:]);
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Pauses the contract
|
* @dev Pauses the contract
|
||||||
@@ -388,6 +390,20 @@ contract TychoRouter is
|
|||||||
*/
|
*/
|
||||||
receive() external payable {}
|
receive() external payable {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Called by UniswapV3 pool when swapping on it.
|
||||||
|
* See in IUniswapV3SwapCallback for documentation.
|
||||||
|
*/
|
||||||
|
function uniswapV3SwapCallback(
|
||||||
|
int256 amount0Delta,
|
||||||
|
int256 amount1Delta,
|
||||||
|
bytes calldata msgData
|
||||||
|
) external {
|
||||||
|
_handleCallback(
|
||||||
|
bytes4(0), abi.encodePacked(amount0Delta, amount1Delta, msgData)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function _unlockCallback(bytes calldata data)
|
function _unlockCallback(bytes calldata data)
|
||||||
internal
|
internal
|
||||||
override
|
override
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import "@interfaces/IExecutor.sol";
|
|||||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||||
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
||||||
import "@uniswap/v3-updated/CallbackValidationV2.sol";
|
import "@uniswap/v3-updated/CallbackValidationV2.sol";
|
||||||
|
import "forge-std/console.sol";
|
||||||
|
|
||||||
error UniswapV3Executor__InvalidDataLength();
|
error UniswapV3Executor__InvalidDataLength();
|
||||||
error UniswapV3Executor__InvalidFactory();
|
error UniswapV3Executor__InvalidFactory();
|
||||||
@@ -69,11 +70,10 @@ contract UniswapV3Executor is IExecutor {
|
|||||||
external
|
external
|
||||||
returns (bytes memory result)
|
returns (bytes memory result)
|
||||||
{
|
{
|
||||||
// Skip first 4 bytes of function selector and decode the two int256 values
|
|
||||||
(int256 amount0Delta, int256 amount1Delta) =
|
(int256 amount0Delta, int256 amount1Delta) =
|
||||||
abi.decode(msgData[4:68], (int256, int256));
|
abi.decode(msgData[:64], (int256, int256));
|
||||||
|
|
||||||
bytes calldata remainingData = msgData[68:];
|
bytes calldata remainingData = msgData[64:];
|
||||||
|
|
||||||
(uint256 amountOwed, address tokenOwed) =
|
(uint256 amountOwed, address tokenOwed) =
|
||||||
_verifyUSV3Callback(amount0Delta, amount1Delta, remainingData);
|
_verifyUSV3Callback(amount0Delta, amount1Delta, remainingData);
|
||||||
@@ -87,9 +87,6 @@ contract UniswapV3Executor is IExecutor {
|
|||||||
int256 amount1Delta,
|
int256 amount1Delta,
|
||||||
bytes calldata data
|
bytes calldata data
|
||||||
) internal view returns (uint256 amountIn, address tokenIn) {
|
) internal view returns (uint256 amountIn, address tokenIn) {
|
||||||
// Skip the first 64 bytes (32 bytes offset + 32 bytes length)
|
|
||||||
data = data[64:];
|
|
||||||
|
|
||||||
tokenIn = address(bytes20(data[0:20]));
|
tokenIn = address(bytes20(data[0:20]));
|
||||||
address tokenOut = address(bytes20(data[20:40]));
|
address tokenOut = address(bytes20(data[20:40]));
|
||||||
uint24 poolFee = uint24(bytes3(data[40:43]));
|
uint24 poolFee = uint24(bytes3(data[40:43]));
|
||||||
|
|||||||
Reference in New Issue
Block a user