Skip to content

Smart Contract Security Interview Questions for Blockchain

25 Smart Contract Security questions with answers for blockchain roles — 5 easy, 13 medium, 7 hard.

About Smart Contract Security

Learn to think like an attacker and an auditor. This topic covers reentrancy, access control flaws, oracle manipulation with flash loans, front-running, denial of service, insecure randomness, proxy storage collisions and signature replay, along with Slither, fuzzing, invariant testing, audit preparation and incident response.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is the checks-effects-interactions pattern?

Save to ▾
Show answer
It is an ordering rule for functions. First do checks: validate inputs, permissions and balances with require. Then apply effects: update all state variables, such as reducing the user's balance. Only then do interactions: external calls, token transfers or ETH sends. Because state is already updated, a re-entering call sees the new state and cannot repeat the action. Combine it with a nonReentrant modifier for defence in depth, especially in functions calling unknown contracts.
02

How did integer overflow bugs happen before Solidity 0.8?

Save to ▾
Show answer
Before 0.8, arithmetic wrapped silently: a uint8 at 255 plus 1 became 0, and 0 minus 1 became the maximum value. Attackers exploited this, for example by making a balance underflow to a huge number or an overflowed multiplication pass a check, as in the 2018 batchOverflow token bug. Developers used the SafeMath library to revert on overflow. Since 0.8 the compiler checks automatically, except inside unchecked blocks and in inline assembly.
03

Why should you not use tx.origin for authorisation?

Save to ▾
Show answer
tx.origin is the EOA that started the transaction, while msg.sender is the immediate caller. If a contract checks require(tx.origin == owner), a phishing contract can trick the owner into calling it, and that contract then calls the victim; tx.origin is still the owner, so the check passes and funds can be stolen. Always use msg.sender for access control. tx.origin also breaks with smart contract wallets and account abstraction.
04

A user approved unlimited token spending to a scam site. What should they do?

Save to ▾
Show answer
Revoke the approval immediately using a token approval checker or by calling approve(spender, 0) from the wallet, because the malicious contract can pull tokens any time. If a drain has started, move remaining assets to a fresh wallet. Check for other suspicious approvals and NFT setApprovalForAll permissions. Going forward, approve exact amounts, read wallet prompts carefully, use a separate hot wallet for new dApps, and prefer wallets that simulate transactions before signing.
05

How do you run Slither on a Foundry project and focus on important findings?

Save to ▾
Show answer
Install it with pip and run it from the project root; it detects Foundry automatically. pip install slither-analyzer slither . # Only medium and high impact issues slither . --exclude-low --exclude-informational # Exclude dependencies slither . --filter-paths 'lib|test' # Print a summary of contracts and functions slither . --print human-summary Triage each finding: fix real bugs and record why false positives are safe.
06

What is a reentrancy attack?

Save to ▾
Show answer
Reentrancy happens when a contract makes an external call, such as sending ETH, before updating its own state, and the receiver calls back into the contract to repeat the action. For example, a withdraw that sends funds and then sets the balance to zero can be re-entered to withdraw many times. The 2016 DAO hack drained millions this way. Prevent it with checks-effects-interactions, reentrancy guards, and pull payments.
07

What are front-running and sandwich attacks, and how do you mitigate them?

Save to ▾
Show answer
Pending transactions are public, so bots can copy or outbid them. Front-running is placing a transaction ahead of a victim's, for example buying before a large purchase. A sandwich attack buys before the victim's swap and sells right after, profiting from the price impact. Mitigations include slippage limits and deadlines, commit-reveal schemes, batch auctions, private transaction relays, and design that does not reward ordering, such as using time-weighted prices.
08

What are common access control vulnerabilities?

Save to ▾
Show answer
Typical bugs include missing onlyOwner or role checks on sensitive functions such as mint, withdraw or setOracle, initialiser functions in upgradeable contracts that anyone can call, misconfigured roles, and a single EOA owning critical powers. Use OpenZeppelin Ownable2Step or AccessControl, give each role the minimum rights, protect admin actions with a multisig and timelock, and write tests confirming that every privileged function reverts for unauthorised callers.
09

How can a smart contract suffer denial of service?

Save to ▾
Show answer
Common causes: loops over arrays that grow with users until they exceed the block gas limit; push payments in a loop where one reverting recipient blocks everyone; relying on an external call that an attacker can make fail; and griefing by filling storage cheaply. For example, an auction that refunds the previous bidder will freeze if that bidder is a contract that reverts. Use pull payments, bounded loops, pagination and failure isolation.
10

Why is on-chain randomness insecure, and what should you use instead?

Save to ▾
Show answer
Values like block.timestamp, blockhash or block.prevrandao are visible to or partly controlled by block producers, and any contract can read them in the same transaction and only proceed when the outcome is favourable. So lotteries and NFT trait reveals based on them can be gamed. Use a verifiable random function such as Chainlink VRF, which delivers randomness with a cryptographic proof in a later transaction, or a commit-reveal scheme for simpler cases.
11

Why should you check return values of low-level calls and use SafeERC20?

Save to ▾
Show answer
Low-level call, send and delegatecall return false instead of reverting on failure, so ignoring the result means the contract continues as if the transfer succeeded. Similarly, some ERC-20 tokens do not return a bool from transfer, and others return false instead of reverting. OpenZeppelin's SafeERC20 wraps transfer, transferFrom and approve to handle both cases and revert on failure. Always write (bool ok, ) = to.call{value: x}(''); require(ok).
12

What is a signature replay attack and how do you prevent it?

Save to ▾
Show answer
If a contract accepts a signed message to perform an action, an attacker can resubmit the same signature to repeat it, or replay it on another chain or another contract using the same code. Prevent it by including a per-user nonce that increments on use, a deadline, the chain ID and the verifying contract address in the signed data. EIP-712 typed data with a domain separator gives a standard way to include these fields.
13

What does a smart contract audit process look like?

Save to ▾
Show answer
It starts with scoping: fixed commit, documentation, threat model and test coverage. Auditors run automated tools like Slither and fuzzers, then do manual line-by-line review, checking business logic, access control, economic attacks and integrations. They write findings rated critical, high, medium, low and informational with fixes. The team fixes issues, auditors review the fixes, and a final report is published. Audits reduce risk but do not guarantee safety, so add bug bounties and monitoring.
14

Which tools do you use for static analysis and fuzzing of smart contracts?

Save to ▾
Show answer
Slither performs static analysis and quickly flags reentrancy, unchecked calls, shadowing and more. Aderyn is another fast static analyser. Foundry provides fuzz and invariant testing, where random sequences of calls try to break properties you define. Echidna and Medusa are property-based fuzzers. Mythril and Halmos use symbolic execution, and Certora offers formal verification. Combining them with manual review and high test coverage catches far more than any single tool.
15

An auditor flags that a single owner key can mint tokens and change fees. How do you address it?

Save to ▾
Show answer
This is centralisation risk: if the key is compromised or misused, users lose funds. Move ownership to a multisig with signers on separate devices, add a timelock so users can see and react to changes, set hard-coded bounds such as a maximum fee, and remove powers that are not needed, like unlimited minting. Use role-based access instead of one all-powerful owner, and document the remaining admin powers publicly.
16

Your team is preparing a contract for an external audit. What do you do beforehand?

Save to ▾
Show answer
Freeze the code at a commit and stop adding features. Write clear documentation: architecture, roles, trust assumptions, invariants and known risks. Reach high test coverage including fuzz and invariant tests, and run Slither and fix its findings. Remove dead code, add NatSpec comments, and make the build reproducible. Share a scope list and a walkthrough call. A clean, well-documented codebase lets auditors spend their limited time on deep logic bugs.
17

Show a contract vulnerable to reentrancy and a fixed version.

Save to ▾
Show answer
Vulnerable: the balance is cleared after sending. function withdraw() external { uint256 bal = balances[msg.sender]; (bool ok, ) = msg.sender.call{value: bal}(''); require(ok); balances[msg.sender] = 0; } Fixed: update state first and add a guard. import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol'; function withdraw() external nonReentrant { uint256 bal = balances[msg.sender]; require(bal > 0, 'nothing'); balances[msg.sender] = 0; (bool ok, ) = msg.sender.call{value: bal}(''); require(ok, 'send failed'); }
18

Tell me about a bug you missed and what you learned from it.

Save to ▾
Show answer
Situation: I shipped a rewards contract where a rounding error let users claim slightly more than earned when claiming very often. Task: fix it and prevent repeats. Action: I owned the mistake in the team call, wrote a failing test reproducing it, changed the division order to round down in the protocol's favour, and added fuzz tests on claim frequency. Result: losses were tiny, and I now always fuzz any maths involving division.
19

How do flash loans enable oracle manipulation attacks?

Save to ▾
Show answer
A flash loan lets anyone borrow huge amounts without collateral if it is repaid in the same transaction. An attacker borrows, makes a large trade in a thin DEX pool to move its spot price, then uses a protocol that reads that pool as its price oracle, for example borrowing too much against inflated collateral, and finally reverses the trade and repays. Defend with decentralised oracles like Chainlink, TWAPs, multiple sources and sanity bounds.
20

What are storage collision and uninitialised implementation risks in proxies?

Save to ▾
Show answer
With delegatecall, the implementation's code writes to the proxy's storage. If the proxy stores its admin or implementation address in a normal slot, implementation variables can overwrite it, so EIP-1967 uses pseudo-random slots. New implementation versions must only append variables, or use namespaced storage (ERC-7201). Implementations must also disable initialisers in their constructor; otherwise an attacker can initialise the implementation directly, take ownership and, in UUPS, potentially destroy or hijack it.
21

What are cross-function and read-only reentrancy?

Save to ▾
Show answer
Cross-function reentrancy happens when an attacker re-enters a different function that shares state with the one making the external call, so a guard on only one function does not help. Read-only reentrancy happens when a view function, such as a pool's price getter, returns inconsistent state mid-execution, and another protocol reads it during the callback and misprices assets. Mitigate by guarding all state-sharing functions, updating state before calls, and checking a reentrancy lock in view functions other protocols rely on.
22

Your protocol is being exploited right now. What do you do?

Save to ▾
Show answer
Act fast with a prepared runbook. Pause affected contracts through the guardian or multisig, and disable front-end actions. Gather the core team and security partners in a war room. Trace the attack transactions to understand the bug and estimate losses, and check whether a white-hat rescue of remaining funds is needed. Communicate publicly with facts and no speculation, contact exchanges and bridges to flag stolen funds, then fix, audit the fix and publish a post-mortem.
23

A lending protocol reads collateral prices from one DEX pool's current reserves. What is the risk and fix?

Save to ▾
Show answer
Spot prices from a single pool can be moved within one transaction by a flash-loaned swap, letting an attacker inflate collateral value and borrow far more than it is worth, or trigger unfair liquidations. Replace it with a robust oracle such as Chainlink price feeds, or a long-window TWAP from deep pools, check staleness and deviation between sources, cap borrow amounts per block, and add circuit breakers for extreme price moves.
24

Write a Foundry invariant test for a token's total supply.

Save to ▾
Show answer
Invariant tests call random functions on target contracts and check a property after every call. import {Test} from 'forge-std/Test.sol'; import {MyToken} from '../src/MyToken.sol'; import {Handler} from './Handler.sol'; contract SupplyInvariant is Test { MyToken token; Handler handler; function setUp() public { token = new MyToken(); handler = new Handler(token); targetContract(address(handler)); } function invariant_supplyMatchesBalances() public view { assertEq(token.totalSupply(), handler.sumOfBalances()); } } The handler bounds inputs and tracks actors so calls stay realistic.
25

Management wants to launch before the audit is complete. How do you handle it?

Save to ▾
Show answer
Situation: marketing had fixed a launch date, but the audit had two open high-severity findings. Task: protect users without blocking the business. Action: I explained the risk in money terms, proposed a guarded launch with a low deposit cap, pausable contracts and only the audited modules enabled, and shared a timeline for the fixes. Result: leadership accepted, we launched on time with caps, and raised limits two weeks later after fixes were verified.

Frequently asked questions

How important is Smart Contract Security in Blockchain interviews?

Learn to think like an attacker and an auditor. This topic covers reentrancy, access control flaws, oracle manipulation with flash loans, front-running, denial of service, insecure randomness, proxy storage collisions and signature replay, along with Slither, fuzzing, invariant testing, audit preparation and incident response.

How should I use the Smart Contract Security sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.