Balancer limits are 30% Weighted Pool balance caps
Balancer limits are hard WeightedPool guards that cap an exact-in amount entering pool math at 30% of the live input-token balance and an exact-out request at 30% of the live output-token balance. In Balancer V3, the Vault scales balances and amounts to 18-decimal fixed-point units, deducts the swap fee from an exact-in amount, and then calls WeightedMath. A request beyond the applicable cap reverts rather than settling partially. The rule protects exponentiation and invariant calculations; it isn’t a slippage setting or a wallet allowance. This page maps fee ordering, balance snapshots, revert paths, route splitting, weight effects, and the separate 70% to 300% invariant corridor for unbalanced liquidity.
Updated on
Weighted Pools accept two to eight tokens, and every normalized weight must be at least 1%.
Fees change the exact-in headroom before the 30% check
Seen from the other side, Balancer V3 WeightedPool fees are pre-math deductions that reduce the exact-in amount tested against the 30% ceiling.
A standard V3 WeightedPool accepts a static swap fee from 0.001% through 10%. The Vault represents percentages in 18-decimal fixed point, stores fee fields with 24-bit precision, and resolves them in 0.00001% steps. On an exact-in swap, it rounds the total fee up, subtracts that fee, and passes the remaining scaled amount into WeightedMath. Consequently, the 30% comparison applies to net input after fees in V3, while the wallet pays the gross input and network gas. An exact-out quote applies the 30% output check first and adds its fee to the required input afterward.
Three cost drivers remain distinct: the fee that the pool charges, price impact along its weighted curve, and transaction gas. Ethereum, Arbitrum, and Base price gas in their native execution environments, so splitting an order adds calls even when it avoids a pool cap. A Balancer SDK quote must model fee ordering before comparing routes; subtracting 30% directly from a wallet amount produces the wrong exact-in boundary.
The 30% rule measures live scaled balances
The 30% swap ratio is a live-balance constraint applied separately to the input and output sides. Balancer’s Vault supplies WeightedPool with scaled balances from the transaction’s current state, after decimal scaling and applicable token rates.
The exact-in boundary follows the input token
An exact-in swap tests the net amount that reaches WeightedMath against floor(balanceIn × 0.30). The input balance belongs to the selected pool, not the wallet, token contract, or aggregate liquidity shown across Balancer. An amount equal to the integer threshold passes this particular comparison because the contract reverts only when the tested amount is greater. Other checks still apply, including the minimum calculated trade amount, the user’s minimum output, and the token-out minimum balance.
The exact-out boundary follows the output token
An exact-out swap tests the requested output against floor(balanceOut × 0.30). The contract first verifies that output quantity, then computes the input with the weighted exponent and adds the swap fee through the Vault. This direction matters when the output side is shallow: a well-funded input token doesn’t enlarge the maximum withdrawal from the selected output balance. The 30% cap resets only when the live pool balance changes, not when a user raises maximum input.
WeightedPool reverts enforce the ceiling on-chain
WeightedPool reverts are deterministic contract outcomes triggered before an oversized weighted swap updates pool balances. They consume gas only when submitted as transactions; a read-only simulation returns the same failure data without settlement.
Pool-math errors identify the breached side
Balancer V3 exposes MaxInRatio for an oversized exact-in request and MaxOutRatio for an oversized exact-out request. Balancer V2 encoded the same conditions as BAL#304 and BAL#305. Neither error means that a slippage tolerance was too tight. The errors say the selected Weighted Pool rejected the quantity before its power calculation completed.
The surrounding hard checks clarify where a failed operation belongs:
| Constraint | Durable boundary | Failure signal | Security tier |
|---|---|---|---|
| Exact-in weighted swap | At most 30% of scaled input balance after fee |
MaxInRatio
|
Pool-math hard limit |
| Exact-out weighted swap | At most 30% of scaled output balance |
MaxOutRatio
|
Pool-math hard limit |
| Normalized token weight | At least 1% |
MinWeight
|
Pool-construction hard limit |
| Normalized weight sum | Exactly 100% |
NormalizedWeightInvariant
|
Pool-construction hard limit |
| Unbalanced add invariant | At most 300% |
InvariantRatioAboveMax
|
Liquidity-math hard limit |
| Unbalanced remove invariant | At least 70% |
InvariantRatioBelowMin
|
Liquidity-math hard limit |
| Live token balance | Configured minimum, never below 1,000,000 scaled18 units |
TokenBalanceBelowMin
|
Pool-balance hard limit |
| Summary | Seven enforced boundaries | Creation or execution reverts | Protocol-level hard checks |
Factory and liquidity checks use separate error families
Construction checks fix the Weighted Pool’s shape before trading starts. A standard V3 WeightedPool holds from two through eight ERC-20 tokens, assigns each at least 1%, and requires all normalized weights to total 100%. Liquidity checks use invariant ratios instead. The shared enforcement style is a full revert, but quote software should preserve each error name because the corrective action differs.
The Balancer Router, Balancer SDK, and EVM simulation tools should reject impossible calldata before a wallet submits it. Raising gas, widening slippage, or increasing an ERC-20 allowance won’t cure MaxInRatio. A valid correction changes the pool, route, amount, or swap kind. That distinction prevents repeated submissions of the same mathematically invalid order.
A single pool balance determines the usable size
The usable Balancer swap size is a balance-based quantity, not a percentage of total pool value. Each token side receives its own threshold.
WeightedMath rejects an exact-in amount above 30% of balanceIn and an exact-out amount above 30% of balanceOut.
Balancer limits therefore move whenever liquidity, swaps, fees, or rate-provider updates alter those live scaled balances. V3 accepts tokens with no more than 18 decimals and normalizes supported amounts into scaled18 units. The Vault also packs raw and derived balances into two 128-bit fields, placing an outer storage ceiling of 2
128
− 1 on each packed value. Those representation limits sit outside the much smaller 30% trading boundary.
Route splitting distributes size across independent pools
Route splitting is an execution method that allocates one order across several pools beneath each independent 30% cap. Balancer’s Smart Order Router and Balancer API can return multi-path quotes, while the Balancer SDK builds the corresponding calls. Every Weighted Pool still runs its own check against its own live balance. Repeating swaps against one pool changes its balances and compounds price impact; using genuinely separate pools adds capacity, though extra legs increase gas and execution dependencies.
Slippage bounds and pool caps fail at different layers
Swap limits are user-specified settlement bounds that operate independently from WeightedMath’s fixed pool-balance ratios.
For an exact-in call, the Vault compares calculated output with the caller’s minimum output and raises SwapLimit when output falls short. For exact-out, it compares calculated input with the caller’s maximum input and raises the same error when input is too high. A transaction can sit below 30% and still fail its user bound after price movement. It can also satisfy generous slippage settings yet revert at MaxInRatio or MaxOutRatio. Decoding the error separates a stale quote from a mathematically oversized swap.
Token weights shape price impact before the cap
Normalized weights are immutable WeightedPool parameters that set the curve’s exponent while leaving both 30% swap ratios unchanged. A standard pool supports two to eight tokens, every weight starts at 1% or higher, and the complete set equals 100%.
A 50/50 pair keeps the exponent symmetric
In a 50/50 Weighted Pool, weightIn ÷ weightOut equals 1 for either direction. The familiar constant-product shape still steepens as one reserve falls, so a trade near 30% carries substantial price impact before it reaches the hard ceiling. The cap protects the numerical domain; it doesn’t promise an economical quote at the boundary.
An 80/20 pair makes direction decisive
In an 80/20 pool, the exponent is 4 in one direction and 0.25 in the reverse direction. The same 30% balance fraction therefore produces different output and price impact by direction. WeightedMath rounds output down and required input up, favoring the pool across both paths. Quotes for WETH, BAL, USDC, or any other supported ERC-20 pair must preserve token order, normalized weights, fee order, and live balances.
Unbalanced liquidity uses a 70% to 300% invariant corridor
Invariant-ratio bounds are liquidity-operation constraints that protect Weighted Pool calculations outside ordinary token-to-token swaps. They govern disproportionate adds and removes that mint or burn Balancer Pool Tokens.
Either way, Balancer V3 sets the maximum new-to-old invariant ratio for an unbalanced add at 300%, or 3.00. It sets the minimum ratio for an unbalanced remove at 70%, or 0.70. Crossing the upper side raises InvariantRatioAboveMax; crossing the lower side raises InvariantRatioBelowMin. These figures don’t mean that one token amount has a 300% deposit allowance or a 70% withdrawal allowance. WeightedMath derives the invariant from every balance and normalized weight, then the Vault tests the combined ratio.
Proportional liquidity operations follow BPT supply ratios and use caller-supplied maximum inputs or minimum outputs. Unbalanced operations also charge the pool’s swap fee on the taxable imbalance. That fee treatment reflects the virtual swaps embedded in a disproportionate deposit or withdrawal, while the 70% and 300% bounds keep inverse-invariant calculations inside their supported numerical range. There is a fuller treatment in Balancer basics.
Balancer V2 continuity explains the enduring cap
Where that applies, Balancer V2 continuity is the historical reason integrations still describe the same 30% weighted-swap boundary. V2’s WeightedMath stored each cap as 0.3e18 and reported BAL#304 or BAL#305. V3 expresses the constants as 30e16 and returns named custom errors, while retaining the 70% minimum and 300% maximum invariant ratios. Error decoding changed; the central weighted-math limits did not.
Practical questions about Balancer limits
Does an ERC-20 allowance change the 30% Balancer ceiling?
An ERC-20 allowance doesn’t change the WeightedMath 30% ceiling. The allowance only authorizes the Balancer Router or Vault transfer path to move a stated quantity from the wallet. If allowance is too small, token transfer logic fails before settlement; if allowance is sufficient but the pool amount exceeds its ratio, MaxInRatio or MaxOutRatio still ends the transaction. These checks use different state and solve different constraints.
Can rounding make a trade displayed at exactly 30% fail?
An amount displayed as exactly 30% can still fail after conversion, rounding, or a balance update. Balancer V3 compares 18-decimal scaled values, rounds exact-in fees up, and rounds the 30% product down. Another transaction can also change the live balance between quote and execution. A route should leave headroom below the displayed boundary and use a fresh on-chain query for the final integer amounts.
When should a Balancer quote near the cap be refreshed?
Refresh a near-cap quote immediately before building or submitting the transaction. The relevant balance changes whenever that pool processes swaps, adds liquidity, removes liquidity, yield-fee accounting, or a rate update for a rate-bearing token. A quote has no protocol-guaranteed lifetime measured in blocks. Its usable window ends as soon as state changes enough to move the scaled 30% threshold below the quoted amount.
Do rate-provider tokens change how the 30% ratio is measured?
Rate-provider tokens don’t replace the 30% ratio; they change the scaled values used in that comparison. Balancer V3 converts raw balances and raw amounts to 18-decimal live units using decimal scaling and the configured token rate. Because both sides enter the same accounting system, the limit remains percentage-based. A refreshed rate can still alter rounding, minimum-balance checks, and the exact raw-token amount that fits.
Which limit applies after a Balancer hook adjusts the result?
A Balancer V3 hook-adjusted result must still respect the user’s settlement bound. If an after-swap hook changes the calculated amount beyond the supplied minimum output or maximum input, the Vault raises HookAdjustedSwapLimit. The original WeightedPool calculation already passed MaxInRatio or MaxOutRatio before that stage. Integrators therefore need to decode both pool-math errors and Vault or hook limit errors rather than treating every revert as the 30% cap.
Can Balancer governance or a pool manager raise the 30% limit?
Balancer governance and pool managers can’t raise the standard WeightedPool 30% ceiling. MaxInRatio and MaxOutRatio are compiled constants inside WeightedMath, not mutable pool parameters. Authorized roles can update settings such as the static swap fee within its permitted bounds, but that doesn’t rewrite either ratio. A different pool implementation can use different math and therefore needs its own limit handling rather than standard WeightedPool assumptions.
Do Balancer Stable Pools use the Weighted Pool 30% cap?
Balancer Stable Pools don’t use WeightedMath’s 30% max-in and max-out guards. Their StableMath calculation instead requires the integer quotient between the highest and lowest live balances to stay below 10,000, supports at most five tokens, and uses a 60% to 500% invariant-ratio corridor for unbalanced liquidity. Stable Pools and Weighted Pools therefore need separate quote validation and error handling, even when both execute through the Balancer Vault.