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.
How to Set Security Assumptions Clearly
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.
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.
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.
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.
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: 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.
Security Assumption Examples by Component
Examples of explicit security assumptions for different components of a blockchain system.
| System Component | Weak Assumption Example | Strong Assumption Example | Rationale |
|---|---|---|---|
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. |
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.
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.
Tools and Resources
Clear security assumptions reduce misaligned expectations, unsafe integrations, and audit gaps. These tools and frameworks help teams explicitly document trust boundaries, attacker models, and operational constraints.
Security Assumptions Document Template
A dedicated security assumptions document makes implicit trust decisions explicit and reviewable. This is usually a standalone file linked from the README.
Key elements to include:
- Trusted actors: multisig signers, admins, off-chain relayers
- Threat model scope: what attackers can and cannot do
- Environmental assumptions: honest-majority L1, block reorg depth, timestamp manipulation
- Upgrade and pause powers: who can act and under which conditions
Well-known audit firms routinely request this document before engagement. Writing it early reduces redesign late in development.
Role-Based Access Control Inventory
Explicitly enumerating roles and privileges prevents silent trust expansion over time. This is critical for upgradable contracts and DAO-operated systems.
Best practices:
- List every role and associated functions
- Identify which roles can move user funds
- Specify rotation and revocation procedures
- State whether roles are EOAs, multisigs, or contracts
Many exploits stem from misunderstanding who can call sensitive functions. A role inventory surfaces this risk early for auditors and users.
Public Risk Disclosure Sections
User-facing documentation should include a concise risk and assumption disclosure section. This is not legal boilerplate but technical transparency.
Common disclosures:
- Dependency on specific oracles or bridges
- Upgrade risk and admin intervention scenarios
- Economic assumptions such as liquid markets or rational arbitrageurs
- Failure modes that result in loss or stuck funds
Protocols that publish these sections reduce support load and improve informed adoption by integrators and front-end teams.
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 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.