본문으로 건너뛰기
mip.watch
⌘K

MRC-17

PropAMM Router Interface

초안 표준 트랙 MRC GitHub ↗ 포럼 ↗
아이디어 초안 검토 중 최종 검토 확정 유지 중

Minimal routing interface for proprietary AMMs

작성자
Category Labs
생성일
2026-09-28
수정일
2026. 10. 6.

이해관계자 영향

이 MIP이 각 대상에게 무엇을 바꾸는지 보여줍니다. 심각도와 조치 플래그는 모델이 도출하며, MIP 유형/카테고리별로 결정론적 최소값이 적용됩니다.

AI 요약을 사용할 수 없음 — 구조적 기본값으로 대체

핵심 요약

이 MIP의 AI 인사이트를 사용할 수 없습니다 — 아래에 구조적 기본값을 표시합니다.

무엇이 바뀌나

  • 이 MIP의 AI 인사이트를 사용할 수 없습니다 — 아래에 구조적 기본값을 표시합니다.
⌘

개발자

스마트 컨트랙트 및 dapp 개발자, RPC 사용자, 도구 제작자

중간
◉

사용자

지갑 사용자, EOA 보유자, dapp 방문자

낮음
◆

검증자

노드 운영자, RPC 운영자, 위임자

낮음
✦

재단

Monad 재단 및 Category Labs 코어 개발자

낮음

명세

인용

## Abstract

This MRC defines a standard routing interface for proprietary automated market makers (“propAMMs”). A compatible propAMM or its adapter contract exposes functions for exact input quoting and swap execution. Quotes may return opaque venue-specific data that is passed back during execution.

The standard defines functions that are mainly used by onchain aggregators. The propAMM internal mechanisms are not enforced by this proposal.

## Motivation

PropAMMs derive prices following different mechanisms: from venue-specific logic, oracle updates, offchain market-making systems, signed price commitments, inventory constraints, or other custom mechanisms rather than a pre-defined onchain curve.

This flexibility creates fragmentation for routers and onchain aggregators as existing venues expose different interfaces. Without a common interface, every router must implement and maintain an integration code specific to a single propAMM.

Common integration frictions include:

1. **Non-standard quote functions:** propAMMs expose different input conventions, return values, and some of them do state mutation during asset quoting.
2. **Non-standard swap functions:** swap interfaces vary in direction encoding, recipient semantics, slippage checks, and callbacks, etc.
3. **Inconsistent token transfer:** some venues transfer the input token from addresses via allowance, while others expect tokens to be explicitly transferred before swap execution.
4. **Requirement of supplementary data for swap execution:** certain propAMMs require signed prices or quote identifiers to execute a swap.
5. **Different deployment architectures:** propAMMs may use per-pair contracts, others follow the singleton design.

This MRC allows onchain aggregators to quote and execute swaps via any propAMM contract or adapter through one interface without implementing any venue-specific logic.

## Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.

### Interface

Every compatible propAMM contract MUST implement the following interface:

```solidity
/// @title Proprietary AMM Router Interface
/// @dev A contract may serve one or more markets.
///      `tokenIn` and `tokenOut` specify the requested assets and direction.
interface IPropAMMRouter {
    /// @notice Emitted after a successful swap.
    /// @param sender The caller that funded the swap.
    /// @param to The recipient credited with the output token.
    /// @param tokenIn The input token transferred from `sender`.
    /// @param tokenOut The output token credited to `to`.
    /// @param amountIn The exact input amount pulled from `sender`.
    /// @param amountOut The actual output amount credited to `to`.
    event PropAMMSwap(
        address indexed sender,
        address to,
        address indexed tokenIn,
        address indexed tokenOut,
        uint256 amountIn,
        uint256 amountOut
    );

    /// @notice Quotes an exact input swap.
    /// @param tokenIn The ERC-20 input token.
    /// @param tokenOut The ERC-20 output token.
    /// @param amountIn The exact input amount in base units of `tokenIn`.
    /// @param quoteData Opaque venue specific quote input, may be empty.
    /// @return amountOut The expected output amount in base units of `tokenOut`.
    /// @return swapData Opaque venue specific data to supply to `swap()`, may be empty.
    /// @dev This function is intentionally non-view. Routers that integrate
    ///      with `IPropAMMRouter` must execute it in a call frame whose state
    ///      changes are reverted.
    function getAmountOut(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        bytes calldata quoteData
    ) external returns (uint256 amountOut, bytes memory swapData);

    /// @notice Executes an exact input swap.
    /// @dev Before calling, `msg.sender` must grant this contract an ERC-20
    ///      allowance of at least `amountIn` for `tokenIn`. The contract
    ///      pulls exactly `amountIn` of `tokenIn` during this call and credits
    ///      the actual output in `tokenOut` to `to` before returning.
    /// @param tokenIn The ERC-20 input token.
    /// @param tokenOut The ERC-20 output token.
    /// @param to The recipient of the output token.
    /// @param amountIn The exact amount of `tokenIn` pulled from `msg.sender`.
    /// @param amountOutMin The minimum amount of `tokenOut` credited to `to`.
    /// @param deadline The timestamp after which the swap must revert.
    /// @param swapData Opaque venue specific execution data, may be empty.
    /// @return amountOut The actual amount of `tokenOut` credited to `to`.
    function swap(
        address tokenIn,
        address tokenOut,
        address to,
        uint256 amountIn,
        uint256 amountOutMin,
        uint256 deadline,
        bytes calldata swapData
    ) external returns (uint256 amountOut);
}
```

### Interface Scope and Asset Selection

A compatible `IPropAMMRouter` MAY be a native propAMM contract or an adapter and MAY represent one or more markets. `tokenIn` and `tokenOut` specify the market’s assets and swap direction.

Market discovery is outside the scope of this MRC. Implementations MAY expose additional getters, but routers SHALL NOT require such extensions to use the interface defined here. Discovery MAY be standardized separately.

### Caller and Taker Semantics

When an MRC-17 compatible contract is called through a router, `msg.sender` is the router and is the address from which the contract pulls input tokens. It is not necessarily the original token owner or the output token recipient.

Given that the interface does not include a separate taker input, A propAMM that have a dynamic pricing and swapping mechanism based on a taker input MAY use `quoteData` and `swapData` fields to encode the taker address.

### Quoting

The `getAmountOut()` returns the expected output for an exact input swap and any opaque data required to execute that quote.

If `swap()` is called by the same `msg.sender`, with the `tokenIn`, `tokenOut` and `amountIn`, using the returned `swapData`, before its expiry and without relevant venue state changes, the MRC-17 compatible contract MUST be capable of delivering at least the quoted `amountOut`.

`getAmountOut()` is intentionally non-view and is not required to be called using the `STATICCALL` opcode. An MRC-17-compatible propAMM MAY apply state changes before returning a quote, including executing a swap that deliberately reverts and bubble up its result through revert data.

If the `swapData` returned by `getAmountOut()` is relied on during `swap()` execution, then it MUST be valid when `swap()` is invoked as long as it’s not expiring and not impacted by state changes.

### Swap Execution

`swap()` executes an exact input swap through the conforming contract.

Requirements:

- `amountIn` MUST be interpreted as the exact input amount.
- `amountOutMin` MUST be interpreted as the minimum actual output amount credited to `to`.
- `to` MUST NOT be the zero address.
- `deadline` MUST be enforced by the conforming contract. If `block.timestamp > deadline`, the call MUST revert.
- `swapData` is opaque to the router and MAY contain venue specific execution data.
- Before calling `swap()`, `msg.sender` MUST grant the conforming contract an ERC-20 allowance of at least `amountIn` for the input token.
- During `swap()`, the conforming contract MUST transfer exactly `amountIn` of the input token from `msg.sender` using ERC-20 `transferFrom` semantics, with the contract acting as the approved spender.
- The conforming contract MUST NOT require input tokens to be transferred before `swap()` is called.
- The conforming contract MUST NOT use a pre existing token balance as a substitute for transferring `amountIn` from `msg.sender` for the current invocation.
- The actual `amountOut` MUST be at least `amountOutMin`, otherwise the conforming contract MUST revert.

Recipient and deadline validation are under the MRC obligations. A compatible propAMM contract MUST enforce them independently for every caller and MUST NOT rely on the router to validate either value.

### Token Semantics

This MRC defines behavior in terms of ERC-20 allowances and transfers. Native assets MUST be represented by an ERC-20 compatible wrapped token.

Fee on transfer, rebasing, or otherwise non standard tokens are compatible only if the contract normalizes their behavior and still satisfies every exact input and actual output requirement in this specification.

### Exact Input Only

This interface is a standard for exact input quoting and execution only. Exact output swaps are excluded from the base interface because they are not supported by every propAMM venue.

Implementations MAY expose exact output methods outside this MRC.

### Events

A compatible contract SHOULD emit the `PropAMMSwap` event after each successful `swap()`.

In `PropAMMSwap`:

- `sender` MUST equal the `msg.sender` that invoked `swap()`
- `to` MUST equal the output recipient passed to `swap()`
- `tokenIn` and `tokenOut` MUST equal the corresponding arguments passed to `swap()` and identify the actual input and output assets.
- `amountIn` MUST equal the exact input amount transferred from `sender`
- `amountOut` MUST equal the actual output amount credited to `to`

For routed swaps, `sender` is normally the integrating router rather than the actual taker. A propAMM contract MAY emit additional venue specific events containing the taker identity.

### Quote Isolation

Routers MUST treat every quote path as state changing and untrusted, even when a contract declares `getAmountOut` as `view`. Each quote MUST execute in an isolated child frame that reverts unconditionally after its success status and returndata have been captured.

When an integration leaves quote gas and returned data size unrestricted onchain, a candidate can exhaust the transaction’s available gas or cause the complete router request to fail. The offchain route or calldata generator MUST simulate the exact complete router call and enforce its resource policy before submitting the candidate set.

### Allowances and Token Custody

Routers integrating MRC-17 contracts SHOULD approve only the selected contract and SHOULD limit the allowance to the exact `amountIn` required for the current swap.

### Chain Specifics

This MRC defines an application layer interface and does not require a precompile, canonical deployment address, registry, or privileged implementation.

## Rationale

### Why a Routing Interface?

Standardizing propAMM contracts would force venues to redesign their core architecture.
A routing interface permits native propAMM contracts to conform directly, while a thin adapter gives existing venues a common integration target without changing their core mechanisms.

A popular design that aggregators rely on is directly using  the venue’s swap logic to retrieve the quote amount, by calling the swap function, reverting any state change in the call frame, decoding, and returning the swapped amount as a quote. Even for such aggregators that don’t rely on a quoting method, this proposal unifies the swap function and allows those aggregators to use the revert pattern without embedding any venue-specific logic.

### Why Explicit Input and Output Tokens

Explicit token addresses allow the same interface to support per-pair contracts and singleton venues that serve multiple markets. Routers specify the assets and direction directly, without requiring token-ordering getters or a separate adapter for every pair.

### Why `quoteData` and `swapData`?

propAMMs have different requirements across the quote to execution boundary. Some require no additional data, while others may require data such as signed prices, quote identifiers…etc

Opaque byte fields support these designs without requiring the standard to understand every venue specific format.

### Why is `getAmountOut` non-view?

Some venues derive quotes by using the same state changing logic used for execution and deliberately reverting after the output is known. These quote paths work under RPC `eth_call` but fail under EVM `STATICCALL`, even though their effects are intended to be discarded.

Making `getAmountOut` non-view permits aggregators to integrate those venues without reimplementing their pricing logic. Static compatible contracts remain valid and are still called successfully through an ordinary `CALL`.

### Why No Pair Discovery?

Discovery differs substantially between venues. Some use factories or singleton registries, while others rely on deterministic deployment. This MRC focuses only on the router facing quote and execution boundary.

## Backwards Compatibility

This MRC introduces a new application layer interface and does not modify existing contracts, the EVM, consensus or any existing token standard.

Existing propAMMs can integrate by deploying a wrapper for their quote and swap logic following the `IPropAMMRouter` interface.

## Security Considerations

The [quote isolation](#quote-isolation) requirements address state changes and resource exhaustion during quoting.
The [allowance and token custody](#allowances-and-token-custody) requirements limit approvals to the selected contract and the current swap's exact input.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).

포럼 토론

게시물 2개 · 좋아요 0개 · 6일 전
포럼에서 더 읽기 ↗
  1. @Haythem #1 2026. 9. 29. 오후 12:39

    Routing Standard For Proprietary Market Makers “PropAMMs” This standard proposes a common routing interface for proprietary automated market makers (“propAMMs”). It mainly defines exact input quoting and swap execution functions. A shared interface would reduce integration work for aggregators and make it easier for market makers to make their liquidity available across the Monad ecosystem. Why This Is Needed? PropAMMs derive prices following different mechanisms: from venue-specific logic, oracle updates, offchain market-making systems, signed price commitments, inventory constraints, or other custom mechanisms rather than a pre defined onchain curve. This flexibility creates fragmentation for routers and on-chain aggregators as existing venues expose different interfaces. Without a common interface, every router must implement and maintain an integration code specific to a sing...

  2. @Haythem #2 2026. 9. 30. 오전 11:50

    I’m sharing this mrc-17-adapters repository as a reference implementation for propAMMs adapters following the proposed standard GitHub - haythemsellami/mrc-17-adapters · GitHub . The repository ships five venue adapters: - PoeAdapter : LFJ POE markets. - CloberAdapter : Clober V2 markets, including native MON books normalized to WMON. - MetricAdapter : legacy Metric OMM pools using rollback-isolated non-view quoting. - HanjiAdapter : Hanji order-book markets using helper ladders and exact-execution checks. - ThogAdapter : ThogAMM markets with rotating pool discovery.