Solidity and smart contract interview questions covering security, gas optimisation, DeFi patterns, and EVM fundamentals.
State the pattern clearly: "I follow checks-effects-interactions religiously — validate inputs, update state, then make external calls. I also use OpenZeppelin ReentrancyGuard as defence in depth."
Reentrancy occurs when a contract makes an external call before updating its own state, allowing the called contract to re-enter and repeat the action (e.g., withdraw funds multiple times). The DAO hack (2016) exploited this to drain 3.6M ETH. Prevention: checks-effects-interactions pattern (update state before external calls), ReentrancyGuard modifier (OpenZeppelin), or pull payment pattern. Strong candidates discuss read-only reentrancy via view functions and cross-function reentrancy.
Fundamental smart contract security. Candidates who cannot explain reentrancy should not be writing contracts that handle funds. Ask about cross-function reentrancy to test depth beyond the basic single-function case.
Lead with the biggest wins: "Packing structs into fewer storage slots saves thousands of gas per transaction. After that, caching storage reads in memory variables and using calldata for read-only function parameters."
Storage is the most expensive operation (~20,000 gas for SSTORE). Optimisations: pack struct variables to fill 32-byte storage slots, use memory/calldata instead of storage for temporary data, cache storage reads in local variables, use events instead of storage for data only needed off-chain, use mappings instead of arrays when possible, and batch operations. Strong candidates discuss EIP-2929 cold/warm storage access costs, SSTORE refunds, and when to use immutable/constant.
Critical for production smart contracts where users pay gas. Candidates who write readable but gas-wasteful code need to understand the real cost. Ask them to estimate gas savings from a specific optimisation.
Show layered thinking: "I use OpenZeppelin AccessControl for role-based permissions, behind a timelock for admin functions, with a multi-sig as the timelock admin. This gives transparency and time for users to react."
Approaches: simple owner pattern (Ownable), role-based access (AccessControl from OpenZeppelin), multi-sig requirements, time-locks for sensitive operations, and governance voting. Trade-offs: single owner is simple but a single point of failure; role-based is more flexible but more complex; multi-sig adds security but operational overhead. Strong candidates discuss: renouncing ownership, two-step ownership transfer, and the risks of upgradeability combined with access control.
Tests security architecture thinking. Contracts with weak access control are frequently exploited. Candidates who only know the Ownable pattern may not have built production-grade systems.
Address the trust trade-off: "Upgradeable contracts sacrifice immutability for flexibility. I use UUPS with a timelock and storage gaps. Every upgrade is tested against the previous storage layout."
Proxy contracts delegate calls to an implementation contract via delegatecall. The proxy holds storage; the implementation holds logic. Patterns: Transparent Proxy (admin vs user call routing), UUPS (upgrade logic in implementation). Risks: storage collision between proxy and implementation, initializer re-execution (use initializer modifier instead of constructor), function selector clashes, and centralised upgrade authority. Mitigation: use OpenZeppelin libraries, thorough testing of upgrade paths, storage gap patterns, and timelocks on upgrades.
Senior Solidity question. Proxy patterns are powerful but dangerous. Candidates who cannot explain storage layout risks will introduce critical bugs. Ask about a specific upgrade they have performed.
Describe the full pipeline: "Unit tests in Foundry for logic, fuzz tests for edge cases, Slither for static analysis, fork tests against mainnet, then external audit. Post-launch, we run a bug bounty on Immunefi."
Layered testing: unit tests (Foundry/Hardhat) for individual functions, integration tests for contract interactions, fuzz testing (Foundry fuzz or Echidna) for edge cases, formal verification for critical invariants, fork testing against mainnet state, and gas benchmarks. Pre-deployment: internal review, external audit for high-value contracts, bug bounty programme post-launch. Strong candidates mention Slither for static analysis and specific fuzzing strategies.
Tests professional practices. Smart contracts are immutable and handle real value — inadequate testing is unacceptable. Candidates who only write basic unit tests are not ready for production contracts. Ask about a bug their testing caught.
Walk through methodically: "Transaction enters mempool, validator orders by priority fee, EVM executes opcodes consuming gas, state is applied atomically on success or fully reverted on failure, block is finalised by consensus."
Transaction lifecycle: user signs transaction, broadcasts to mempool, validator/miner selects and includes in block, EVM executes bytecode in a sandboxed environment (stack-based, 256-bit words), state changes are applied if execution succeeds (or reverted on failure), gas is consumed per opcode, block is proposed and finalised by consensus. Strong candidates discuss: gas estimation, nonce management, EIP-1559 fee mechanism, and the difference between transaction execution and block finality.
Foundational EVM knowledge. Candidates who cannot explain execution at this level will struggle to debug on-chain issues or optimise gas. Ask what happens when a transaction runs out of gas mid-execution.
Explain the core clearly: "The constant product formula sets the price. As someone buys token A, its supply in the pool decreases, raising its price. LPs earn fees proportional to their share of the pool."
AMMs use the constant product formula (x * y = k) to determine prices. Liquidity providers deposit paired assets into pools and receive LP tokens representing their share. Swaps change the ratio, moving the price along the curve. Key patterns: pair contracts as minimal proxies, factory pattern for pool creation, flash swaps, price oracles (TWAP), and fee distribution to LPs. Strong candidates discuss: impermanent loss, concentrated liquidity (Uniswap V3), and sandwich attack protection.
Tests DeFi knowledge depth. Candidates who understand AMM mechanics can reason about a wide range of DeFi protocols. Ask about impermanent loss — it is the most common misunderstanding.
Emphasise the cost benefit: "Events cost around 375 gas plus 8 gas per byte versus 20,000 for SSTORE. I use events for all state changes that frontends need to track and index the key lookup fields."
Events emit log entries stored in transaction receipts, not in contract storage (much cheaper than storage). Indexed parameters (up to 3) become log topics that can be efficiently filtered by indexing services like The Graph or ethers.js event filters. Non-indexed parameters are ABI-encoded in the data field. Use cases: tracking state changes for frontends, building off-chain indexes, audit trails, and cross-contract communication. Strong candidates discuss event-driven architecture with The Graph subgraphs.
Fundamental Solidity pattern. Candidates who store data on-chain that should be in events waste user gas. Those who understand the indexing pipeline (events to The Graph to frontend) have built real dapps.
Prioritise by impact: "Oracle manipulation and access control flaws cause the biggest losses after reentrancy. I use Chainlink for price feeds, TWAP for on-chain prices, and OpenZeppelin AccessControl with timelocks for admin functions."
Critical vulnerabilities: integer overflow/underflow (Solidity 0.8+ has built-in checks), front-running/MEV (commit-reveal schemes, private mempools), oracle manipulation (TWAP over multiple blocks, multiple oracle sources), access control flaws, unchecked external call return values, denial of service (unbounded loops, block gas limit), and flash loan attacks on governance. Strong candidates prioritise by real-world exploit frequency and discuss specific mitigation patterns for each.
Tests security breadth. Candidates focused only on reentrancy miss the majority of real exploits. Those who can discuss oracle manipulation, flash loan governance attacks, and front-running demonstrate production security awareness.
Frame it as a trust question: "Only put logic on-chain when users need to verify it without trusting anyone. Everything else goes off-chain to reduce cost and increase flexibility."
On-chain: asset ownership, critical business rules that require trustlessness, token transfers, governance votes. Off-chain: complex computation, data storage, user interfaces, metadata, and anything that does not need consensus. Hybrid patterns: IPFS for data with on-chain hashes, oracles for external data, off-chain signing with on-chain verification (EIP-712), and Layer 2 for scalability. Strong candidates discuss gas cost budgets, user experience trade-offs, and the trust spectrum.
Senior architecture question. Candidates who put everything on-chain create expensive, slow systems. Those who put too little on-chain undermine the value proposition of blockchain. Look for thoughtful trade-off reasoning.