feat: Change signature of _handleCallback to take only bytes calldata
The selector and executor are decoded inside this function now. For Uniswap V3 I had to manually slice the msg.data from uniswapV3SwapCallback to get the data that matters for the callback Took 3 hours 12 minutes
This commit is contained in:
@@ -82,11 +82,10 @@ contract Dispatcher {
|
||||
calculatedAmount = abi.decode(result, (uint256));
|
||||
}
|
||||
|
||||
function _handleCallback(
|
||||
bytes4 selector,
|
||||
address executor,
|
||||
bytes memory data
|
||||
) internal {
|
||||
function _handleCallback(bytes calldata data) internal {
|
||||
bytes4 selector = bytes4(data[data.length - 4:]);
|
||||
address executor = address(uint160(bytes20(data[data.length - 24:])));
|
||||
|
||||
if (!executors[executor]) {
|
||||
revert Dispatcher__UnapprovedExecutor();
|
||||
}
|
||||
|
||||
@@ -218,12 +218,7 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
|
||||
* @dev We use the fallback function to allow flexibility on callback.
|
||||
*/
|
||||
fallback() external {
|
||||
address executor =
|
||||
address(uint160(bytes20(msg.data[msg.data.length - 20:])));
|
||||
bytes4 selector =
|
||||
bytes4(msg.data[msg.data.length - 24:msg.data.length - 20]);
|
||||
bytes memory protocolData = msg.data[:msg.data.length - 24];
|
||||
_handleCallback(selector, executor, protocolData);
|
||||
_handleCallback(msg.data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,19 +360,17 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
|
||||
* See in IUniswapV3SwapCallback for documentation.
|
||||
*/
|
||||
function uniswapV3SwapCallback(
|
||||
int256 amount0Delta,
|
||||
int256 amount1Delta,
|
||||
int256, /* amount0Delta */
|
||||
int256, /* amount1Delta */
|
||||
bytes calldata data
|
||||
) external {
|
||||
if (data.length < 24) revert TychoRouter__InvalidDataLength();
|
||||
bytes4 selector = bytes4(data[data.length - 4:]);
|
||||
address executor = address(uint160(bytes20(data[data.length - 24:])));
|
||||
bytes memory protocolData = data[:data.length - 24];
|
||||
_handleCallback(
|
||||
selector,
|
||||
executor,
|
||||
abi.encodePacked(amount0Delta, amount1Delta, protocolData)
|
||||
);
|
||||
uint256 dataOffset = 4 + 32 + 32 + 32; // Skip selector + 2 ints + data_offset
|
||||
uint256 dataLength =
|
||||
uint256(bytes32(msg.data[dataOffset:dataOffset + 32]));
|
||||
|
||||
bytes calldata fullData = msg.data[4:dataOffset + 32 + dataLength];
|
||||
_handleCallback(fullData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -388,11 +381,7 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
|
||||
returns (bytes memory)
|
||||
{
|
||||
if (data.length < 24) revert TychoRouter__InvalidDataLength();
|
||||
bytes4 selector = bytes4(data[data.length - 4:]);
|
||||
address executor =
|
||||
address(uint160(bytes20(data[data.length - 24:data.length - 4])));
|
||||
bytes memory protocolData = data[:data.length - 24];
|
||||
_handleCallback(selector, executor, protocolData);
|
||||
_handleCallback(data);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,41 +66,23 @@ contract UniswapV3Executor is IExecutor, ICallback {
|
||||
}
|
||||
}
|
||||
|
||||
function uniswapV3SwapCallback(
|
||||
int256 amount0Delta,
|
||||
int256 amount1Delta,
|
||||
bytes calldata data
|
||||
) external {
|
||||
// slither-disable-next-line low-level-calls
|
||||
(bool success, bytes memory result) = self.delegatecall(
|
||||
abi.encodeWithSelector(
|
||||
ICallback.handleCallback.selector,
|
||||
abi.encodePacked(
|
||||
amount0Delta, amount1Delta, data[:data.length - 20]
|
||||
)
|
||||
)
|
||||
);
|
||||
if (!success) {
|
||||
revert(
|
||||
string(
|
||||
result.length > 0
|
||||
? result
|
||||
: abi.encodePacked("Callback failed")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCallback(bytes calldata msgData)
|
||||
external
|
||||
public
|
||||
returns (bytes memory result)
|
||||
{
|
||||
// The data has the following layout:
|
||||
// - amount0Delta (32 bytes)
|
||||
// - amount1Delta (32 bytes)
|
||||
// - dataOffset (32 bytes)
|
||||
// - dataLength (32 bytes)
|
||||
// - protocolData (variable length)
|
||||
|
||||
(int256 amount0Delta, int256 amount1Delta) =
|
||||
abi.decode(msgData[:64], (int256, int256));
|
||||
|
||||
address tokenIn = address(bytes20(msgData[64:84]));
|
||||
address tokenIn = address(bytes20(msgData[128:148]));
|
||||
|
||||
verifyCallback(msgData[64:]);
|
||||
verifyCallback(msgData[128:]);
|
||||
|
||||
uint256 amountOwed =
|
||||
amount0Delta > 0 ? uint256(amount0Delta) : uint256(amount1Delta);
|
||||
@@ -118,6 +100,20 @@ contract UniswapV3Executor is IExecutor, ICallback {
|
||||
CallbackValidationV2.verifyCallback(factory, tokenIn, tokenOut, poolFee);
|
||||
}
|
||||
|
||||
function uniswapV3SwapCallback(
|
||||
int256, /* amount0Delta */
|
||||
int256, /* amount1Delta */
|
||||
bytes calldata /* data */
|
||||
) external {
|
||||
uint256 dataOffset = 4 + 32 + 32 + 32; // Skip selector + 2 ints + data_offset
|
||||
uint256 dataLength =
|
||||
uint256(bytes32(msg.data[dataOffset:dataOffset + 32]));
|
||||
|
||||
bytes calldata fullData = msg.data[4:dataOffset + 32 + dataLength];
|
||||
|
||||
handleCallback(fullData);
|
||||
}
|
||||
|
||||
function _decodeData(bytes calldata data)
|
||||
internal
|
||||
pure
|
||||
|
||||
Reference in New Issue
Block a user