feat: delegatecall to executor in SwapExecutionDispatcher

This commit is contained in:
TAMARA LIPOWSKI
2025-01-22 16:55:17 -05:00
parent 70509f547d
commit e91ee96129
4 changed files with 133 additions and 1 deletions

View File

@@ -1,6 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;
import "@interfaces/ISwapExecutor.sol";
error SwapExecutionDispatcher__UnapprovedExecutor();
/**
* @title SwapExecutionDispatcher - Dispatch swap execution to external contracts
* @author PropellerHeads Devs
@@ -10,8 +14,61 @@ pragma solidity ^0.8.28;
* be called using delegatecall so they can share state with the main
* contract if needed.
*
* Note Executor contracts need to implement the ISwapExecutor interface
* Note Executor contracts need to implement the ISwapExecutor interface unless
* an alternate selector is specified.
*/
contract SwapExecutionDispatcher {
mapping(address => bool) public swapExecutors;
/**
* @dev Calls an executor, assumes swap.protocolData contains
* token addresses if required by the executor.
*/
function _callSwapExecutor(
uint8 exchange,
uint256 amount,
bytes calldata data
) internal returns (uint256 calculatedAmount) {
address executor;
bytes4 decodedSelector;
bytes memory protocolData;
(executor, decodedSelector, protocolData) =
_decodeExecutorAndSelector(data);
bytes4 selector = decodedSelector == bytes4(0)
? ISwapExecutor.swap.selector
: decodedSelector;
if (!swapExecutors[executor]){
revert SwapExecutionDispatcher__UnapprovedExecutor();
}
(bool success, bytes memory result) = executor.delegatecall(
abi.encodeWithSelector(selector, amount, protocolData)
);
if (!success) {
revert(
string(
result.length > 0
? result
: abi.encodePacked("Swap execution failed")
)
);
}
calculatedAmount = abi.decode(result, (uint256));
}
function _decodeExecutorAndSelector(bytes calldata data)
internal
pure
returns (address executor, bytes4 selector, bytes memory protocolData)
{
require(data.length >= 24, "Invalid data length");
executor = address(uint160(bytes20(data[:20])));
selector = bytes4(data[20:24]);
protocolData = data[24:];
}
}