Making a Swap with POE
InvalidCallback
Callback didn't return correct selector 0xfa483e72
ZeroTokenReceived
Callback didn't transfer any tokens to the pool
InsufficientTokenReceived
Callback transferred less than required
OraclePool__OracleNotSet
Pool's oracle is not configured
OracleData__Expired
Oracle data has expired, operator needs to update
This guide explains how to integrate with OraclePool to execute token swaps. The pool uses a callback pattern similar to Uniswap V3 - you call swap(), receive tokens optimistically, then must pay via a callback.
Getting a Quote
Before executing a swap, you can preview the expected output using getQuote():
function getQuote(bool swapXtoY, uint256 amountIn)
external view
returns (uint256 amountOut, uint256 actualAmountIn, uint256 feeIn, uint256 feeOut);Parameters:
swapXtoY- Direction of the swap.true= sell tokenX for tokenY,false= sell tokenY for tokenXamountIn- The amount of input token you want to swap (fee-inclusive)
Returns:
amountOut- Amount of output token the recipient will receive (afterfeeOut, if any)actualAmountIn- Gross input amount the pool will consume (fee-inclusive). May be less thanamountInif the curve would otherwise drain the pool.feeIn- Fee charged in the input token. Non-zero only for Y → X swaps.feeOut- Fee charged in the output token. Non-zero only for X → Y swaps.
Exactly one of feeIn / feeOut is non-zero. Both fees are denominated in tokenY (the pool's quote token), since X → Y fees come out of the output side and Y → X fees come out of the input side.
Example:
Reading Pool Info
To understand what tokens are involved:
Executing a Swap
The swap function uses an optimistic transfer pattern with a callback:
Parameters:
recipient- Address that receives the output tokensswapXtoY- Direction:true= tokenX → tokenY,false= tokenY → tokenXamountIn- Amount of input token to swapdata- Arbitrary data passed through to the callback
Returns:
deltaX- Change in tokenX from pool's perspective (positive = pool received, negative = pool sent)deltaY- Change in tokenY from pool's perspective
Swap Flow
Implementing the Callback
Your contract must implement the ISwapCallback interface:
The callback must:
Transfer the required input tokens to the pool (msg.sender in the callback).
Return the selector 0xfa483e72 (which is ISwapCallback.swapCallback.selector).
Important: The callback is called with deltaX and deltaY from the pool's perspective:
Positive delta = pool expects to receive that token
Negative delta = pool has sent that token
Solidity Example: Router Contract
Here's a complete example of a router contract that can swap through OraclePool:
Usage Example
TypeScript Example: Reading Quotes
Error Handling
Selected reverts you may encounter on the swap path:
Callback__InvalidCallback()
Callback library
Callback didn't return the selector 0xfa483e72, or the call reverted.
Callback__ZeroTokenReceived(address token)
Callback library
Pool's balance of token did not increase during the callback.
Callback__InsufficientTokenReceived(address, uint256, uint256)
Callback library
Pool received some token but less than amountIn.
Callback__Overflow()
Callback library
amountIn or amountOut ≥ 2^255 (would overflow signed delta).
OraclePool__OracleNotSet()
OraclePool
Pool's oracle is address(0).
OraclePool__ZeroAmount()
OraclePool
Quote produced amountOut == 0.
OracleData__Expired()
OracleData library
Oracle data for this pair has expired; operator must call setData again.
OracleData__InvalidPrice()
OracleData library
Oracle has no data (or price == 0) for this pair.
Security Considerations
Callback Verification: Always verify that the callback caller is the expected pool to prevent malicious contracts from draining your tokens.
Slippage Protection: Always use
minAmountOutchecks to protect against price movement between quote and execution.Reentrancy: The callback pattern can be vulnerable to reentrancy. Use reentrancy guards if your callback does anything complex.
Token Approvals: Be careful with token approvals. Only approve what's needed for the specific swap.
Agent Instructions: Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.
Perform an HTTP GET request on the current page URL with the ask query parameter:
The question should be specific, self-contained, and written in natural language. The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.
Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
Last updated