Routing External Calls
The aggregator includes a fallback that inspects msg.sig, fetches a Route, and forwards the calldata to the configured modules. This lets users and bots interact with complex modules via the same address used for hooks.
Route structure
struct Route {
uint16[] moduleIndices; // reference into _modules[]
ExecMode mode; // FIRST or ALL
}
- FIRST – invoke the first module only and return immediately.
- ALL – loop through every module, returning the returndata from the last call.
Configuring a route
Single-target example:
bytes4 selector = ILimitOrderModule.placeOrder.selector;
uint16[] memory modules = new uint16[](1);
modules[0] = limitOrderModuleIndex;
aggregator.setRoute(selector, modules, MODLAggregator.ExecMode.FIRST);
Multi-target example:
bytes4 selector = IRebalanceNotifier.notify.selector;
uint16[] memory modules = new uint16[](2);
modules[0] = analyticsIndex;
modules[1] = monitoringIndex;
aggregator.setRoute(selector, modules, MODLAggregator.ExecMode.ALL);
If you later remove a module, call clearRoute(selector) to avoid stale indices.
External usage
Once routed, call the aggregator directly:
ILimitOrderModule.PlaceOrderParams memory params = ILimitOrderModule.PlaceOrderParams({
key: poolKey,
tickToSellAt: 1230,
zeroForOne: true,
amountIn: 1e18
});
bytes32 orderId = ILimitOrderModule(address(aggregator)).placeOrder(params);
Behind the scenes the aggregator fallback invokes the module, enforces its gas limit, and forwards returndata or reverts.
Failure semantics
Routing honors the same critical flag and gas limit as hooks:
- If a FIRST route hits a critical module that reverts, the entire call reverts.
- If the module is non-critical the aggregator reverts with the module's reason (fallback does not swallow errors).
- For ALL routes, the first revert stops the loop and bubbles the reason.
End-to-end example
- Register
LimitOrderModule(module index 2) withcritical = trueandgasLimit = 160_000. - Configure
setRoute(ILimitOrderModule.placeOrder.selector, [2], ExecMode.FIRST). - A user calls
MODLAggregator.placeOrder(...)with encoded params. - Fallback forwards the calldata to module index 2, which records the order and emits events.
- The call returns a
bytes32 orderIddirectly to the user.
No additional entrypoints are required, and the user only needs the aggregator address.