> For the complete documentation index, see [llms.txt](https://docs.valantis.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.valantis.xyz/amms-and-vaults/design-space/modules/liquidity-module.md).

# Liquidity Module

*The Liquidity Module implementation for **STEX** is detailed* [*here*](/amms-and-vaults/staked-amm/swap.md)*.*

<figure><img src="https://986147118-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1hNJeG4CApeBcE2NlR61%2Fuploads%2Fgit-blob-5f3dca6f9541ca22da2ab28c98c7f2b7233eadb4%2FLiqudity%20Module%20Fig.%201_V2%20(1).jpg?alt=media" alt=""><figcaption><p>Liquidity Module in context</p></figcaption></figure>

A Liquidity Module (LM) is a mandatory contract in a Valantis Sovereign Pool construction. LMs handle the underlying pricing logic for swaps. A Liquidity Module can host whatever internal logic it wants for asset pricing and it communicates with the Sovereign Pool by implementing the function `getLiquidityQuote`. During a swap, a call is made to the LM function `getLiquidityQuote` which returns an `ALMLiquidityQuote` struct.

There are two callback functions an LM must implement which allow the contract to update its internal state and execute logic post-swap and post-deposit.

## getLiquidityQuote

The Liquidity Module’s `getLiquidityQuote` function hosts the logic for swap pricing and is defined as follows:

```solidity
    /** 
        @notice Called by the Sovereign pool to request a liquidity quote from the ALM.
        @param _almLiquidityQuoteInput Contains fundamental data about the swap.
        @param _externalContext Data received by the pool from the user.
        @param _verifierData Verification data received by the pool from the verifier module
        @return almLiquidityQuote Liquidity quote containing tokenIn and tokenOut amounts filled.
    */
    function getLiquidityQuote(
        ALMLiquidityQuoteInput memory _almLiquidityQuoteInput,
        bytes calldata _externalContext,
        bytes calldata _verifierData
    ) external returns (ALMLiquidityQuote memory);
```

### Inputs

#### Liquidity Quote Struct

This struct contains the user's requested swap along with the fees deducted from the Swap Fee Module.

```solidity
struct ALMLiquidityQuoteInput {
    bool isZeroToOne;
    uint256 amountInMinusFee;
    uint256 feeInBips;
    address sender;
    address recipient;
    address tokenOutSwap;
}
```

`ALMLiquidityQuoteInput` contains the following fields:

* `isZeroToOne` Direction of the swap
* `amountInMinusFee` Amount of input token that `sender` intends to swap, excluding the fee.
* `feeInBips` Fee in bips, returned by Swap Fee Module. **Note:** This fee will be applied to `ALMLiquidityQuote.amountInFilled`
* `sender` Address of `msg.sender` during the swap (the user).
* `recipient` Address which is meant to receive output tokens by the end of the swap
* `tokenOutSwap` Token which the user is meant to receive. This will not necessarily be one of the tokens in the pool in case the LM contains logic that handles more than 2 tokens.

#### External Context

Optional context passed by the user initiating the trade. This context is used by the Sovereign Pool to inform the Swap Fee Module, Verifier Module, and/or Liquidity Module about some external conditions that might affect the user's execution. This field allows the LM to directly implement special logic based on external data, such as: Signed Quotes, Oracle Data, Onchain credentials, etc.

#### Verifier Data

This is optional context produced by the Verifier Module which can be used to inform the Liquidity Module about different swap conditions based on the user's credentials. This allows the Verifier Module to provide the user with different execution based on the external context provided.

### Output Struct

The `getLiquidityQuote` function outputs a quote for the user's trade and returns it to the Sovereign Pool to execute.

```solidity
struct ALMLiquidityQuote {
    bool isCallbackOnSwap;
    uint256 amountOut;
    uint256 amountInFilled;
}
```

`ALMLiquidityQuote` contains the following fields:`amountOut` worth of them to `_almLiquidityQuoteInput.recipient`

* `isCallbackOnSwap` True if the LM requires a callback at the end of the swap.
* `amountOut` Amount of token out which the LM commits to transfer to the user.
* `amountInFilled` Amount of input token which the LM expects from the user, excluding the swap fee portion.

## Callbacks

The liquidity module contains two functions that can be called if the LM is configured to require callbacks. Arbitrary data can be returned back to the LM to update its internal state upon deposits

### Swap Callback

At the end of a swap, the pool can pass data back to the Liquidity Module by calling `onSwapCallback`. This allows a Liquidity Module to update its internal state post-swap, or execute any other necessary logic. The Liquidity Module can request a callback by specifying `isCallbackOnSwap` as True when returning from the `getLiquidityQuote` call. It is important this is set correctly if the LM requires a callback to function properly. The function can execute any logic necessary post-swap.

```solidity
/**
        @notice Callback to ALM after swap into liquidity pool.
        @dev Only callable by pool.
        @param _isZeroToOne Direction of swap.
        @param _amountIn Amount of tokenIn in swap.
        @param _amountOut Amount of tokenOut in swap. 
     */
    function onSwapCallback(bool _isZeroToOne, uint256 _amountIn, uint256 _amountOut) external;
```

### Deposit Callback

Deposits are initially made directly to the LM, and the LM forwards the funds to the proper reserve address (either directly to the Sovereign Pool or a custom Sovereign Vault). The LM can request a callback from the address where the reserves are held by setting `onDepositCallback` to true when calling the `depositLiquidity` on the proper reserve address. The Liquidity Module is responsible for implementing a user-facing deposit function, handling internal accounting/tokenization of LP funds, and forwarding reserves to the proper address.

```solidity
/**
        @notice Callback function for `depositLiquidity` .
        @param _amount0 Amount of token0 being deposited.
        @param _amount1 Amount of token1 being deposited.
        @param _data Context data passed by the ALM, while calling `depositLiquidity`.
    */
    function onDepositLiquidityCallback(uint256 _amount0, uint256 _amount1, bytes memory _data) external;
```
