Crypto & Security

Chapter 9
Smart Contract and dApp Security

Diploma in Blockchain
Crypto & Security   •   Diploma

Smart Contract and dApp Security

Introduction and Context

Smart contracts are programs deployed on a blockchain whose execution is governed by transaction input, stored state, and the rules of a virtual machine. Decentralised applications (dApps) combine smart contracts with wallets, user interfaces, back-end services, indexing systems, bridges, and external data sources. This combination creates a security environment different from conventional software: deployed code may be difficult or impossible to alter, transactions are publicly observable, assets can be transferred immediately, and an attacker may be able to compose a vulnerable contract with many other protocols.

Security therefore cannot be reduced to avoiding syntax errors. It requires a secure development lifecycle (SDL) that addresses economic incentives, adversarial transaction ordering, privileged administration, external calls, cryptographic assumptions, and operational governance. A defect in an ordinary application may expose information or cause downtime; a defect in a high-value contract can permanently transfer assets within a few blocks.

This chapter presents a practical security framework for identifying and mitigating reentrancy, access-control failures, arithmetic errors, oracle manipulation, front-running, flash-loan exploits, and denial-of-service (DoS) risks. It also examines testing, static analysis, fuzzing, formal verification, and secure upgrade patterns.

Learning Objectives

By the end of this chapter, a learner should be able to:

  1. Explain the threat model of smart contracts and dApps.
  2. Identify common vulnerability classes and describe their exploit paths.
  3. Apply checks-effects-interactions, least privilege, safe arithmetic, and oracle-design principles.
  4. Distinguish front-running, sandwich attacks, flash-loan attacks, and governance manipulation.
  5. Design a practical SDL involving review, testing, analysis, deployment, monitoring, and incident response.
  6. Select suitable techniques from unit testing, fuzzing, invariant testing, static analysis, symbolic execution, and formal verification.
  7. Evaluate upgradeability and administrative controls as security risks.

1. The Smart-Contract Threat Model

A threat model identifies assets, actors, trust assumptions, attack surfaces, and unacceptable outcomes. Typical assets include native currency, tokens, collateral, voting power, user privacy, protocol solvency, and administrative keys. Threat actors may be ordinary users, automated bots, malicious token contracts, compromised administrators, oracle operators, validators, or attackers combining several protocols.

The public blockchain environment creates several distinctive assumptions:

  • Adversarial input: Every externally supplied value should be assumed to be deliberately chosen.
  • Public state: Contract storage, transaction data, and often pending transactions are observable.
  • Composability: A contract can call another contract whose behaviour may be unknown or malicious.
  • Atomic transactions: Several operations can succeed together or revert together, enabling complex temporary strategies.
  • Economic attacks: A technically valid transaction can still exploit an incentive or pricing mechanism.
  • Irreversibility: A confirmed transfer may not be recoverable through conventional administrative action.

A useful security property is preservation of an invariant. An invariant is a condition that should remain true after every permitted state transition. For example, a collateralised lending contract may require that the value of assets held is at least the value of liabilities, subject to explicitly defined rounding and timing rules. Security review should ask not only whether individual functions appear correct, but also whether every sequence of calls preserves critical invariants.

Terminology

  • Externally owned account (EOA): An account controlled by a private key.
  • Contract account: An account controlled by deployed code.
  • Caller (msg.sender): The immediate account or contract invoking a function.
  • Transaction origin (tx.origin): The original EOA that initiated a transaction; it should generally not be used for authorisation.
  • State transition: The change from one contract state to another caused by execution.
  • Invariant: A property intended to remain true across valid state transitions.
  • Gas: The computational resource consumed by execution.
  • Oracle: A mechanism that supplies external information, such as an asset price, to a contract.

2. A Secure Development Lifecycle

A professional SDL treats security as a continuous activity rather than a final audit. A suitable lifecycle contains the following stages.

2.1 Requirements and threat modelling

The team first specifies intended behaviour, trust boundaries, roles, assets, invariants, and failure responses. Requirements should identify what happens when an oracle is unavailable, a token behaves unexpectedly, a privileged key is compromised, or a user submits a transaction at an unfavourable price.

A threat model should document:

AreaQuestions
AssetsWhat can be stolen, frozen, diluted, or manipulated?
AuthorityWho can pause, upgrade, mint, withdraw, or change parameters?
External callsWhich tokens, oracles, bridges, and protocols are trusted?
Economic assumptionsWhat liquidity, collateral, price, and participation assumptions exist?
Failure modesCan the system fail safely, pause, or recover?
MonitoringWhich events and metrics reveal abnormal behaviour?

2.2 Design and implementation

The design should minimise complexity, isolate privileged operations, define explicit state machines, and use established libraries where appropriate. Developers should avoid implementing cryptographic primitives, token standards, proxy mechanisms, or mathematical libraries without a strong reason and specialist review.

Code should follow the principle of least privilege: each account, contract, and function receives only the authority necessary for its task. State-changing functions should validate inputs, update state in a predictable order, and emit events sufficient for monitoring.

2.3 Verification and validation

Verification asks whether implementation satisfies a specification; validation asks whether the specification meets the actual business and security need. Both are necessary. A contract can be perfectly verified against an insecure specification, such as “the administrator may withdraw all user funds.”

2.4 Deployment and operations

Deployment should use reproducible scripts, verified source code, documented addresses, controlled configuration, and staged release. Production operations require multisignature administration, hardware-protected keys, monitoring, alert thresholds, incident playbooks, and a tested pause or containment process.

3. Reentrancy and Unsafe External Calls

Reentrancy occurs when a contract makes an external call and the recipient calls back before the first invocation has completed. If state has not yet been updated, the callback may observe an outdated balance and repeat an action.

A simplified vulnerable withdrawal pattern is:

function withdraw(uint256 amount) external {
    require(balances[msg.sender] >= amount);
    (bool ok, ) = msg.sender.call{value: amount}("");
    require(ok);
    balances[msg.sender] -= amount;
}

The recipient may call withdraw again during the external call. The recorded balance remains unchanged until the original invocation resumes.

The principal defence is checks-effects-interactions:

  1. Check conditions and permissions.
  2. Update internal state.
  3. Make external calls last.
function withdraw(uint256 amount) external {
    require(balances[msg.sender] >= amount);
    balances[msg.sender] -= amount;
    (bool ok, ) = msg.sender.call{value: amount}("");
    require(ok);
}

A reentrancy guard can provide an additional defence by preventing nested entry into protected functions. However, it is not a substitute for correct state design. Reentrancy can also occur through token hooks, callbacks, cross-function interactions, read-only reentrancy, and calls to apparently trusted contracts that later change.

Developers should ask whether an external call can alter an assumption used later in the function. Pull-payment designs, in which users claim funds rather than the contract pushing funds to arbitrary recipients, often reduce risk. External calls should have deliberately bounded effects, and failure behaviour should be explicit.

4. Access-Control Failures

Access control determines who may execute sensitive operations. Failures include missing modifiers, incorrect role checks, publicly callable initialisation, reliance on tx.origin, unprotected upgrade functions, and confused distinctions between an owner, operator, guardian, and ordinary user.

A robust design:

  • Defines roles and capabilities explicitly.
  • Uses least privilege and separation of duties.
  • Prevents initialisation more than once.
  • Protects role-management functions.
  • Emits events when roles or critical parameters change.
  • Uses multisignature control for high-impact administration.
  • Applies timelocks where delay improves user protection.
  • Provides a transparent emergency pause with narrowly defined authority.

tx.origin is unsafe for authorisation because a malicious intermediary contract can cause a victim to call the target while tx.origin remains the victim. Authorisation should normally use msg.sender and, where relevant, signatures with nonce and deadline checks.

Signature-based authorisation must prevent replay. A signed message should be bound to the intended contract, chain, operation, signer, nonce, and expiry. Domain-separated standards such as typed structured data reduce ambiguity, but implementation must still validate signatures and stateful nonces correctly.

5. Arithmetic, Token, and Validation Errors

Arithmetic errors include integer overflow, underflow, division by zero, precision loss, incorrect decimal assumptions, rounding direction, and unsafe type conversions. Modern Solidity versions revert on ordinary integer overflow and underflow by default, but unchecked blocks, older compiler versions, and application-level arithmetic remain risks.

For unsigned integers, a calculation such as a * b / c may overflow before division even when the final mathematical result would fit. Developers should use carefully reviewed full-precision libraries where necessary and verify the order of operations. Rounding must favour the protocol’s safety direction: for example, a debt calculation may need to round upward while a collateral credit may need to round downward.

Token behaviour is not uniform. Some tokens charge transfer fees, return no Boolean value, block transfers, rebase balances, or invoke hooks. Safe token-transfer libraries can handle common return-value differences, but no library can make an economically incompatible token safe automatically.

Input validation should cover zero addresses, zero amounts, maximum limits, array lengths, stale values, duplicate entries, unsupported tokens, and state transitions that are logically impossible. A function should reject invalid states rather than relying on a later operation to fail.

6. Oracle Manipulation

A contract cannot directly know off-chain facts; it depends on an oracle or a price mechanism. Oracle attacks exploit inaccurate, stale, manipulable, or insufficiently decentralised data. If a lending protocol accepts the price of an asset from a shallow exchange, an attacker may temporarily move that price, borrow against the inflated collateral, and reverse the trade.

Safer oracle design considers:

  • Multiple independent sources.
  • Time-weighted or volume-weighted prices rather than one spot trade.
  • Freshness limits and heartbeat checks.
  • Deviation bounds and circuit breakers.
  • Liquidity and market-depth requirements.
  • Decimal normalisation and signed-value validation.
  • Fallback and stale-data behaviour.
  • Governance over feed configuration.

A price is not safe merely because it comes from a known provider. The protocol must check whether the reported value is recent, within plausible bounds, and appropriate for the asset and transaction size. Oracle risk is both technical and economic: an honest feed can still be unsuitable if market liquidity is too low.

7. Front-Running, MEV, and Flash Loans

Front-running occurs when an actor observes a pending transaction and submits a transaction intended to execute before it. The attacker may exploit a known trade, liquidation, token sale, or governance action. A sandwich attack places one transaction before and another after a victim’s trade, profiting from the resulting price movement.

Mitigations depend on the application:

  • Use minimum-output and maximum-input limits for trades.
  • Include deadlines and nonces.
  • Use commit–reveal schemes for auctions or sensitive choices.
  • Use batch auctions or private transaction submission where appropriate.
  • Avoid exposing valuable information before it is needed.
  • Design slippage and liquidation rules explicitly.

A commit–reveal scheme normally has two phases. In the commit phase, a participant submits a commitment such as a hash of a choice, secret, and nonce. In the reveal phase, the participant discloses the values, and the contract recomputes the hash. The secret and nonce prevent others from learning or cheaply copying the commitment. The design must address non-revelation, timing, griefing, and incentive compatibility.

A flash loan provides uncollateralised liquidity that must be borrowed and repaid within one atomic transaction. Flash loans are not inherently malicious; they support arbitrage and efficient capital use. They become an attack tool when a protocol assumes that a user’s temporary balance represents long-term wealth, or when a price, voting weight, or reserve can be manipulated within one transaction.

Defences include:

  • Measuring voting power at a historical snapshot rather than current balance.
  • Using robust oracles and independent price sources.
  • Applying liquidity, collateral, and rate limits.
  • Avoiding assumptions that a balance cannot change during execution.
  • Checking post-operation solvency and preserving invariants.

8. Denial of Service and Gas Risks

A DoS vulnerability prevents legitimate users or administrators from completing necessary operations. Causes include unbounded loops, storage growth, malicious recipients that always revert, block gas-limit exhaustion, and dependence on a single failing external contract.

A common anti-pattern is distributing funds by iterating over an arbitrary user list. As the list grows, execution may exceed the block gas limit. A pull-based design lets each recipient claim independently. Pagination, bounded batches, and off-chain computation with on-chain verification can also control gas use.

Developers should avoid making system progress depend on an untrusted external call. If a recipient can revert and thereby block an entire distribution, the contract may be vulnerable. Options include recording credit before allowing later withdrawal, isolating failures, or allowing authorised recovery under transparent rules.

Gas is a resource constraint, not merely a cost. Security testing should examine worst-case loop sizes, storage expansion, revert paths, and malicious callback behaviour. Emergency functions must themselves remain executable under realistic conditions.

9. Testing and Analysis Techniques

No single tool proves that a dApp is secure. Assurance comes from combining techniques with different strengths.

Unit and integration testing

Unit tests check individual functions and edge cases. Integration tests examine interactions among contracts, tokens, oracles, proxies, and user interfaces. Tests should include successful and reverting paths, role boundaries, zero and maximum values, repeated calls, unexpected token behaviour, and chain-specific configuration.

Property and invariant testing

A property describes behaviour that should hold across many inputs. Examples include “total claims never exceed funded reserves,” “only authorised roles can change the oracle,” and “a user cannot withdraw more than their recorded balance.” Invariant testing generates sequences of calls and checks these properties after each sequence.

Fuzzing

Fuzzing supplies numerous automatically generated inputs. Effective fuzzing requires meaningful constraints and assertions; random inputs alone may rarely reach important states. Stateful fuzzers can generate call sequences, while differential fuzzing compares two implementations or a reference model and the contract.

Static analysis

Static analysers inspect source or bytecode without executing every path. They can identify reentrancy patterns, dangerous calls, unreachable code, shadowed variables, access-control weaknesses, and compiler issues. Findings require expert triage: tools produce false positives and may miss economic vulnerabilities.

Symbolic execution and formal verification

Symbolic execution represents inputs symbolically and explores paths subject to constraints. It can reveal conditions leading to assertion failure or unexpected states, although path explosion limits scalability.

Formal verification expresses a specification mathematically and proves that implementation satisfies it under stated assumptions. It is particularly valuable for invariants, arithmetic libraries, permission systems, and critical protocol logic. A proof does not establish safety if the specification omits an attack, the model excludes an external contract, or trusted assumptions are false.

Independent review and audit

An audit should occur after requirements and tests are mature, not as a replacement for them. Reviewers need source code, deployment scripts, documentation, assumptions, privileged roles, and known limitations. A strong process records findings, remediation, regression tests, and residual risk. Bug bounties can provide additional adversarial scrutiny but should not be the first security control.

10. Secure Upgrade Patterns

Upgradeability allows logic to change while users interact with a stable address. It is operationally useful but introduces a powerful control plane. Risks include storage-layout corruption, uninitialised implementations, malicious upgrades, selector collisions, incompatible assumptions, and compromised upgrade keys.

Common patterns include proxy architectures in which a proxy stores state and delegates execution to an implementation contract. The precise storage layout and delegation rules must be understood; changing variable order or types can corrupt state. Upgrade functions should be restricted, emit events, and ideally use a multisignature and timelock. Users should be able to identify the current implementation and understand the governance process.

Secure upgrade practice includes:

  • Initialising implementation and proxy state exactly once.
  • Maintaining storage-layout compatibility and automated layout checks.
  • Testing upgrades against live-like state snapshots.
  • Separating emergency pause authority from upgrade authority where practical.
  • Publishing upgrade notices and review results.
  • Defining immutable or delayed parameters for high-risk functions.
  • Planning migration and rollback procedures.

Immutability is not automatically safer: an immutable contract may contain an unfixable defect. Upgradeability is not automatically unsafe: controlled, transparent, delayed upgrades can reduce operational risk. The correct choice depends on threat model, governance, user expectations, and protocol complexity.

11. Applied Case: Illustrative Lending-Protocol Incident

Background

Consider an illustrative lending dApp called HarborLend. Users deposit Token X as collateral and borrow a stable token. HarborLend obtains the Token X price from a single decentralised exchange pool and allows an administrator-controlled oracle address to be changed immediately.

Problem

An attacker obtains a flash loan, buys Token X in the shallow pool, and temporarily raises its observed price. HarborLend reads that manipulated price, treats the attacker’s collateral as highly valuable, and permits excessive borrowing. The attacker then reverses the pool trade, leaving HarborLend with under-collateralised debt. During the same transaction, the attacker invokes a callback-enabled token path that re-enters a withdrawal function before its accounting is finalised.

Analysis

The incident combines several weaknesses rather than one isolated bug:

  1. A spot price from an illiquid pool is an unsafe oracle.
  2. The protocol has no freshness, deviation, or market-depth checks.
  3. Flash-loan liquidity can amplify temporary price movement.
  4. The withdrawal function violates checks-effects-interactions.
  5. Oracle administration is concentrated in one immediately effective key.
  6. Tests cover ordinary prices but not adversarial call sequences.

Approach and solution

The team pauses new borrowing while preserving safe user withdrawals. It replaces the spot price with a robust feed using multiple sources and freshness checks, adds a deviation circuit breaker, and limits the collateral factor for thinly traded assets. Voting or balance-sensitive operations use snapshots rather than current flash-borrowed balances. Withdrawal accounting is updated before external calls and protected by a reentrancy guard. Oracle and upgrade authority move to a multisignature with a timelock, while a narrowly scoped guardian can pause borrowing.

The team then writes invariants for solvency and withdrawal accounting, adds stateful fuzz tests, runs static and symbolic analysis, performs an independent review, and deploys first to a test network with simulated hostile tokens and price movements.

Outcome and learning points

The immediate loss is contained, but the deeper outcome is a revised security process. The case demonstrates that smart-contract security is compositional: a flash loan, weak oracle, reentrancy defect, and governance weakness can interact to create a much larger failure. Security controls must therefore address code, economics, operations, and governance together.

12. Governance, Ethics, and Professional Practice

Security decisions distribute risk among users, developers, administrators, validators, and external service providers. Teams should disclose material vulnerabilities responsibly, avoid misleading claims of “fully secure” code, publish assumptions, and communicate residual risks to users. Emergency powers should be narrowly defined and auditable; they should not become an excuse for arbitrary confiscation or opaque censorship.

Regulatory obligations vary by jurisdiction and application. A dApp may involve custody, financial services, consumer protection, sanctions compliance, privacy, or data-protection responsibilities. Technical decentralisation does not automatically remove legal or ethical accountability. Security documentation should identify who controls keys, who can pause the system, how incidents are reported, and how users can obtain reliable information.

Artificial intelligence can assist with code search, test generation, and triage, but generated code and findings require expert validation. AI tools may reproduce insecure patterns, miss economic assumptions, or create false confidence. They should support—not replace—specification, review, testing, and accountable engineering judgement.

13. Practical Security Checklist

Before deployment, a team should be able to answer “yes” to the following questions:

  • Are assets, roles, trust assumptions, and invariants documented?
  • Are all sensitive functions protected by explicit authorisation?
  • Are external calls minimised, ordered safely, and tested with malicious recipients?
  • Are arithmetic, decimals, rounding, and token behaviours handled deliberately?
  • Are oracle freshness, deviation, source diversity, and liquidity addressed?
  • Are front-running, flash loans, and transaction-order dependence considered?
  • Are loops bounded and withdrawal or distribution operations resistant to DoS?
  • Have unit, integration, property, invariant, fuzz, and adversarial tests been run?
  • Have static analysis, independent review, and appropriate formal methods been used?
  • Are upgrade keys, initialisation, storage layout, timelocks, and monitoring controlled?
  • Are deployment addresses, source code, permissions, and emergency procedures documented?

Chapter Summary

Smart-contract and dApp security requires a lifecycle approach that begins with requirements and threat modelling and continues through implementation, verification, deployment, monitoring, and incident response. Reentrancy is reduced by checks-effects-interactions, guarded entry, and careful external-call design. Access-control security depends on least privilege, secure initialisation, role separation, multisignature administration, and avoidance of tx.origin authorisation. Arithmetic, token-interface, and validation errors require explicit treatment of overflow, rounding, decimals, and non-standard token behaviour.

Oracle manipulation, front-running, flash loans, and DoS risks demonstrate that security is economic and architectural as well as syntactic. Robust feeds, snapshots, slippage controls, commit–reveal mechanisms, bounded computation, and pull-based payments address important classes of attack. Unit testing, fuzzing, invariant testing, static analysis, symbolic execution, formal verification, and independent review provide complementary assurance. Upgradeability must be governed as a security-critical capability, with protected initialisation, storage compatibility, transparent administration, and tested migration procedures.

Key Terms

Threat model: A structured description of assets, actors, assumptions, attack surfaces, and impacts.

Invariant: A property intended to remain true after valid state transitions.

Reentrancy: Repeated entry into a contract before an earlier call has completed.

Checks-effects-interactions: A design pattern that validates, updates state, and then performs external calls.

Access control: Rules determining which accounts may perform particular operations.

Least privilege: Giving each role only the authority required for its task.

Oracle: A mechanism supplying external data to a smart contract.

Oracle manipulation: Deliberate distortion or exploitation of data used by a contract.

Front-running: Executing a transaction before an observed pending transaction to gain advantage.

MEV: Value extracted by controlling or influencing transaction ordering and inclusion.

Sandwich attack: Front-running and back-running a victim transaction to profit from its price impact.

Flash loan: An atomic, uncollateralised loan that must be repaid within one transaction.

Denial of service: Prevention of legitimate system operation or user access.

Fuzzing: Automated testing with numerous generated inputs or call sequences.

Invariant testing: Testing that specified properties hold across generated state transitions.

Static analysis: Examination of code or bytecode without executing every path.

Formal verification: Mathematical analysis or proof that implementation satisfies a specification.

Proxy: A contract that delegates execution to another implementation, often while retaining state.

Multisignature wallet: An account requiring signatures from multiple authorised parties.

Timelock: A mandatory delay between approval and execution of a sensitive action.

Review Questions

Short Answer Questions

  1. What makes smart-contract security different from ordinary application security?
  2. Explain the checks-effects-interactions pattern.
  3. Why is tx.origin generally unsuitable for authorisation?
  4. State two risks associated with using a single spot-market price as an oracle.
  5. What is the purpose of invariant testing?

Long Answer Questions

  1. Describe a secure development lifecycle for a high-value smart contract, from requirements through operations.
  2. Explain how reentrancy can occur through token callbacks and compare at least three mitigation techniques.
  3. Discuss the relationship among flash loans, oracle manipulation, and economic insolvency.
  4. Compare static analysis, fuzzing, symbolic execution, formal verification, and independent audit.
  5. Evaluate the security benefits and risks of upgradeable proxy contracts.

Analytical / Application Questions

  1. A distribution contract loops through every registered user and sends tokens directly. Analyse its DoS risks and propose a safer design.
  2. A governance contract counts current token balances during voting. Explain how a flash loan could affect voting and design a more robust alternative.
  3. Design a threat model for a lending dApp, identifying its assets, privileged roles, external dependencies, key invariants, and emergency controls.

Multiple Choice Questions with Answers

Question 1

Which sequence best represents the checks-effects-interactions pattern?

A. External call, state update, input check

B. Input check, state update, external call

C. State update, external call, input check

D. Input check, external call, state update

Correct Answer: B. Input check, state update, external call

Question 2

Why is using tx.origin for authorisation dangerous?

A. It always changes during internal calls

B. It cannot identify an externally owned account

C. A malicious intermediary contract can cause a victim to call the target while tx.origin remains the victim

D. It prevents all contract-to-contract calls

Correct Answer: C. A malicious intermediary contract can cause a victim to call the target while tx.origin remains the victim

Question 3

Which design most directly reduces denial-of-service risk in a large payment distribution?

A. Use an unbounded loop over all recipients

B. Require every recipient to accept a pushed payment

C. Use a pull-based claim mechanism

D. Store recipients in a single string

Correct Answer: C. Use a pull-based claim mechanism

Question 4

What is a principal danger of using a shallow exchange pool as a price oracle?

A. The pool cannot execute swaps

B. A temporary trade can move the observed price significantly

C. The price is always older than one year

D. It prevents flash loans by definition

Correct Answer: B. A temporary trade can move the observed price significantly

Question 5

Which mechanism helps prevent a flash loan from granting temporary excessive voting power?

A. Counting the current balance at execution time

B. Using a historical voting snapshot

C. Removing all voting limits

D. Increasing transaction gas

Correct Answer: B. Using a historical voting snapshot

Question 6

What does fuzzing primarily do?

A. Encrypt deployed bytecode

B. Generate many inputs or call sequences to explore behaviour

C. Replace all human review

D. Guarantee that a specification is complete

Correct Answer: B. Generate many inputs or call sequences to explore behaviour

Question 7

Which statement about formal verification is correct?

A. It proves safety even when the specification omits an attack

B. It is mathematical assurance relative to a stated specification and assumptions

C. It only tests the user interface

D. It eliminates the need for access control

Correct Answer: B. It is mathematical assurance relative to a stated specification and assumptions

Question 8

Which control is most appropriate for a high-impact upgrade authority?

A. An unprotected public function

B. A single undocumented private key

C. Multisignature control with a transparent timelock

D. A user-interface button with no contract restriction

Correct Answer: C. Multisignature control with a transparent timelock

Question 9

What is a sandwich attack?

A. A denial-of-service attack against storage

B. A pair of transactions placed before and after a victim transaction to profit from its price impact

C. A cryptographic signature format

D. A method for upgrading proxy storage

Correct Answer: B. A pair of transactions placed before and after a victim transaction to profit from its price impact

Question 10

Which is an example of an invariant for a funded claims contract?

A. Every user must claim at the same time

B. The contract must have an unbounded loop

C. Total claims must not exceed funded reserves

D. All external calls must succeed permanently

Correct Answer: C. Total claims must not exceed funded reserves

Crypto & Security
Chapter 9 of 14