LogoLogo
  • Introduction
    • Overview
    • Concepts
      • Decentralised Exchange (DEX)
      • Liquidity Pools
      • Swaps
      • Automated Market Maker (AMM)
      • Fees
  • Developers
    • Smart Contracts
      • Error Codes
      • Flash Loans
      • Internal User Balances
      • Pool Interface
    • Joins and Exits
      • Pool Joins
      • Pool Exits
    • Maths
      • Weighted Maths
    • Arbitrage System
      • Arbitrage Functions
    • Swaps
      • Single Swap
      • Batch Swaps
    • Arbitrage Profit Distributor
  • Resources
    • Code Licensing
    • Change Log
    • Glossary
    • Web3
    • Security & Audits
Powered by GitBook
On this page
  • Overview
  • Key Concepts
  • Function Reference: arbFromTokensWithVault
  • Underlying Mechanics: Vault Strategy
  1. Developers
  2. Arbitrage System

Arbitrage Functions

PreviousArbitrage SystemNextSwaps

Last updated 2 months ago

Overview

The contract is a core component of the A360 AMM’s arbitrage infrastructure. It allows whitelisted market makers (or other specialized addresses) to execute multi-route arbitrage through the A360 Protocol.

Because A360 AMM focuses on Real-World Assets (RWAs) such as publicly and privately traded stocks, the system requires permissioned arbitrage to remain compliant. This permissioning is achieved through the whitelist mapping, which restricts function calls to approved addresses only. Whitelisted addresses can execute arbitrage feelessly (or under special fee arrangements) to keep on-chain and off-chain prices aligned.

Key Concepts

  1. Whitelist Permissioning

    • Only addresses in the whitelist can call the arbitrage functions.

    • The contract owner can add or remove addresses via setWhitelist(address user, bool isWhitelist).

  2. Profit Distribution

    • After each arbitrage, profits are separated from principal via the internal function _transferProfit(amountIn, tokenOut).

    • Principal (amountIn) is returned to the caller (the whitelisted address), and the profit remainder is transferred to the treasury (which can be another contract such as a “Profit Distributor” or the main treasury wallet).

  3. Vault Strategy (Arbitraging with the A360/Balancer V2–Style Vault)

    • The function arbFromTokensWithVault uses the Balancer-style batchSwap mechanism to swap tokens in the A360 Vault.

    • By leveraging IVault.BatchSwapStep[] and a single transaction, the ArbBot can perform multiple hops within the Vault to source the best rates.


Function Reference: arbFromTokensWithVault

solidityCopyfunction arbFromTokensWithVault(bytes calldata data)
    external
    nonReentrant
    whenNotPaused
    onlyWhitelist
{
    (
        address vault,
        IVault.BatchSwapStep[] memory swaps,
        address[] memory assets,
        uint256 amountIn,
        uint256 amountOut,
        uint256 deadline,
        uint256 status
    ) = abi.decode(data, (address, IVault.BatchSwapStep[], address[], uint256, uint256, uint256, uint256));

    // 1. Transfer & approve
    uint256 len = swaps.length;
    for (uint256 i = 0; i < len; i++) {
        uint256 stepAmount = swaps[i].amount;
        if (stepAmount > 0) {
            IERC20Upgradeable tokenIn = IERC20Upgradeable(assets[swaps[i].assetInIndex]);
            tokenIn.safeTransferFrom(msg.sender, address(this), stepAmount);
            tokenIn.safeIncreaseAllowance(vault, stepAmount);
        }
    }

    // 2. Execute batchSwap
    IVault.FundManagement memory funds = IVault.FundManagement({
        sender: address(this),
        fromInternalBalance: false,
        recipient: payable(address(this)),
        toInternalBalance: false
    });

    IVault(vault).batchSwap(
        IVault.SwapKind.GIVEN_IN,
        swaps,
        assets,
        funds,
        getLimitsForVault(assets.length),
        deadline
    );

    // 3. Transfer profit
    IERC20Upgradeable tokenOut = IERC20Upgradeable(assets[swaps[len - 1].assetOutIndex]);
    _transferProfit(amountIn, tokenOut);
}

Purpose

Executes a batch swap in the A360 Vault, moving from an input token to a final output token. Once the swaps are complete, the function checks for profit and distributes it accordingly.

Parameters (Decoded from bytes data)

  • vault: The address of the A360 Vault contract implementing IVault.

  • swaps: An array of IVault.BatchSwapStep structs, each describing one step of the multi-hop swap.

    • poolId: ID of the pool to swap with.

    • assetInIndex / assetOutIndex: Index of the token in the assets array to swap in/out.

    • amount: The token amount used or received in that swap step (depending on SwapKind).

    • userData: Extra data for the pool (rarely needed for standard Weighted Pools).

  • assets: An array of token addresses used in this batch swap.

  • amountIn: The principal amount that the ArbBot expects to use in the arbitrage.

  • amountOut: (Not directly used in the function logic but can be included in the data for off-chain or mid-swap reference.)

  • deadline: The UNIX timestamp by which the swap must complete.

  • status: A generic field that can store custom data or flags for the aggregator (not used in the core logic).

Process Flow

  1. Transfer & Approve For each swap step, if a positive amount is specified, ArbBot pulls the required tokens from the caller (msg.sender) and approves them for the Vault to execute the swap.

  2. Execute batchSwap Using IVault.SwapKind.GIVEN_IN, ArbBot calls batchSwap.

    • The FundManagement struct directs swapped tokens to return back to address(this).

    • getLimitsForVault sets high limits to avoid reverts due to the Vault’s built-in limit checks.

  3. Profit Transfer

    • After the swap completes, the final output token balance in ArbBot is checked via _transferProfit(amountIn, tokenOut).

    • If amountOut <= amountIn, the transaction reverts with Errors.NO_PROFIT.

    • Otherwise, amountIn is returned to the arbitrageur, and the difference (profit) is sent to treasury.

Access Control

  • onlyWhitelist: Restricts this function to addresses in whitelist.

  • nonReentrant and whenNotPaused: Standard modifiers to protect against re-entrancy attacks and paused state.

Returns

This function does not return a value directly. However, the arbitrageur receives:

  • Their original principal (amountIn) back, plus

  • The entire swapped output is momentarily held by ArbBot, from which the profit is separated and sent to treasury.

Events

No explicit events are emitted by arbFromTokensWithVault in the current code. The underlying Vault emits Swap events for each step of the batch swap.


Underlying Mechanics: Vault Strategy

  • Multi-hop routes within a single transaction

  • Potentially better prices by combining liquidity from multiple pools

  • Lower gas overhead compared to multiple separate swaps on external DEXs


The ArbBot calls the A360 (Balancer-like) Vault via batchSwap. Internally, this logic can be delegated to a separate strategy contract (e.g., ). The key takeaway is that Vault-based swaps allow:

ArbBot.sol
VaultAMMStrategy.sol