> ## Documentation Index
> Fetch the complete documentation index at: https://docs.berachain.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Single Swap

> Exchange one token for another in a single BEX pool via the Vault.

A single swap in BEX allows you to exchange one token for another within a single liquidity pool by calling the `swap` function on the BEX Vault. This function is implemented in the Vault contract, which serves as the main entry point for all BEX operations.

## Swap

```solidity theme={null}
function swap(
    SingleSwap memory singleSwap,
    FundManagement memory funds,
    uint256 limit,
    uint256 deadline
) returns (uint256 amountCalculated)
```

**Parameters**

| Name           | Type           | Description                                                                                                                      |
| -------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **singleSwap** | SingleSwap     | A definition of the swap to be executed                                                                                          |
| **funds**      | FundManagement | A definition of where funds are going to/from                                                                                    |
| **limit**      | uint256        | The minimum amount to receive (for GIVEN\_IN swaps) or the maximum amount to send (for GIVEN\_OUT swaps) i.e. slippage tolerance |
| **deadline**   | uint256        | The UNIX timestamp by which the swap must be completed                                                                           |

**Returns**

| Name             | Type    | Description                                                                        |
| ---------------- | ------- | ---------------------------------------------------------------------------------- |
| amountCalculated | uint256 | The amount of tokens sent (for GIVEN\_IN swaps) or received (for GIVEN\_OUT swaps) |

## Structs

### SingleSwap

```solidity theme={null}
struct SingleSwap {
    bytes32 poolId;
    SwapKind kind;
    IAsset assetIn;
    IAsset assetOut;
    uint256 amount;
    bytes userData;
}
```

| Field    | Type     | Description                                                                  |
| -------- | -------- | ---------------------------------------------------------------------------- |
| poolId   | bytes32  | The id of the pool to swap with                                              |
| kind     | SwapKind | The type of swap to perform (GIVEN\_IN or GIVEN\_OUT)                        |
| assetIn  | IAsset   | The address of the token to swap into the pool                               |
| assetOut | IAsset   | The address of the token to receive in return                                |
| amount   | uint256  | The amount of tokens being sent (for GIVEN\_IN) or received (for GIVEN\_OUT) |
| userData | bytes    | Any additional data required by the pool for the swap                        |

### FundManagement

```solidity theme={null}
struct FundManagement {
    address sender;
    bool fromInternalBalance;
    address payable recipient;
    bool toInternalBalance;
}
```

| Field               | Type            | Description                                                     |
| ------------------- | --------------- | --------------------------------------------------------------- |
| sender              | address         | The address from which tokens will be taken to perform the swap |
| fromInternalBalance | bool            | Whether to use tokens stored in the Vault                       |
| recipient           | address payable | The address to which tokens will be sent after the swap         |
| toInternalBalance   | bool            | Whether to store tokens in the recipient's internal balance     |

## Example

Here's a small example of how to call the swap function in Solidity:

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "balancer-v2-monorepo/pkg/interfaces/contracts/vault/IVault.sol";
import "balancer-v2-monorepo/pkg/interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol";

contract BalancerExampleTest is Test {
    IVault public vault;
    address public user;

    address constant VAULT_ADDRESS = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
    address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
    bytes32 constant WETH_USDC_POOL_ID = 0x96646936b91d6b9d7d0c47c496afbf3d6ec7b6f8000200000000000000000019;

    function setUp() public {
        vm.createSelectFork("rpc-url");

        vault = IVault(VAULT_ADDRESS);

        user = makeAddr("user");

        deal(WETH, user, 1 ether);

        vm.startPrank(user);
        IERC20(WETH).approve(VAULT_ADDRESS, type(uint256).max);
        vm.stopPrank();
    }

    function testDirectSwap() public {
        uint256 amountIn = 1 ether;
        uint256 minAmountOut = 1000 * 1e6; // 1000 USDC

        uint256 balanceBefore = IERC20(USDC).balanceOf(user);

        IVault.SingleSwap memory singleSwap = IVault.SingleSwap({
            poolId: WETH_USDC_POOL_ID,
            kind: IVault.SwapKind.GIVEN_IN,
            assetIn: IAsset(WETH),
            assetOut: IAsset(USDC),
            amount: amountIn,
            userData: ""
        });

        IVault.FundManagement memory funds = IVault.FundManagement({
            sender: user,
            fromInternalBalance: false,
            recipient: payable(user),
            toInternalBalance: false
        });

        vm.startPrank(user);
        vault.swap(singleSwap, funds, minAmountOut, block.timestamp);
        vm.stopPrank();

        uint256 balanceAfter = IERC20(USDC).balanceOf(user);
        uint256 amountReceived = balanceAfter - balanceBefore;

        assertGe(amountReceived, minAmountOut, "Received less than minimum amount");
        console.log("USDC received:", amountReceived);
    }
}
```
