Solidity Panic 0x12: Division or Modulo by Zero Resolution
Solidity Panic 0x12 (selector 0x4e487b71) occurs when a smart contract attempts a division (/) or modulo (%) operation where the divisor evaluates to zero. Division by zero is mathematically undefined and cannot be executed by the EVM. This error commonly appears in DeFi contracts when calculating token exchange ratios on empty liquidity pools, or when calculating reward distributions with zero total staked tokens. Add zero-checks to divisors.
# Root Cause & Technical Architecture
In Solidity 0.8+, the compiler inserts runtime checks before any division or modulo operation. If the denominator evaluates to zero at execution time, the compiler executes an invalid assertion, triggering `revert Panic(0x12)`. This frequently happens when staking pools compute `rewardsPerToken = totalRewards / totalStaked` while `totalStaked == 0`, or when DEX AMMs calculate price formulas on uninitialized or drained liquidity reserves.
# 4-Step Actionable Diagnostic Protocol
Step-by-Step ResolutionCheck Denominators for Zero State Conditions
Inspect formula denominators: totalShares, totalSupply, timeDelta, and liquidity. Add require(denominator > 0) checks before dividing.
Verify Pool Initialization and First Deposit States
Ensure staking and vault contracts handle initial deposits separately to prevent division by an initial zero total supply.
Audit Time-Weighted Average Price (TWAP) Intervals
Ensure time elapsed (block.timestamp - lastTimestamp) cannot evaluate to 0 when multiple transactions occur within the same block.
Simulate with Foundry to Trace Denominator Value
Use forge test -vvvv to log variable states right before the reverting arithmetic instruction to identify why the divisor evaluated to zero.
# Diagnostic Verification Code / Command
solidity// Prevent Solidity Panic(0x12) with Denominator Validation
function calculateSharePrice(uint256 totalAssets, uint256 totalShares) public pure returns (uint256) {
// If totalShares == 0 -> Division triggers Panic(0x12)
if (totalShares == 0) {
return 1e18; // Default initial 1:1 exchange rate
}
return (totalAssets * 1e18) / totalShares;
} Launch ERC-4337 UserOp Decoder
Execute client-side cryptographic simulation and parameter checks safely in your browser via native WebCrypto without sending private keys or mnemonics over the wire.
Read Full Investigation & Recovery Workflow
Explore complete architectural diagrams, edge-case failure trees, and detailed post-mortem analysis in our verified deep guide.
# Related Diagnostic Codes in EVM & JSON-RPC
Related Hex StatusesJSON-RPC Error -32000: Insufficient Funds for Gas * Price + Value
Fix JSON-RPC error -32000 insufficient funds for gas * price + value. Resolve native token balance shortages, fee estimation surges, and gas caps.
JSON-RPC Error -32000: Replacement Transaction Underpriced Fix
Fix JSON-RPC error -32000 replacement transaction underpriced. Apply mandatory 10%+ maxPriorityFeePerGas bump on same nonce to replace stuck mempool txs.
JSON-RPC Error -32000: Nonce Too Low Stale Wallet State Fix
Fix JSON-RPC error -32000 nonce too low. Troubleshoot stale local wallet nonce caches, pending mempool transactions, and reset account state.
# Frequently Asked Questions
FAQ SchemaWhat is Panic code 0x12 in Solidity?
Panic code 0x12 is the compiler standard error code indicating that a division or modulo by zero was attempted.
Can unchecked blocks prevent Panic 0x12?
No. Division by zero is fundamentally impossible in the EVM instruction set. unchecked blocks only bypass overflow/underflow checks.
Why did my staking contract work until everyone withdrew?
When the last user withdrew, totalStaked dropped to 0. Subsequent reward calculations divided by 0, locking the contract until guarded.