Balancer
Balancer V1
Balancer V1
  • Home
  • Getting Started
    • Use Cases
    • FAQ
  • Core Concepts
    • Protocol
      • Background
      • Glossary
      • Pool Lifecycle
      • Limitations
      • Math
        • Exponentiation
    • BAL Governance Token
      • BAL for Gas
    • Liquidity Mining
      • Exchange Listing
      • Liquidity Mining Estimates API
    • Security
      • Audits
      • Bug Bounty
  • Smart Contracts
    • Exchange Proxy
    • Smart Order Router
      • Development & Examples
    • Smart Pools
      • Overview
      • Configurable Rights Pool
      • Component Libraries
        • Rights Manager
      • Smart Pool Templates
      • Liquidity Bootstrapping FAQ
    • On Chain Registry
    • Interfaces
    • Addresses
  • API
    • Migration to Version 1.0
    • Events
    • API Index
    • UML Docs
  • Guides
    • Interact via Etherscan
    • Using the SOR
    • Creating a Shared Pool
    • Creating a Smart Pool
    • CRP Tutorial
      • Liquidity Bootstrapping Example
    • Smart Pool Use Cases
      • Liquidity Bootstrapping Pool
      • Swing Trading Pool
      • Smart Treasury
      • Perpetual Synthetic Pool
      • Investors' Club
      • Experimental
    • Testing on Kovan
    • Hackathons
      • Hacking & Testing
      • Judging
      • Ideas
Powered by GitBook
On this page
  • Exponentiation Approximation
  • Spot Price
  • Out-Given-In
  • In-Given-Out
  • All-Asset Deposit/Withdrawal
  • Single-Asset Deposit / Withdrawal

Was this helpful?

  1. Core Concepts
  2. Protocol

Math

PreviousLimitationsNextExponentiation

Last updated 4 years ago

Was this helpful?

The describes a set of formulas derived from the value function for interacting with the protocol. The formulas in the Theory section are sufficient to describe the functional specification, but they are not straightforward to implement for the EVM, in part due to a lack of mature fixed-point math libraries.

Our implementation uses a combination of a few algebraic transformations, approximation functions, and numerical hacks to compute these formulas with bounded maximum error and reasonable gas cost.

Exponentiation Approximation

Spot Price

SPio=BiWiBoWoSP^o_i = \frac{ \frac{B_i}{W_i} }{ \frac{B_o}{W_o} }SPio​=Wo​Bo​​Wi​Bi​​​

Where:

  • Bi is the balance of token i, the token being sold by the trader which is going into the pool.

  • Bo is the balance of token o, the token being bought by the trader which is coming out of the pool.

  • Wi is the weight of token i

  • Wo is the weight of token o

When we consider swap fees, we do exactly the same calculations as without fees, but using Ai⋅(1−swapFee)A_i \cdot (1-swapFee)Ai​⋅(1−swapFee) instead of AiA_iAi​. This strategy is referred to as charging fees "on the way in." With the swap fee, the spot price increases. It then becomes:

SPio=BiWiBoWo⋅1(1−swapFee)SP^o_i = \frac{ \frac{B_i}{W_i} }{ \frac{B_o}{W_o} } \cdot \frac{1}{(1-swapFee)}SPio​=Wo​Bo​​Wi​Bi​​​⋅(1−swapFee)1​

Out-Given-In

Ao=Bo⋅(1−(BiBi+Ai)WiWo)A_{o} = B_{o} \cdot \left(1 - \left(\frac{B_{i}}{B_{i}+A_{i}}\right)^{\frac{W_{i}}{W_{o}}}\right)Ao​=Bo​⋅​1−(Bi​+Ai​Bi​​)Wo​Wi​​​

To take into account the swap fees charged by the Balancer pool, we replaceAiA_iAi​withAi⋅(1−swapFee)A_i \cdot (1-swapFee)Ai​⋅(1−swapFee). This is known as charging the fees "on the way in"

Ao=Bo⋅(1−(BiBi+Ai⋅(1−swapFee))WiWo)A_{o} = B_{o} \cdot \left(1 - \left(\frac{B_{i}}{B_{i}+A_{i} \cdot (1-swapFee)}\right)^{\frac{W_{i}}{W_{o}}}\right)Ao​=Bo​⋅​1−(Bi​+Ai​⋅(1−swapFee)Bi​​)Wo​Wi​​​

In-Given-Out

Ai=Bi⋅((BoBo−Ao)WoWi−1)A_{i} = B_{i} \cdot \left(\left(\frac{B_{o}}{B_{o}-A_{o}}\right)^{\frac{W_{o}}{W_{i}}}-1\right)Ai​=Bi​⋅((Bo​−Ao​Bo​​)Wi​Wo​​−1)

Since AiA_iAi​ is the amount the user has to swap to get a desired amount out AoA_oAo​, all we have to do to include swap fees is divide the formula above by (1−swapFee)(1-swapFee)(1−swapFee). This is because we know the fee charged on the way in will multiply that amountAiA_iAi​ by (1−swapFee)(1-swapFee)(1−swapFee). This will cross out both terms (1−swapFee)(1-swapFee)(1−swapFee) and the amount out will be AoA_oAo​ as desired:

Ai=Bi⋅((BoBo−Ao)WoWi−1)⋅1(1−swapFee)A_{i} = B_{i} \cdot \left(\left(\frac{B_{o}}{B_{o}-A_{o}}\right)^{\frac{W_{o}}{W_{i}}}-1\right) \cdot \frac{1}{(1-swapFee)}Ai​=Bi​⋅((Bo​−Ao​Bo​​)Wi​Wo​​−1)⋅(1−swapFee)1​

All-Asset Deposit/Withdrawal

Anyone can be issued Balancer pool tokens (provided the pool is finalized) by depositing proportional amounts of each of the assets contained in the pool. So, for each token k in the pool, the amounts of token k –DkD_kDk​– that need to be deposited for someone to get PissuedP_{issued}Pissued​pool tokens are:

Dk=(Psupply+PissuedPsupply−1)⋅BkD_k = \left(\frac{P_{supply}+P_{issued}}{P_{supply}}-1\right) \cdot B_kDk​=(Psupply​Psupply​+Pissued​​−1)⋅Bk​

Conversely, if a user wants to redeem their pool tokens to get their proportional share of each of the underlying tokens in the pool, the amounts of token k –AkA_kAk​– a user gets for redeeming PredeemedP_{redeemed}Predeemed​pool tokens will be:

Ak=(1−Psupply−PredeemedPsupply)⋅BkA_k = \left(1-\frac{P_{supply}-P_{redeemed}}{P_{supply}}\right) \cdot B_kAk​=(1−Psupply​Psupply​−Predeemed​​)⋅Bk​

All Balancer Protocol smart contracts were coded supporting a protocol-level exit fee to be charged that goes to Balancer Labs for supporting the development of the protocol. However, after careful consideration the Balancer Labs team decided to launch the first version of Balancer without any protocol fees whatsoever. (For technical reasons, this is unlikely to change.)

Single-Asset Deposit / Withdrawal

Single-Asset Deposit

Pissued=Psupply⋅((1+AtBt)Wt−1)P_{issued} = P_{supply} \cdot \left(\left(1+\frac{A_t}{B_t}\right)^{W_t} -1\right)Pissued​=Psupply​⋅((1+Bt​At​​)Wt​−1)

Since Balancer allows for depositing and withdrawing liquidity to Balancer pools using only one of the tokens present in the pool, this could be used to do the equivalent of a swap: provide liquidity depositing token A, and immediately withdraw that liquidity in token B. Therefore a swap fee has to be charged, proportional to the tokens that would need to be swapped for an all-asset deposit.

Another justification for charging a swap fee when a liquidity provider does a single-asset deposit is that they are getting a share of a pool that contains a basket of different assets. So what they are really doing is trading one of the pool assets (the token t being deposited) for proportional shares of all the pool assets.

Since the pool already has a share of its value in token t, represented by the weightWtW_tWt​, it only makes sense to charge a swap fee for the remaining portion of the deposit At⋅(1−Wt)A_t \cdot(1 - W_t)At​⋅(1−Wt​)

The formula then becomes:

Pissued=Psupply⋅((1+(At−At⋅(1−Wt)⋅swapFee)Bt)Wt−1)P_{issued} = P_{supply} \cdot \left(\left(1+\frac{\left(A_t-A_t\cdot(1 - W_t)\cdot swapFee\right)}{B_t}\right)^{W_t} -1\right)Pissued​=Psupply​⋅((1+Bt​(At​−At​⋅(1−Wt​)⋅swapFee)​)Wt​−1)

The formula above calculates the amount of pool tokens one receives in return for a deposit of a given amount of a single asset. We also allow for users to define a given amount of pool tokens they desire to get – PissuedP_{issued}Pissued​– and calculate what amount of tokens t is needed – AtA_tAt​:

At=Bt⋅((1+PissuedPsupply)1Wt−1)A_t = B_t \cdot \left(\left(1+\frac{P_{issued}}{P_{supply}}\right)^{\frac{1}{W_t}} -1\right)At​=Bt​⋅((1+Psupply​Pissued​​)Wt​1​−1)

Taking into account the swap fees, we have:

At=Bt⋅((1+PissuedPsupply)1Wt−1)(1−Wt)⋅swapFeeA_t = B_t \cdot \frac{\left(\left(1+\frac{P_{issued}}{P_{supply}}\right)^{\frac{1}{W_t}} -1\right)}{(1 - W_t)\cdot swapFee}At​=Bt​⋅(1−Wt​)⋅swapFee((1+Psupply​Pissued​​)Wt​1​−1)​

Single-Asset Withdrawal

Without considering swap fees, each withdrawal formula is simply the inverse of the corresponding deposit formula. In other words, if you deposit a given amount of token t for pool tokens and then immediately redeem these pool tokens for token t, you should receive exactly what you started off with.

The formula without considering swap fees is then:

At=Bt⋅(1−(1−PredeemedPsupply)1Wt)A_t = B_t \cdot \left(1-\left(1-\frac{P_{redeemed}}{P_{supply}}\right)^\frac{1}{W_t}\right)At​=Bt​⋅(1−(1−Psupply​Predeemed​​)Wt​1​)

Where AtA_tAt​ is the amount of token t one receives when redeeming PredeemedP_{redeemed}Predeemed​pool tokens.

Considering swap fees, we have the following:

At=Bt⋅(1−(1−PredeemedPsupply)1Wt)⋅(1−(1−Wt)⋅swapFee)A_t = B_t \cdot \left(1-\left(1-\frac{P_{redeemed}}{P_{supply}}\right)^\frac{1}{W_t}\right)\cdot \left(1-(1 - W_t)\cdot swapFee\right)At​=Bt​⋅(1−(1−Psupply​Predeemed​​)Wt​1​)⋅(1−(1−Wt​)⋅swapFee)

If there were an exit fee, it would be taken from the amount of tokens redeemed PredeemedP_{redeemed}Predeemed​but as mentioned above this fee is zero in the first version of Balancer.

Balancer also allows for a liquidity provider to choose a desired amount of token t, AtA_tAt​, they would like to withdraw from the pool, and calculates the necessary amount of pool tokens required for that,PredeemedP_{redeemed}Predeemed​. The formula without considering swap fees is:

Predeemed=Psupply⋅(1−(1−AtBt)Wt)P_{redeemed} = P_{supply} \cdot \left(1-\left(1-\frac{A_t}{B_t}\right)^{W_t} \right)Predeemed​=Psupply​⋅(1−(1−Bt​At​​)Wt​)

Where AtA_tAt​ is the amount of token t one receives when redeeming PredeemedP_{redeemed}Predeemed​pool tokens.

Considering swap fees, we have the following:

Predeemed=Psupply⋅(1−(1−At(1−(1−Wt)⋅swapFee)Bt)Wt)P_{redeemed} = P_{supply} \cdot \left(1-\left(1-\frac{\frac{A_t}{\left(1-(1 - W_t)\cdot swapFee\right)}}{B_t}\right)^{W_t} \right)Predeemed​=Psupply​⋅​1−(1−Bt​(1−(1−Wt​)⋅swapFee)At​​​)Wt​​

In the , we derive the following formula to calculate the amount of tokens out –AoA_oAo​– a trader gets in return for a given amount of tokens in –AiA_iAi​, considering a Balancer pool without any swap fees:

In the , we derive the following formula for the amount of tokens in –AiA_iAi​– a trader needs to swap to get a desired amountAoA_oAo​of tokens out in return, considering a Balancer pool without any swap fees:

In the , we derive the following formula for the amount of pool tokens –PissuedP_{issued}Pissued​– a liquidity provider gets in return for depositing an amount AtA_tAt​of a single token t present in the pool:

Balancer whitepaper
Whitepaper
Whitepaper
Whitepaper