Error Codes
All error codes for the Balancer V2 core contracts are defined in the BalancerErrors.sol
(opens in a new tab) contract. Comments and context for the specific errors can be found in the tables below.
Math
Code | Error | Comment |
---|---|---|
000 | ADD_OVERFLOW | |
001 | SUB_OVERFLOW | |
002 | SUB_UNDERFLOW | |
003 | MUL_OVERFLOW | |
004 | ZERO_DIVISION | |
005 | DIV_INTERNAL | Multiplication overflow during FixedPoint Division |
006 | X_OUT_OF_BOUNDS | Invalid x in ExpMath.pow(x, y) |
007 | Y_OUT_OF_BOUNDS | Invalid y in ExpMath.pow(x, y) |
008 | PRODUCT_OUT_OF_BOUNDS | In LogExpMath.pow(x, y), error computing x^y as exp(y * ln(x)) |
009 | INVALID_EXPONENT | In LogExpMath.exp(x) = e^x; x out of bounds |
Input
Code | Error | Comment |
---|---|---|
100 | OUT_OF_BOUNDS | |
101 | UNSORTED_ARRAY | See UNSORTED_TOKENS |
102 | UNSORTED_TOKENS | Tokens must be sorted in address order on pool registration |
103 | INPUT_LENGTH_MISMATCH | Used to ensure array inputs intended to be parallel have the same length |
104 | ZERO_TOKEN | Address to be interpreted as a token cannot be 0 |
105 | INSUFFICIENT_DATA | Used to ensure minimum bytes length |
Shared pools
Code | Error | Comment |
---|---|---|
200 | MIN_TOKENS | All pools must contain at least two tokens |
201 | MAX_TOKENS | Token count exceeds the maximum for a given pool type |
202 | MAX_SWAP_FEE_PERCENTAGE | |
203 | MIN_SWAP_FEE_PERCENTAGE | |
204 | MINIMUM_BPT | On pool initialization, a small amount of BPT is minted to the zero address (keeps math well behaved). If initial balances are too small, initialization can fail |
205 | CALLER_NOT_VAULT | Certain pool callbacks need to be external, but could be exploited if called by anyone but the Vault |
206 | UNINITIALIZED | Pools must be initialized with a special "Init" join, before they can be joined by LPs |
207 | BPT_IN_MAX_AMOUNT | Slippage/front-running protection check failed on a pool exit |
208 | BPT_OUT_MIN_AMOUNT | Slippage/front-running protection check failed on a pool join |
209 | EXPIRED_PERMIT | |
210 | NOT_TWO_TOKENS | Pools with oracles are limited to two tokens (e.g., WeightedPool2Tokens and MetastablePools). A pool with the TWO_TOKEN specialization must have exactly two tokens |
211 | DISABLED | Pool factories can be disabled to prevent new pools being created |
Pools
Code | Error | Comment |
---|---|---|
300 | MIN_AMP | Amplification factor out of range (Stable/Metastable pools) |
301 | MAX_AMP | |
302 | MIN_WEIGHT | Weighted Pool minimum weight |
303 | MAX_STABLE_TOKENS | |
304 | MAX_IN_RATIO | Token in unbalanced the pool too much on a swap |
305 | MAX_OUT_RATIO | Token out unbalanced the pool too much on a swap |
306 | MIN_BPT_IN_FOR_TOKEN_OUT | Disproportionate exit unbalanced the pool too much |
307 | MAX_OUT_BPT_FOR_TOKEN_IN | Disproportionate join unbalanced the pool too much |
308 | NORMALIZED_WEIGHT_INVARIANT | Weighted Pool normalized weights must add to 1.0 |
309 | INVALID_TOKEN | |
310 | UNHANDLED_JOIN_KIND | Some joins are pool type-specific |
311 | ZERO_INVARIANT | Pool balances must be > 0 |
312 | ORACLE_INVALID_SECONDS_QUERY | The "ago" timestamp when querying the oracle must be in the past |
313 | ORACLE_NOT_INITIALIZED | Cannot query an oracle with no data |
314 | ORACLE_QUERY_TOO_OLD | Cannot query before the oracle's earliest data sample |
315 | ORACLE_INVALID_INDEX | Cannot query a sample outside the buffer (1024) |
316 | ORACLE_BAD_SECS | Oracle query window must have non-zero duration |
317 | AMP_END_TIME_TOO_CLOSE | Amplification parameter change has less than the minimum duration |
318 | AMP_ONGOING_UPDATE | Cannot start an amplification parameter update if one is already ongoing |
319 | AMP_RATE_TOO_HIGH | The requested amplification parameter change is too fast (cannot halve or double over less than a day) |
320 | AMP_NO_ONGOING_UPDATE | Cannot cancel an update if there isn't one |
321 | STABLE_INVARIANT_DIDNT_CONVERGE | |
322 | STABLE_GET_BALANCE_DIDNT_CONVERGE | |
323 | RELAYER_NOT_CONTRACT | |
324 | BASE_POOL_RELAYER_NOT_CALLED | |
325 | REBALANCING_RELAYER_REENTERED | |
326 | GRADUAL_UPDATE_TIME_TRAVEL | start > end time in a gradual weights update |
327 | SWAPS_DISABLED | |
328 | CALLER_IS_NOT_LBP_OWNER | |
329 | PRICE_RATE_OVERFLOW | Rate returned from a rateProvider must fit in 128 bits |
330 | INVALID_JOIN_EXIT_KIND_WHILE_SWAPS_DISABLED | Investment pools only allow proportional joins and exits when swaps are disabled (to prevent unbalancing the pool) |
331 | WEIGHT_CHANGE_TOO_FAST | Gradual weight update duration too short (minimum 1 day) |
332 | LOWER_GREATER_THAN_UPPER_TARGET | Invalid Linear Pool operating range |
333 | UPPER_TARGET_TOO_HIGH | Linear Pool max balance must fit in 112 bits |
334 | UNHANDLED_BY_LINEAR_POOL | Some joins/exits are pool type-specific |
335 | OUT_OF_TARGET_RANGE | Cannot reset Linear Pool targets if pool is unbalanced |
336 | UNHANDLED_EXIT_KIND | Some exits are pool type-specific |
337 | UNAUTHORIZED_EXIT | Management fees can only be collected by the pool owner |
338 | MAX_MANAGEMENT_SWAP_FEE_PERCENTAGE | |
339 | UNHANDLED_BY_MANAGED_POOL | Some joins/exits are pool type-specific |
340 | UNHANDLED_BY_PHANTOM_POOL | Some joins/exits are pool type-specific |
341 | TOKEN_DOES_NOT_HAVE_RATE_PROVIDER | |
342 | INVALID_INITIALIZATION | |
343 | OUT_OF_NEW_TARGET_RANGE | |
344 | FEATURE_DISABLED | |
345 | UNINITIALIZED_POOL_CONTROLLER | |
346 | SET_SWAP_FEE_DURING_FEE_CHANGE | |
347 | SET_SWAP_FEE_PENDING_FEE_CHANGE | |
348 | CHANGE_TOKENS_DURING_WEIGHT_CHANGE | |
349 | CHANGE_TOKENS_PENDING_WEIGHT_CHANGE | |
350 | MAX_WEIGHT | |
351 | UNAUTHORIZED_JOIN | |
352 | MAX_MANAGEMENT_AUM_FEE_PERCENTAGE | |
353 | FRACTIONAL_TARGET | |
354 | ADD_OR_REMOVE_BPT | |
355 | INVALID_CIRCUIT_BREAKER_BOUNDS | |
356 | CIRCUIT_BREAKER_TRIPPED | |
357 | MALICIOUS_QUERY_REVERT | |
358 | JOINS_EXITS_DISABLED |
Lib
Code | Error | Comment |
---|---|---|
400 | REENTRANCY | |
401 | SENDER_NOT_ALLOWED | |
402 | PAUSED | |
403 | PAUSE_WINDOW_EXPIRED | |
404 | MAX_PAUSE_WINDOW_DURATION | |
405 | MAX_BUFFER_PERIOD_DURATION | |
406 | INSUFFICIENT_BALANCE | |
407 | INSUFFICIENT_ALLOWANCE | |
408 | ERC20_TRANSFER_FROM_ZERO_ADDRESS | |
409 | ERC20_TRANSFER_TO_ZERO_ADDRESS | |
410 | ERC20_MINT_TO_ZERO_ADDRESS | |
411 | ERC20_BURN_FROM_ZERO_ADDRESS | |
412 | ERC20_APPROVE_FROM_ZERO_ADDRESS | |
413 | ERC20_APPROVE_TO_ZERO_ADDRESS | |
414 | ERC20_TRANSFER_EXCEEDS_ALLOWANCE | |
415 | ERC20_DECREASED_ALLOWANCE_BELOW_ZERO | |
416 | ERC20_TRANSFER_EXCEEDS_BALANCE | |
417 | ERC20_BURN_EXCEEDS_ALLOWANCE | |
418 | SAFE_ERC20_CALL_FAILED | |
419 | ADDRESS_INSUFFICIENT_BALANCE | |
420 | ADDRESS_CANNOT_SEND_VALUE | |
421 | SAFE_CAST_VALUE_CANT_FIT_INT256 | |
422 | GRANT_SENDER_NOT_ADMIN | In AccessControl, the caller of grantRole must be an admin |
423 | REVOKE_SENDER_NOT_ADMIN | In AccessControl, the caller of revokeRole must be an admin |
424 | RENOUNCE_SENDER_NOT_ALLOWED | In AccessControl, callers can onlyrenounceRole for their own account |
425 | BUFFER_PERIOD_EXPIRED | |
426 | CALLER_IS_NOT_OWNER | |
427 | NEW_OWNER_IS_ZERO | |
428 | CODE_DEPLOYMENT_FAILED | |
429 | CALL_TO_NON_CONTRACT | |
430 | LOW_LEVEL_CALL_FAILED | |
431 | NOT_PAUSED | |
432 | ADDRESS_ALREADY_ALLOWLISTED | |
433 | ADDRESS_NOT_ALLOWLISTED | |
434 | ERC20_BURN_EXCEEDS_BALANCE | |
435 | INVALID_OPERATION | |
436 | CODEC_OVERFLOW | |
437 | IN_RECOVERY_MODE | |
438 | NOT_IN_RECOVERY_MODE | |
439 | INDUCED_FAILURE | |
440 | EXPIRED_SIGNATURE | |
441 | MALFORMED_SIGNATURE | |
442 | SAFE_CAST_VALUE_CANT_FIT_UINT64 | |
443 | UNHANDLED_FEE_TYPE | |
444 | BURN_FROM_ZERO |
Vault
Code | Error | Comment |
---|---|---|
500 | INVALID_POOL_ID | |
501 | CALLER_NOT_POOL | Some Vault hooks can only be called by the pool (e.g., register tokens) |
502 | SENDER_NOT_ASSET_MANAGER | |
503 | USER_DOESNT_ALLOW_RELAYER | Relayers must be allowed by both governance and the user account |
504 | INVALID_SIGNATURE | |
505 | EXIT_BELOW_MIN | Exit would yield fewer than the user-supplied minimum tokens out |
506 | JOIN_ABOVE_MAX | Join would cost more than the user-supplied maximum tokens in |
507 | SWAP_LIMIT | Swap violates user-supplied limits (min out or max in) |
508 | SWAP_DEADLINE | Swap transaction not mined within the specified deadline |
509 | CANNOT_SWAP_SAME_TOKEN | |
510 | UNKNOWN_AMOUNT_IN_FIRST_SWAP | A batch swap must start with a non-zero amount in |
511 | MALCONSTRUCTED_MULTIHOP_SWAP | |
512 | INTERNAL_BALANCE_OVERFLOW | Unused in current code |
513 | INSUFFICIENT_INTERNAL_BALANCE | |
514 | INVALID_ETH_INTERNAL_BALANCE | Cannot transfer native ETH to/from internal balance |
515 | INVALID_POST_LOAN_BALANCE | Flashloan transactions must repay the loan in the same transaction |
516 | INSUFFICIENT_ETH | |
517 | UNALLOCATED_ETH | Unused in current code |
518 | ETH_TRANSFER | Relayers cannot receive ETH directly (only through the Vault) |
519 | CANNOT_USE_ETH_SENTINEL | Internal Balance transfers cannot use ETH |
520 | TOKENS_MISMATCH | |
521 | TOKEN_NOT_REGISTERED | |
522 | TOKEN_ALREADY_REGISTERED | |
523 | TOKENS_ALREADY_SET | |
524 | TOKENS_LENGTH_MUST_BE_2 | |
525 | NONZERO_TOKEN_BALANCE | |
526 | BALANCE_TOTAL_OVERFLOW | |
527 | POOL_NO_TOKENS | |
528 | INSUFFICIENT_FLASH_LOAN_BALANCE |
Fees
Code | Error | Comment |
---|---|---|
600 | SWAP_FEE_PERCENTAGE_TOO_HIGH | |
601 | FLASH_LOAN_FEE_PERCENTAGE_TOO_HIGH | |
602 | INSUFFICIENT_FLASH_LOAN_FEE_AMOUNT |
FeeSplitter
Code | Error | Comment |
---|---|---|
700 | SPLITTER_FEE_PERCENTAGE_TOO_HIGH |
Misc
Code | Error | Comment |
---|---|---|
998 | UNIMPLEMENTED | |
999 | SHOULD_NOT_HAPPEN |