feat: delegatecall to executor in SwapExecutionDispatcher
This commit is contained in:
@@ -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:];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user