Sovereign Vault

Sovereign Vault is an optional smart contract that holds all the pool’s token balances between interactions: such as deposits, withdrawals, and swaps. In the absence of a Sovereign Vault, all funds are stored directly in the Sovereign Pool, which natively supports rebase tokens. External Vaults allow for pools to integrate with external reserve structures which reduce liquidity fragmentation such as yield aggregating vaults and singleton contracts shared across many pools.

Problem Statement: Monolithic Vaults

Monolithic DEX liquidity pools create liquidity fragmentation for:

  • Traders: To interact with N monolithic DEXes, a user or aggregator needs to interact with N distinct smart contracts, and execute at least 2 * N token transfers. This creates significant gas overheads and places significant barriers for developers to integrate with due to the lack of standardized interfaces or common security assumptions.

  • LPs: Most DEXes of today tend to lock in the liquidity of LPs into their protocol, making it difficult for LPs to switch across venues. This prevents LPs from capturing opportunities that provide the best yield, most favorable LP strategies or flexible liquidity management primitives, or even non-toxic order flow which ends up being distributed across different onchain protocols or liquidity pools.

While Singleton centric DEX designs mitigate liquidity fragmentation for traders by lowering gas costs of multi-pool swaps, they provide no easy mechanism for LPs to specify custom vaults that integrate across multiple sovereign DEX/Defi protocols. This is a requirement to tackle liquidity fragmentation for LPs deploying complex yield-bearing strategies. This becomes particularly difficult if the Singleton is opinionated about the pricing logic of the underlying DEX.

Solution: Sovereign Vaults

Valantis permits the rise of microcosms of DEX ecosystems with shared rules and properties, as opposed to enforcing a single architecture upon all pools built on the protocol. Valantis core protocol is structured to allow the most natural DEX programmability with clearly defined assumptions and minimized introduced risk.

Valantis' approach to liquidity pool fragmentation is to allow a poolManager to specify a custom vault responsible for holding all LP reserves: sovereignVault. Sovereign Vaults can implement custom logic to give LPs preferable yield-bearing strategies and minimize fragmentation for traders.

  • Traders: Sovereign Vaults enable gas-efficient multi-hop swaps. A Sovereign Pool might have a custom Sovereign Vault which supports a large number of tokens and liquidity sources. When calling the Sovereign Pool’s swap function, the user can specify their desired _swapTokenOut which is not necessarily one of the pool's paired tokens. The pool's Liquidity Module can handle pricing logic between multiple token pairs, potentially even querying other external modules in the process. If multiple Sovereign Pools share the same Sovereign Vault, Valantis can support multi-hop swaps without needing to execute multiple token transfers.

  • LPs: Liquidity Management primitives built on top of Valantis can specify custom Sovereign Vault logic for sharing funds across multiple Sovereign pools and deploying reserves in external yield-bearing strategies with minimal gas overhead. For example, singleton reserves can be deployed in yield-bearing defi protocols, such as another DEX or lending protocols, and funds can atomically be made available as active liquidity at swap time. LPs recover the benefits of a singleton architecture DEX, simple integrations with custom yield-bearing vault strategies, all while preserving an opt-in system.

If sovereignVault is not set, funds will by default be stored in the Sovereign Pool itself. Following interactions reserves will be updated and tokens transferred into/out of the pool. If a sovereignVault is specified, funds are transferred to/from the specified vault contract and reserves are updated after every interaction. This custom vault can be a custom singleton shared amongst several Valantis and even non-Valantis pools or can be a vault where funds are stored for more complex DeFi, crosschain, or yield-bearing interactions. In other words, when specified, a sovereignVault can be any custom vault design, allowing LPs and pool managers to express a broad range of preferences when it comes to liquidity allocation, management, and passive use of funds. It must implement the following minimal interface:

/**
    @title Minimal interface for Sovereign Pool's custom vault.
    @dev Sovereign Pools can choose to store their token0 and token1
         reserves in this contract.
         Sovereign Vault allows LPs to define where funds should be stored
         on deposits, withdrawals, and swaps. Examples:
         - A custom LP vault that can provide liquidity to multiple pools on request.
         - A singleton contract.
         - Any external protocol that provides liquidity to incoming swaps on request.
         Moreover, it supports any number of tokens.
    @dev This is meant to be a minimal interface, containing only the functions
         required for Sovereign Pools to interact with.
 */
interface ISovereignVaultMinimal {
    /**
        @notice Returns an array of tokens that can be swapped against for a given Sovereign Pool.
        @param _pool Sovereign Pool to query tokens for.
     */
    function getTokensForPool(address _pool) external view returns (address[] memory);

    /**
        @notice Returns reserve amounts available for a given Sovereign Pool.
        @param _pool Sovereign Pool to query token reserves for.
        @param _tokens Token addresses to query reserves for.
        @dev The full array of available tokens can be retrieved by calling `getTokensForPool` beforehand.
     */
    function getReservesForPool(address _pool, address[] calldata _tokens) external view returns (uint256[] memory);

    /**
        @notice Allows pool to attempt to claim the due amount of `poolManager` fees.
        @dev Only callable by a Sovereign Pool. 
        @dev This is required, since on every swap, input token amounts are transferred
             from the user into `sovereignVault`, to save on gas. Hence manager fees
             can only be claimed via this separate call.
        @param _feePoolManager0 Amount of token0 due to `poolManager`.
        @param _feePoolManager1 Amount of token1 due to `poolManager`.
     */
    function claimPoolManagerFees(uint256 _feePoolManager0, uint256 _feePoolManager1) external;
}

The interface above only contains the essential methods required for the Sovereign Pool to communicate with the Sovereign Vault, but custom LMs and external contracts are free to extend it to specify more custom ways to manage deposits, withdrawals, and even multi-hop swaps.

Note: In case sovereignVault is not the pool, poolManagerFees are retrieved from the external Sovereign Vault. The pool cannot guarantee the correct functioning of a Sovereign Vault's claimPoolManagerFees implementation, hence as a security measure the pool tracks the expected pool manager fees and enforces that the Sovereign Vault's returned tokens do not exceed this expected value during the claim process. This protects the Vault from leaking funds but does not ensure the Pool Manager receives the fair amount of manager fees. Attention should be paid to a Sovereign Vault's claimPoolManagerFees implementation.

WARNING: It is recommended that sovereignVault implements appropriate reentrancy protections. Depending on its intended use case, it might interact with multiple contracts via a non-trivial sequence of callbacks.

Last updated