Long Pool Integration

1. Rebalance Operations

For long pools, the rebalance operation has to be invoked through FxUSDBasePool.

Rebalance can only be operated when debt ratio is between the values fetched in getRebalanceRatios

As for tokenIn address, both fxUSD and USDC tokens are supported. The FxUSDBasePool contract uses the _beforeRebalanceOrLiquidate function to handle token conversion:

function _beforeRebalanceOrLiquidate(
    address tokenIn,
    uint256 maxAmount
) internal view returns (RebalanceMemoryVar memory op) {
    op.stablePrice = getStableTokenPriceWithScale();
    op.totalYieldToken = totalYieldToken;
    op.totalStableToken = totalStableToken;

    uint256 amountYieldToken = op.totalYieldToken;
    uint256 amountStableToken;
    
    if (tokenIn == yieldToken) {
        // User pays fxUSD - direct usage
        // ... fxUSD handling logic
    } else {
        // User pays USDC - convert to USD equivalent
        uint256 maxAmountInUSD = (maxAmount * op.stablePrice) / PRECISION;
        if (maxAmountInUSD < amountYieldToken) {
            amountYieldToken = maxAmountInUSD;
        } else {
            amountStableToken = ((maxAmountInUSD - amountYieldToken) * PRECISION) / op.stablePrice;
        }
    }
    
    // Ensure we don't exceed available stable tokens
    if (amountStableToken > op.totalStableToken) {
        amountStableToken = op.totalStableToken;
    }

    op.yieldTokenToUse = amountYieldToken;
    op.stableTokenToUse = amountStableToken;
}

1.1 Pool-Wide Rebalance

/**
 * @notice Rebalance all eligible ticks in the pool through FxUSDBasePool
 * @param pool The address of the long pool
 * @param tokenIn The token to use (fxUSD or stable token)
 * @param maxAmount Maximum token amount to use
 * @param minBaseOut Minimum collateral expected
 * @return tokenUsed Amount of input token consumed
 * @return baseOut Amount of collateral tokens received
 */
function rebalance(
    address pool,
    address tokenIn,
    uint256 maxAmount,
    uint256 minBaseOut
) external returns (uint256 tokenUsed, uint256 baseOut);

Usage Example:

// Approve tokens for rebalancing
IERC20(fxUSD).approve(fxUSDBasePool, maxFxUSD);
IERC20(stableToken).approve(fxUSDBasePool, maxStable);

// Rebalance entire pool
(uint256 tokenUsed, uint256 collateralReceived) = 
    IFxUSDBasePool(fxUSDBasePool).rebalance(
        poolAddress,      // target pool
        fxUSD,            // use fxUSD
        maxFxUSD,         // max amount
        minCollateral     // minimum expected
    );

1.2 Tick-Specific Rebalance

/**
 * @notice Rebalance positions in a specific tick through FxUSDBasePool
 * @param pool The address of the long pool
 * @param tick The specific tick to rebalance (risk level)
 * @param tokenIn The token to use (fxUSD or stable token)
 * @param maxAmount Maximum token amount to use
 * @param minBaseOut Minimum collateral expected
 * @return tokenUsed Amount of input token consumed
 * @return baseOut Amount of collateral tokens received
 */
function rebalance(
    address pool,
    int16 tick,
    address tokenIn,
    uint256 maxAmount,
    uint256 minBaseOut
) external returns (uint256 tokenUsed, uint256 baseOut);

Notice: The tick provided must always be a root tickβ€”i.e., its node's parent must be 0. Otherwise, you need to trace the tick upward to identify the corresponding root tick.

Usage Example:

// Get highest risk tick
int16 topTick = ILongPool(poolAddress).getTopTick(); // you may want to replace this with your own logic to fetch ticks

// Prepare tokens (fxUSD or USDC)
IERC20(tokenIn).approve(fxUSDBasePool, maxAmount);

// Rebalance specific tick
(uint256 tokenUsed, uint256 collateralReceived) = 
    IFxUSDBasePool(fxUSDBasePool).rebalance(
        poolAddress,      // target pool
        topTick,          // highest risk tick
        tokenIn,          // fxUSD or USDC address
        1000e18,          // max 1000 tokens
        0                 // minimum collateral (set based on slippage tolerance)
    );

2. Liquidation Operations

Rebalance can only be operated when debt ratio is between the values fetched in getLiquidateRatios

Contract Interface

/**
 * @notice Liquidate high-risk positions through FxUSDBasePool
 * @param pool The address of the long pool
 * @param tokenIn The token to use (fxUSD or stable token)
 * @param maxAmount Maximum token amount to use
 * @param minBaseOut Minimum collateral expected
 * @return tokenUsed Amount of input token consumed
 * @return baseOut Amount of collateral tokens received
 */
function liquidate(
    address pool,
    address tokenIn,
    uint256 maxAmount,
    uint256 minBaseOut
) external returns (uint256 tokenUsed, uint256 baseOut);

Usage Example:

// Check liquidation opportunity
bool canLiquidate = ILongPool(poolAddress).canLiquidate();
require(canLiquidate, "No liquidation opportunity");

// Prepare liquidation tokens
IERC20(tokenIn).approve(fxUSDBasePool, maxAmount);

// Execute liquidation
(uint256 tokenUsed, uint256 collateralReceived) = 
    IFxUSDBasePool(fxUSDBasePool).liquidate(
        poolAddress,      // target pool
        tokenIn,          // fxUSD or USDC
        maxAmount,        // max token amount
        minCollateral     // minimum expected collateral
    );

3. CreditNote Received

If it happens that the long pool does not have enough collateral in the contract (it is still overcollateralized, but the collateral is held elsewhere β€” for example, lent to short pools), you may receive the CreditNote from the long pool instead of the collateral asset. In this case, you can use redeemByCreditNote to obtain the collateral asset.

  • for WBTC pools, you may receive fxBTC: 0xB25a554033C59e33e48c5dc05A7192Fb1bbDdfc6

  • for wstETH pools, you may receive fxETH: 0x7c5350BaC0eB97F86A366Ee4F9619a560480F05A

Please double-check those addresses before using them.

For more details, see CreditNotes

Last updated