Making a Swap with POE

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);

Parameters:

  • swapXtoY - Direction of the swap. true = sell tokenX for tokenY, false = sell tokenY for tokenX

  • amountIn - The amount of input token you want to swap

Returns:

  • amountOut - Amount of output token you will receive

  • actualAmountIn - Actual input amount that will be consumed (may be less than amountIn if it would drain reserves)

  • feeIn - Fee amount deducted from the input

Example:

// Check how much tokenY we'd get for 1000 tokenX
(uint256 amountOut, uint256 actualAmountIn, uint256 feeIn) = pool.getQuote(true, 1000e18);

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 tokens

  • swapXtoY - Direction: true = tokenX → tokenY, false = tokenY → tokenX

  • amountIn - Amount of input token to swap

  • data - 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

1

Call swap()

Your contract calls pool.swap(recipient, swapXtoY, amountIn, data).

2

Pool transfers output

Pool calculates amountOut and transfers tokenOut to recipient.

3

Pool calls back

Pool calls swapCallback(deltaX, deltaY, data) on msg.sender (your contract).

4

Your callback pays

Your callback must transfer tokenIn to the pool.

5

Callback returns selector

Your callback must return 0xfa483e72 (the function selector).

6

Pool verifies payment

Pool verifies it received enough tokens.

7

swap() returns

swap() returns with the final deltas.

Implementing the Callback

Your contract must implement the ISwapCallback interface:

The callback must:

1

Transfer the required input tokens to the pool (msg.sender in the callback).

2

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

Error
Cause

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

Security Considerations

  1. Callback Verification: Always verify that the callback caller is the expected pool to prevent malicious contracts from draining your tokens.

  2. Slippage Protection: Always use minAmountOut checks to protect against price movement between quote and execution.

  3. Reentrancy: The callback pattern can be vulnerable to reentrancy. Use reentrancy guards if your callback does anything complex.

  4. Token Approvals: Be careful with token approvals. Only approve what's needed for the specific swap.

Last updated