Error Codes
Debug table of revert strings encountered when calling yb-core contracts. Strings are drawn from
yb-core-mastersource. ERC-4626 strings (erc4626: deposit/mint/withdraw/redeem more than maximum) are listed once per family rather than repeated for each method.
Core
LT.vy
| String | Cause |
|---|---|
Access | Caller neither admin nor factory admin |
Already set | Second set_amm |
Slippage | min_shares / min_assets not met |
Debt too high | Deposit/redeem value would exceed AMM.max_debt() / 2 |
Withdrawing nothing | withdraw(0) |
Withdraw to/from staker | Staker is msg.sender or receiver |
We're dead. Use emergency_withdraw | Normal withdraw while AMM killed |
Remainder too small | Supply would drop below MIN_SHARE_REMAINDER (1e6) |
Deposit to staker | receiver == staker in deposit |
N>2 | Constructor: Cryptoswap pool has more than 2 coins (coins(2) did not revert) |
receiver | emergency_withdraw: emergency-admin / admin caller must set receiver == owner |
owner | emergency_withdraw: non-owner caller is not the position owner |
Not killed | Emergency withdrawal path used while AMM is live |
Need factory | withdraw_admin_fees called when admin is not a factory contract |
Killed | Admin-fee withdrawal while AMM killed |
No fee_receiver | Factory fee receiver is unset |
Staker=fee_receiver | Fee receiver equals staker |
Loss made admin fee negative | Admin-fee withdrawal attempted while admin bucket is negative |
Staker already set | Second set_staker |
GAS | Gauge checkpoint retry path: _checkpoint_gauge falls back to a fixed-gas call (200k) and requires the caller to supply at least that much — guards against gas-griefing of reward checkpoints |
AMM.vy
| String | Cause |
|---|---|
Fee too high | Constructor: fee > MAX_FEE (10%). set_fee reverts without a message on the same check. |
Unsafe min | debt < coll_value · MIN_SAFE_DEBT / 1e18 |
Unsafe max | debt > coll_value · MAX_SAFE_DEBT / 1e18 |
Access | set_rate / set_fee / set_killed from non-LT |
Access violation | _deposit / _withdraw from non-LT |
Rate too high | rate > MAX_RATE (100% APR) |
Amount too large | get_dy(i=0, in_amount > debt) |
Slippage | exchange with out < min_out |
Empty AMM | exchange with collateral_amount == 0 |
Bad final state | Post-swap x0 < x0_pre |
VirtualPool.vy
| String | Cause |
|---|---|
Wrong caller | onFlashLoan not from FACTORY.flash() |
Slippage | Output below min_out |
Factory.vy
| String | Cause |
|---|---|
Access | Non-admin on admin function |
Wrong stablecoin | Pool's coin 0 ≠ factory STABLECOIN |
Only set once | set_mint_factory re-called |
Minter | set_allocator targets mint_factory |
Already set | set_gauge_controller re-called |
Admin fee too high | min_admin_fee > 1e18 |
Bad aggregator | Init / set_agg with agg.price() ∉ [0.9e18, 1.1e18) (open interval, both ends) |
Too many markets | market_count ≥ 50000 |
Nonexistent market | fill_staker_vpool(i ≥ market_count) |
HybridVault.vy
| String | Cause |
|---|---|
Already initialized | Re-init |
Access | Generic non-owner caller on owner-only function (deposit, withdraw, emergency_withdraw, stake, unstake, redeem_crvusd, withdraw_scrvusd, recover_tokens) |
Only admin | set_personal_limit from non-vault-factory-admin |
Only owner | Owner-gated call from non-owner (set_crvusd_vault) |
Vault not allowed | New crvusd_vault not in allow-list |
Has active positions | set_crvusd_vault while positions exist |
Bad pool_id | market.lt == 0 |
Not enough crvUSD | Insufficient backing without deposit_stablecoins flag |
Beyond pool limit | Deposit exceeds cap |
Debt made too high | Sanity: debt > 1.1 · additional_crvusd |
No liquidity given | lt_shares == 0 from deposit |
Cannot withdraw stables | Oracle broken, not opting into stablecoin path |
Not enough crvUSD left | Backing would drop below requirement |
Token not allowed | recover_tokens targets protected token |
Oracle is broken | Global and per-pool oracle both fail |
Zero shares | emergency_withdraw(0) |
HybridVaultFactory.vy
| String | Cause |
|---|---|
Already created | User already has a vault |
Vault not allowed | crvusd_vault not in allow-list |
Vault impl not set | vault_impl == 0 |
Access | Non-ADMIN on admin function |
Only vaults can call | update_* from non-registered vault |
Vault wind-down | Requirement increase on disallowed vault |
Beyond vault limit | Increase exceeds crvusd_vault_limits |
LTMigrator.vy
| String | Cause |
|---|---|
lt_to deprecated | Migration target has been deprecated |
not enough out | shares_out < min_out in migrate_staked |
DAO
YB.vy
| String | Cause |
|---|---|
erc20: access is denied | emit not from a minter |
VotingEscrow.vy
| String | Cause |
|---|---|
Min value | create_lock / increase_amount value < UMAXTIME |
Withdraw old tokens first | create_lock with existing lock |
Can only lock until time in the future | unlock_time ≤ now |
Voting lock can be 4 years max | Exceeds 4y |
No existing lock found | increase_amount on empty |
Cannot add to expired lock. Withdraw | Expired lock |
Nothing is locked | increase_unlock_time on empty |
Lock expired | Expired lock |
Can only increase lock duration | New end ≤ current end |
Not allowed | infinite_lock_toggle blocked by clearance checker |
The lock didn't expire | withdraw before expiry |
Not supported | delegate / delegateBySig |
erc721: caller is not token owner or approved | Transfer auth fail |
Wrong token ID | Token ID mismatches owner's address |
Need max veLock | Transfer with non-max or non-infinite locks |
GaugeController.vy
| String | Cause |
|---|---|
Gauge already added | Duplicate gauge registration |
Gauge not alive | Gauge has no live weight |
Vote checker not set | veYB's transfer_clearance_checker ≠ this |
Mismatch in lengths | Array-length mismatch |
Expired | User's veYB lock expired |
Weight too large | Single weight > 10000 bps |
Killed | Voting for killed gauge |
Gauge not added | Unregistered gauge (vote_for_gauge_weights or set_killed) |
Cannot vote so often | Same-gauge re-vote within 10 days |
Used too much power | Sum of veYB vote weights across gauges exceeds 10000 bps (100%) after this vote |
LiquidityGauge.vy
| String | Cause |
|---|---|
YB | add_reward / deposit_reward targets YB |
LP_TOKEN | add_reward targets LT |
Already added | Duplicate add_reward |
Not added | Unknown reward in change_reward_distributor / deposit_reward |
No rewards | deposit_reward(0) |
Finishes in the past | New finish time ≤ now |
Rate unknown | Extending past old finish time |
No reward | Zero distributor |
erc4626: deposit/mint/withdraw/redeem more than maximum | Cap breach |
receiver | Kill-mode redeem with receiver ≠ owner |
FeeDistributor.vy
| String | Cause |
|---|---|
Ded | fill_epochs when killed |
Might be a vest | Fee claim routed through a vesting escrow when direct receiver rules do not allow it |
InflationaryVest.vy
| String | Cause |
|---|---|
Admin required | start / set_recipient from non-owner |
Already started | Second start() |
VestingEscrow.vy
| String | Cause |
|---|---|
Lengths mismatch | fund with mismatched arrays |
Rugged | Re-target rugged recipient |
Disabled | Re-fund disabled recipient |
Cannot disable | toggle_disable when can_disable = False |
Not disabled | rug_disabled on enabled |
CliffEscrow.vy
| String | Cause |
|---|---|
Empty recipient | initialize(recipient=0) |
Already initialized | Re-init |
Cliff still applies | Transfer/approve before unlock_time |
Not authorized | Non-recipient ve op |
Cannot recover YB | recover_token(YB) |
SnapshotSplitter.vy
| String | Cause |
|---|---|
Already claimed | Double-claim |
CallComparator.vy
| String | Cause |
|---|---|
Not equal | check_equal |
Equal | check_nonequal |
Not greater | check_gt |
Not less | check_lt |
Timestamp not greater | check_timestamp_gt |
Timestamp not less | check_timestamp_lt |
Too early | check_called_after rate limit |
TokenSender, Multisend, StakeZap
No custom revert strings. Fail on token-transfer reverts.