Aggregator Smart Contract Interface
Aggregator Contract (On-Chain)
The Aggregator contract is the core on-chain interface that powers Madhouse swaps. It handles routing across multiple adapters and liquidity sources, applies protocol and integrator fees, and enforces all swap validations.
All swaps whether initiated via the API, SDK, or directly on-chain ultimately route through this contract.
Overview
The Aggregator contract supports three swap patterns, each using the same underlying logic:
Basic Swap β Simple swap execution without any integrator attribution or fees. Ideal for personal wallets, internal protocol use, or when you don't need fee collection. This is the most gas-efficient option since it skips fee accounting logic.
Tracked Swap β tags your
integratorAddressfor volume tracking and attribution purposes, but doesn't charge any fee. Useful when the integrator wants to monitor the integration's usage without taking a cut. The protocol can use this data for partnership analytics and incentive programs.Fee-Bearing Swap β tags your
integratorAddressand charges a customintegratorFee, which is automatically deducted from the input amount and sent to your address. This enables monetization for integrators. The protocol may also take a share of integratorsβ fee based on governance settings.
All three patterns are handled via a single unified interface for simplicity and consistency.
Swap Parameters
Below are the key parameters used in all swap() variants.
tokenFromAddress
address
Token being sold (input token).
tokenFromAmount
uint256
Amount of the input token to swap.
tokenToAddress
address
Token being received (output token).
tokenToAmount
uint256
Expected output amount (used to calculate positive slippage).
tokenToMinAmount
uint256
Minimum output amount accepted after slippage.
routes
Route[]
List of routes and adapters used in the swap.
integratorAddress
address
Address credited for tracking or fee sharing (optional).
integratorFee
uint128
Optional integrator fee as a percentage (1e18 = 100%).
Route Structure
Each Route defines one segment of the trade and allows splitting swaps across multiple DEXs or adapters.
tokenFrom
address
Token being sold for this route.
tokenTo
address
Token being received for this route.
adapter
address
Adapter contract handling execution on a DEX.
percent
uint256
Percentage of input to route here, scaled by ROUTE_PERCENT_BASE (1e16 = 100%).
additionalParams
bytes
Optional adapter-specific data (e.g., pool IDs, extra calldata).
Note: The sum of all
percentvalues in a swap must equal1e16(100%). Otherwise, the contract reverts withInvalidRoutePercent.
Fee Model
Madhouse implements a flexible and transparent fee model consisting of three layers:
1. Protocol Fee
A single configurable fee applied to all swaps.
Exemption rule: single-hop swaps through a fee-free adapter (marked in
freeOfChargeFeeAdapters) pay no protocol fee.
2. Integrator Fee (Optional)
Integrators can specify their own
integratorFeeon any swap.The fee must be between
minIntegratorFeeandmaxIntegratorFee.Fees are automatically split between the integrator and the protocol using
protocolIntegratorFeeShare.
3. Positive Slippage Share
When a swap executes at a better rate than expected, the profit (positive slippage) is shared between:
The user
The protocolβs fee receiver (
feeReceiver)
Controlled by
protocolPositiveSlippageShare.
Default Fee Configuration
Note: The protocolIntegratorFeeShare represents the percentage of the integrator fee that the protocol receives when an integrator charges a fee.
Example
If an integrator sets a 0.10% fee (i.e., 1e18-scaled value = 1000000000000000000 / 1000):
The integrator keeps 0.08%
The protocol receives 0.02% (20% of 0.10%)
Fee Configuration & View Functions
protocolFee()
uint128
Current protocol fee (scaled by 1e18).
minIntegratorFee()
uint128
Minimum allowed integrator fee.
maxIntegratorFee()
uint128
Maximum allowed integrator fee.
protocolIntegratorFeeShare()
uint128
Protocol share of integrator fee.
protocolPositiveSlippageShare()
uint128
Protocol share of positive slippage profit.
feeReceiver()
address
Address receiving all protocol fees and shares.
PERCENTAGE_BASE()
uint128
Constant base (1e18 = 100%).
ROUTE_PERCENT_BASE()
uint128
Constant route base (1e16 = 100%).
freeOfChargeFeeAdapters(address)
bool
Returns true if adapter is exempt from protocol fees (single-hop only).
activeAdapters(address)
bool
Returns true if the adapter is currently active.
Events
SwapExecuted(tokenFrom, tokenFromAmount, tokenTo, tokenToAmount)
Emitted when a swap completes successfully.
IntegratorFeePaid(integrator, token, amount)
Emitted when an integrator receives their fee share.
ProtocolFeeUpdated(protocolFee)
Emitted when the protocol fee is changed.
MinIntegratorFeeUpdated(minIntegratorFee)
Emitted when the minimum allowed integrator fee is updated.
MaxIntegratorFeeUpdated(maxIntegratorFee)
Emitted when the maximum allowed integrator fee is updated.
ProtocolIntegratorFeeShareUpdated(protocolIntegratorFeeShare)
Emitted when the protocol share of integrator fee is changed.
ProtocolPositiveSlippageShareUpdated(protocolPositiveSlippageShare)
Emitted when the slippage profit share ratio is updated.
FreeOfChargeFeeAdapterUpdated(adapter, isFreeOfCharge)
Emitted when an adapterβs fee-free status changes.
Errors
Fee Validation Errors
FeeReceiverAddressZero()β Attempt to setfeeReceiverto zero address.ProtocolFeeTooHigh()βprotocolFeeexceedsPERCENTAGE_BASE.ProtocolFeeAlreadySet()β New value equals the currentprotocolFee.MaxIntegratorFeeTooHigh()/MinIntegratorFeeTooHigh()β Value exceeds limits.MaxIntegratorFeeLessThanMinIntegratorFee(max, min)β Inconsistent bounds.MinIntegratorFeeGreaterThanMaxIntegratorFee(min, max)β Inconsistent bounds.ProtocolIntegratorFeeShareTooHigh()/ProtocolIntegratorFeeShareAlreadySet()β Invalid or duplicate protocol share.ProtocolPositiveSlippageShareTooHigh()/ProtocolPositiveSlippageShareAlreadySet()β Invalid or duplicate slippage share.IntegratorAddressZero()βintegratorFee > 0but nointegratorAddressprovided.IntegratorFeeExceedsMaxIntegratorFee(fee, max)β Exceeds maximum allowed.IntegratorFeeBelowMinIntegratorFee(fee, min)β Below minimum allowed.
Swap Validation Errors
RoutesLengthZero()β No routes provided.TokenFromCannotBeEqualToTokenTo()β Input and output tokens identical.TokenFromAddressMismatch()/TokenToAddressMismatch()β Route mismatch with top-level swap params.TokenFromAmountZero()β Input amount is zero.TokenToAmountLessThanMinAmount()β Minimum output exceeds expected.TokenFromAmountExceedsBalance()β Sender balance too low.ReceivedAmountLessThanMinAmount()β Received less thantokenToMinAmount.AdapterNotActive(adapter)β Route adapter inactive.InvalidRoutePercent(percent)β Route percent invalid or > 100%.InputAmountNotFullyUsed(remainingAmount)β Unused input left over.NativeTokenAmountMismatch(expected, received)β Mismatch between sent and expected native value.UnexpectedNativeTokenSent()β ETH sent for non-native token swap.TransferFailed()β Native token transfer failed.
Example Usage
Below is an example of executing a swap directly on Monad:
Last updated