Foundational principles governing the design and behavior of constant function automated market makers with non-equal token weights.
Weighted Pools and Multi-Asset Liquidity Designs
Core Concepts of Weighted Pools
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.
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
swapFeePercentageas a WAD (18 decimal) value. - Sub-step 4: Designate the
owneraddress and asaltfor deployment.
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._calcBptOutGivenExactTokensInto estimate minted BPT. - Sub-step 4: Specify the
recipientaddress for the initial BPT.
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.
solidityIWeightedPoolFactory 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).
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
JoinPoolRequestwith joinKind1(ExactTokensInForBptOut). - Sub-step 2: Set
maxAmountsInas yourinitialBalances. - Sub-step 3: Calculate and set
minimumBptAmountOutwith slippage (e.g., 0.995 * estimated BPT). - Sub-step 4: Call
vault.joinPool(poolId, sender, recipient, request).
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.
| Feature | Constant 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.
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.
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.
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.
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.
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.
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.
Advanced Pool Mechanics and Governance
Protocol Implementations and Resources
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.