# evm-internals Knowledge about the Ethereum Virtual Machine's execution model, opcodes, gas mechanics, storage layout, memory model, and runtime behavior. ## Storage & Memory - [[solidity compiler packs multiple small values into one storage slot but writing requires reading the full slot]]: read-modify-write pattern for packed slots - [[storage variable ordering affects gas costs because suboptimal ordering wastes storage slots]]: declaration order determines packing efficiency - [[memory and calldata values are not packed unlike storage]]: packing is a storage-only optimization - [[transient storage introduces new storage semantics with novel security implications]]: EIP-1153, new bug classes emerging - [[transient storage violates composability assumptions in multi-contract interactions because values persist across external calls within a transaction]]: transaction-scoped persistence creates cross-call state leakage - [[custom storage layouts enable powerful proxy patterns but manual slot math errors can corrupt data]]: manual slot computation risks - [[storage layout must remain consistent across proxy implementation versions]]: proxy storage consistency requirement - [[arbitrary storage writes enable attackers to overwrite critical variables when dynamic array slot calculations are manipulable]]: dynamic array slot wrapping enables any-slot writes - [[dangling storage references from array pop operations allow writes to unintended storage locations]]: .pop() creates dangling references to invalid slot positions - [[solidity delete on mappings contained within arrays leaves orphaned data in storage because mappings cannot track their keys]]: mapping data persists after containing array deletion - [[memory-to-memory assignment in solidity creates references not copies enabling aliasing bugs when both variables modify the same data]]: memory assignment creates references, not copies - [[unbounded return data from external calls forces quadratic memory cost gas consumption via RETURNDATASIZE]]: EIP-211 return data auto-copy creates gas griefing vector ## Memory Layout - [[Solidity scratch space at memory addresses 0x00-0x3f is overwritten by mapping and array storage slot calculations between assembly blocks]]: scratch space corrupted by compiler hash computation between assembly blocks; distinct from FMP corruption at 0x40 ## Gas Mechanics - [[evm memory gas costs grow quadratically making large allocations prohibitively expensive]]: quadratic memory expansion cost formula - [[EIP-2929 warm and cold storage access costs create gas-limit dependent reentrancy guard failures in contracts using hardcoded gas amounts]]: cold/warm access cost divergence broke 2300 gas stipend reentrancy prevention, motivating send/transfer deprecation ## Execution Model - [[hand-written EVM code shares a specific set of vulnerability classes that are structurally impossible in compiler-generated code]]: synthesis of six compiler-absent safety guarantees in Huff, Yul, and raw EVM bytecode - [[delegatecall executes code from another contract using the callers storage context]]: foundation of all proxy patterns - [[writing contract logic in yul or assembly can bypass access control mechanisms only implemented in solidity]]: assembly bypasses compiler-level protections - [[low-level calls to non-existent contracts succeed silently because the EVM treats empty addresses as successful]]: CALL to empty address returns true - [[EXTCODESIZE returns zero during constructor execution allowing contracts to bypass code-size-based EOA checks]]: constructor timing defeats code-size checks - [[EVM opcode incompatibility across chains causes failures when contracts assume uniform opcode support]]: PUSH0, CREATE/CREATE2, SELFDESTRUCT semantics differ across L2s; enriched with OpDiffer findings and metamorphic pattern cross-chain divergence - [[CREATE2 enables contract recreation at the same address with different bytecode when the constructor queries external state]]: deterministic address reuse enables address-squatting attacks - [[CREATE2 enables metamorphic contract attacks by allowing a self-destructed contract to be redeployed with different bytecode at the same trusted address]]: selfdestruct + same-salt redeploy breaks address-based trust; governance bait-and-switch; mitigated by EIP-6780 on Cancun chains - [[newer EVM opcodes introduced in recent forks are disproportionately buggy across implementations because implementations lag specification maturity]]: OpDiffer ISSTA 2025: 26 bugs in 9 implementations; 7.21% of deployed contracts affected; PUSH0/TSTORE/MCOPY disproportionate - [[metamorphic contract patterns remain exploitable on L2s that have not adopted EIP-6780 Cancun changes]]: SELFDESTRUCT semantics diverge across chains; L1 restriction from EIP-6780 does not extend to non-adopting L2s - [[solidity pure functions use STATICCALL but cannot prevent state reads at the EVM level creating a false safety guarantee]]: STATICCALL prevents writes but not reads, pure guarantee is compiler-only - [[yul division by zero returns zero rather than reverting unlike solidity checked arithmetic]]: EVM div/mod opcodes return 0 on zero divisor, no exception - [[signed integer division overflow occurs when dividing the minimum value by negative one because the positive result exceeds the type maximum]]: EVM sdiv of int_min by -1 silently wraps; the only division producing a nonzero wrong result - [[low-level EVM code must explicitly validate calldata input bit widths because the EVM performs no type-level masking on function parameters]]: calldata arrives as raw 256-bit words; compiler masking absent in Yul/Huff/assembly - [[hand-written EVM function dispatchers that lack a terminal revert allow execution to fall through into unrelated bytecode]]: missing terminal revert in Huff/raw EVM dispatch causes unintended code execution from unrecognized selectors ## Precompiles - [[EVM precompiles for BN256 elliptic curve operations never revert on invalid input requiring explicit return value checks to detect proof verification failures]]: ecAdd (0x06), ecMul (0x07), ecPairing (0x08); unchecked return value means invalid ZK proofs silently pass; EIP-196, 197, 1108 - [[EVM-compatible chain precompile implementations diverge from mainnet specifications creating silent failures for contracts that are safe on Ethereum]]: Moonbeam reverts on under-length input; Aurora v2.7.0 reverts on identity point; 7.21% of contracts affected by cross-chain incompatibilities - [[BLS signature aggregation enables rogue-key attacks where an attacker forges multi-signatures by registering a cancellation public key]]: EIP-2537 (BLS12-381) in Pectra makes BLS verification native to Solidity; rogue-key resistance requires either PoP with domain-separated hash functions or BDN construction ## Tensions - Storage packing saves gas but creates complexity: [[solidity compiler packs multiple small values into one storage slot but writing requires reading the full slot]] saves SSTORE calls but requires the read-modify-write pattern, and in proxy contexts since [[storage layout must remain consistent across proxy implementation versions]], packing decisions are permanently locked. - Custom storage layouts enable flexibility but introduce manual computation risk: [[custom storage layouts enable powerful proxy patterns but manual slot math errors can corrupt data]] represents the tradeoff between compiler-guaranteed safety and developer-controlled precision. <!-- ## Open Questions - What is the gas impact profile of quadratic memory costs in real-world contracts, how often do contracts approach the quadratic region? --> Topics: - [[index]]