Skip to content

Smart Contract Auditor Interview Questions & Answers

40 questions for Smart Contract Auditor interviews — 2 easy, 20 medium, 18 hard.

About the Smart Contract Auditor role

A smart contract auditor reviews protocols before and after launch to find vulnerabilities and economic risks. Auditors combine manual review with Slither, fuzzers and formal tools, write clear findings with severity and fixes, and verify remediations. The role suits developers with strong Solidity experience, a deep knowledge of past exploits, and the patience to reason about every possible attack path. Audit contests are a common way to build a public track record.

Manual code review Attack pattern knowledge Fuzzing and Slither DeFi economics Report writing
Solved for this roleStart 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

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).
02

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.
03

How do you read a Chainlink price feed in Solidity safely?

Save to ▾
Show answer
import {AggregatorV3Interface} from '@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol'; AggregatorV3Interface public feed; uint256 constant MAX_DELAY = 1 hours; function getPrice() public view returns (uint256) { (, int256 answer, , uint256 updatedAt, ) = feed.latestRoundData(); require(answer > 0, 'bad price'); require(block.timestamp - updatedAt <= MAX_DELAY, 'stale price'); return uint256(answer); // scale using feed.decimals(), often 8 } Always check staleness, sign and decimals; on L2s also check the sequencer uptime feed.
04

A stablecoin used as collateral in your protocol loses its peg. How do you respond?

Save to ▾
Show answer
Activate the risk plan: pause new borrowing against that asset and freeze its use as new collateral through governance or the guardian. Switch its oracle to a market price rather than a hard-coded one dollar, so positions are valued honestly, which may trigger liquidations. Reduce its loan-to-value and supply caps. Communicate clearly with users. Longer term, cap exposure per stablecoin, diversify collateral and model depeg scenarios in risk dashboards.
05

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.
06

What is the difference between receive and fallback functions?

Save to ▾
Show answer
receive() external payable runs when a contract receives plain ETH with empty calldata, for example a transfer from a wallet. fallback() runs when calldata matches no function, or when ETH arrives with data and no receive exists; it must be payable to accept ETH. Proxies use fallback to delegatecall all unknown calls to the implementation. Keep both simple, since a reverting or gas-heavy receive can break senders that use transfer with its 2300 gas stipend.
07

What is account abstraction, and how do ERC-4337 and EIP-7702 differ?

Save to ▾
Show answer
Account abstraction makes accounts programmable, so wallets can support batching, gas paid in tokens or by sponsors, passkeys, spending limits and social recovery. ERC-4337 does this without protocol changes: users send UserOperations to an alternate mempool, bundlers submit them to an EntryPoint contract, and paymasters can sponsor gas. EIP-7702 is a protocol change that lets an existing EOA point to smart account code, so users keep their address while gaining these features.
08

What is storage packing, and what are other key gas optimisations?

Save to ▾
Show answer
The EVM stores data in 32-byte slots, so consecutive small variables like uint128, uint64, address and bool can share a slot if declared next to each other, saving expensive SSTOREs. Other optimisations: use calldata for external arrays, cache storage reads in local variables, use immutable and constant, prefer custom errors over strings, avoid unbounded loops, use events instead of storing history, and use unchecked for counters that cannot overflow. Always measure with forge snapshot.
09

Tell me about a technical decision you made where you had to balance trade-offs.

Save to ▾
Show answer
Situation: our loyalty-points product needed on-chain points but users would not pay mainnet fees. Task: pick a chain. Action: I compared three rollups and a sidechain on fees, security model, wallet support and bridge maturity, built a quick benchmark, and wrote a one-page decision record with risks. Result: we chose a rollup with live fraud proofs, cut per-transaction cost by over 95 percent, and documented a migration path if our requirements changed.
10

What is DeFi?

Save to ▾
Show answer
DeFi, decentralised finance, means financial services such as trading, lending, borrowing, stablecoins and derivatives built as smart contracts on public blockchains. Anyone with a wallet can use them without a bank account or approval, contracts are transparent, and protocols can be combined like building blocks. Examples are automated market maker exchanges, overcollateralised lending markets and liquid staking. The risks are smart contract bugs, oracle failures, volatile collateral and unclear regulation.
11

Your contract fails to deploy because it exceeds the 24 KB size limit. What do you do?

Save to ▾
Show answer
The EIP-170 limit is 24,576 bytes of runtime code. First enable the optimiser and try a lower runs value or via-IR. Replace revert strings with custom errors, move repeated logic out of modifiers into internal functions, and remove unused code. If still too big, split logic into separate contracts or external libraries, or use a modular pattern like the Diamond (EIP-2535). Splitting also often improves clarity and auditability.
12

How do upgradeable contracts work, and how do Transparent and UUPS proxies differ?

Save to ▾
Show answer
A proxy holds the state and delegates every call to an implementation contract whose address is stored in a standard EIP-1967 slot; upgrading means pointing to a new implementation. In the Transparent pattern, upgrade logic lives in the proxy and an admin cannot call implementation functions, which avoids selector clashes. In UUPS, upgrade logic lives in the implementation, making proxies cheaper, but a faulty upgrade can brick it. Both use initialisers instead of constructors and require storage-layout compatibility.
13

Write the core reward-per-token logic for a staking rewards contract.

Save to ▾
Show answer
uint256 public rewardRate; // tokens per second uint256 public rewardPerTokenStored; uint256 public lastUpdate; uint256 public totalStaked; mapping(address => uint256) public paid; mapping(address => uint256) public rewards; mapping(address => uint256) public staked; function rewardPerToken() public view returns (uint256) { if (totalStaked == 0) return rewardPerTokenStored; return rewardPerTokenStored + (block.timestamp - lastUpdate) * rewardRate * 1e18 / totalStaked; } modifier updateReward(address a) { rewardPerTokenStored = rewardPerToken(); lastUpdate = block.timestamp; rewards[a] += staked[a] * (rewardPerTokenStored - paid[a]) / 1e18; paid[a] = rewardPerTokenStored; _; }
14

A fee-on-transfer token breaks your DEX's accounting. What happened and how do you fix it?

Save to ▾
Show answer
Fee-on-transfer tokens deduct a percentage on every transfer, so when your contract calls transferFrom for 100 tokens it may receive only 98. If the code assumes 100 arrived, balances and reserves drift and can be exploited. Fix it by measuring the actual amount received: read the contract's balance before and after the transfer and use the difference. Also decide whether to support such tokens at all and document unsupported token behaviours like rebasing.
15

Write a Foundry unit test and a fuzz test for a contract.

Save to ▾
Show answer
Foundry tests are Solidity contracts; functions starting with test run as tests, and parameters make them fuzz tests. import {Test} from 'forge-std/Test.sol'; import {Vault} from '../src/Vault.sol'; contract VaultTest is Test { Vault v; function setUp() public { v = new Vault(); } function testDeposit() public { v.deposit{value: 1 ether}(); assertEq(v.balanceOf(address(this)), 1 ether); } function testFuzzDeposit(uint96 amt) public { vm.assume(amt > 0); vm.deal(address(this), amt); v.deposit{value: amt}(); assertEq(address(v).balance, amt); } } Run with forge test -vvv.
16

A sharp market fall causes cascading liquidations in your lending protocol and bad debt. How do you design against it?

Save to ▾
Show answer
Set conservative loan-to-value ratios and liquidation thresholds per asset based on volatility and on-chain liquidity. Use supply and borrow caps for illiquid tokens, isolation mode for risky assets, and a liquidation bonus that attracts liquidators without over-penalising users. Allow partial liquidations so positions shrink gradually. Keep reliable oracles, an insurance or reserve fund to absorb bad debt, and run stress tests simulating 30 to 50 percent price drops.
17

How do you handle unclear or changing requirements from a client?

Save to ▾
Show answer
Situation: a client asked for a marketplace dApp but kept changing royalty and fee rules. Task: deliver without endless rework. Action: I wrote a short spec with examples and edge cases, got sign-off, and made fees configurable parameters with limits instead of hard-coded logic. Changes went through a simple change log with impact estimates. Result: we delivered in eight weeks, and later fee changes needed only a governance transaction, not a redeployment.
18

Compare ERC-20, ERC-721 and ERC-1155 tokens.

Save to ▾
Show answer
ERC-20 defines fungible tokens where every unit is identical, with functions like transfer, approve, transferFrom and balanceOf; used for currencies, stablecoins and governance tokens. ERC-721 defines non-fungible tokens where each tokenId is unique, used for NFTs like art, tickets or certificates. ERC-1155 is a multi-token standard where one contract manages many token types, fungible or not, with batch transfers; it is popular in games where items have quantities.
19

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.
20

You need to send ETH to hundreds of winners. Should you push payments or let them pull?

Save to ▾
Show answer
Prefer pull payments. If a contract pushes ETH in a loop, one recipient that reverts, perhaps a contract without receive, can block everyone, and the loop may exceed the gas limit. With pull payments, the contract records each winner's amount in a mapping and winners call withdraw, which zeroes their balance before sending. This isolates failures and limits reentrancy risk. Push only for small fixed lists using call with a checked result.
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

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.
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

What are seed phrases and HD wallets (BIP-39, BIP-32, BIP-44)?

Save to ▾
Show answer
BIP-39 encodes random entropy as a 12 or 24 word mnemonic, which is turned into a binary seed. BIP-32 defines hierarchical deterministic wallets that derive a tree of key pairs from that seed. BIP-44 standardises the derivation path, for example m/44'/60'/0'/0/0 for the first Ethereum account. So one backed-up seed phrase can restore unlimited addresses across chains. Whoever knows the phrase controls every derived account, so it must never be stored online.
26

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.
27

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.
28

What is MEV and what is proposer-builder separation?

Save to ▾
Show answer
MEV, maximal extractable value, is profit a block producer or searcher earns by including, excluding or reordering transactions, for example arbitrage, liquidations and sandwich attacks on swaps. On Ethereum, most validators use MEV-Boost, where specialised builders assemble profitable blocks and bid for them through relays, separating block building from proposing. This spreads MEV revenue to validators but concentrates building power. Enshrined PBS and inclusion lists are being researched to reduce censorship risk.
29

An attacker borrows governance tokens with a flash loan to pass a malicious DAO proposal. How do you prevent it?

Save to ▾
Show answer
Use snapshot-based voting power: count votes from token balances at a past block, as ERC20Votes does, so tokens acquired in the same transaction have no weight. Add a voting delay before voting starts, a quorum, and a timelock between approval and execution so the community can react or a guardian can veto. Require a proposal threshold, and keep critical actions such as treasury transfers behind additional safeguards like spending limits.
30

A client in India wants to tokenise real estate for fractional ownership. What do you consider?

Save to ▾
Show answer
Regulation comes first: fractional real estate is likely a security or collective investment, so SEBI rules, including those for fractional ownership platforms, apply, and crypto-like tokens are taxed as virtual digital assets at 30 percent with 1 percent TDS. Use a permissioned token with KYC-gated transfers, such as ERC-3643, and a legal SPV that holds the property. Keep title documents off-chain, put hashes on-chain, and plan for rent distribution, transfer restrictions and recovery.
31

How does a constant product automated market maker work, and what is impermanent loss?

Save to ▾
Show answer
A constant product AMM holds two tokens with reserves x and y and keeps x times y equal to k. A trader adds one token and removes the other so that k stays constant after fees, which makes price equal to the reserve ratio and rise with trade size. Liquidity providers earn fees, but when prices move, arbitrage rebalances the pool, leaving them worse off than simply holding; that gap is impermanent loss.
32

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'); }
33

The business wants to change contract logic after launch. How do you plan for it?

Save to ▾
Show answer
Decide early whether upgradeability is needed, because it adds trust and storage risks. Options are a proxy (UUPS or Transparent) controlled by a multisig with a timelock, a parameter-driven design where only settings like fees change through governed setters, or a migration plan to a new immutable version. Whatever you choose, document it for users, protect upgrade rights, keep storage layout append-only, and test each upgrade on a fork before executing.
34

A product team wants to store user documents and personal details directly on a public chain. What do you advise?

Save to ▾
Show answer
Do not put personal data on a public chain. Data there is permanent, public and replicated globally, which conflicts with the right to erasure under India's DPDP Act and GDPR, and storage is extremely expensive. Store documents encrypted in off-chain storage, keep only a salted hash or commitment on-chain for integrity, and control access through the application. If the data must be deleted, delete the off-chain copy and the encryption key; the hash alone reveals nothing.
35

A function that distributes rewards loops over all users and is getting too expensive. How do you fix it?

Save to ▾
Show answer
Unbounded loops eventually exceed the block gas limit. Switch to a pull-based accounting model: maintain a global reward-per-token accumulator that grows when rewards are added, and store each user's last checkpoint. Users claim with reward equals balance times (current accumulator minus their checkpoint). This makes distribution O(1) for any number of users. Alternatively, use a Merkle distributor where rewards are computed off-chain and users claim with proofs.
36

How does inheritance work in Solidity, including virtual and override?

Save to ▾
Show answer
A contract inherits with is, for example contract Token is ERC20, Ownable. Parent functions that may be changed must be marked virtual, and the child must use override; with several parents you list them, as in override(A, B). Solidity uses C3 linearisation, so the order of the parent list matters, from most base to most derived, and super calls the next contract in that order. Constructors of parents run first in linearised order.
37

How do you build a tokenised vault using ERC-4626?

Save to ▾
Show answer
ERC-4626 standardises yield vaults: users deposit an asset and receive shares, and share price rises as the vault earns yield. import {ERC4626} from '@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol'; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; contract YieldVault is ERC4626 { constructor(IERC20 asset_) ERC20('Vault Share', 'vSHR') ERC4626(asset_) {} function totalAssets() public view override returns (uint256) { return IERC20(asset()).balanceOf(address(this)); // plus deployed funds } } OpenZeppelin uses virtual shares to defend against the first-depositor inflation attack.
38

Write a basic voting contract using a struct, mapping and event.

Save to ▾
Show answer
pragma solidity ^0.8.24; contract Voting { struct Proposal { string name; uint256 votes; } Proposal[] public proposals; mapping(address => bool) public hasVoted; event Voted(address indexed voter, uint256 indexed id); constructor(string[] memory names) { for (uint256 i; i < names.length; i++) proposals.push(Proposal(names[i], 0)); } function vote(uint256 id) external { require(!hasVoted[msg.sender], 'already voted'); hasVoted[msg.sender] = true; proposals[id].votes++; emit Voted(msg.sender, id); } } An out-of-range id reverts automatically.
39

Tell me about working with product, legal or compliance teams on a blockchain feature.

Save to ▾
Show answer
Situation: we planned a token reward feature for Indian users, and legal raised VDA tax and securities concerns. Task: as tech lead I had to find a compliant design. Action: I ran workshops to understand their constraints, proposed non-transferable points that convert to vouchers, and documented the data flow for compliance. Result: we launched a month later than planned but with sign-off from all teams, and avoided a costly redesign after launch.
40

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.

Frequently asked questions

What does a Smart Contract Auditor do?

A smart contract auditor reviews protocols before and after launch to find vulnerabilities and economic risks. Auditors combine manual review with Slither, fuzzers and formal tools, write clear findings with severity and fixes, and verify remediations. The role suits developers with strong Solidity experience, a deep knowledge of past exploits, and the patience to reason about every possible attack path. Audit contests are a common way to build a public track record.

Which skills are tested in a Smart Contract Auditor interview?

Expect questions on Manual code review, Attack pattern knowledge, Fuzzing and Slither, DeFi economics, Report writing. Most rounds also ask you to explain a project and solve one practical problem live.

How do I prepare for a Smart Contract Auditor interview?

Revise Smart Contract Security, Solidity Programming, DeFi, Tokens and NFTs first using the topic sheets, practise the questions on this page aloud, then do one full mock interview to practise timing.