ChainScore Labs
All Guides

Weighted Pools and Multi-Asset Liquidity Designs

LABS

Weighted Pools and Multi-Asset Liquidity Designs

Chainscore © 2025

Core Concepts of Weighted Pools

Foundational principles governing the design and behavior of constant function automated market makers with non-equal token weights.

Constant Weighted Product Formula

The invariant function that defines the pool's bonding curve, expressed as ∏ (token_balance ^ weight) = k. Unlike constant product pools, each token's weight is an exponent in the formula.

  • Balances are constrained so the weighted product remains constant.
  • Price impact is a function of both the weight and the relative balance of the tokens.
  • This formula ensures the pool always has liquidity, enabling continuous trading.

Token Weights & Capital Efficiency

Predefined, fixed weight ratios (e.g., 80/20) that determine each asset's influence on price and pool fees.

  • A higher-weighted token experiences less price impact per unit traded.
  • Weights dictate the pool's fee distribution; fees are earned proportional to a token's weight.
  • Strategic weight selection (like 80/20 WBTC/ETH) optimizes capital for a target market while reducing impermanent loss for the dominant asset.

Spot Price & Effective Price

The instantaneous exchange rate between two tokens in the pool, derived from the derivative of the invariant. It differs from the effective price paid in a trade due to slippage.

  • Spot Price = (Balance_A / Weight_A) / (Balance_B / Weight_B).
  • The effective price includes slippage, which increases with trade size relative to liquidity.
  • Understanding this difference is critical for arbitrageurs and traders executing large orders.

Swap Fee Mechanism

A percentage fee charged on the input token amount for every trade, accruing to liquidity providers as an incentive.

  • Fees are added to the pool's reserves, increasing the value of LP shares.
  • The fee is applied before the swap executes, affecting the output amount.
  • Fee levels (e.g., 0.3%, 0.05%) are a governance parameter balancing volume attraction and LP yield.

Liquidity Provider Tokens (LP Tokens)

ERC-20 tokens representing a proportional share of the entire pool's reserves. Minted on deposit and burned on withdrawal.

  • LP token quantity represents ownership percentage of the pooled assets.
  • Their value appreciates from accrued swap fees and changes in the underlying asset prices.
  • They are composable, used as collateral in other DeFi protocols like lending markets.

Impermanent Loss (Divergence Loss)

The opportunity cost LPs face when the value of their deposited assets diverges compared to simply holding them.

  • Loss is greatest when token prices diverge significantly and pool weights are balanced (e.g., 50/50).
  • Pools with skewed weights (e.g., 98/2) reduce IL for the dominant asset.
  • IL is 'impermanent' as losses are unrealized until withdrawal; accrued fees can offset it.

Creating and Configuring a Weighted Pool

Process overview for deploying a custom Balancer V2 WeightedPool via the Vault and WeightedPoolFactory.

1

Define Pool Parameters and Token Weights

Determine the initial composition and economic parameters for the pool.

Detailed Instructions

Define the pool's invariant parameters which are immutable after deployment. This includes the list of ERC-20 token addresses, their corresponding normalized weights (which must sum to 1e18), and the swap fee percentage. Weights are crucial for pricing and impermanent loss dynamics; a 50/50 pool uses weights [0.5e18, 0.5e18]. The swap fee is a value like 0.002e18 for a 0.2% fee. You must also decide on the pool's owner address, which can be an EOA or a contract (like a DAO multisig) for future administrative actions. Finally, generate a unique poolId salt for the CREATE2 deployment.

  • Sub-step 1: Compile token addresses into an array tokens[].
  • Sub-step 2: Calculate normalized weights (1e18 = 100%) into array weights[].
  • Sub-step 3: Set swapFeePercentage as a WAD (18 decimal) value.
  • Sub-step 4: Designate the owner address and a salt for deployment.
2

Prepare Token Approvals and Initial Balances

Ensure the deploying contract has sufficient token allowances and determine initial liquidity.

Detailed Instructions

Before pool creation, the deployer must grant the Balancer Vault contract unlimited or sufficient allowance for each token in the pool via the IERC20.approve() function. The Vault holds all pool assets. Simultaneously, calculate the initial mint BPT amount by deciding on the initial investment for each asset. The pool's initial BPT supply will be minted to the recipient address based on these deposits. The amounts must respect the defined weights to avoid immediate arbitrage; for example, in a 50/50 WBTC/WETH pool, the USD value of each deposit should be equal. Use a helper library like WeightedMath to calculate the expected BPT output for given deposits to inform your transaction.

  • Sub-step 1: For each token, call token.approve(vaultAddress, MAX_UINT256).
  • Sub-step 2: Determine the initialBalances[] array in token native decimals.
  • Sub-step 3: Use WeightedMath._calcBptOutGivenExactTokensIn to estimate minted BPT.
  • Sub-step 4: Specify the recipient address for the initial BPT.
3

Deploy via WeightedPoolFactory

Call the factory contract to create a new WeightedPool instance.

Detailed Instructions

Interact with the verified WeightedPoolFactory contract. Call its create function with a struct containing all parameters. This function will deploy a new WeightedPool contract via CREATE2, register it with the Vault, and fund it with the initial balances. The function returns the new pool's address and its unique Vault poolId. This poolId is a keccak256 hash of the pool address and a specialization identifier, used in all future Vault interactions. Monitor the transaction for the PoolCreated event. After deployment, the pool is in an unpaused state by default, but the owner can later enable emergency pauses if a vulnerability is detected.

solidity
IWeightedPoolFactory factory = IWeightedPoolFactory(0x...); (address poolAddress, bytes32 poolId) = factory.create( "My Pool Token", "MPT", tokens, weights, swapFeePercentage, owner, salt );

Tip: Always verify the factory address on the target network (e.g., Ethereum Mainnet: 0x8E9aa87E45e92bad84D5F8DD1bff34Fb92637dE9).

4

Initialize Pool Liquidity via the Vault

Fund the newly created pool with the initial token deposits to mint the first BPT.

Detailed Instructions

The factory's create function internally calls the Vault to initialize the pool. However, you must separately execute the joinPool transaction to provide the initial liquidity. Construct a JoinPoolRequest for the Vault. Use the EXACT_TOKENS_IN_FOR_BPT_OUT join kind, providing the initialBalances array and a minimum BPT amount out (slippage tolerance). This request is passed to IVault.joinPool(poolId, sender, recipient, request). The sender must be the address holding the tokens (likely the deployer). Upon success, the Vault transfers tokens from the sender to its internal balances and mints BPT to the recipient. The pool is now active and ready for swaps.

  • Sub-step 1: Encode a JoinPoolRequest with joinKind 1 (ExactTokensInForBptOut).
  • Sub-step 2: Set maxAmountsIn as your initialBalances.
  • Sub-step 3: Calculate and set minimumBptAmountOut with slippage (e.g., 0.995 * estimated BPT).
  • Sub-step 4: Call vault.joinPool(poolId, sender, recipient, request).
5

Post-Deployment Configuration and Verification

Set optional pool parameters and verify the deployment was successful.

Detailed Instructions

After the pool is live, the owner address can execute administrative functions on the pool contract itself. This includes setting optional swap fee parameters (if the pool was created with swap fee governance enabled), updating the protocol fee percentage, or enabling an emergency pause. Immediately verify the pool's state by querying the Vault for the pool's getPoolTokens(poolId), checking that balances match expectations. Register the pool with on-chain and off-chain liquidity monitors (e.g., subgraphs, DeFi Llama). For public pools, provide liquidity on a decentralized front-end like Balancer's UI by whitelisting the pool ID. Ensure the pool's amplification parameter (not applicable to standard Weighted Pools, but relevant for StablePool variants) is fixed.

  • Sub-step 1: As owner, call pool.setSwapFeePercentage(newSwapFee) if permitted.
  • Sub-step 2: Query vault.getPoolTokens(poolId) to verify reserves.
  • Sub-step 3: Check pool address on a block explorer to confirm contract creation.
  • Sub-step 4: Add pool to a front-end interface for user accessibility.

Comparing AMM Pool Designs

Comparison of key operational and economic parameters for different Automated Market Maker pool designs.

FeatureConstant Product (Uniswap V2)Weighted Pool (Balancer V2)StableSwap (Curve Finance)

Core Formula

x * y = k

∏ (B_i) ^ w_i = k

(A * ∑ x_i) + (D / (∏ x_i))

Primary Use Case

Volatile Asset Pairs

Multi-Asset Index/Portfolios

Stablecoin/Pegged Asset Pairs

Swap Fee (Typical)

0.3%

Configurable (e.g., 0.05%-1%)

0.04%

Impermanent Loss Profile

High for volatile pairs

Variable based on weight divergence

Minimal for pegged assets

Capital Efficiency

Low (requires 50/50 ratio)

Flexible (custom token weights)

Very High (low-slippage zone)

Oracle Support

Time-Weighted Average Price (TWAP)

Internal oracles from pool balances

Requires external price feeds

Governance Token Emissions

Yes (UNI)

Yes (BAL)

Yes (CRV/veCRV)

Gas Cost for Swap (Approx.)

~100k gas

~150k gas

~200k gas

Liquidity Provision Strategies

Understanding Your Role

Providing liquidity means depositing token pairs into a pool so others can trade. You earn fees from every swap. In a Weighted Pool, like those on Balancer, you can deposit more than two assets with custom weightings (e.g., 80% ETH, 20% WBTC). This design lets you create a personalized portfolio that earns yield.

Key Considerations

  • Impermanent Loss (IL): Your portfolio value changes vs. holding assets separately when prices diverge. Pools with stable assets (like DAI/USDC) have lower IL risk.
  • Fee Earnings: Revenue comes from trading fees, which are higher during volatile markets. Concentrated liquidity pools on Uniswap V3 can amplify fees but require active management.
  • Capital Efficiency: Weighted pools allow for multi-asset exposure in a single position, reducing gas costs and management overhead compared to multiple two-asset pools.

Practical Example

When providing liquidity to a Balancer 80/20 ETH/WBTC pool, you are essentially running a mini-index fund. If ETH outperforms BTC, the pool's automated market maker (AMM) will automatically rebalance by selling some ETH for BTC to maintain the 80/20 ratio, which is the source of IL.

Calculating Risk and Impermanent Loss

Process for quantifying exposure and potential losses in weighted pools.

1

Define Pool Parameters and Initial State

Establish the baseline for all calculations.

Detailed Instructions

First, identify the pool's invariant and the weighting scheme. For a two-asset pool with assets A and B, weights are expressed as percentages (e.g., 80/20). Record the initial reserve balances (R_A, R_B) and the initial spot prices of the assets at the time of deposit. Calculate your initial LP token share as a percentage of the total supply. This share determines your claim on the pool's underlying reserves. The core relationship is defined by the constant product formula with weights: (R_A)^(w_A) * (R_B)^(w_B) = k. This invariant k is the foundation for all subsequent impermanent loss calculations.

Tip: Use on-chain data from the pool's contract or a subgraph to get precise initial reserve values, as manual estimates can introduce significant error.

2

Simulate Price Change Scenarios

Model asset price movements to assess impact.

Detailed Instructions

Define a range of price ratios for the assets. For example, if ETH (Asset A) starts at $2,000 and USDC (Asset B) at $1, simulate ETH price changes to $1,000, $4,000, etc. The key variable is the price ratio P = Price_A / Price_B. For each scenario, calculate the new equilibrium pool reserves required to satisfy the weighted invariant k. The formulas for the new reserves R_A' and R_B' given a new price ratio P' are derived from the invariant and the condition P' = (R_B' / w_B) / (R_A' / w_A). Solving these equations gives you the pool's adjusted composition after an external market move, before any fees are considered.

Tip: Automate this with a script to model multiple scenarios and visualize the non-linear relationship between price change and reserve rebalancing.

3

Calculate Value of LP Position vs. Hodling

Compare the value of your liquidity position to a simple buy-and-hold strategy.

Detailed Instructions

For each price scenario from Step 2, compute two values. First, the value of the LP position: V_lp = (your_share * R_A') * Price_A + (your_share * R_B') * Price_B. This uses the new simulated reserves. Second, the value of the initial hodled assets: V_hold = (initial_A * Price_A) + (initial_B * Price_B), where initial_A and initial_B are the amounts you originally deposited. The difference between these values, V_lp - V_hold, represents your profit and loss from providing liquidity, excluding fees. A negative result indicates impermanent loss. The magnitude of this loss is highly sensitive to the weight divergence; a 50/50 pool has a known IL formula, but an 80/20 pool will exhibit asymmetric loss profiles.

Tip: Impermanent loss is maximized when the price change is large and the weights are balanced. Extreme weights can mitigate IL for the dominant asset but increase risk for the minor asset.

4

Quantify Impermanent Loss Percentage

Express the opportunity cost as a standardized percentage.

Detailed Instructions

Calculate the impermanent loss percentage using the values from Step 3. The standard formula is IL_% = (V_lp - V_hold) / V_hold * 100. A result of -5% means your LP position is worth 5% less than if you had simply held the assets. For weighted pools, this percentage is not symmetric. A price doubling for the heavier-weighted asset may cause less IL than a price doubling for the lighter-weighted asset. Document the IL percentage across your simulated price range. Additionally, factor in pool trading fees earned during the period. The net outcome is V_lp + fees_earned. Your position is profitable overall if accumulated fees exceed the absolute value of the impermanent loss.

Tip: In low-volatility, high-volume markets, fees can often offset moderate impermanent loss, making liquidity provision profitable despite the IL.

5

Associate Risk with Pool Composition and Volatility

Evaluate how pool design and market conditions affect risk.

Detailed Instructions

Pool-specific risk is tied to its weightings. A pool with a 95/5 weight is essentially a single-sided exposure to the major asset, with high concentration risk on the minor side. Analyze the correlation between the pool's assets. Pairs with low or negative correlation (e.g., a stablecoin and a volatile asset) will experience more frequent and severe rebalancing, leading to higher IL. Use historical volatility data (e.g., annualized volatility from CoinMetrics) to estimate the likelihood of extreme price moves in your scenarios. Finally, consider divergence loss from oracles in derivative or lending pools, where internal prices may lag external markets, creating arbitrage opportunities at the LP's expense.

Tip: The highest risk often exists in pools with balanced weights containing two highly volatile, uncorrelated assets. Stablecoin/stablecoin or wrapped asset pools have near-zero IL risk.

6

Implement Monitoring and Mitigation Strategies

Set up systems to track and manage exposure.

Detailed Instructions

Continuous monitoring is essential. Use tools like The Graph to subscribe to pool reserve updates or set up alerts for significant weight drift or total value locked (TVL) changes. For mitigation, consider dynamic fee tiers (if supported by the AMM) that adjust based on volatility. Hedging strategies can involve taking offsetting positions in derivatives (e.g., shorting the asset you are effectively long on due to pool weights). Programmatic range orders or concentrated liquidity, if available, allow you to provide capital only within a specified price range, limiting exposure. Regularly re-evaluate your position using the steps above, especially after major market events.

Tip: Simple monitoring can be scripted using the pool's contract getReserves() function and an external price feed via an oracle or DEX aggregator API.

SECTION-ADVANCED_MECHANICS

Advanced Pool Mechanics and Governance

Ready to Start Building?

Let's bring your Web3 vision to life.

From concept to deployment, ChainScore helps you architect, build, and scale secure blockchain solutions.