Solidity Smart Contract Developer Certification (SSCD+) — Questions and Answers
Question 1: Which built-in array operations are available for a dynamic storage array in Solidity?
- push(value) and pop() (Correct answer)
- remove(index) and insert(index, value)
- splice(start, count) and concat(array)
- append(value) and trim()
Correct answer: push(value) and pop()
Dynamic storage arrays in Solidity support push() to append an element and pop() to remove the last element; there is no built-in remove-by-index.
Question 2: In Solidity, what is 'calldata' as a data location?
- Storage that is cleared after the transaction
- Read-only non-persistent data location for external function input parameters (Correct answer)
- An alias for 'memory'
- A temporary memory area that persists between calls
Correct answer: Read-only non-persistent data location for external function input parameters
Calldata is a read-only, non-persistent area where external function arguments are stored, cheaper than memory.
Question 3: What is the recommended pattern to prevent reentrancy attacks in Solidity?
- Proxy pattern
- Factory pattern
- Observer pattern
- Checks-Effects-Interactions pattern (Correct answer)
Correct answer: Checks-Effects-Interactions pattern
The Checks-Effects-Interactions pattern requires you to perform all state changes (effects) before calling external contracts (interactions), preventing reentrancy.
Question 4: What is the risk of using `delegatecall` to an untrusted contract?
- The callee's storage layout is used instead of the caller's
- The callee can overwrite the caller's storage with malicious data (Correct answer)
- The callee receives the caller's ETH balance permanently
- It always reverts when used in a loop
Correct answer: The callee can overwrite the caller's storage with malicious data
With `delegatecall`, the called contract's code runs in the caller's storage context, so a malicious callee can corrupt or drain the caller's state.
Question 5: What does the ERC-777 standard add over ERC-20?
- Native DEX integration without a router contract
- On-chain governance for token parameter changes
- Cross-chain transfer capabilities via bridge hooks
- Hooks that notify sender and recipient contracts on every transfer, enabling richer interactions without separate approve+transferFrom calls (Correct answer)
Correct answer: Hooks that notify sender and recipient contracts on every transfer, enabling richer interactions without separate approve+transferFrom calls
ERC-777 adds `tokensToSend` and `tokensReceived` hooks called on registered operator and recipient contracts, enabling automatic reactions to transfers.
Question 6: What does a Solidity mapping return for a key that has never been set?
- null
- An error is thrown
- undefined
- The default zero value for the value type (Correct answer)
Correct answer: The default zero value for the value type
Mappings return the default zero value of their value type (e.g., 0 for uint, false for bool) for any key that has not been explicitly set.
Question 7: What is a 'Multisig wallet' and why is it used for managing smart contract ownership?
- A wallet that requires a time lock before any transaction executes
- A contract that automatically splits ETH among multiple owners
- A contract requiring M-of-N key signatures to execute transactions, distributing trust and preventing single-point-of-failure (Correct answer)
- A wallet that batches multiple transactions into one for gas savings
Correct answer: A contract requiring M-of-N key signatures to execute transactions, distributing trust and preventing single-point-of-failure
A multisig requires multiple authorized signers to approve each transaction, ensuring no single compromised key can unilaterally control protocol funds or upgrades.
Question 8: What is the Factory pattern in Solidity and what problem does it solve?
- A pattern that caches expensive computations across multiple calls
- A pattern that batches multiple ERC-20 transfers into one transaction
- A contract that deploys other contracts programmatically, enabling on-chain contract creation with tracked addresses (Correct answer)
- A contract that generates random salt values for CREATE2 deployments
Correct answer: A contract that deploys other contracts programmatically, enabling on-chain contract creation with tracked addresses
The Factory pattern lets a single contract deploy and register many instances of another contract, enabling on-chain tracking of all deployed children.
Question 9: What does the `TimelockController` in OpenZeppelin provide for contract governance?
- A mandatory delay between proposing and executing privileged operations, giving users time to exit if they disagree (Correct answer)
- Scheduled gas price adjustments
- Automatic rate limiting of token transfers
- A time-based access control replacing Ownable
Correct answer: A mandatory delay between proposing and executing privileged operations, giving users time to exit if they disagree
TimelockController enforces a waiting period (e.g., 48 hours) between queuing and executing admin operations, allowing users to review and react before changes take effect.
Question 10: What does the reducing length property do?
- Keep only the first N elements
- Keep the elements in the array but reduce their length
- Delete elements from the array (Correct answer)
- Keep all elements in the array
Correct answer: Delete elements from the array
For dynamic arrays in Solidity, reducing the `length` property effectively truncates the array. This action 'deletes' elements from the end of the array by making them inaccessible and freeing up their associated storage. It's a common method to manage the size of dynamic arrays and remove unwanted elements.
Question 11: What does the `safeTransferFrom` function in ERC-721 check that the plain `transferFrom` does not?
- Whether the recipient contract implements onERC721Received to confirm it can handle NFTs (Correct answer)
- Whether the token ID exists in the contract's storage
- Whether the sender has sufficient ETH to cover gas
- Whether the NFT metadata URI is reachable
Correct answer: Whether the recipient contract implements onERC721Received to confirm it can handle NFTs
`safeTransferFrom` calls `onERC721Received` on the recipient if it is a contract; if the function is not implemented, the transfer reverts, preventing NFTs from being permanently locked.
Question 12: What is a Chainlink oracle and why is it important for smart contracts?
- A token bridge between EVM-compatible chains
- A decentralized data feed network that provides tamper-resistant external data (like price feeds) to smart contracts (Correct answer)
- A Layer 2 scaling solution for Ethereum
- A Solidity compiler plugin for checking contract security
Correct answer: A decentralized data feed network that provides tamper-resistant external data (like price feeds) to smart contracts
Chainlink aggregates data from multiple independent nodes and on-chain verification, providing smart contracts with reliable price feeds and off-chain data without trusting a single source.
Question 13: What is the primary advantage of using calldata over memory for external function parameters in Solidity?
- calldata is read-only and avoids an extra copy, making it more gas-efficient (Correct answer)
- calldata allows modifying the input data
- calldata is permanent and persists after the call
- calldata supports nested dynamic types that memory does not
Correct answer: calldata is read-only and avoids an extra copy, making it more gas-efficient
calldata is the raw, read-only transaction input and avoids copying data into memory, making it the most gas-efficient location for external function parameters that are not modified.
Question 14: What is the key difference between UUPS and Transparent Proxy upgrade patterns?
- UUPS requires a multisig while Transparent Proxy does not
- UUPS uses delegatecall while Transparent Proxy uses staticcall
- Transparent Proxy supports ERC-20 while UUPS does not
- UUPS places upgrade logic in the implementation contract; Transparent Proxy places it in the proxy contract (Correct answer)
Correct answer: UUPS places upgrade logic in the implementation contract; Transparent Proxy places it in the proxy contract
In UUPS, the upgrade function lives in the implementation contract (smaller proxy, lower deployment cost); in Transparent Proxy, the proxy itself handles upgrades.
Question 15: Which data location is most gas-efficient for read-only external function parameters of reference types?
- calldata (Correct answer)
- stack
- storage
- memory
Correct answer: calldata
calldata is the most gas-efficient location for read-only external function parameters because it reads directly from the transaction input without copying data.
Question 16: Can Solidity events be read by other smart contracts during execution?
- No, events are write-only from the EVM's perspective and can only be read off-chain via node APIs (Correct answer)
- Yes, using the LOGREAD opcode in assembly
- Yes, using the eth_getLogs opcode inside a contract
- Yes, but only events from the same contract
Correct answer: No, events are write-only from the EVM's perspective and can only be read off-chain via node APIs
Event logs are stored in the transaction receipt, not in contract storage or memory accessible to the EVM — they are only readable off-chain via JSON-RPC or indexers like The Graph.
Question 17: What is the gas cost difference between deploying a contract and calling a function on an existing contract?
- Function calls on existing contracts are always free
- Deployment and calls both cost exactly 21,000 gas base
- Deployment costs are measured in ETH, not gas
- Deployment costs at least 32,000 base gas plus code storage; function calls cost 21,000 base plus execution (Correct answer)
Correct answer: Deployment costs at least 32,000 base gas plus code storage; function calls cost 21,000 base plus execution
Contract creation has a base cost of 32,000 gas plus 200 gas per byte of bytecode stored, making deployment significantly more expensive than function calls.
Question 18: What does the 'storage' keyword indicate when used as a data location in Solidity?
- The variable is stored in calldata
- The variable is temporary and cleared after the call
- The variable persists on the blockchain between calls (Correct answer)
- The variable is read-only
Correct answer: The variable persists on the blockchain between calls
Storage variables are persistent and saved to the blockchain, making reads/writes more expensive.
Question 19: What data location must be explicitly specified for reference type parameters in Solidity functions?
- mutable or immutable
- heap or stack
- memory, storage, or calldata (Correct answer)
- local or global
Correct answer: memory, storage, or calldata
Reference type parameters must declare a data location — memory, storage, or calldata — so the compiler knows where the data resides.
Question 20: What happens to variables stored in the memory data location after a Solidity function call ends?
- They are stored permanently in the contract's storage
- They are erased and the memory is freed (Correct answer)
- They are moved to calldata for the next call
- They persist until the next transaction is mined
Correct answer: They are erased and the memory is freed
Memory variables are temporary and only exist for the duration of a function call; they are discarded when the function returns.
Question 21: What is the gas benefit of using `unchecked` arithmetic blocks in Solidity 0.8+?
- It allows arithmetic to use fewer storage slots
- It disables the ABI encoder for numeric types
- It converts all math to bitwise operations automatically
- It skips the automatic overflow/underflow checks, saving ~20 gas per operation (Correct answer)
Correct answer: It skips the automatic overflow/underflow checks, saving ~20 gas per operation
Wrapping arithmetic in `unchecked {}` disables the compiler-inserted overflow checks, saving gas when you have already proven the values cannot overflow.
Question 22: What is the purpose of the `receive()` function in Solidity?
- It validates incoming ERC-20 token transfers
- It is called when a contract is deployed with an initial ETH value
- It handles all external calls including those with calldata
- It handles plain ETH transfers sent to the contract without calldata (Correct answer)
Correct answer: It handles plain ETH transfers sent to the contract without calldata
The `receive()` function is triggered when the contract receives ETH with empty calldata (e.g., a simple transfer), and must be declared `external payable`.
Question 23: What is the role of the `Assembly` (Yul) language in Solidity optimization?
- It allows writing low-level EVM opcodes directly for fine-grained gas optimization beyond what high-level Solidity allows (Correct answer)
- It enables parallel execution of multiple function calls
- It compiles Solidity to native machine code for faster execution
- It is used exclusively for generating ABI encodings
Correct answer: It allows writing low-level EVM opcodes directly for fine-grained gas optimization beyond what high-level Solidity allows
Inline assembly using Yul lets developers write EVM opcodes directly, enabling optimizations like tight memory packing, custom storage layouts, and bypassing Solidity's safety checks.
Question 24: What is a 'price oracle manipulation' attack in DeFi?
- Submitting false data to a Chainlink node
- Overflowing the oracle's price accumulator variable
- Using flash loans or large trades to temporarily distort a price source that a vulnerable contract trusts for liquidations or borrowing (Correct answer)
- Replacing the oracle contract address via a governance vote
Correct answer: Using flash loans or large trades to temporarily distort a price source that a vulnerable contract trusts for liquidations or borrowing
Attackers use large capital (often flash loans) to move prices on a DEX that a protocol uses as an oracle, triggering profitable liquidations or under-collateralized borrows.
Question 25: What is the purpose of EIP-1155 Multi-Token Standard compared to ERC-721?
- EIP-1155 adds royalty support to ERC-721 tokens
- EIP-1155 enables cross-chain token transfers natively
- EIP-1155 replaces ERC-20 with a more gas-efficient fungible token standard
- EIP-1155 allows a single contract to manage multiple token types (fungible and non-fungible) with batch transfer support (Correct answer)
Correct answer: EIP-1155 allows a single contract to manage multiple token types (fungible and non-fungible) with batch transfer support
ERC-1155 uses a single contract with a mapping from token ID to supply, supporting both fungible (supply > 1) and non-fungible (supply = 1) tokens with efficient batch transfers.
Question 26: What does 'storage collision' mean in the context of upgradeable proxy contracts?
- Two transactions write to the same slot simultaneously
- The proxy and logic contract use the same storage slots, causing one to overwrite the other's variables (Correct answer)
- Storage is corrupted when deploying to a new chain
- A mapping and an array occupy the same slot
Correct answer: The proxy and logic contract use the same storage slots, causing one to overwrite the other's variables
Storage collision happens when the proxy contract's own state variables occupy the same slots as the logic contract's variables, leading to data corruption.
Question 27: What vulnerability is introduced by the `selfdestruct` opcode in Solidity?
- It can forcibly send ETH to any contract, breaking balance-based invariants (Correct answer)
- It resets all storage slots to zero without refund
- It causes all pending transactions to revert
- It permanently bans the contract from the blockchain
Correct answer: It can forcibly send ETH to any contract, breaking balance-based invariants
`selfdestruct` forces ETH into a target address even if it has no payable fallback, which can break contracts that assume their balance only changes through defined functions.
Question 28: Which Solidity type correctly declares a fixed-size byte array of exactly 32 bytes?
- bytes32 (Correct answer)
- byte[32]
- fixed32
- bytes(32)
Correct answer: bytes32
bytes32 is Solidity's built-in fixed-size byte array type that holds exactly 32 bytes.
Question 29: Which Solidity integer type is recommended for most use cases to avoid implicit conversion issues?
- uint256 (Correct answer)
- uint32
- int8
- int128
Correct answer: uint256
uint256 is the default and most commonly used integer type in Solidity, matching the EVM's native 256-bit word size and minimizing implicit conversion overhead.
Question 30: What is a 'rebasing token' in DeFi and what challenge does it pose for Solidity integrations?
- A token that automatically compounds staking rewards every block
- A token whose total supply and all balances adjust periodically, causing balance reads to return different values without transfer events (Correct answer)
- A token that resets its price to $1 on every rebase
- A token that requires re-approval on every use
Correct answer: A token whose total supply and all balances adjust periodically, causing balance reads to return different values without transfer events
Rebasing tokens like AMPL adjust all account balances proportionally when supply changes, breaking protocols that cache balance snapshots between transactions.
Question 31: What gas optimization does Solidity variable packing in structs provide?
- It allows using calldata for struct parameters
- Packed structs are stored in memory instead of storage automatically
- Packing removes the need for ABI encoding
- Multiple small variables can share a single 32-byte storage slot, reducing SSTORE/SLOAD calls (Correct answer)
Correct answer: Multiple small variables can share a single 32-byte storage slot, reducing SSTORE/SLOAD calls
When consecutive struct members fit within 32 bytes, Solidity packs them into one slot, reducing the number of expensive storage reads/writes.
Question 32: What gas optimization does 'lazy initialization' or 'default value avoidance' provide in Solidity?
- Variables initialized to zero skip the constructor
- Zero values are stored in calldata instead of storage
- Default values are inlined by the optimizer as constants
- Avoiding writing 0 to storage saves 20,000 gas because SSTORE to a non-zero slot costs less than creating a new slot (Correct answer)
Correct answer: Avoiding writing 0 to storage saves 20,000 gas because SSTORE to a non-zero slot costs less than creating a new slot
Writing a non-zero value to a zero storage slot costs 20,000 gas (SSTORE cold write), but resetting a slot to zero triggers a gas refund — so avoid unnecessary zero-to-nonzero writes.
Question 33: Which of the following correctly uses a struct in Solidity?
- define struct Person(string name, uint age);
- struct Person { name: string; age: uint; }
- Person struct { string name; uint age; }
- struct Person { string name; uint age; } (Correct answer)
Correct answer: struct Person { string name; uint age; }
Solidity struct syntax places the type before the variable name inside curly braces, without colons.
Question 34: What is the purpose of 'selfdestruct(address)' in Solidity?
- It deletes the contract bytecode from the blockchain and sends remaining Ether to the given address (Correct answer)
- It pauses the contract temporarily
- It resets all state variables to zero
- It transfers ownership of the contract
Correct answer: It deletes the contract bytecode from the blockchain and sends remaining Ether to the given address
selfdestruct removes the contract's bytecode from the blockchain and forcefully sends its Ether balance to the specified address.
Question 35: Why is it more gas-efficient to use `uint256` instead of `uint8` or `uint128` for standalone state variables?
- Smaller types are deprecated in Solidity 0.8
- uint256 uses fewer storage slots than smaller types
- The EVM operates on 32-byte words, so smaller types require masking operations that cost extra gas (Correct answer)
- The compiler converts all uints to uint256 at compile time anyway
Correct answer: The EVM operates on 32-byte words, so smaller types require masking operations that cost extra gas
The EVM natively works with 32-byte (256-bit) values; using smaller integer types triggers extra masking/padding opcodes unless they are packed together in structs.
Question 36: What is 'impermanent loss' in the context of Automated Market Maker (AMM) liquidity provision?
- Transaction fees lost due to failed or reverted swaps
- Slippage costs incurred when adding large liquidity positions
- Gas costs that cannot be recovered from a liquidity position
- The loss LPs experience relative to holding tokens when token prices diverge from the deposit ratio (Correct answer)
Correct answer: The loss LPs experience relative to holding tokens when token prices diverge from the deposit ratio
When prices change from deposit time, arbitrageurs rebalance the pool, causing LPs to hold more of the depreciating token — the difference from just holding is impermanent loss.
Question 37: How many EVM storage slots does a single uint256 state variable occupy?
- 8 slots
- 2 slots
- 4 slots
- 1 slot (Correct answer)
Correct answer: 1 slot
A uint256 is 32 bytes (256 bits), which fits exactly into one 32-byte EVM storage slot.
Question 38: What does a developer of Solidity do?
- Auditing smart contracts
- Developing and deploying smart contracts
- All of the above (Correct answer)
- Communicating with users to translate business goals into technical requirements
Correct answer: All of the above
A Solidity developer's role is comprehensive and multifaceted, encompassing all the listed responsibilities. They are primarily involved in developing and deploying secure smart contracts, often auditing existing contracts for vulnerabilities, and communicating with stakeholders to translate business requirements into technical specifications for decentralized applications. This broad scope ensures the integrity and functionality of blockchain projects.
Question 39: What is the gas benefit of marking a function as `view` or `pure`?
- They use calldata instead of memory for all parameters
- They can bypass the require() checks
- External callers pay zero gas when calling them off-chain via eth_call (Correct answer)
- They skip input validation entirely
Correct answer: External callers pay zero gas when calling them off-chain via eth_call
View and pure functions called externally via `eth_call` (not in a transaction) are executed locally by the node and cost zero gas.
Question 40: Which of the following is a value type in Solidity?
- string
- uint256 (Correct answer)
- bytes (dynamic)
- mapping
Correct answer: uint256
uint256 is a value type stored directly on the stack, while bytes, string, and mapping are reference types.
Question 41: What is the ERC-20 `allowance` mechanism and what attack does it enable?
- It enables the contract to burn tokens automatically
- It is a blacklist mechanism to block specific addresses
- It prevents token transfers above a daily limit
- It lets owners approve spenders to transfer tokens, but a race condition allows double-spending if approval amount is changed (Correct answer)
Correct answer: It lets owners approve spenders to transfer tokens, but a race condition allows double-spending if approval amount is changed
The ERC-20 approve/transferFrom pattern has a race condition: if a spender acts between an owner reducing allowance from N to M, they can spend N+M tokens total.
Question 42: What is the purpose of EIP-712 typed structured data signing in Solidity?
- It enables users to sign structured off-chain messages that can be verified on-chain, with human-readable type information (Correct answer)
- It replaces ECDSA with a cheaper signature scheme
- It compresses calldata for cheaper ERC-20 transfers
- It defines a standard for contract metadata storage
Correct answer: It enables users to sign structured off-chain messages that can be verified on-chain, with human-readable type information
EIP-712 provides a standard way to hash and sign structured data off-chain, enabling meta-transactions and gasless approvals where wallets show readable type information to users.
Question 43: What is the 'fallback' function used for in Solidity?
- To destroy the contract
- To execute when a contract receives a call with no matching function selector (Correct answer)
- To handle failed transactions
- To initialize state variables
Correct answer: To execute when a contract receives a call with no matching function selector
The fallback function is invoked when a call doesn't match any declared function signature.
Question 44: What does `CREATE2` opcode allow that `CREATE` does not?
- Deploying contracts without a constructor
- Deploying contracts that can be self-destructed and redeployed
- Deterministic contract address calculation before deployment, based on deployer + salt + bytecode hash (Correct answer)
- Deploying to a different chain with the same address automatically
Correct answer: Deterministic contract address calculation before deployment, based on deployer + salt + bytecode hash
CREATE2 lets you compute a contract's address before deployment using the deployer address, a salt, and the init code hash, enabling counterfactual contracts.
Question 45: What is 'gas griefing' in the context of forwarding gas with `call` in Solidity?
- A malicious callee can consume all forwarded gas, causing the caller to run out and revert (Correct answer)
- It occurs when two contracts mutually call each other
- Gas griefing is a compiler bug affecting loops
- The caller steals gas from the callee by setting a low gas limit
Correct answer: A malicious callee can consume all forwarded gas, causing the caller to run out and revert
When a contract forwards all available gas to an external call, a malicious recipient can burn it all, forcing the calling contract to revert due to out-of-gas.
Question 46: What is the purpose of a 'fee-on-transfer' token and what challenge does it create for DeFi contracts?
- It prevents flash loan attacks by taxing instant repayments
- It automatically stakes a portion of every transfer
- It charges extra gas on each transfer stored in a treasury
- It deducts a percentage fee on every transfer, so the received amount is less than sent, breaking contracts assuming transfer amounts are exact (Correct answer)
Correct answer: It deducts a percentage fee on every transfer, so the received amount is less than sent, breaking contracts assuming transfer amounts are exact
Fee-on-transfer tokens (like SAFEMOON) deduct a tax during transfer, so if you send 100 tokens the recipient gets 98 — DeFi contracts that assume exact amounts receive less than expected.
Question 47: What is the `constant` keyword in Solidity and how does it save gas compared to storage variables?
- Constants are cached in memory automatically
- Constants are inlined at compile time as literal values, using zero gas to read (Correct answer)
- Constants skip ABI encoding when passed to functions
- Constants are stored in a dedicated cheap storage area
Correct answer: Constants are inlined at compile time as literal values, using zero gas to read
Constants are replaced by their literal values during compilation, so accessing them requires no storage read at all — they are embedded directly in the bytecode.
Question 48: Do I need a certification to become a Solidity developer?
- Yes
- No (Correct answer)
Correct answer: No
No, a certification is not a mandatory requirement to become a Solidity developer. While certifications can demonstrate a foundational understanding, the blockchain industry highly values practical experience, a strong portfolio of deployed smart contracts, and a deep understanding of blockchain principles. Continuous learning and hands-on projects are often more impactful than formal certifications.
Question 49: What is the ERC-2612 Permit extension for ERC-20 tokens?
- A permit system for deploying new ERC-20 tokens via factory
- An extension that adds minting and burning caps to ERC-20
- A standard for cross-chain ERC-20 token bridges
- An off-chain signature-based approval that lets users set ERC-20 allowances without a separate on-chain approve transaction (Correct answer)
Correct answer: An off-chain signature-based approval that lets users set ERC-20 allowances without a separate on-chain approve transaction
ERC-2612 adds a `permit(owner, spender, value, deadline, v, r, s)` function so users can sign approvals off-chain and have a relayer or protocol submit them on-chain, saving one transaction.
Question 50: What is the purpose of the `initializer` modifier in OpenZeppelin's upgradeable contracts?
- It ensures the initialization function can only be called once, replacing the constructor for proxy-based contracts (Correct answer)
- It prevents the contract from being paused during initialization
- It automatically calls the parent contract's constructor
- It marks a function as payable during deployment only
Correct answer: It ensures the initialization function can only be called once, replacing the constructor for proxy-based contracts
Upgradeable contracts cannot use constructors (which run at deploy time in the implementation, not the proxy), so `initializer` gates a setup function to run exactly once.
Question 51: What is the purpose of the `interface` keyword vs `abstract contract` in Solidity?
- Interfaces compile to smaller bytecode while abstract contracts compile to full bytecode
- Abstract contracts cannot be inherited from; interfaces can
- They are interchangeable in all contexts
- Interfaces have no implementations at all; abstract contracts can have partial implementations with some functions left abstract (Correct answer)
Correct answer: Interfaces have no implementations at all; abstract contracts can have partial implementations with some functions left abstract
Interfaces define a pure API contract with no logic; abstract contracts allow mixing implemented and unimplemented functions, useful for base classes with shared logic.
Question 52: What is the gas cost benefit of using `immutable` vs regular state variables in Solidity?
- Immutable variables cost zero gas to declare
- Immutable values are embedded in bytecode and read with cheap PUSH opcodes instead of SLOAD (Correct answer)
- Immutable removes the need for a constructor
- Immutable variables are stored in calldata instead of storage
Correct answer: Immutable values are embedded in bytecode and read with cheap PUSH opcodes instead of SLOAD
Immutable variables are baked into the contract bytecode at deployment, so reading them costs only a few gas (PUSH opcode) instead of the 100–2100 gas of SLOAD.
Question 53: What is the key difference between int256 and uint256 in Solidity?
- int256 can store negative values while uint256 cannot (Correct answer)
- int256 uses less gas than uint256
- They are identical types with different names
- uint256 can only store even numbers
Correct answer: int256 can store negative values while uint256 cannot
int256 is a signed integer that can hold both positive and negative values, while uint256 is unsigned and only holds non-negative values.
Question 54: What does the `totalSupply()` function return in an ERC-20 contract?
- The maximum number of tokens that can ever be minted
- The number of tokens held in the contract itself
- The sum of all token balances across all addresses, representing the currently circulating supply (Correct answer)
- The number of unique token holder addresses
Correct answer: The sum of all token balances across all addresses, representing the currently circulating supply
`totalSupply()` returns the total number of tokens currently in existence (minted minus burned), not a cap or the balance of any specific address.
Question 55: Why does emitting events instead of storing data in storage save gas in Solidity?
- Events are never included in the blockchain state
- Events bypass the EVM entirely and are handled by the node off-chain
- Events are stored in transaction logs, which cost ~8 gas/byte vs 20,000 gas for new storage writes (Correct answer)
- Events use calldata encoding which is cheaper than storage encoding
Correct answer: Events are stored in transaction logs, which cost ~8 gas/byte vs 20,000 gas for new storage writes
Writing to storage (SSTORE) costs 20,000 gas for a new slot, while event logs cost approximately 375 gas plus ~8 gas per byte of data.
Question 56: What is the gas impact of the Solidity optimizer and what setting controls its strength?
- The optimizer removes all require() statements below a threshold
- The `runs` parameter tells the optimizer to trade deployment cost for execution cost — higher runs = cheaper calls but larger bytecode (Correct answer)
- Higher runs values compress storage layout
- The optimizer only affects view and pure functions
Correct answer: The `runs` parameter tells the optimizer to trade deployment cost for execution cost — higher runs = cheaper calls but larger bytecode
Setting `optimizer.runs` to a high number (e.g., 200+) optimizes for repeated execution efficiency at the expense of larger deployment bytecode.
Question 57: What is the default data location for state variables in a Solidity contract?
- stack
- storage (Correct answer)
- calldata
- memory
Correct answer: storage
State variables are always stored in storage (on-chain persistent storage) by default, which is why they persist between function calls.
Question 58: What does the `emit` keyword do in Solidity and when was it made mandatory?
- It sends ETH to the event listener addresses
- It writes event data to contract storage
- It broadcasts the event to all connected nodes immediately
- It triggers event emission; the keyword was made mandatory in Solidity 0.4.21 to distinguish events from function calls (Correct answer)
Correct answer: It triggers event emission; the keyword was made mandatory in Solidity 0.4.21 to distinguish events from function calls
The `emit` keyword explicitly marks event emission statements, added in 0.4.21 to improve code readability by visually distinguishing events from function calls.
Question 59: Who created Ethereum?
- Joseph Lubin
- Gavin James Wood (Correct answer)
- Vitalik Buterin
- None of the above
Correct answer: Gavin James Wood
While Vitalik Buterin is widely recognized as the founder of Ethereum, Gavin Wood played a pivotal role in its creation and technical foundation. He co-founded Ethereum, authored the Ethereum Yellow Paper which formally specified the Ethereum Virtual Machine (EVM), and invented the Solidity programming language. His contributions were instrumental in establishing the platform's core architecture.
Question 60: What is the 'vault share' model used in yield protocols like Yearn Finance?
- Users deposit assets and receive shares representing their proportional claim on the vault; share value increases as the vault earns yield (Correct answer)
- Each depositor receives a unique NFT representing their exact deposit amount
- The vault pools deposits and distributes fixed APY regardless of performance
- Shares are minted by validators and distributed to liquidity providers weekly
Correct answer: Users deposit assets and receive shares representing their proportional claim on the vault; share value increases as the vault earns yield
Yield vaults issue shares at a ratio based on total assets; as the vault earns yield, total assets grow while share count stays constant, making each share worth more assets over time.
Question 61: What is the Multicall pattern in Solidity and what benefit does it provide?
- It parallelizes EVM execution across multiple threads
- It bundles multiple function calls into a single transaction, reducing gas overhead and enabling atomic batch operations (Correct answer)
- It calls the same function on multiple contracts simultaneously
- It allows calling functions on other chains in one transaction
Correct answer: It bundles multiple function calls into a single transaction, reducing gas overhead and enabling atomic batch operations
Multicall aggregates several contract calls into one transaction, saving the 21,000 gas base cost per transaction and ensuring all operations succeed or fail atomically.
Question 62: What is the purpose of the Proxy Upgrade Pattern (UUPS or Transparent Proxy) in Solidity?
- It allows replacing a contract's logic while preserving its storage state and address (Correct answer)
- It provides automatic circuit-breaker functionality
- It enables a contract to call itself recursively without a stack limit
- It allows a contract to pay its own gas fees
Correct answer: It allows replacing a contract's logic while preserving its storage state and address
Proxy upgrade patterns separate storage (proxy) from logic (implementation), enabling developers to fix bugs or add features without migrating user data to a new address.
Question 63: What vulnerability arises when Solidity arithmetic operations exceed the maximum or minimum value of the data type?
- Integer overflow/underflow (Correct answer)
- Access control flaw
- Timestamp dependence
- Reentrancy
Correct answer: Integer overflow/underflow
Integer overflow/underflow occurs when arithmetic results exceed the bounds of the integer type, wrapping around to unexpected values.
Question 64: What does the 'immutable' keyword do in Solidity?
- Makes a variable settable only at declaration
- Makes a variable settable once in the constructor and then read-only (Correct answer)
- Makes a function unable to modify state
- Prevents a variable from being read externally
Correct answer: Makes a variable settable once in the constructor and then read-only
Immutable variables can be assigned in the constructor only and are stored in bytecode, not storage.
Question 65: What kind of testing does a Solidity developer need to do?
- System
- Integration
- Unit Testing (Correct answer)
- None of the above
Correct answer: Unit Testing
Unit testing is a critical practice for Solidity developers to ensure the correctness and security of smart contracts. By testing individual functions and components in isolation, developers can verify that each part behaves as expected under various conditions. This helps identify and mitigate vulnerabilities before deployment, which is crucial for immutable blockchain code.
Question 66: What is the byte size of the address type in Solidity?
- 20 bytes (Correct answer)
- 64 bytes
- 32 bytes
- 16 bytes
Correct answer: 20 bytes
An Ethereum address is always 20 bytes (160 bits), so the address type in Solidity occupies 20 bytes of storage.
Question 67: What is the key difference between a fixed-size array and a dynamic array in Solidity?
- Fixed-size arrays can only hold value types
- Dynamic arrays are always cheaper to use
- Fixed-size arrays are stored in memory while dynamic arrays go to storage
- Fixed-size arrays have their length set at compile time while dynamic arrays can grow (Correct answer)
Correct answer: Fixed-size arrays have their length set at compile time while dynamic arrays can grow
Fixed-size arrays have a length determined at compile time, while dynamic arrays can have elements pushed or popped at runtime.
Question 68: What is the difference between the `fallback()` and `receive()` functions in Solidity 0.6+?
- receive() handles ETH with empty calldata; fallback() handles calls with calldata that match no function selector (Correct answer)
- receive() only handles ERC-20 tokens while fallback() handles ETH
- They are identical; receive() is just an alias for fallback()
- fallback() is called first, then receive() if no logic executes
Correct answer: receive() handles ETH with empty calldata; fallback() handles calls with calldata that match no function selector
When calldata is empty and ETH is sent, `receive()` is called; when calldata is present but no function selector matches, `fallback()` is called instead.
Question 69: What is a 'meta-transaction' in Solidity and how does it work?
- A transaction submitted to multiple chains simultaneously
- A transaction that executes only if a prior transaction succeeded
- A transaction where a relayer pays gas on behalf of a user, with the user signing an EIP-712 message instead (Correct answer)
- A transaction that wraps multiple calls into one using Multicall
Correct answer: A transaction where a relayer pays gas on behalf of a user, with the user signing an EIP-712 message instead
In meta-transactions, the user signs a message off-chain; a relayer submits it on-chain and pays gas, enabling gasless UX while the contract verifies the user's signature.
Question 70: What storage slot number is assigned to the first state variable declared in a Solidity contract?
- Slot 1
- Depends on the variable type
- Slot 0 (Correct answer)
- Slot 2
Correct answer: Slot 0
Solidity assigns storage slots sequentially starting at slot 0, so the first declared state variable occupies slot 0.
Question 71: What is the Commit-Reveal scheme used for in Solidity?
- Hiding user inputs until all participants commit, then revealing to prevent front-running (Correct answer)
- Committing to an upgrade before executing it
- Encrypting contract state so only the owner can read it
- Compressing large arrays into a hash for cheaper storage
Correct answer: Hiding user inputs until all participants commit, then revealing to prevent front-running
In commit-reveal, users first submit a hash of their choice (commit), then reveal the plaintext after all commits are collected, preventing front-runners from copying the winning move.
Question 72: What is the constant product formula used by Uniswap V2 AMMs?
- x * y = k, where x and y are token reserve amounts and k remains constant through every swap (Correct answer)
- x / y = k, where the price ratio is fixed
- x^2 + y^2 = k, using a stableswap invariant
- x + y = k, where the sum of reserves is constant
Correct answer: x * y = k, where x and y are token reserve amounts and k remains constant through every swap
Uniswap V2 maintains x × y = k; swapping ΔX tokens in gives ΔY tokens out such that (x + ΔX) × (y - ΔY) = k, keeping the product constant.
Question 73: How is a function selector computed in Solidity?
- It is an incrementing counter assigned at compile time
- It is the keccak256 hash of the function name only
- It is the first 4 bytes of the function's bytecode
- It is the first 4 bytes of the keccak256 hash of the function's signature string (e.g., 'transfer(address,uint256)') (Correct answer)
Correct answer: It is the first 4 bytes of the keccak256 hash of the function's signature string (e.g., 'transfer(address,uint256)')
A function selector is `bytes4(keccak256('functionName(type1,type2,...)'))` — the canonical signature string is hashed and the first 4 bytes are used as a compact identifier.
Question 74: What is a 'wrapped token' in Solidity DeFi contexts?
- A token that automatically wraps multiple assets into a basket
- A token that compresses its metadata to save gas
- An NFT that wraps a fungible ERC-20 for marketplace trading
- An ERC-20 token backed 1:1 by a native asset (like WETH) or another token, enabling assets without ERC-20 interfaces to be used in DeFi protocols (Correct answer)
Correct answer: An ERC-20 token backed 1:1 by a native asset (like WETH) or another token, enabling assets without ERC-20 interfaces to be used in DeFi protocols
Wrapped tokens (e.g., WETH) are ERC-20 contracts where you deposit native ETH and receive an equivalent amount of WETH, making ETH compatible with ERC-20-based DeFi protocols.
Question 75: What is the default value of an uninitialized bool state variable in Solidity?
- true
- null
- undefined
- false (Correct answer)
Correct answer: false
In Solidity, all uninitialized state variables are set to their zero value; for bool that is false.
Question 76: What is the name of the property that you can use to delete elements from an array?
- Updating
- Clear
- Reducing length (Correct answer)
- Deleting an element using its index
Correct answer: Reducing length
For dynamic arrays in Solidity, elements are typically 'removed' or made inaccessible by reducing the array's `length` property. This action effectively truncates the array from the end, making the 'deleted' elements no longer part of the array's accessible range. While the `delete` keyword exists, it resets a slot to its initial value rather than truly shrinking a dynamic array.
Question 77: What is the name of the Ethereum dapp development environment?
- Blimp
- Hardhat (Correct answer)
- Ethereum Studio
- Geth
Correct answer: Hardhat
Hardhat is a widely used and powerful development environment for Ethereum. It provides a comprehensive suite of tools for compiling, deploying, testing, and debugging smart contracts. This makes it an essential platform for developers building decentralized applications (dApps) on the Ethereum blockchain.
Question 78: How do Solidity custom errors (introduced in 0.8.4) save gas compared to `require` with string messages?
- String messages are charged at 20,000 gas per character
- Custom errors are stored in a separate cheaper memory area
- Custom errors encode only a 4-byte selector in revert data, while string messages store and return the full string (Correct answer)
- Custom errors skip the revert opcode entirely
Correct answer: Custom errors encode only a 4-byte selector in revert data, while string messages store and return the full string
Custom errors revert with just a 4-byte function selector (plus encoded parameters), whereas string error messages cost gas to encode, store, and return.
Question 79: What is the Diamond Pattern (EIP-2535) in Solidity?
- A storage pattern using diamond inheritance for cheaper reads
- A proxy pattern that routes function calls to multiple implementation contracts (facets) based on function selectors (Correct answer)
- A token standard combining ERC-20 and ERC-721 in one contract
- A multi-sig pattern where approvals form a diamond graph
Correct answer: A proxy pattern that routes function calls to multiple implementation contracts (facets) based on function selectors
The Diamond Pattern allows a single proxy contract to delegate to multiple logic contracts (facets), bypassing the 24KB contract size limit and enabling modular upgrades.
Question 80: What is function selector-based routing and how do proxy contracts use it?
- The proxy's fallback reads the first 4 bytes of calldata as a selector and routes the call to the correct implementation using a lookup table (Correct answer)
- It uses the function name hash stored in an off-chain database
- It is performed by the Solidity compiler, not at runtime
- It routes calls based on the caller's address and permission level
Correct answer: The proxy's fallback reads the first 4 bytes of calldata as a selector and routes the call to the correct implementation using a lookup table
Proxy contracts (especially Diamonds) read `msg.sig` (the 4-byte function selector) in their fallback, look up the corresponding implementation address, and delegatecall it.
Solidity Smart Contract Developer Certification (SSCD+)
The Cyfrin Updraft SSCD+ certifies proficiency in Solidity smart contract development, covering gas optimization, security, advanced patterns, DeFi mechanics, and EVM internals for professional blockchain developers.
Exam Rules
- You can skip questions and return to them later
- Flag questions for review before submitting
- No feedback shown until you submit the entire exam
- Unanswered questions count as wrong — answer everything
- 10 pretest questions are mixed in and don't affect your score
- Timer auto-submits when time runs out
- Your progress is auto-saved every 30 seconds