Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Guides

How to Set Security Assumptions Clearly

A technical guide for developers on defining, documenting, and validating explicit security assumptions for blockchain protocols and smart contracts to improve audit outcomes and reduce risk.
Chainscore © 2026
introduction
FOUNDATION

How to Set Security Assumptions Clearly

The first step in any security review is explicitly defining the system's assumptions. This guide explains how to document them for smart contracts and blockchain protocols.

Security assumptions are the explicit and implicit conditions under which a system is considered secure. For a smart contract, this includes assumptions about the underlying blockchain (e.g., honest majority of validators), the behavior of external dependencies like oracles or other contracts, and the trust model for users and admins. Failing to document these creates a critical blind spot, as auditors and users cannot evaluate risks for scenarios outside the intended operating environment. Clear assumptions act as a security perimeter, defining the boundary of responsibility for the protocol developers.

To document assumptions effectively, categorize them. Common categories include: Cryptographic Security (e.g., ECDSA signatures are unforgeable), Liveness & Network Assumptions (e.g., the chain does not halt, transactions are included within a known time), Economic Incentives (e.g., rational actors are profit-maximizing), and Trusted Entities (e.g., a 4-of-7 multisig is honest). For each, state the assumption plainly and its impact if violated. For instance: "Assumption: The Chainlink ETH/USD price feed is accurate and timely. Impact of Violation: Protocol liquidation logic may fail, leading to bad debt."

Integrate assumptions directly into your code and documentation. Use NatSpec comments in Solidity for function-level preconditions (e.g., /// @dev Assumes msg.sender has approved sufficient tokens). Maintain a standalone ASSUMPTIONS.md file in your repository that is referenced in your audit reports and protocol documentation. This practice, followed by projects like Compound and Aave, ensures the assumptions are living artifacts reviewed with each code change, not an afterthought.

Finally, test the boundaries of your assumptions. Use fuzzing tools like Foundry or Echidna to deliberately violate assumed conditions—such as providing malformed price feed data or simulating validator censorship—and verify the system fails safely (e.g., pauses operations) rather than entering an undefined state. This process transforms assumptions from passive statements into active, validated components of your security model, significantly reducing unexamined risk.

prerequisites
PREREQUISITES

How to Set Security Assumptions Clearly

Before deploying a smart contract, explicitly defining your security assumptions is a critical first step for formal verification and audit preparation.

Security assumptions are explicit statements about the expected behavior of the external systems and components your smart contract interacts with. These are not guarantees, but rather the foundational beliefs upon which your contract's logic is built. Common categories include assumptions about the underlying blockchain (e.g., "the EVM executes opcodes correctly"), oracle data feeds (e.g., "the Chainlink price feed will not be manipulated"), governance systems, and the behavior of other integrated smart contracts. Writing these down forces you to identify and document your system's trust boundaries.

To write effective assumptions, use a structured format. Each assumption should be a clear, testable (or falsifiable) statement. For example: ASM-01: The WETHcontract correctly implements the ERC-20 standard and itstransferFrom function will not revert for approved amounts. This format includes a unique identifier (ASM-01), a specific component (WETH contract), and an expected behavior. Avoid vague language like "the oracle will be reliable." Instead, specify: ASM-02: The Chainlink ETH/USD price feed will report a price within 5% of the CEX spot price and will update at least once per hour.

These documented assumptions become the direct inputs for your formal verification efforts. Tools like Certora, Solidity SMTChecker, or Halmos can be configured to prove that your contract's logic holds provided that the stated assumptions are true. For instance, you can formally verify that your liquidation logic is sound assuming the price feed provides accurate data. This shifts the security burden from proving absolute correctness to validating a specific, documented set of dependencies, making the audit scope clear and manageable for both developers and reviewers.

key-concepts-text
FOUNDATION

What Are Security Assumptions?

Security assumptions are the explicit, foundational conditions that a blockchain protocol or smart contract system relies upon to be secure. They define the boundaries of trust.

In blockchain and smart contract development, a security assumption is a formal statement about the environment, participants, or underlying technologies that must hold true for the system's security guarantees to be valid. Unlike traditional software that assumes a trusted server, decentralized systems explicitly list their trust model. Common categories include cryptographic assumptions (e.g., the computational hardness of SHA-256), economic assumptions (e.g., honest majority of stake), and network assumptions (e.g., bounded network delay). Failing to document these creates a critical vulnerability, as users and auditors cannot properly assess the system's risk profile.

Clear security assumptions act as a contract between developers and users. For a Proof-of-Stake chain, a core assumption might be that at least two-thirds of the staked tokens are controlled by honest validators. For a bridging protocol, an assumption could be that a majority of its multi-sig signers will not collude. Writing these down forces rigorous thinking about failure modes. The Ethereum protocol specification is a prime example, detailing assumptions about validator behavior and network synchrony. Without this clarity, security becomes ambiguous and attacks can emerge from unstated expectations.

To set assumptions effectively, start by modeling your system's trust boundaries. Ask: What components must be trusted? Is it a committee, a cryptographic primitive, or an external data feed? Document each assumption with its impact and failure consequence. For instance, Assumption: The underlying blockchain (e.g., Ethereum) is live and censoring transactions is prohibitively expensive. Consequence if false: Users cannot withdraw funds. Use precise, testable language. Avoid vague statements like "the oracle is reliable" in favor of "the oracle's data has a 99.9% uptime SLA and uses a decentralized attestation committee." This precision is crucial for formal verification and audit scope.

Integrate these documented assumptions directly into your code and documentation. In smart contracts, use NatSpec comments to annotate functions with their preconditions. For example, a function that settles a bet might include: /// @notice Settles the wager. Assumes: Chainlink price feed has not been manipulated. Public documentation, such as a SECURITY.md file or a dedicated audit report section, should list all high-level assumptions. This transparency allows users to make informed decisions and enables auditors to focus their review on validating that the system's logic correctly upholds these stated conditions, rather than searching for hidden dependencies.

assumption-categories
FOUNDATIONS

Categories of Security Assumptions

Security assumptions define the core trust model of a blockchain system. Clearly articulating them is the first step in threat modeling and risk assessment.

step-by-step-process
SECURITY FOUNDATION

Step-by-Step: Defining Your Assumptions

A clear, documented set of security assumptions is the bedrock of any robust smart contract system. This guide details how to formally define what your protocol trusts and what it does not.

Security assumptions are explicit statements about the environment and components your smart contracts rely on to function correctly. They define the trust boundaries of your system. For example, a decentralized exchange might assume its underlying oracle provides accurate price feeds, or a bridge might assume the validity of messages signed by a specific multi-sig. Writing these down forces you to identify and acknowledge external dependencies and trusted actors, which is the first step in managing their associated risks. Without documented assumptions, security reviews are ambiguous and threat modeling is incomplete.

Start by cataloging all external dependencies. This includes oracles (e.g., Chainlink, Pyth), bridges (e.g., Wormhole, LayerZero), governance mechanisms, upgradeable proxy admins, and privileged roles (e.g., owner, guardian). For each, document the specific assumption. Instead of "the oracle is secure," write "The protocol assumes that the Chainlink ETH/USD price feed on Ethereum mainnet, at address 0x5f4eC3..., does not deviate from the real-world market price by more than 2% for longer than one hour." This precision is critical for audit scope and monitoring.

Next, define system invariants—conditions that must always hold true. For a lending protocol, an invariant might be totalAssets >= totalDebt. For an AMM, it could be k = x * y (constant product). Code these as require() statements or formal properties in a specification language like Certora or Halmos. Clearly state which actors (users, admins, external contracts) are permitted to break which invariants and under what conditions, such as during a scheduled protocol upgrade executed by a 5-of-9 multi-sig.

Document assumptions about the underlying blockchain itself. These are often overlooked but vital. Examples include: "The protocol assumes the Ethereum network will not undergo a reorg deeper than 5 blocks," or "The contract assumes the block.timestamp is manipulable by miners within a ~15 second range and does not use it for critical timing." For Layer 2s or alternative L1s, specify assumptions about sequencer liveness, data availability, and proof systems.

Finally, compile assumptions into a living document, such as a SECURITY.md file in your repository. Structure it with clear sections: External Dependencies, Trusted Actors, System Invariants, and Blockchain Assumptions. This document should be the first reference for auditors and the basis for your monitoring and alerting systems. Regularly revisit and update it as the protocol evolves, ensuring your security model remains explicit and current.

COMMON PATTERNS

Security Assumption Examples by Component

Examples of explicit security assumptions for different components of a blockchain system.

System ComponentWeak Assumption ExampleStrong Assumption ExampleRationale

Consensus Mechanism

Validators are rational actors.

At least 2/3 of the validator set's stake is controlled by non-colluding, honest parties.

Quantifies the Byzantine fault tolerance threshold required for safety.

Bridge Validator Set

The bridge is secured by a trusted multisig.

The bridge's 8-of-12 MPC threshold signature scheme assumes no more than 3 signers are compromised.

Specifies the exact adversarial model for the signing group.

Oracle Network

The oracle provides accurate price data.

The Chainlink oracle network assumes no more than f/3 nodes in a decentralized oracle network are Byzantine at any time.

Defines the maximum faulty nodes the oracle's consensus can tolerate.

Smart Contract Upgradability

The proxy admin key is held securely.

The TimelockController contract enforces a 7-day delay on upgrades, assuming governance detects malicious proposals within that period.

Adds a time-based safety assumption for detecting malicious governance actions.

Sequencer (L2)

The sequencer does not censor transactions.

Users can force-include transactions via L1 if the sequencer is offline for more than 24 hours.

Provides a concrete, enforceable fallback mechanism with a defined timeline.

Economic Security

Slashing disincentivizes bad behavior.

A validator's stake must be at least 32 ETH, and slashing for provable attacks removes this stake, making attack cost > potential profit.

Explicitly ties the cost of an attack to the economic value at risk.

Client Diversity

The network runs multiple client implementations.

No single client implementation constitutes more than 33% of the network to avoid consensus failures from a single bug.

Sets a measurable target to mitigate systemic risk from client bugs.

documentation-and-specs
SECURITY BEST PRACTICES

Documenting Assumptions in Code and Specs

Clear documentation of security assumptions is a critical, yet often overlooked, component of robust smart contract and protocol development.

Every smart contract and protocol specification operates on a set of implicit assumptions. These are conditions that the system expects to be true for its security and correctness to hold. Common examples include assumptions about oracle accuracy, validator honesty, economic incentives, maximum slippage, and governance participation. When these assumptions are not explicitly documented, they become hidden failure points. Developers making future upgrades or integrations may unknowingly violate them, and users cannot properly assess the risks they are taking. Formalizing these assumptions transforms them from hidden risks into explicit, auditable constraints.

Documentation should exist at multiple levels. In code comments, use a standard tag like @assumption to annotate specific lines or functions. For example, a function relying on a price oracle should state: @assumption The Chainlink oracle price feed has not been manipulated and is updated within the last hour. In technical specifications or whitepapers, create a dedicated "Security Assumptions" section. This section should list all high-level premises, such as "The majority of staked ETH is held by honest validators" or "The governance timelock is longer than the longest liquidity withdrawal period."

The most rigorous approach is to encode assumptions as formal properties or invariants using tools like Foundry's invariant tests or Certora's specification language. For instance, you can write a test that asserts: invariant totalSupply() == sum(userBalances) to document the assumption that no tokens can be created or destroyed outside of mint/burn functions. This moves documentation from passive text to active, executable checks. Frameworks like OpenZeppelin's Contracts library often document their security assumptions, such as the reentrancy guard's assumption about the order of state changes, providing a model to follow.

Assumptions must be periodically reviewed and tested. As the external ecosystem changes—new bridge vulnerabilities emerge, oracle designs evolve, or economic conditions shift—previously safe assumptions can become invalid. Establish a review process, perhaps tied to major protocol upgrades or incident post-mortems. Ask: Are our oracle safeguards still sufficient given new flash loan capabilities? Does our liquidation logic hold under extreme network congestion? Treating assumptions as living documentation ensures your system's security model remains aligned with reality.

Finally, communicate critical assumptions to end-users and integrators. This is a core component of transparent risk disclosure. A protocol's front-end or documentation should clearly state, for example, "This vault assumes the underlying Curve pool maintains its peg; significant depeg may result in loss." This empowers users to make informed decisions and aligns with growing regulatory expectations for clear communication of financial risks in decentralized systems. Clear assumption documentation is not just a developer convenience; it is a foundational practice for building and maintaining trust.

SECURITY ASSUMPTIONS

Common Mistakes and Pitfalls

Incorrect or implicit security assumptions are a leading cause of smart contract vulnerabilities and bridge exploits. This guide clarifies how to define, document, and validate them.

Security assumptions are explicit statements about the expected behavior of external components, actors, or environmental conditions that your system relies on to remain secure. They define the trust boundaries.

Examples include:

  • Assuming an oracle provides accurate, timely price data.
  • Assuming a multisig wallet requires M-of-N signatures.
  • Assuming the underlying blockchain's consensus is secure (e.g., 51% attack is improbable).

Failing to document these creates implicit trust, leading to vulnerabilities when assumptions are violated. The 2022 Wormhole bridge hack ($325M) resulted from a failure to validate a core assumption about the guardian set's signature verification.

SECURITY ASSUMPTIONS

Frequently Asked Questions

Clear security assumptions are the foundation of safe smart contract development. These questions address common developer confusion and best practices for defining and communicating trust boundaries.

Security assumptions are explicit statements about the conditions a smart contract relies on to function correctly and securely. They define the trust boundaries of your system. For example, a decentralized exchange (DEX) might assume the underlying oracle (like Chainlink) provides accurate price data, or a lending protocol assumes the underlying collateral asset is not a rebasing token.

Failing to document these assumptions is a leading cause of vulnerabilities. The 2022 Nomad bridge hack, resulting in a $190M loss, stemmed from an incorrect assumption about how a initialization function would be called. Clearly stating assumptions helps auditors focus their review, informs users of risks, and serves as a checklist for future protocol upgrades or integrations.

conclusion
SECURITY FUNDAMENTALS

Conclusion and Next Steps

Clearly defined security assumptions are the foundation of a robust smart contract system. This final section summarizes the key principles and provides concrete steps for implementing them in your development workflow.

Security assumptions are not a one-time declaration but a living document that evolves with your protocol. The process involves three core activities: explicit documentation, continuous validation, and proactive communication. Document every assumption in your codebase using NatSpec comments and a dedicated SECURITY.md file. Validate these assumptions through rigorous testing, including invariant testing with tools like Foundry's forge, and formal verification where applicable. Finally, communicate critical assumptions to users through your interface and documentation, ensuring they understand the system's trust model.

To operationalize this, integrate assumption tracking into your development lifecycle. During the design phase, use threat modeling frameworks like STRIDE to identify implicit assumptions. In development, enforce them with require statements and custom errors, making violations impossible to ignore. For example, a bridge contract should explicitly check and revert if an oracle's reported block hash is older than a defined MAX_ORACLE_DELAY. In auditing, provide auditors with a prioritized list of your top ten security assumptions to focus their review. Post-deployment, monitor for events that could invalidate your assumptions, such as a validator set change in a connected chain.

Your next steps should be practical and immediate. First, audit your most critical smart contract and list every implicit assumption you find. Second, formalize at least five of these into explicit, testable checks in your code. Third, explore tools like the Chainlink Automation for monitoring off-chain conditions or OpenZeppelin Defender for admin action timelocks that protect against governance assumptions failing. By baking security assumptions into your process, you shift from reactive patching to proactive resilience, building systems that are secure by design and transparent by default.

How to Set Security Assumptions for Smart Contracts | ChainScore Guides