Add DODO-only EnhancedSwapRouterV2 routing helpers

This commit is contained in:
defiQUG
2026-04-29 23:50:26 -07:00
parent 1a14622b22
commit 6aaa100bbc
12 changed files with 564 additions and 173 deletions

View File

@@ -86,10 +86,10 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
_initializeDefaultRouting();
}
function setProviderAdapter(
RouteTypesV2.Provider provider,
address adapter
) external onlyRole(ROUTING_MANAGER_ROLE) {
function setProviderAdapter(RouteTypesV2.Provider provider, address adapter)
external
onlyRole(ROUTING_MANAGER_ROLE)
{
if (adapter == address(0)) revert ZeroAddress();
providerAdapters[uint8(provider)] = adapter;
emit ProviderAdapterSet(provider, adapter);
@@ -103,36 +103,32 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
bytes calldata providerData,
bool enabled
) external onlyRole(ROUTING_MANAGER_ROLE) {
if (tokenIn == address(0) || tokenOut == address(0) || target == address(0)) revert ZeroAddress();
providerRoutes[tokenIn][tokenOut][uint8(provider)] = ProviderRouteConfig({
target: target,
providerData: providerData,
enabled: enabled
});
if (tokenIn == address(0) || tokenOut == address(0) || target == address(0)) {
revert ZeroAddress();
}
providerRoutes[tokenIn][tokenOut][uint8(provider)] =
ProviderRouteConfig({target: target, providerData: providerData, enabled: enabled});
emit ProviderRouteSet(tokenIn, tokenOut, provider, target, enabled);
}
function getProviderRoute(
address tokenIn,
address tokenOut,
RouteTypesV2.Provider provider
) external view returns (address target, bytes memory providerData, bool enabled) {
function getProviderRoute(address tokenIn, address tokenOut, RouteTypesV2.Provider provider)
external
view
returns (address target, bytes memory providerData, bool enabled)
{
ProviderRouteConfig storage config = providerRoutes[tokenIn][tokenOut][uint8(provider)];
return (config.target, config.providerData, config.enabled);
}
function setProviderEnabled(
RouteTypesV2.Provider provider,
bool enabled
) external onlyRole(ROUTING_MANAGER_ROLE) {
function setProviderEnabled(RouteTypesV2.Provider provider, bool enabled) external onlyRole(ROUTING_MANAGER_ROLE) {
providerEnabled[uint8(provider)] = enabled;
emit ProviderToggled(provider, enabled);
}
function setRoutingConfig(
uint256 sizeCategory,
RouteTypesV2.Provider[] calldata providers
) external onlyRole(ROUTING_MANAGER_ROLE) {
function setRoutingConfig(uint256 sizeCategory, RouteTypesV2.Provider[] calldata providers)
external
onlyRole(ROUTING_MANAGER_ROLE)
{
require(sizeCategory < 3, "EnhancedSwapRouterV2: invalid size category");
require(providers.length > 0, "EnhancedSwapRouterV2: empty providers");
@@ -144,19 +140,23 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
emit RoutingConfigUpdated(sizeCategory, providers);
}
function executeRoute(
RouteTypesV2.RoutePlan calldata plan
) external payable nonReentrant returns (uint256 amountOut) {
function executeRoute(RouteTypesV2.RoutePlan calldata plan)
external
payable
nonReentrant
returns (uint256 amountOut)
{
RouteTypesV2.RoutePlan memory memoryPlan = _copyPlan(plan);
return _executeRoute(memoryPlan, msg.sender, msg.value);
}
function quoteConfiguredProviders(
address tokenIn,
address tokenOut,
uint256 amountIn
) external view returns (RouteTypesV2.ProviderQuote[] memory quotes) {
RouteTypesV2.ProviderQuote[] memory temp = new RouteTypesV2.ProviderQuote[](uint256(type(RouteTypesV2.Provider).max) + 1);
function quoteConfiguredProviders(address tokenIn, address tokenOut, uint256 amountIn)
external
view
returns (RouteTypesV2.ProviderQuote[] memory quotes)
{
RouteTypesV2.ProviderQuote[] memory temp =
new RouteTypesV2.ProviderQuote[](uint256(type(RouteTypesV2.Provider).max) + 1);
uint256 count = 0;
for (uint8 providerId = 0; providerId <= uint8(type(RouteTypesV2.Provider).max); providerId++) {
@@ -172,32 +172,13 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
if (!routeConfig.enabled || routeConfig.target == address(0)) {
continue;
}
RouteTypesV2.RouteLeg memory leg = RouteTypesV2.RouteLeg({
provider: RouteTypesV2.Provider(providerId),
tokenIn: tokenIn,
tokenOut: tokenOut,
amountSource: RouteTypesV2.AmountSource.UserInput,
minAmountOut: 0,
target: routeConfig.target,
providerData: routeConfig.providerData
});
(bool ok,) = IRouteExecutorAdapter(adapter).validate(leg);
if (!ok) {
continue;
RouteTypesV2.ProviderQuote memory quote = _quoteConfiguredProvider(
tokenIn, tokenOut, amountIn, RouteTypesV2.Provider(providerId), routeConfig, adapter
);
if (quote.executable) {
temp[count] = quote;
count++;
}
(uint256 amountOut, uint256 estimatedGas) = IRouteExecutorAdapter(adapter).quote(leg, amountIn);
temp[count] = RouteTypesV2.ProviderQuote({
provider: RouteTypesV2.Provider(providerId),
target: routeConfig.target,
amountOut: amountOut,
estimatedGas: estimatedGas,
executable: amountOut > 0,
providerData: routeConfig.providerData
});
count++;
}
quotes = new RouteTypesV2.ProviderQuote[](count);
@@ -206,12 +187,69 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
}
}
function swapTokenToToken(
function quoteConfiguredProvider(
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 amountOutMin
) external returns (uint256 amountOut) {
RouteTypesV2.Provider provider
) external view returns (RouteTypesV2.ProviderQuote memory quote) {
uint8 providerId = uint8(provider);
if (!providerEnabled[providerId]) revert ProviderDisabled();
address adapter = providerAdapters[providerId];
if (adapter == address(0)) revert ProviderAdapterNotConfigured();
ProviderRouteConfig storage routeConfig = providerRoutes[tokenIn][tokenOut][providerId];
if (!routeConfig.enabled || routeConfig.target == address(0)) revert RouteNotConfigured();
return _quoteConfiguredProvider(tokenIn, tokenOut, amountIn, provider, routeConfig, adapter);
}
function _quoteConfiguredProvider(
address tokenIn,
address tokenOut,
uint256 amountIn,
RouteTypesV2.Provider provider,
ProviderRouteConfig storage routeConfig,
address adapter
) internal view returns (RouteTypesV2.ProviderQuote memory quote) {
RouteTypesV2.RouteLeg memory leg = RouteTypesV2.RouteLeg({
provider: provider,
tokenIn: tokenIn,
tokenOut: tokenOut,
amountSource: RouteTypesV2.AmountSource.UserInput,
minAmountOut: 0,
target: routeConfig.target,
providerData: routeConfig.providerData
});
(bool ok,) = IRouteExecutorAdapter(adapter).validate(leg);
if (!ok) {
return RouteTypesV2.ProviderQuote({
provider: provider,
target: routeConfig.target,
amountOut: 0,
estimatedGas: 0,
executable: false,
providerData: routeConfig.providerData
});
}
(uint256 amountOut, uint256 estimatedGas) = IRouteExecutorAdapter(adapter).quote(leg, amountIn);
return RouteTypesV2.ProviderQuote({
provider: provider,
target: routeConfig.target,
amountOut: amountOut,
estimatedGas: estimatedGas,
executable: amountOut > 0,
providerData: routeConfig.providerData
});
}
function swapTokenToToken(address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin)
external
returns (uint256 amountOut)
{
return swapTokenToToken(tokenIn, tokenOut, amountIn, amountOutMin, _defaultPreferredProvider());
}
@@ -295,11 +333,10 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
return _executeRoute(plan, msg.sender, msg.value);
}
function _executeRoute(
RouteTypesV2.RoutePlan memory plan,
address payer,
uint256 nativeValue
) internal returns (uint256 amountOut) {
function _executeRoute(RouteTypesV2.RoutePlan memory plan, address payer, uint256 nativeValue)
internal
returns (uint256 amountOut)
{
_validatePlan(plan);
address currentToken = plan.inputToken;
@@ -360,29 +397,29 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
return currentAmount;
}
function _getRouteConfig(
address tokenIn,
address tokenOut,
RouteTypesV2.Provider preferredProvider
) internal view returns (ProviderRouteConfig memory) {
function _getRouteConfig(address tokenIn, address tokenOut, RouteTypesV2.Provider preferredProvider)
internal
view
returns (ProviderRouteConfig memory)
{
RouteTypesV2.Provider[] memory providers = _getRoutingProviders(preferredProvider);
for (uint256 i = 0; i < providers.length; i++) {
uint8 providerId = uint8(providers[i]);
ProviderRouteConfig storage config = providerRoutes[tokenIn][tokenOut][providerId];
if (config.enabled && config.target != address(0) && providerEnabled[providerId]) {
return ProviderRouteConfig({
target: config.target,
providerData: config.providerData,
enabled: config.enabled
target: config.target, providerData: config.providerData, enabled: config.enabled
});
}
}
revert RouteNotConfigured();
}
function _getRoutingProviders(
RouteTypesV2.Provider preferredProvider
) internal view returns (RouteTypesV2.Provider[] memory providers) {
function _getRoutingProviders(RouteTypesV2.Provider preferredProvider)
internal
view
returns (RouteTypesV2.Provider[] memory providers)
{
if (providerEnabled[uint8(preferredProvider)]) {
providers = new RouteTypesV2.Provider[](1);
providers[0] = preferredProvider;
@@ -420,9 +457,11 @@ contract EnhancedSwapRouterV2 is AccessControl, ReentrancyGuard {
sizeBasedRouting[2].push(RouteTypesV2.Provider.Balancer);
}
function _copyPlan(
RouteTypesV2.RoutePlan calldata plan
) internal pure returns (RouteTypesV2.RoutePlan memory copied) {
function _copyPlan(RouteTypesV2.RoutePlan calldata plan)
internal
pure
returns (RouteTypesV2.RoutePlan memory copied)
{
copied.chainId = plan.chainId;
copied.inputToken = plan.inputToken;
copied.outputToken = plan.outputToken;

View File

@@ -5,22 +5,23 @@ import "../RouteTypesV2.sol";
import "../LiquidityPoolETH.sol";
interface IEnhancedSwapRouterV2 {
function executeRoute(
RouteTypesV2.RoutePlan calldata plan
) external payable returns (uint256 amountOut);
function executeRoute(RouteTypesV2.RoutePlan calldata plan) external payable returns (uint256 amountOut);
function quoteConfiguredProviders(
address tokenIn,
address tokenOut,
uint256 amountIn
) external view returns (RouteTypesV2.ProviderQuote[] memory quotes);
function quoteConfiguredProviders(address tokenIn, address tokenOut, uint256 amountIn)
external
view
returns (RouteTypesV2.ProviderQuote[] memory quotes);
function swapTokenToToken(
function quoteConfiguredProvider(
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 amountOutMin
) external returns (uint256 amountOut);
RouteTypesV2.Provider provider
) external view returns (RouteTypesV2.ProviderQuote memory quote);
function swapTokenToToken(address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin)
external
returns (uint256 amountOut);
function swapToStablecoin(
LiquidityPoolETH.AssetType inputAsset,