@mayflower-sys/evm-avm-interfaces
v2026.5.11-t180505
Published
Solidity interfaces, shared types, errors, and event schemas for AVM EVM markets.
Downloads
47
Readme
AVM EVM Interfaces
Public Solidity interfaces, shared types, errors, and event schemas for AVM EVM markets.
This package is the ABI boundary. Use it to discover markets, read market state, quote actions, submit user transactions, and index canonical events.
Source Of Truth
- Exact ABI signatures, event fields, errors, units, and per-method warnings
live in Solidity NatSpec under
src/. - Method-level reference is generated by running
forge docagainst this package's source. - This README is the integration map. It explains how the interfaces fit together topologically without duplicating the function catalog.
Treat Solidity symbols, event names, public structs, and branded unit aliases as integration API.
Topology
An AVM EVM deployment is organized around one directory, many markets, and one canonical event stream:
Directory
|-- tenants
| `-- market groups
| `-- markets
|-- market id -> market proxy registry
|-- market kind -> pricing engine route
|-- event emitter pointer
`-- shared runtime pointers used by markets
Factory
`-- deploys market proxy + market tokens, then registers the market
Market proxy
|-- owns per-market state, token custody, positions, and operation flags
|-- exposes views and permissionless actions at the market address
|-- resolves its active engine through the directory by market kind
`-- emits canonical logs through the directory's event emitter
Event emitter
`-- canonical log address for indexers
Quoter
`-- read-only quote adapter that composes market fees with engine quotesThe basic containment chain is:
Tenant -> MarketGroup -> MarketA tenant is a top-level namespace. A market group belongs to one tenant and carries group-level policy such as the fee schedule. A market belongs to one group, has one market kind, owns one reserve token / AVM token / option token set, and stores its own balances, positions, flags, and opaque engine state.
MarketKind is not an engine address. It is a stable semantic identifier. The
directory maps each kind to the currently active pricing-engine contract, and a
market resolves that route when it needs it.
Interface Map
| Interface or library | Main public use |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| IAvmDirectoryViews | Discover directories, tenants, groups, market records, engine routes, and the canonical event emitter. |
| IAvmFactory | Create markets where market creation is exposed, and predict market addresses from market ids. |
| IAvmEventEmitter | Index the canonical event stream for topology, policy, market actions, positions, and snapshots. |
| IMarketViews | Read one market's identity, tokens, flags, balances, snapshot, and user positions. |
| IMarketQuoter | Get fee-aware, read-only buy, sell, and floor-redemption quotes before submitting transactions. |
| IMarketActions | Submit permissionless market actions: buy, sell, exercise, collateral, debt, leverage, and donation flows. |
| ILeveragedPositionManagement | Submit atomic expand and shrink flows for collateralized positions. |
| IMarketToken | Detect AVM and option ERC-20 tokens owned by a market. |
| IPricingCurve | Engine boundary for quotes and state transitions. Most frontends use IMarketQuoter instead. |
| DataTypes | Shared structs, branded identifiers, unit aliases, flags, balances, snapshots, and quote payloads. |
| Errors | Shared custom errors surfaced by implementations. |
Discovering Markets
Start from a known directory address.
To resolve a market from an off-chain id, call:
IAvmDirectoryViews.getMarket(marketId)to get the registered market record.IAvmDirectoryViews.isMarket(address)to check whether an address is a registered market.IAvmDirectoryViews.marketIdOf(address)to map a market address back to its id.
Once you have a market address, call IMarketViews on that address:
marketId(),groupId(),tenantId(), andmarketKind()identify where the market sits in the topology.tokens()returns the reserve token, AVM token, option token, and shared decimals.flags()tells you which user actions are currently enabled.balances()returns the market's aggregate reserve, debt, collateral, and revenue-escrow balances.snapshot()returns the richer state payload used by events.getPosition(holder)returns one holder's collateral and debt in that market.
Use the directory to walk upward:
market.groupId() -> directory.getMarketGroup(groupId) -> tenantId
tenantId -> directory.getTenant(tenantId)
marketKind -> directory.engineForKind(marketKind)For indexing-first applications, MarketCreated carries the same genesis facts
needed to seed a market without an immediate follow-up read.
Viewing State
IMarketViews.snapshot() and event snapshots use
DataTypes.MarketStateSnapshot. The snapshot is intentionally broad: it
captures the market's current policy, runtime pointers, token supplies, internal
reserve accounting, actual ERC-20 custody balances, current price and floor
values, total debt and collateral, and the full opaque engine-state bytes.
For application display, the most commonly used fields are:
flags,groupFees, andplatformFeefor availability and fees.avmPriceInReserveTokenandfloorPriceInReserveTokenfor current price and floor display.avmTokenSupply,optionTokenSupply,reserveTokenBalance,totalDebtInReserveToken, andtotalCollateralInAvmTokenfor aggregate market stats.engine,engineStateHash, andengineStatefor forensic or engine-aware consumers.
Do not decode engineState unless you know the engine behind the market kind
and that engine's state encoding. For generic UIs, treat it as opaque bytes and
use engineStateHash for consistency checks.
Quoting And Actions
The usual transaction flow is:
- Read
IMarketViews.flags()and disable actions whose flag is false. - Format user input as
RawTokenQuantityin the relevant token's native decimals. - Call
IMarketQuoterfor fee-aware buy, sell, and floor-redemption previews. - Ask for the required ERC-20 allowance where the action pulls tokens from the caller.
- Submit the matching
IMarketActionscall with a slippage bound where the method exposes one. - Confirm the transaction from the canonical event emitted through
IAvmEventEmitter.
Quote results are previews against current chain state. A quote can go stale if another transaction changes the market before the user's transaction is mined, so variable-price buy and sell actions include a minimum-output or maximum-input guard. Floor redemption is the exception: it is an exact AVM input redeemed at the guaranteed floor price, so its action method has no slippage parameter.
| User intent | Interface method |
| --------------------------------- | ------------------------------------------------------------------------------ |
| Buy with exact reserve input | buyWithExactReserveTokensIn(grossReserveTokensIn, minAvmTokensOut, receiver) |
| Buy exact AVM output | buyWithExactAvmTokensOut(avmTokensOut, maxReserveTokensIn, receiver) |
| Sell exact AVM input | sellWithExactAvmTokensIn(avmTokensIn, minReserveTokensOut, receiver) |
| Redeem exact AVM at the floor | redeemAtFloorWithExactAvmTokensIn(avmTokensIn, receiver) |
| Sell for exact reserve output | sellWithExactReserveTokensOut(netReserveTokensOut, maxAvmTokensIn, receiver) |
| Exercise option tokens | exerciseOptionTokens(optionTokenAmount, maxReserveTokensIn, receiver) |
| Deposit AVM collateral | depositCollateral(amount, onBehalfOf) |
| Withdraw AVM collateral | withdrawCollateral(amount) |
| Draw a reserve-token cash advance | borrow(grossDebtIncrease) |
| Repay reserve-token debt | repay(amount, onBehalfOf) |
| Expand a position atomically | expandWithExactReserveIn(...) or expandWithExactAvmOut(...) |
| Shrink a position atomically | shrinkWithExactAvmIn(...) or shrinkWithExactReserveOut(...) |
| Donate reserve liquidity | donateLiquidity(amount) |
Token movement depends on the action:
- Reserve-token inputs, such as buys, repayments, option exercise costs, leverage inputs, and donations, require the caller to let the market pull the reserve token.
depositCollateraltransfers AVM tokens from the caller into the market, so it requires the normal ERC-20 allowance path.- Sells, floor redemption, and option exercise burn market-owned AVM or option tokens through the market-token authority; frontends should still show the resulting balance change clearly.
Indexing Events
IAvmEventEmitter is the canonical event catalog. Markets and control-plane
contracts emit through the configured emitter, and the directory exposes the
current emitter address through eventEmitter().
Indexers should:
- Resolve the emitter from the directory before indexing.
- Watch
EventEmitterChangedin case the directory intentionally migrates to a different emitter proxy. - Treat
MarketCreatedas the canonical "market exists" event. - Store both
marketaddress andmarketId; the address is the call target, and the id is the stable off-chain key. - Use post-action
MarketStateSnapshotpayloads to update market state without a follow-up multicall. - Treat event evolution as append-only. New events may be added; existing event shapes should not be reinterpreted.
Important event families:
| Event family | What it tells an indexer |
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| TenantCreated, MarketGroupCreated, MarketCreated | Topology and genesis records. |
| TenantFeeChanged, MarketGroupFeesChanged, MarketFlagsChanged | Policy and availability timeline. |
| MarketKindEngineChanged, MarketBeaconUpgraded, MarketActionsImplChanged | Runtime pointer changes that may affect later behavior. |
| AvmTokensBought, AvmTokensSold, AvmTokensRedeemedAtFloor, OptionTokensExercised | Spot and option user actions. |
| PositionCreated, CollateralDeposited, CollateralWithdrawn, DebtBorrowed, DebtRepaid | Position lifecycle and cash-advance state. |
| LeveragedPositionExpanded, LeveragedPositionShrunk | Atomic leverage composition flows. |
| LiquidityDonated, RevenueCollected | Reserve top-ups and revenue escrow withdrawals. |
Market events include the market address and MarketId. State-changing market
events include a post-action snapshot unless the event NatSpec says otherwise.
Units And Identifiers
DataTypes.sol carries the shared unit vocabulary:
RawTokenQuantityis an unscaled integer count of a token's smallest unit. It uses the token's own decimals and does not imply 18 decimals.ExchangeRateis an unsigned 18-decimal ratio, used for prices and floor levels.Fixed18ValueandSignedFixed18Valueare 18-decimal fixed-point transports used at the engine boundary.MicroBpsis a raw integer count of micro basis points, where100_000_000is 100%.TenantId,GroupId,MarketId, andMarketKindare brandedbytes32identifiers.
External market entry points generally use RawTokenQuantity for token amounts
and ExchangeRate for price-like ratios. The engine boundary uses
Fixed18Value and SignedFixed18Value; markets handle the conversion between
raw token units and engine fixed-point values.
