Omnipools

Omnipools are liquidity pools that Opal uses to allocate a single underlying asset across various Balancer pools. The core mechanisms of Omnipools are: deposits and withdrawals, Balancer LP token pricing and rebalancing liquidity across Balancer pools.

Deposits and withdrawals

Each Omnipool has a single underlying asset which can be exchanged for the Omnipool LP Token (depositing), and the LP Tokens can be redeemed for the underlying (withdrawing) at any time.

One of the key challenges faced when depositing and withdrawing single sided liquidity is ensuring that the pool is protected from slippage incurred during these transactions. If not handled carefully, several attack vectors could exist that allow a malicious agent to drain funds from the pool.

Slippage is unavoidable, and so Opal mitigates this risk by passing all slippage on to the depositing and withdrawing user during their transaction. This is done by using a new method to calculate Omnipools LP token minting and burning. When a user deposits into the pool, the current TVL of the pool is calculated first before any other steps.

The pricing of the LP Tokens for this calculation uses the process outlined in the next section which is manipulation resistant. Then the deposit or withdrawal is processed. After this, the TVL is calculated again. During a deposit the amount of LP Tokens minted is based on the difference in the TVL from before and after the deposit (opposed to the amount of underlying deposited).

Similarly, the amount of underlying redeemed depends on the change in TVL during a withdrawal. The impact of this is that any slippage incurred during deposits or withdrawals is passed on to the user. This ensures the assets in the pool are safe from any attack or ongoing cost of slippage. To protect users from excessive slippage, they can specify a slippage tolerance during the deposit or withdrawal process.

When depositing into an Omnipool, a calculation is done first to assess which Balancer pool is the most under-allocated relative to its target allocation. The deposit will then be made into that Balancer pool. Similarly, when withdrawing from an Omnipool, the withdrawal will always be made from the most over-allocated Balancer pool.

The exception to this is when the deposit or withdrawal is so large, that it would push the balance of that Balancer pool the other way, resulting in it being more imbalanced than before and over a specified imbalance threshold. In this case, a full deposit is made, where the deposit is split over several Balancer pools such that the Omnipool is perfectly balanced after the deposit/withdrawal.

This full deposit case should be quite rare and only affect extremely large deposits and withdrawals. This approach results in deposits and withdrawals being a lot more gas efficient, as most of the time, they only deposit into one Balancer pool. Furthermore, regular deposits and withdrawals assist in maintaining the target balance of the Omnipool set by governance.

Reentrancy Security

Opal's roadmap aims to achieve the development of a DEX agnostic liquidity as a service (LaaS) protocol, deploying assets into the largest subset of available pools and farming opportunities, since the initial growth of the project is made possible by a strategic bootstrap on Balancer ecosystem, it is the most efficient to combine already existing and battle tested security measures with Opal's homemade protections.

Balancer ReentrancyLib is a library that helps to protect smart contracts against reentrancy attacks. Reentrancy attacks are a type of exploit that can be used to drain funds from a smart contract. They work by calling a function in the smart contract, and then calling another function before the first function has finished executing. This can be used to manipulate the state of the smart contract in a way that is not intended.

Balancer ReentrancyLib works by preventing a function from being called recursively. This means that a function can only be called once, and it cannot be called from within itself. This helps to prevent reentrancy attacks by ensuring that the state of the smart contract is always consistent.

In addition to preventing reentrancy attacks, Balancer ReentrancyLib also helps to improve the security of smart contracts by making them more predictable. This is because the library ensures that functions are called in a specific order, which makes it more difficult for attackers to exploit vulnerabilities.

As a result, the usage of Balancer ReentrancyLib is good for security and there is no risk of price manipulation. This is because the library helps to prevent reentrancy attacks, which are a common way to manipulate the price of assets on decentralized exchanges.

Balancer ReentrancyLib mechanism were reviewed and improved after as per forum post "Reentrancy Vulnerability Scode Extended", and ensures that no state-altering functions on pools can be called externally when inside the Vault’s re-entrancy context:

i.e., a public call that updates a protocol fee or rate cache can be called externally on its own, but cannot be called during a Vault operation (swap/join/exit).

Benefits of using Balancer ReentrancyLib

  • Helps to prevent reentrancy attacks

  • Makes smart contracts more predictable

  • Reduces gas costs

  • Improves performance of smart contracts

  • Makes smart contracts more resistant to other types of attacks

How to use

To use Balancer ReentrancyLib, you need to add the library to your smart contract project. You can do this by importing the library in your contract code.

Once you have imported the library, you can use it to protect your smart contract against reentrancy attacks. For example, you can use the isReentrant function to check if a function is allowed to be called recursively.

At Opal, we take security very seriously. We believe that security is the most important aspect of Web3, and we are committed to providing our users with a safe and secure environment.

BPT Price Calculation for Different Pool Types

Introduction

The following documentation explains how to calculate the price of Balancer Pool Tokens (BPT) for different types of pools: Stable Pools, Linear Pools, and Weighted Pools. The pricing mechanisms vary based on the pool type and the underlying assets.

RedStone Oracles

RedStone is a Modular Oracle delivering token pricing by fetching price feeds from off-chain sources (CEXes, aggregators) and on-chain sources (DEXes). Since RedStone provides unique LST & LRT Tokens pricing it’s a naturally good fit for Opal. Opal utilizes RedStone price feeds to compute the price of several LP tokens underlying to the Omnipools.


Stable Pools

Description: Stable Pools consist of multiple stablecoins such as DAI, USDC, and USDT. The pool.getRate() function returns the exchange rate of a BPT to the underlying base asset of the pool.

Examples:

WETH/wstETH pool: The rate is relative to WETH.


Linear Pools

Description: Linear Pools have a pool.getRate() function that returns the exchange rate of a BPT to the underlying base asset (mainToken) of the pool.

Example:

  • For a Linear Pool with mainToken X, pool.getRate() returns the rate relative to X.


Weighted Pools

Description: Weighted Pools have an invariant formula:

V = n ∏ (B_i ^ W_i)

Where:

  • n is the number of tokens in the pool.

  • B_i is the balance of token i in the pool.

  • W_i is the normalized weight of token i in the pool.

Pricing Calculation Steps:

  1. Retrieve the invariant of the pool: V = pool.getInvariant().

  2. Obtain fair prices for tokens using reliable price feeds.

  3. Calculate fair balances in the pool based on the invariant and fair prices.

    • For token i: B_i_fair = (V / (P_W_2^(1/2) * (W_1 / W_2)) * P_W_1^(1/2) * (W_2 / W_1)) / P_W_i^(1/2)

    • Where P_W_i^(1/2) is the square root of the fair relative price of token i in units of token W.

  4. Calculate the BPT price using fair balances:

    • BPT_price = (B_1_fair * P_1 + B_2_fair * P_2) / totalSupply


Conclusion

Understanding the pricing mechanisms of different types of pools helps in determining the value and market price of Balancer Pool Tokens (BPT) within various pool compositions. It involves calculations based on underlying asset prices, weights, and other factors unique to each pool type.

For any queries or clarifications, refer to the provided Solidity code and relevant documentation of the Balancer protocol.

Liquidity Rebalancing

Shifting liquidity between Balancer pools is fundamental to the workings of Opal. Fortunately, Balancer offers very convenient deposits and withdrawals routers for single sided liquidity, however cash flows between rounds might still unbalance the expected allocations.

In order to restore and retain balance in terms of liquidity allocations being in line with their target, Opal relies on an incentivized arbitrage and passive rebalancing system based on deposits to and withdrawals from events in Omnipools.

When a liquidity provider deposits into an Omnipool the deposit will always go to the least allocated Balancer Pool. Similarly, when a liquidity provider withdraws funds from an Omnipool, the withdrawal will come from the most over-allocated Balancer Pool.

This means that with regular deposits and withdrawals the pool will maintain a balanced state. To incentivize regular deposits and withdrawals, $GEM emissions will be distributed to liquidity providers who deposit into Omnipools while the pools are imbalanced.

The $GEM received will be based on the amount deposited, and will also increase over time while a pool is imbalanced, and will stop when the pool is balanced again (with a 5% APR cap). This boost in rewards will be distributed linearly over the next epoch. Removing liquidity from the pools will result in forfeiting the boosted yield which will be redistributed to $vlGEM holders.

There is a limiter in the $GEM emissions, which ensures that the $GEM rewards a user receives is based on how far they bring the pools in line with being rebalanced. For example, if the pools are currently 30% imbalanced, and the user brings them to being 20% imbalanced, then they would receive 33% of the remaining $GEM rewards allocated for the rebalancing period. Once the pool is balanced, the rewards are set to zero and will remain at zero until the next rebalance period.

Opal for liquidity providers

Liquidity providers receive a share of the rewards generated by omnipools based on the quantity of omnipool LP tokens they hold. The rewards acquired by the omnipool are contingent on the composition of its underlying pools, which currently consist solely of Aura pools.

These pools consistently distribute at least BAL and AURA tokens as rewards. In addition, underlying pools may provide other tokens. This other tokens are referred to as "extra-reward tokens." These extra-reward tokens are converted into GEM tokens, which serve Opal's governance purposes.

This implies that liquidity providers can only receive BAL, AURA, and GEM tokens.

Rewards calculation

To claim their rewards, users must interact with the Opal omnipool contract. During this interaction, the omnipool will iterate through all its underlying pools to claim the rewards offered in exchange for providing liquidity. This process quantifies the rewards held by the omnipool at a specific epoch, enabling users who wish to recover their rewards to receive a quantity of tokens based on their share of the omnipool's LP.

Users will then receive a quantity of AURA, BAL, and GEM tokens depending on their share of the total omnipool LP tokens.

Conversion of Extra-Reward Tokens into GEM

Why do we swap extra-reward tokens for GEM token?

The tokens provided as rewards to the omnipool and obtained from its underlying pools can be BAL, AURA, or any other tokens, referred to as extra-reward tokens. While BAL and AURA tokens are directly distributed to liquidity providers, the extra-reward tokens are exchanged for GEM tokens and subsequently distributed.

There are two primary reasons for exchanging extra-reward tokens for GEM tokens:

  • Firstly, we aim to provide Opal users with a consistent and straightforward user experience across all omnipools. This is achieved by disregarding extra-reward tokens and systematically ensuring that users receive their rewards in a clear and easy-to-manage format.

  • This approach benefits the GEM token and incentivizes its liquidity provision.

How do we swap extra-reward tokens for GEM token?

To facilitate the exchange of extra-reward tokens for GEM tokens, a dedicated Balancer pool is required. For each extra-reward token, the DAO can initiate a vote to add a Balancer pool where the extra-reward tokens will be exchanged. In cases where the DAO does not propose a pool, the extra-reward tokens will be retained by the omnipool until a pool proposal is submitted and accepted by the DAO.

This system ensures that extra-reward tokens are efficiently converted into GEM tokens, maintaining a consistent user experience and contributing to the health of the GEM token within Opal's ecosystem.

Last updated