AggregatorExecAdapterLib
Title: AggregatorExecAdapterLib
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from LI.FI (https://github.com/lifinance/contracts)
Logic + ERC-7201 storage for the generic swap/bridge EXECUTION adapter. execute forwards
off-chain-built calldata to an admin-allow-listed (aggregator, selector) pair, making an ARBITRARY
external call from a fund-holding diamond — so the entire design is confused-deputy prevention.
SECURITY MODEL (why each step exists):
- Allow-list:
bytes4(callData)is the selector the aggregator dispatches on, so gating_allowedCall[aggregator][selector]gates exactly what the aggregator will do.address(0)andaddress(this)can never be allow-listed (the latter would let crafted calldata re-enter privileged facets — the classic confused-deputy on a diamond). - Fund isolation: funds are pulled from
msg.sender(never the diamond balance) and the aggregator is granted an EXACT, immediately-reset approval. Balance snapshots taken BEFORE the pull/call make every sweep DELTA-based, so a pre-existing standing balance of any token (or native) is provably untouched: crafted calldata cannot route the diamond's OTHER holdings out. - Approval hygiene: the input allowance is reset to 0 after every call (no standing grant to drain).
- Leftover sweep: unspent input (delta above the standing balance), the output-token delta, and any
unspent native are all returned to
msg.sender, so the diamond nets zero from the call. COMPOSITION INVARIANT (the delta-sweep protects ONLY input/output/native): this adapter itself never leaves a standing ERC-20 allowance to any aggregator (it resets to 0 on every call), so it is safe standalone. But if a DIFFERENT facet composed into the same diamond leaves a live allowance to an allow-listed aggregator for some third token Z the diamond also holds, crafted calldata could swap that Z out (its proceeds swept as the output delta). Integrators MUST NOT grant standing allowances to any address that is (or may become) an allow-listed aggregator; a composability CI guard asserting zero standing aggregator allowances is the recommended enforcement. Reuses the shared safe-transfer / force-approve helpers (BridgeFungibleLib.pullExact,AdapterBaseLib.forceApprove/transferHonest/balanceOfSelf); no bespoke ERC-20 plumbing.
Functions
aggregatorExecAdapterStorage
function aggregatorExecAdapterStorage() internal pure returns (AggregatorExecAdapterStorage storage $);Returns
| Name | Type | Description |
|---|---|---|
| $ | AggregatorExecAdapterStorage |
__AggregatorExecAdapter_init
Registers the IAggregatorExecAdapter ERC-165 id. Called inside the diamond initializing window.
function __AggregatorExecAdapter_init() internal;registerInterface
Writes true to the ERC-165 map slot for IAggregatorExecAdapter.
function registerInterface() internal;isAllowedCall
function isAllowedCall(address aggregator, bytes4 selector) internal view returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| aggregator | address | |
| selector | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
setAllowedCall
Toggles allow-listing of the (aggregator, selector) pair. Admin only. address(0) and
address(this) are rejected — the diamond must NEVER be able to call ITSELF through this adapter.
function setAllowedCall(address aggregator, bytes4 selector, bool allowed) internal;Parameters
| Name | Type | Description |
|---|---|---|
| aggregator | address | |
| selector | bytes4 | |
| allowed | bool |
execute
Forwards callData to an allow-listed (aggregator, bytes4(callData)) under strict CEI, pulling
amount of inputToken from msg.sender, approving EXACTLY that amount, then resetting the
approval to 0 and sweeping every leftover (unspent input, output delta, unspent native) back to
the caller. See AggregatorExecAdapterLib security model for why each step is present.
function execute(
address aggregator,
address inputToken,
uint256 amount,
address outputToken,
bytes calldata callData
) internal returns (bytes memory ret);Parameters
| Name | Type | Description |
|---|---|---|
| aggregator | address | |
| inputToken | address | |
| amount | uint256 | |
| outputToken | address | |
| callData | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| ret | bytes |