Skip to content

Conversation

@2PykeETH
Copy link

@2PykeETH 2PykeETH commented Oct 7, 2025

Overview

This PR adds a new external view function getAmountOut to the Test_AMMContract, enabling users and external contracts to query expected swap amounts before executing trades. This function implements the constant product AMM formula (x * y = k) for price calculations.

Changes

1. New Function - getAmountOut

Added a gas-efficient view function that calculates the expected output amount for a given input without executing the swap.

Function Signature:

function getAmountOut(
    bytes32 marketId, 
    uint256 amountIn, 
    bool zeroForOne
) external view returns (uint256 amountOut)

Parameters:

  • marketId - The unique identifier for the liquidity pool
  • amountIn - The amount of input tokens
  • zeroForOne - Direction flag (true = tokenA → tokenB, false = tokenB → tokenA)

Returns:

  • amountOut - The calculated output amount based on current pool reserves

2. Implementation Details

Validation Checks:

  1. Input Amount Validation: Ensures amountIn > 0 to prevent zero-amount queries
  2. Pool Status Check: Verifies the pool is initialized and active via pool.poolInitialized
  3. Liquidity Check: Confirms both reserves are greater than zero to prevent division by zero

Calculation Logic:

  • Uses the constant product formula: amountOut = (reserveOut * amountIn) / (reserveIn + amountIn)
  • Correctly identifies input/output reserves based on swap direction (zeroForOne)
  • Pure mathematical calculation with no state changes (view function)

Swap Direction Handling:

  • When zeroForOne = true: Swaps tokenA for tokenB (uses reserveA as input, reserveB as output)
  • When zeroForOne = false: Swaps tokenB for tokenA (uses reserveB as input, reserveA as output)

3. Code Formatting

Applied forge fmt to maintain consistent code styling.

Use Cases

This function enables several important workflows:

  1. Price Discovery:

    • Users can check expected output amounts before committing to a swap
    • Frontend applications can display real-time exchange rates
  2. Arbitrage Detection:

    • External contracts can compare prices across multiple pools
    • Bots can identify profitable arbitrage opportunities without gas costs
  3. Slippage Calculation:

    • Calculate expected amounts for slippage protection
    • Set appropriate minAmountOut parameters for actual swap transactions
  4. Multi-hop Route Planning:

    • Chain multiple getAmountOut calls to calculate optimal routing paths
    • Evaluate different swap sequences for best rates

Files Changed

  • src/onchain/TestAMMContract.sol - Added getAmountOut function with 21 new lines

Technical Notes

Gas Efficiency:

  • Function is view only - no gas cost when called externally
  • Reads pool data from storage once and caches in memory
  • Simple arithmetic operations minimize computation

Important Considerations:

  • This function does NOT account for swap fees (if implemented elsewhere in the contract)
  • The actual swap output may differ slightly due to:
    • Front-running and reserve changes between query and execution
    • Rounding differences in actual swap implementation
    • Any fees applied during the swap

Formula Breakdown:

Given: x * y = k (constant product)
amountOut = (y * amountIn) / (x + amountIn)

Where:
- x = reserveIn (current input token reserve)
- y = reserveOut (current output token reserve)
- k = constant product (x * y)

Testing Recommendations

Suggested test cases:

  1. Valid Swap Query: Test both swap directions with normal amounts
  2. Zero Amount Input: Should revert with appropriate error message
  3. Uninitialized Pool: Should revert when pool is not active
  4. Zero Liquidity: Should revert when reserves are zero
  5. Large Amount Input: Test with amounts close to reserve size
  6. Price Impact: Verify output decreases proportionally as input increases
  7. Symmetry: Verify reverse swaps produce consistent results

Security Impact

Risk Level: Very Low

Security considerations:

  • Read-only function with no state modifications
  • All inputs are validated before calculations
  • No external calls or reentrancy risks
  • Reverts safely on invalid conditions

Breaking Changes

None. This is a purely additive change that doesn't modify existing functionality.

Integration Example

// Get expected output for swapping 1000 tokenA for tokenB
uint256 expectedOutput = ammContract.getAmountOut(
    poolMarketId,
    1000 * 10**18,  // 1000 tokens
    true            // tokenA → tokenB
);

// Use expectedOutput to set minimum acceptable amount with slippage tolerance
uint256 minOut = expectedOutput * 95 / 100;  // 5% slippage tolerance

Next Steps

Consider adding:

  • Fee calculation integration (if swap fees exist)
  • Batch query function for multiple pools
  • Price impact percentage calculation helper
  • Time-weighted average price (TWAP) integration

@Neros0 Neros0 self-requested a review October 7, 2025 15:39
@Neros0 Neros0 added documentation Improvements or additions to documentation enhancement New feature or request labels Oct 7, 2025
@Neros0 Neros0 merged commit 700522e into Arenium-Social:main Oct 7, 2025
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants