For the complete documentation index, see llms.txt. This page is also available as Markdown.

Discovering Pools

POE supports an unbounded number of pools. Integrators do not have to hard-code each market: the Factory keeps a registry, so you can enumerate pools or look them up by pair on-chain.

The Factory address is the same on every supported chain (see POE Contracts):

Factory: 0x78120F2C0EBF0cc8B7E7749e62D36e6523dD711D

Factory Lookup API

interface IFactory {
    // Total number of pools ever created.
    function getPoolsLength() external view returns (uint256);

    // Index-based access. `poolId` is in [0, getPoolsLength()).
    function getPoolAt(uint256 poolId) external view returns (address);

    // Look up a pool by token pair. Returns address(0) if no pool exists.
    function getPool(address tokenX, address tokenY) external view returns (address);

    event PoolCreated(
        uint256 indexed poolId,
        address indexed pool,
        address tokenX,
        address tokenY,
        bytes data
    );
}

getPool sorts the two token addresses internally. getPool(tokenX, tokenY) and getPool(tokenY, tokenX) return the same pool.

Listing every pool

Enumerate [0, getPoolsLength()) and resolve each pool to its token pair:

The pool exposes the pair via getTokens() (returns the same (tokenX, tokenY) tuple the pool was initialized with) and its current balances via getBalances(). See Tracking Liquidity for the full pool read API.

TypeScript

Python

Looking up a specific pair

If you already know the pair, skip enumeration:

If getPool(a, b) returns address(0), getPool(b, a) will return the same result. A zero result means no pool exists for that token pair.

Reacting to new pools

Pool creation emits a PoolCreated event from the Factory. Indexers and integrators can subscribe to this to discover new markets without polling:

poolId is the index used by getPoolAt; data is the per-pool initialization blob (currently maxValue (12 bytes) | oracle (20 bytes)).

Last updated