# The Complete Guide to Securing Web3 Projects

Security is a top priority for web3 users when choosing decentralized applications (dApps). They prefer platforms with a proven track record of safety and a clear commitment to secure practices. While much has been written about vulnerabilities in smart contracts, there’s less focus on practical steps to prevent them.

At [OptimumSec](https://optimumsec.xyz/), we’ve seen that projects succeed when security is treated as a continuous process rather than a one-time checklist. This guide distills that approach into a clear, actionable framework for integrating security throughout the smart contract lifecycle—from design and coding to deployment and ongoing maintenance.

Whether launching a new project or improving an existing one, use this resource to reduce risks, streamline processes, and build a strong foundation for secure operations.

We welcome community contributions! If you have suggestions or additional insights, feel free to open a PR on our [GitHub repository](https://github.com/optimumsec/the-complete-guide-to-securing-web3-projects) to help improve this guide.


# Design


# Design a Gradual Path Towards Immutability

Achieving perfect, bug-free smart contracts at launch is nearly impossible. Instead, treat **immutability** as a **gradual process**, building resilience through extensive testing, community review, and real-world use.

By starting with upgradeable contracts and gradually transitioning key components to immutability, you can ensure a balance between security and adaptability as your system matures.

***

## Why Gradual Immutability?

* **Flexibility:** Allows for fixes and improvements in the early stages.
* **Risk Mitigation:** Reduces the impact of unforeseen vulnerabilities.
* **Progressive Security:** Confidence in the code grows over time as it is battle-tested.

***

## Staged Approach to Immutability

1. **Start with Upgradeable Contracts**
   * Design most contracts to be upgradeable at launch, especially those with:
     * Complex or novel logic.
     * Dependencies on other upgradeable components.
     * Frequent interactions with external systems.
2. **Identify Candidates for Immutability**
   * Mature contracts with:
     * Simple, self-contained logic.
     * Code derived from trusted libraries.
     * Extensive audits and real-world use.
3. **Transition Gradually**
   * As confidence builds, evaluate contracts for immutability using these factors:
     * **Code Maturity:** Proven stability over time.
     * **Usage:** Widespread adoption and testing by the community.
     * **Isolation:** Minimal interaction with upgradeable components.

***

## Examples

### 1. **Good Candidate for Immutability**

* **Token Contracts:** Based on trusted libraries like OpenZeppelin and with self-contained logic.

### 2. **Better Suited for Upgradeability**

* **New AMM Models:** Complex or experimental algorithms that may require adjustments post-deployment.

***

## Best Practices

* **Leverage a Security Council:** Regularly assess which components are ready to transition to immutability.
* **Audit Thoroughly:** Ensure each contract has undergone rigorous testing and review before making it immutable.
* **Document the Process:** Maintain a clear record of which components are upgradeable and which are immutable.


# Core/Periphery Design Pattern for Immutable Protocols

For teams that decide **not** to use upgradeable contracts (see the [gradual immutability path](https://github.com/optimumsec/the-complete-guide-to-securing-web3-projects/blob/main/design/gradual-immutability-path.md)), the **core/periphery split** is a practical design choice that can minimize security issues while still allowing controlled changes of functionality.

## What Is the Core/Periphery Split?

The **core** is the immutable, minimal set of contracts that define protocol-critical logic and invariants. The **periphery** is the replaceable layer that handles user interactions, UX improvements, and convenience features.

### Core

* Immutable once deployed.
* Holds critical state and enforces protocol-level invariants.
* Example: Uniswap V2/V3 Pool contracts (AMM math, reserves, invariant checks).

### Periphery

* Can be re-deployed and versioned over time.
* Abstracts away complexity and adds features like batching, multicall, safer UX.
* Example: Uniswap Router, NonfungiblePositionManager.

## Why Use This Pattern?

* **Security:** Core stays locked down, surface area minimized.
* **Flexibility:** Teams can adapt UX, improve efficiency, or patch integration bugs without touching core.
* **Clarity:** Easier to communicate security guarantees: "The pool logic is immutable. Routers can change."

## Upgrade Strategy Without Proxies

Even if core is immutable, periphery contracts can evolve. Typical approaches include:

* **Versioned Routers:** Deploy new routers with improved logic; users migrate voluntarily.
* **Registries:** Maintain a registry contract pointing to the latest periphery; frontends can read from it.
* **Migrations:** Encourage/force users to migrate state from old periphery to new periphery.

## Security Model

* **Core**: must be fully audited, formally verified if possible, and designed for immutability.
* **Periphery**: can be updated, but still requires review since it can influence user behavior.
* **Interaction**: Core contracts should never trust periphery; only enforce strict invariants.

## Common Patterns

* **Router → Pool Calls:** Router bundles user actions and calls into pools.
* **Callback Interfaces:** Core pools define strict callback requirements, which routers must satisfy.
* **Position Managers:** Higher-level contracts for abstracting LP positions.
* **Fee Hooks / Incentives:** Kept in periphery to avoid contaminating invariant logic.

## Pitfalls

* **Too Much in Periphery:** If periphery enforces invariants instead of core, security assumptions break.
* **Silent Upgrades:** Replacing periphery without notice can create governance or trust issues.
* **Registry Risks:** If the registry is compromised, users may be routed to malicious periphery contracts.

## Example: Minimal Core/Periphery Split

```solidity
// Core: immutable pool
contract Pool {
    uint112 reserve0;
    uint112 reserve1;

    function swap(uint amount0Out, uint amount1Out) external {
        // Invariant: x * y >= k
        require(amount0Out == 0 || amount1Out == 0, "Only one side out");
        // ...
    }
}

// Periphery: router that interacts with core
contract Router {
    function swapExactTokensForTokens(...) external {
        // Handle approvals, slippage checks, path routing
        Pool(pool).swap(...);
    }
}
```


# Actor-Based Threat Modeling

Actor-based threat modeling is a structured approach to identifying potential threats and vulnerabilities in smart contract systems by analyzing the interactions between different entities (actors) and the system.

The actor-based approach to threat modeling offers a more practical, human-centric perspective compared to other methods like [STRIDE](https://en.wikipedia.org/wiki/STRIDE_model), data flow diagrams, or attack trees.

By focusing on the interactions between different actors (e.g., users, administrators, attackers), it better captures the dynamic nature of threats in decentralized systems like smart contracts. This approach allows for tailored mitigation strategies based on actor motivations, priorities risks more effectively, and provides a more comprehensive view of security by considering both technical and human factors. It is particularly well-suited for decentralized systems, where multiple actors, both on-chain and off-chain, interact with the system.

***

## Key principles of Actor-Based Threat Modeling:

1. **Identify Actors** Actors are entities that interact with the smart contract. They can be:

* External Users: Individuals or entities initiating transactions (e.g., token holders, DAO members).
* External Smart Contracts: Other contracts interacting with the system.
* Off-chain Components: Systems like oracles or bridges.
* Administrators: Privileged actors with elevated permissions.

2. **Define Actor Goals and Motivations** Each actor interacts with the smart contract to achieve specific objectives:

* Administrators might upgrade contracts or modify critical parameters.
* Attackers aim to steal funds, disrupt operations, or exploit vulnerabilities for personal gain.

3. **Map Actor Interactions** Document how each actor interacts with the smart contract:

* Which functions they can call.
* What permissions or access controls are in place.
* How data flows between actors and the contract.

4. **Identify Threats and Vulnerabilities** For each interaction, analyze potential threats:

* External Users: Exploiting unchecked inputs, edge cases and/or lack of access control.
* External Smart Contracts: Reentrancy attacks, broken composability.
* Off-chain Components: Oracle manipulation, delayed data updates.
* Administrators: Abuse of privileged roles, key compromise.

5. **Analyze the Impact and Likelihood of Each Threat** Prioritize threats based on their potential impact and likelihood:

High Impact, High Likelihood: Must be addressed immediately.

High Impact, Low Likelihood: Require monitoring and mitigations.

Low Impact, High Likelihood: Address if they affect user experience or trust.

6. **Define and Implement Mitigations** For each identified threat, propose and implement mitigations.
7. **Test and Iterate** Continuously test the smart contract for these threats using:

* Unit tests for specific vulnerabilities.
* Fuzz testing for unexpected inputs.
* Simulations for multi-actor scenarios (e.g., testing oracle failures)


# Principle of Least Privilege

## Overview

Ensuring your smart contract functions are secure is essential. By default, it’s best to restrict access to public functions to avoid unauthorized interactions that could lead to exploits. Only grant access to specific roles, contracts, or addresses that genuinely require it. Before making any function accessible to everyone, take a moment to assess its necessity and the potential security risks.

## Code Example

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/proxy/Clones.sol";

contract Factory {
    function createClone(
        address _implementation,
        bytes calldata _extraData
    ) external returns (address gauge) {
        address clonedContract = Clones.cloneDeterministic(_implementation, keccak256(abi.encode(_extraData)));

        Clone(clonedContract).init(_extraData);

        return clonedContract;
    }
}

interface Clone {
    function init(bytes calldata _extraData) external;
}
```

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./Factory.sol";  // Import the Factory contract

contract CloneCaller {
    Factory factory;  // Instance of the Factory contract
    address public admin;  // Admin address

    modifier onlyAdmin() {
        require(msg.sender == admin, "Caller is not the admin");
        _;
    }

    constructor(address _factoryAddress, address _admin) {
        factory = Factory(_factoryAddress);  // Set the Factory contract address
        admin = _admin;  // Set the admin address
    }

    function createNewClone(address _implementation, bytes calldata _extraData) external onlyAdmin returns (address) {
        // Call the createClone function from the Factory contract
        address newClone = factory.createClone(_implementation, _extraData);
        return newClone;
    }
}
```

This example highlights a potential vulnerability. While `CloneCaller.createNewClone()` is access-controlled, there’s a risk from front runners who could directly call `Factory.createClone()`, potentially blocking `createNewClone()` and causing a denial of service. Therefore, `Factory.createClone()` should be restricted only for `CloneCaller`.

## Best Practices

### 1. Implement Role-Based Access Control (RBAC)

RBAC is a great way to ensure that only those with the proper authority can access sensitive functions. Assign roles carefully, always asking: "Does this role truly need this level of access?"

### 2. Default to Restricting Access

By default, it’s safest to lock down functions until there’s a compelling reason to expose them. If you must make a function public, thoroughly evaluate the potential security implications.

### 3. Define Roles Clearly

Establish clear roles like `ADMIN`, `OPERATOR`, and `USER`, ensuring each role has only the permissions it actually needs. Broad permissions can quickly introduce security risks, so avoid giving too much access by default.

### 4. Regularly Review and Adjust Permissions

Access control should be seen as an ongoing process, not a one-time setup. Regularly revisit your function permissions and make adjustments as needed. If a role no longer requires access to a function, revoke it immediately.


# Implement a Role-Based Access Control (RBAC) Model

In decentralized applications (dApps), multiple user roles with varying levels of permissions are a given. Managing this complexity securely requires a well-defined **Role-Based Access Control (RBAC)** model. By mapping out system assets and actions, and assigning permissions based on roles rather than individual identities, you can ensure robust security and streamlined access management.

***

## Benefits of an RBAC Model

* **Enhanced Security:** Restricts access to critical functions based on user roles, reducing risks of unauthorized actions.
* **Operational Efficiency:** Simplifies permission management by defining roles instead of managing individual identities.
* **Modular Design:** Enables easy updates to roles and permissions without disrupting the system.

***

## Key Components of RBAC

1. **Roles:** Define distinct roles, such as:
   * **Administrator**: Full control over all contract functionalities.
   * **Owner**: Governance-level permissions.
   * **User**: Limited access to application-specific actions.
2. **Permissions:** Assign specific permissions to each role based on responsibilities and access needs.
3. **Separation of Duties:** Enforce role segregation to minimize risks of abuse or mismanagement.

***

## Example Implementation

Using [**OpenZeppelin's AccessControl Library**](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol):

* Define roles like `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, or `PAUSER_ROLE`.
* Assign roles to addresses using `grantRole` and `revokeRole` functions.
* Restrict sensitive functions to specific roles with `onlyRole(role)` modifiers.

***

## Best Practices for RBAC

* **Use Least Privilege:** Assign only the minimum permissions needed for each role.
* **Implement Timelocks:** Add timelocks to administrative actions for added security.
* **Audit Regularly:** Periodically review roles, permissions, and user assignments to ensure they align with current operational requirements.


# Design for Funds Isolation

Pooling user funds in a single contract is a common approach in decentralized applications. While efficient, this design introduces significant risk—if a vulnerability exists in the accounting logic, attackers can potentially compromise the entire pool.

To mitigate this risk, designing smart contracts with **funds isolation** in mind is a critical security best practice. By isolating funds at the contract level, you can minimize the impact of potential exploits.

***

## Benefits of Funds Isolation

* **Reduced Attack Surface:** Exploits affecting one contract cannot spread to others.
* **Enhanced Security:** Logical isolation ensures that vulnerabilities in one part of the system don't jeopardize the entire protocol.
* **Improved Risk Management:** Limits the scale of financial losses in case of an exploit.

***

## Examples of Funds Isolation

### 1. **Vesting Allocations**

Instead of pooling all recipients' allocations in a single contract:

* **Isolated Design:** Create a unique contract instance for each recipient with their pre-allocated amount.
* **Security Benefit:** If a vulnerability exists in the vesting logic, it will only affect one recipient's contract, not the entire pool.

To implement funds isolation in vesting contracts, you can use **reference implementations** such as [OpenZeppelin's finance contracts](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/finance) as a foundation.

### 2. **Separated Liquidity Pools**

In decentralized exchanges (DEXs):

* **Isolated Design:** Deploy a separate contract for each token pair (e.g., ETH/USDC or DAI/USDT).
* **Security Benefit:** If an exploit occurs, only the affected pair's liquidity is at risk, limiting the impact on the rest of the protocol.

***

## Trade-Offs of Isolation

While funds isolation provides strong security benefits, it introduces additional complexities:

* **Maintenance Overhead:** Each isolated contract may need individual updates, increasing administrative effort.
* **Higher Gas Costs:** Deploying multiple contracts can lead to higher deployment and operational costs.


# Implement Circuit Breakers

Circuit breakers are essential for smart contract security, offering a mechanism to pause or stop functions during unexpected events or attacks. This safeguard is particularly critical in decentralized finance (DeFi), where contracts handle significant user funds and are subject to constant transaction activity.

Implementing circuit breakers helps prevent further loss by halting operations when vulnerabilities are exploited or unusual activity is detected. This gives developers time to investigate and address issues, enhancing the contract's security and trustworthiness.

***

## Key Considerations for Effective Circuit Breakers

1. **Minimize Centralization**
   * **Approach 1:** Pause new deposits while allowing withdrawals up to a certain limit, ensuring users can still access their funds.
   * **Approach 2:** Implement a multi-layered consensus system, where withdrawals require input from multiple parties, while a designated operator manages the pause function.
2. **Balance Security and Decentralization**
   * Maintain a level of control to manage risks while avoiding overly centralized decision-making processes that may compromise user trust.

***

## Benefits

* **Immediate Response:** Quickly halts potentially harmful contract operations.
* **User Protection:** Ensures users retain access to their funds during disruptions.
* **Improved Stability:** Reduces the risk of widespread protocol failure.

***

## Best Practices

* **Ensure Transparency:** Make it clear how and when circuit breakers are triggered.
* **Decentralize Control:** Design the system to avoid a single point of failure or excessive control by one party.
* **Test Thoroughly:** Simulate various attack scenarios to ensure the circuit breaker works as intended under different conditions.


# Global Registry for Project Deployed Smart Contracts

## Introduction

A **Global Registry Contract** is a central contract that tracks all deployed contracts within a project. It ensures secure interactions between contracts while enforcing structured access control. Every deployed contract should store the registry’s address and use it to validate interactions.

### Why Use a Global Registry?

* ✅ **Efficient Tracking:** Maintain a single source of truth for deployed contracts.
* 🔐 **Access Control:** Securely manage contract interactions.
* 📂 **Role-Based Grouping:** Aggregate contract instances into structured roles.
* 📉 **Eliminate Redundancy:** Reduce storage costs by keeping addresses in a single registry instead of multiple contracts.

## Benefits

### 🔑 Security & Access Control

* Contracts can verify interactions based on registered roles.
* Reduces unauthorized access and contract misuse.

### 🛠️ Storage Efficiency

* Prevents multiple contracts from storing redundant addresses.
* Saves gas costs by centralizing contract reference data.

## Design Considerations

### 📌 Registry Reference in Every Contract

Each deployed contract should store the **registry address** for validation.

### 🗂️ Key-Value Storage

* Contracts are stored using a **key** (contract name + unique identifier) and a **value** (contract address).

### 👥 Role-Based Access Control

* The registry groups contract instances under **roles**, allowing multiple instances of the same contract to interact securely.

### 👨‍💼 Ownership & Management

* Define **who** can register contracts and assign roles (admin, DAO governance, etc.).


# Coding


# Code Conservatism: Less is More

**Principle:**\
When writing smart contracts, embrace code conservatism: avoid unnecessary complexity. Adding more code doesn't always mean better security. Over-engineering with extra checks or invariants can introduce a false sense of security and increase the risk of unintended consequences, such as unexpected reverts or edge cases that worsen contract reliability.

***

## Why Code Conservatism Matters

1. **Reduced Attack Surface:**
   * More code means more potential vulnerabilities.
   * Every line should serve a critical purpose.
2. **False Sense of Security:**
   * Adding extra invariants or checks can feel like increasing security but may instead:
     * Create untested failure paths.
     * Introduce conditions that trigger unexpected reverts.
3. **Audit Complexity:**
   * Simplicity enhances readability and makes code easier to audit thoroughly.

***

## Actionable Practices

* **Avoid Over-engineering:**
  * Question every line of code. Does it **truly** contribute to security or essential functionality?
* **Minimize State Changes:**
  * Limit external state modifications and interactions.
* **Invariants and Assertions:**
  * Use only essential invariants directly tied to contract integrity.
  * Avoid excessive runtime checks unless absolutely necessary.
* **Fail Fast, Fail Clearly:**
  * When adding reverts, ensure they are predictable and do not block valid user interactions.
* **Iterative Review:**
  * Continuously refactor and simplify.
  * If a piece of code seems redundant or marginal, reconsider its necessity.

***

## Summary

* Less is more: Write only what's necessary for correctness and security.
* Avoid bloat: More code ≠ more secure.
* Think critically: Don't let additional checks create a false sense of security.


# Use a Spell Checker

Using a spell checker in an IDE improves Solidity code security by catching errors in documentation, comments, and variable names that may lead to misinterpretations or vulnerabilities. While some misspellings are caught by the compiler, inconsistencies in hardcoded strings—such as those in EIP-1967 variable declarations—can still introduce risks.

Tools like [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) help maintain clarity and consistency, supporting more secure and reliable smart contracts.


# Use an Up-To-Date Compiler Version

Solidity, functioning as a domain-specific language, remains in its early stages of development. Consequently, it continues to evolve, with recent compiler iterations integrating bug fixes, novel features, enhanced "syntactic sugars", and more. Nonetheless, exercising prudence is imperative.

It's advisable to exercise patience before embracing a new compiler version, owing to the phenomenon commonly referred to as 'early infant mortality failure'. Consider upgrading the Solidity version to >=0.8.0. This significant release inherently incorporates built-in safe math functionality, potentially rendering the SafeMath library and its uses unnecessary.


# Security-Driven Development

Similar to how Test-Driven Development (TDD) focuses on writing tests before the actual code, SDD prioritizes the identification and mitigation of potential security vulnerabilities and correctness issues throughout the development process. While fully adopting all the principles of SDD might be considered heavy or even overkill for many development teams, even implementing them partially can have a significant positive impact on the overall security and reliability of the smart contract.

***

## Key principles of Security-Driven Development (SDD):

1. [**Threat Modeling First**](https://github.com/optimumsec/the-complete-guide-to-securing-web3-protocols/blob/main/coding/actor-based-threat-modeling.md): Begin by identifying potential attack vectors and security risks in the contract’s intended functionality.
2. **Security-Driven Specifications**: Define explicit security and correctness requirements, such as invariants, access control rules, and critical state transitions.
3. **Write Security Tests Before Code**: Develop comprehensive tests to validate these requirements, including unit tests, property-based tests, and fuzz tests.
4. **Iterative Development with Security in Mind**: As the code evolves, continuously revisit and refine threat models and add new security tests.
5. **Automated and Manual Auditing**: Integrate static analysis tools and conduct periodic manual code reviews.
6. **Formal Verification**: For critical components, use formal verification tools to mathematically prove correctness against the defined specifications.


# Define a Security-Oriented CI Environment

A robust CI/CD pipeline is essential for Solidity development, ensuring code quality, security, and streamlined deployments. Below are the key components and tools to incorporate into your pipeline.

***

## 1. Continuous Integration Platforms

* [**GitHub Actions**](https://github.com/features/actions)
* [**GitLab CI/CD**](https://docs.gitlab.com/ee/ci/)
* [**CircleCI**](https://circleci.com/)
* [**Travis CI**](https://travis-ci.com/)

## 2. Test Coverage Tools

* [**solidity-coverage**](https://github.com/sc-forks/solidity-coverage)**:** A Hardhat plugin that measures test coverage for Solidity projects.
* [**Forge Coverage**](https://book.getfoundry.sh/)**:** A feature within Foundry for generating test coverage reports, ideal for Rust-based Solidity workflows.

## 3. Testing Frameworks

* [**Hardhat**](https://hardhat.org/)**:** A flexible development environment for compiling, deploying, and testing smart contracts.
* [**Foundry**](https://book.getfoundry.sh/)**:** A Rust-based framework with powerful testing features, including fuzz testing and gas profiling.

## 4. Security and Static Analysis Tools

* [**Slither**](https://github.com/crytic/slither)**:** A static analysis tool for detecting vulnerabilities and enforcing best practices.
* [**MythX**](https://mythx.io/)**:** A cloud-based smart contract security scanner offering detailed vulnerability reports.
* [**Echidna**](https://github.com/crytic/echidna)**:** A fuzzer for testing invariants and edge cases in Ethereum smart contracts.

## 5. Code Quality and Style Enforcement

* [**Solhint**](https://protofire.github.io/solhint/)**:** A linter for Solidity that enforces coding standards and best practices.
* [**Prettier Plugin for Solidity**](https://github.com/prettier-solidity/prettier-plugin-solidity)**:** Ensures consistent formatting of Solidity code, automating style checks within pipelines.


# Prefer Unstructured Storage for Upgradeable Contracts

Linear storage, which is the default way to manage storage variables, is intuitive but has limitations. When combined with inheritance, it requires us to maintain the well-known (and some would say infamous) [`__gap` array](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps). Managing this array increases complexity and makes audits more challenging.

A proposed alternative is to use [EIP-7201](https://eips.ethereum.org/EIPS/eip-7201) storage slots, which can offer greater flexibility. However, this approach should be used with caution: variable names should be uniquely chosen and consistently referenced. Utilizing [spelling checkers](https://github.com/optimumsec/the-complete-guide-to-securing-web3-protocols/blob/main/coding/use-spelling-checkers.md) can help maintain naming consistency and reduce potential issues.


# Avoid Vendoring Dependencies

Vendoring smart contracts or libraries—copying them directly into your project—can lead to significant risks, including:

1. **Security Risks:** Vendored code doesn't automatically benefit from updates or security patches, leaving your project vulnerable.
2. **Auditing Challenges:** Embedded dependencies are harder to track and audit, reducing transparency.
3. **Upgradability Issues:** Vendoring locks you into outdated versions, making it difficult to adopt new features or fixes.
4. **Increased Complexity:** Managing multiple vendored libraries adds unnecessary project overhead.

***

## Best Practice: Use Package Managers

Leverage tools like **npm**, **yarn**, **Forge**, or **Hardhat** to manage dependencies efficiently. These tools ensure easy updates, version control, and compatibility, keeping your code secure and maintainable.


# Use a Plugin for Safe Upgrades

When setting up a proxy for a contract, there are specific restrictions concerning the contract's code. Notably, the contract mustn't include a constructor, and it's advised to steer clear of utilizing operations like selfdestruct or delegatecall due to security considerations.

In addition, storage variables in the proxy can potentially be overwritten when deploying new versions of the implementation contract. This happens because the storage layout of the proxy and implementation must remain consistent across upgrades. Any mismatch in storage variable declarations or order can result in overwritten or corrupted data, leading to unpredictable behavior.

It is highly recommended to use a [plugin](https://docs.openzeppelin.com/upgrades-plugins/1.x/) that ensures the newly introduced contract complies with the safe upgrades rules.


# Use Reentrancy Guards

Reentrancy is generally not expected behavior in most smart contracts, with the exception of callback systems like those used in Uniswap. As a best practice, this behavior should be restricted unless explicitly necessary.

In practice, all state-changing functions that include external calls should be protected by a reentrancy guard by default, and any removal of this protection should only occur after a thorough assessment of its impact.

If gas optimization is a concern, consider using a reentrancy guard library that leverages [transient storage](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/ReentrancyGuardTransient.sol). Be aware that some EVM chains do not support transient storage. For details on opcode support across different chains, refer to [evmdiff.com](https://www.evmdiff.com/features?feature=opcodes).


# Revert/Return Early

Reverting or returning early in a function is a useful way to improve code clarity, maintainability and save gas. By terminating execution when certain conditions aren't met—like failed input validation or access control—unnecessary logic is skipped, and any changes are rolled back, ensuring contract integrity.


# Revert vs Return

## TL;DR Rules

**Revert** when any of the following is true:

* The function is **state-changing** and a precondition, invariant, or authorization check fails.
* A **security boundary** would be crossed (e.g., missing role, paused state, supply cap breach).
* A downstream call’s failure would produce **partial state** or **ambiguous outcome**.
* The caller **cannot safely proceed** without this operation succeeding.

**Return** when all of the following are true:

* The function is **non–state-changing** (`view`/`pure`) *or* the failure is an **expected, non-security** outcome.
* The caller can **safely decide next steps** using the returned value.
* Soft-failure improves **UX or composability** without hiding risk (e.g., a probe, simulation, or off-chain read).

> Default to **revert** for write functions; opt into **return** for read/probe helpers.

## Decision Tree

1. **Will state change on success?**
   * **Yes** → If any precondition fails → **Revert**.
   * **No** → Proceed.
2. **Is the check about permissions, invariants, or monetary safety?**
   * **Yes** → **Revert**.
   * **No** → Proceed.
3. **Can the caller safely handle a soft-fail?** (No ambiguity, no partial effects)
   * **No** → **Revert**.
   * **Yes** → **Return** a boolean/enum/optional.

## When to **Revert**

* **Authorization & Pausing**: `onlyOwner`, role checks, `Pausable` state.
* **Input Validation**: malformed parameters, invalid array lengths, zero address (when unsafe), overflow conditions not handled by compiler.
* **Economic/Safety Invariants**: caps exceeded, debt ratios violated, collateralization too low, auction not active, deadlines expired.
* **Atomicity & Funds Movement**: any transfer/mint/burn that must succeed to avoid inconsistent state or loss of funds.
* **Protocol-Level Guarantees**: conditions documented as MUST in your spec/README.
* **Unsupported Tokens/Behaviors** when interacting with external standards.

> Use **custom errors** (e.g., `error NotAuthorized();`) for low gas and clearer decoding.

## When to **Return** (Soft-Fail / Informational)

* **Probing/Quoting**: returning whether an action *would* succeed and at what price (`view` quote functions).
* **Best-Effort Operations** that are explicitly non-critical and have **no side effects** on failure.
* **Eligibility Checks** that frontends can call off-chain to pre-screen (e.g., `canClaim(address) returns (bool)`), leaving the write path to **revert** if wrong.
* **Batch Reads** where some elements might be missing; return per-item statuses instead of failing the entire batch.
* **Upgradeable feature flags** or **optional modules** where absence is not a security boundary.

> For write paths, prefer reverting on any failed per-item operation unless the **spec** promises partial success and you **return a per-item report**.

## Mixed Pattern: Soft-Check Helper + Hard-Fail Writer

* Provide a \`\`\*\* helper\*\* that returns `(bool ok, bytes reason)` or an enum.
* The **state-changing** function calls the same internal logic and **reverts** on failure.

```solidity
error NotWhitelisted();

function canMint(address user, uint256 amount) public view returns (bool ok, bytes32 reason) {
    if (!whitelist[user]) return (false, bytes32("NOT_WHITELISTED"));
    if (totalSupply + amount > cap) return (false, bytes32("CAP_EXCEEDED"));
    return (true, bytes32(0));
}

function mint(address to, uint256 amount) external {
    (bool ok, bytes32 reason) = canMint(to, amount);
    if (!ok) revert(reason == bytes32("NOT_WHITELISTED") ? NotWhitelisted() : CapExceeded());
    _mint(to, amount);
}
```

This keeps UX friendly for off-chain callers while keeping on-chain safety strict.

## External Calls: `try/catch` vs Bubble

* If the callee’s failure should **abort your operation**, let the revert **bubble** or explicitly **revert**.
* Use `try/catch` to **translate** low-level failures into your own **custom errors** or **soft-return** for *read* probes.

```solidity
try priceOracle.getPrice(token) returns (uint256 p) {
    return p;
} catch {
    // For reads: return a sentinel, let frontend decide.
    return 0; // document clearly!
}
```

For **writes**, prefer reverting if the external dependency fails and your state would be ambiguous otherwise.

## ERC-20 Transfers: Revert by Default

* Different tokens either **revert** or **return false** on failure. Use OZ’s `SafeERC20` to **normalize** to reverts for safety.
* Avoid ignoring return values from `transfer`/`transferFrom`.

```solidity
using SafeERC20 for IERC20;

token.safeTransfer(to, amount); // reverts on failure across well-known noncompliant tokens
```

If you design your own token-like interface, **document** whether failures revert or return, and remain consistent.

## View/Pure Functions

* Never revert for **normal absence** of data (e.g., querying non-existent optional record); return `false`, `0`, or empty structs.
* Do revert on **caller misuse** even in views (e.g., invalid index) if it prevents misinterpretation.

## Gas, UX & Composability Considerations

* **Reverts** abort execution and undo state changes; callers must handle failure paths.
* **Soft-returns** enable **simulation and batching** but require **strict caller checks**.
* For **batch writes**, consider:
  * `all-or-nothing` (revert entire batch on first failure), or
  * `best-effort` with detailed per-item results and **events** describing partial success.

Document the choice in your spec and tests.

## Security Pitfalls & Anti-Patterns

* **Silent Fail-Open**: returning `true` on error, or returning nothing and proceeding.
* **Ignoring Return Values**: especially for ERC-20-like calls.
* **Access Control Soft-Fail**: returning `false` instead of reverting on unauthorized write.
* **Ambiguous Outcomes**: state changed while reporting failure.
* **Front-Running Windows from Soft-Fail**: if soft-fail reveals intent, ensure no exploitable timing leak.
* **Hidden Assumptions**: view helpers that say `true` but the write path can still revert due to race conditions; mitigate with **checks-effects-interactions** and **fresh reads**.


# Avoid Unlimited ERC-20 Approvals

Approving the maximum value of uint256 is a known practice to save gas. However, this pattern was proven to increase the impact of an attack many times in the past, in case the approved contract gets hacked. Consider approving the exact amount that’s needed to be transferred, or alternatively, add a permissioned function that allows the revocation of unlimited approvals in an emergency case.


# Use the Safe ERC-20 Library

When working with third-party ERC20 tokens, using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) library is crucial to avoid common pitfalls. Functions like `safeTransfer` and `safeApprove` include additional safety checks that standard ERC20 functions often lack.

For example, `SafeERC20` ensures that the target address is a contract, not an externally owned account (EOA), preventing unintended interactions with non-contract addresses. It also addresses issues with non-standard tokens that may return false instead of reverting on failure.


# Beware of "NFT Front Running" in ERC-721 Tokenization

When designing ERC-721 tokens that represent positions, claims, or other dynamic on-chain assets, a subtle but critical vulnerability may arise: **NFT front running**.

This occurs when the seller of a tradeable NFT can degrade the value of the token right before selling—leaving the buyer with a useless or significantly devalued asset.

## The Problem

Many NFTs do not just hold metadata; they also map to *storage inside a smart contract* that represents valuable state (e.g., liquidity, collateral, staking shares).

The ERC-721 `tokenId` is used to access that storage. However, **the** `tokenId` itself does not change when the storage state changes. This allows a malicious seller to:

1. List or offer their NFT for sale (e.g., on OpenSea, Blur, or a custom marketplace).
2. Before the trade executes, insert an on-chain transaction that **depreciates the underlying value** of the token—such as withdrawing liquidity or redeeming collateral.
3. The buyer still receives the `tokenId`, but it now points to depleted or useless storage.

The buyer has no way to guarantee that the `tokenId` still represents the same value as when the order was signed.

## Concrete Example: Uniswap V3 Positions

Uniswap V3 liquidity positions are represented as ERC-721 tokens.

* Suppose Alice owns a Uniswap V3 position NFT with $10,000 of liquidity.
* She lists it for sale on an NFT marketplace.
* Bob agrees to buy it, thinking it includes $10,000 worth of liquidity.
* Right before the trade settles, Alice front runs Bob’s purchase by calling `decreaseLiquidity` and `collect`.
* Now the NFT is still valid, but represents an empty position.
* Bob has purchased a worthless token.

This risk exists in **any NFT design where** the `tokenId` is tied to mutable storage and the buyer cannot enforce that storage is unchanged between signing and settlement.

## Other Vulnerable Designs

* **Staking share NFTs**: If the NFT represents a user’s stake, the seller can unstake right before selling.
* **Vault share NFTs**: If the NFT maps to claimable assets, the seller can withdraw them first.
* **Derivative position NFTs**: If the NFT represents leveraged or collateralized positions, the seller can close/withdraw parts before the transfer.

## Proposed Solution

The root cause is that **a single** `tokenId` is expected to both identify the NFT and the storage data it represents.

To prevent front running, we propose **decoupling the identity of the NFT from its storage state.**

### Two Identifiers

* **Internal Identifier**
  * Constant throughout the life cycle of the position.
  * Implemented as a counter (`internal_id`).
  * Used to reference the actual storage (liquidity, collateral, staking balance, etc.).
* **External Identifier**

  * Represents a *specific snapshot of the internal identifier’s state*.
  * Used as the `tokenId` in the ERC-721 interface.
  * Generated as:

  ```
  external_id = hash(internal_id, version)
  ```

  where `version` increments every time the storage state changes.

### Lifecycle

1. **Creation**
   * When a new position is created, assign it a fresh `internal_id`.
   * Mint an NFT with `external_id = hash(internal_id, 0)`.
2. **State Change**
   * Burn the existing external NFT.
   * Increment the version counter for that `internal_id`.
   * Mint a new NFT with `external_id = hash(internal_id, version)`.
3. **Transfer**
   * Buyers always know that the NFT they receive maps to a specific version of storage.
   * If a seller changes the storage before selling, a *new tokenId must be minted*—invalidating any old listings or signatures.

## Benefits

* Prevents sellers from front running by ensuring **state changes always produce a new NFT**.
* Makes NFT trades safer, especially for financialized NFTs (positions, shares, derivatives).
* Provides a clear, auditable history of changes (via incremented versions).

## Summary

If your ERC-721 tokens reference mutable on-chain state, beware of **NFT front running**.

By introducing a separation between internal (constant) and external (versioned) identifiers, and forcing state changes to mint new NFTs, you eliminate the possibility for sellers to front run buyers by draining or altering the token’s underlying value.

This design pattern ensures that NFTs remain **trustworthy representations of on-chain assets**, protecting both protocols and their users.


# Rounding in Favor of the Protocol with Integer Division in Solidity

In Solidity, integer division truncates toward zero, which can be leveraged to ensure rounding favors the protocol in critical calculations. This approach is crucial to prevent value leakage to users and maintain the protocol's economic integrity. While ERC-4626 vaults are a common example, this concept applies broadly to any financial mechanism, such as fee calculations, token distributions, or staking rewards.

## Key Considerations

* **Integer Division Behavior**: In Solidity, division of two integers (`a / b`) discards the remainder, rounding down. For example, `5 / 2` results in `2`, not `2.5`.
* **Favoring the Protocol**: Structure calculations to round up when distributing shares or benefits to users and round down when returning assets to ensure the protocol retains value. This prevents users from gaining unintended advantages.
* **Security Implications**: Incorrect rounding can allow users to exploit calculations, gaining more assets or shares than intended. Additionally, improper handling of edge cases (e.g., zero values or extreme inputs) may cause unintended reverts, potentially leading to denial-of-service (DoS) issues for other users. Always validate edge cases to prevent such vulnerabilities.

## Example: Rounding in OpenZeppelin's ERC-4626 Implementation

The OpenZeppelin ERC-4626 implementation provides a robust example of rounding in favor of the protocol during asset-to-share and share-to-asset conversions. Below is a snippet from the official OpenZeppelin ERC-4626 contract ([source](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol)) showing the `preview` functions that handle conversions with explicit rounding directions.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Math} from "../../utils/math/Math.sol";
import {IERC20, IERC20Metadata, ERC20} from "../ERC20.sol";

abstract contract ERC4626 is ERC20, IERC4626 {
    // ... (other contract code omitted for brevity)

    /** @dev See {IERC4626-previewDeposit}. */
    function previewDeposit(uint256 assets) public view virtual returns (uint256) {
        return _convertToShares(assets, Math.Rounding.Floor);
    }

    /** @dev See {IERC4626-previewMint}. */
    function previewMint(uint256 shares) public view virtual returns (uint256) {
        return _convertToAssets(shares, Math.Rounding.Ceil);
    }

    /** @dev See {IERC4626-previewWithdraw}. */
    function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
        return _convertToShares(assets, Math.Rounding.Ceil);
    }

    /** @dev See {IERC4626-previewRedeem}. */
    function previewRedeem(uint256 shares) public view virtual returns (uint256) {
        return _convertToAssets(shares, Math.Rounding.Floor);
    }
}
```

### Explanation

* **Concept Generalization**: While this example uses OpenZeppelin's ERC-4626 implementation, the principle of rounding in favor of the protocol applies to any scenario involving division, such as fee calculations, reward distributions, or token minting. For instance, in fee calculations, rounding up the fee ensures the protocol collects slightly more, while in reward distributions, rounding down user rewards preserves protocol value.
* **Rounding in ERC-4626**:
  * **`previewDeposit`**: Converts assets to shares, rounding down (`Math.Rounding.Floor`) to issue fewer shares, favoring the protocol by reducing share dilution.
  * **`previewMint`**: Calculates assets needed to mint a specific number of shares, rounding up (`Math.Rounding.Ceil`) to require more assets, ensuring the protocol receives more value.
  * **`previewWithdraw`**: Converts assets to shares for withdrawal, rounding up (`Math.Rounding.Ceil`) to burn more shares, reducing the protocol's liability.
  * **`previewRedeem`**: Converts shares to assets, rounding down (`Math.Rounding.Floor`) to return fewer assets, preserving protocol value.


# Use the SafeCast Library

Down-casting in Solidity does not inherently trigger a revert on overflow, which can result in unexpected vulnerabilities or bugs. The [`SafeCast`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol) library mitigates this problem by ensuring that the transaction reverts whenever an overflow happens during these operations.

By utilizing `SafeCast` in place of unchecked operations, developers can prevent a significant category of potential bugs, making it advisable for all Solidity developers to adopt this library as part of their coding standards.


# Use Cryptographic Libraries

In Solidity, verifying signatures is a crucial part of ensuring that only authorized parties can perform specific actions in a smart contract. Instead of writing custom signature verification logic, developers should rely on well-established [cryptography libraries](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/utils/cryptography).

These libraries have been thoroughly tested and are less likely to contain critical bugs that could lead to exploits, such as unauthorized access or fraudulent transactions. Issues around `ecrecover`, like signature malleability or improper error handling, as well as potential integration bugs with ERC-1271 signatures, are also addressed by these libraries.


# Consider Non-Sequential Nonces for Digital Signatures

## Introduction

When building smart contracts or blockchain-based applications that rely on off-chain signed messages, managing nonces properly is important. Nonces prevent replay attacks, but the way they are chosen can also affect **flexibility and usability** of your dApp.

> This recommendation is **mainly relevant when sequential nonces are not intended functionality**. If your application does not require strict ordering of signed messages, non-sequential nonces allow more flexibility without enforcing artificial execution order.

Nonces are **per user** — each user has their own set of nonces. Two different users can use the same nonce value without conflict, because replay protection is scoped to the signer.

## Sequential vs Non-Sequential Nonces

### Sequential Nonces

Sequential nonces increment by 1 for each message:

```
nonce = 0, 1, 2, 3, ...
```

**Pros:**

* Simple to implement
* Easy to track

**Cons:**

* **Enforces strict order of execution.** Messages must be submitted in the exact sequence, otherwise they fail.
* Can limit dApp usability when multiple signed messages need to be executed in parallel or out-of-order.
* Adds unnecessary complexity for users or integrations that want flexibility.

### Non-Sequential Nonces

Non-sequential nonces are **randomized or unique identifiers** that do not follow a predictable order:

```
nonce = 0x92f3a1, 0x7b4d8c, 0x4a1f3b, ...
```

**Pros:**

* No enforced execution order — messages can be executed in any order.
* Supports parallel execution of multiple signed messages.
* Reduces friction for dApps where order is not important.
* Still prevents replay attacks, as each nonce is unique per user.

**Cons / Considerations:**

* Requires storing all used nonces for verification, which is slightly **more gas heavy** than a single sequential counter per user.
* **Avoiding collisions:** Off-chain nonce generation must check against all previously used nonces for that user. This can be done by:
  1. Querying the contract for all used nonces for the user (or a mapping of recent nonces if optimized).
  2. Generating a sufficiently large random or pseudo-random nonce to minimize the probability of collision.
  3. Optionally, retrying nonce generation if a collision is detected.

## Recommended On-Chain Verification Pattern

1. **Store used nonces per user**

```solidity
mapping(address => mapping(bytes32 => bool)) public usedNonces;
```

2. **Verify nonce validity before executing the transaction**

```solidity
function executeSignedAction(
    address signer,
    bytes32 nonce,
    bytes calldata signature
) external {
    require(!usedNonces[signer][nonce], "Nonce already used");

    bytes32 messageHash = keccak256(abi.encodePacked(msg.sender, nonce));
    require(recoverSigner(messageHash, signature) == signer, "Invalid signature");

    usedNonces[signer][nonce] = true;

    // Execute action
}
```

3. **Recover signer from signature**

```solidity
function recoverSigner(bytes32 hash, bytes memory signature) internal pure returns (address) {
    bytes32 ethSignedHash = ECDSA.toEthSignedMessageHash(hash);
    return ECDSA.recover(ethSignedHash, signature);
}
```


# Prefer to Avoid Low-Level Calls

Low-level calls, such as `call`, `delegatecall`, and `staticcall`, are powerful but come with increased risk, as they bypass many of Solidity’s built-in safety checks. This can lead to issues such as unchecked return values, reentrancy vulnerabilities, and potential misinterpretation of the contract’s intended logic.

Low-level calls also make error handling more challenging, as they do not revert automatically on failure, do not fail on calls to EOAs, potentially leading to unintended behaviors or funds loss. Instead, favor high-level Solidity functions and interfaces whenever available, as they are safer, easier to audit, and provide clearer, more predictable behavior.


# Use abi.encodeCall for Low Level Calls

**Principle:**\
When working with low-level calls in Solidity, prefer `abi.encodeCall` over manual encoding methods. This approach ensures accuracy, prevents signature mismatches, and reduces human error when interacting with contract functions.

***

## Why Use `abi.encodeCall`?

1. **Reduced Risk of Errors:**
   * Prevents manual mistakes in encoding function selectors.
   * Automates selector generation from function references.
2. **Clearer Intent:**
   * The code more clearly expresses the function being called.
3. **Safer Low-Level Calls:**
   * Ideal for `call`, `delegatecall`, and `staticcall` operations.

***

## Example

When using `abi.encodeWithSignature` with a function signature represented as a string, Solidity can introduce subtle bugs due to type inconsistencies. For example:

```solidity
pragma solidity ^0.8.0;

contract Example {
    // f(uint amount) is changed to f(uint256 amount) after compilation
    function f(uint amount) public pure returns (uint256) {
        return amount * 2;
    }

    function unsafeEncode() public pure returns (bytes memory) {
        // f(uint) does not exist 
        return abi.encodeWithSignature("f(uint)", 123);
    }
}
```

### The Problem Explained:

* The function `f(uint amount)` is described using `uint` in the string format.
* During compilation, `uint` is converted to `uint256`.
* However, the string `"f(uint)"` does not automatically get converted to `"f(uint256)"`.
* This results in a selector mismatch, making the encoded call un-callable.

### Solution: Use `abi.encodeCall`

The `abi.encodeCall` method addresses this issue by ensuring that the function signature and types are determined at compile time, preventing string-based type mismatches.

```solidity
pragma solidity ^0.8.0;

contract Example {
    function f(uint amount) public pure returns (uint256) {
        return amount * 2;
    }

    function safeEncode() public pure returns (bytes memory) {
        return abi.encodeCall(Example.f, (123));
    }
}
```

***

## Actionable Practices

* **Avoid Manual Encoding:**
  * Manual method: `"transfer(address,uint256)"`
  * Safer alternative: `abi.encodeCall(IERC20.transfer, (recipient, amount))`
* **Use Named Function References:**
  * Example: `IERC20.transfer` instead of raw `bytes4` values.
* **Test Selectors During Development:**
  * Validate selectors in unit tests to avoid silent failures.
* **Consistent Usage:**
  * Use `abi.encodeCall` consistently across all low-level calls.


# Careful Vetting of Unchecked Blocks

In Solidity 0.8.x, unchecked math operations are permitted within `unchecked` blocks, offering an opportunity for gas optimization in smart contracts. However, this feature also introduces risks of potential overflows and underflows, which can lead to significant vulnerabilities and unintended consequences. Consequently, the best practice is to prioritize safe math operations by default, resorting to `unchecked` blocks only when clear optimizations can be achieved.

It is essential to meticulously vet and review these `unchecked` sections to ensure they do not compromise the safety and reliability of the contract. By adhering to this philosophy, developers can strike a balance between gas efficiency and robust security.


# Avoid Arbitrary Low-Level External Calls

Arbitrary external calls are low-level calls where both the destination address and the call data—encompassing the function to be invoked and its parameters—can be manipulated. To bolster the security of your code, establish a firm rule against permitting completely arbitrary calls within your contracts.

This precaution helps mitigate vulnerabilities, such as the risk of privilege escalation if the calling contract has special permissions in other contracts or the potential for draining tokens stored in the contract or misusing token approvals.


# Follow the EIP-712 Standard for Digital Signatures

[EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) defines a structured approach for signing typed data, which reduces the likelihood of signature-related vulnerabilities. By standardizing the format of signed messages, it allows users to review and verify the contents of their transaction more easily, helping to prevent phishing attacks and malicious contract interactions.

The structured data hashing and signing outlined in EIP-712 also protect against replay attacks, where attackers attempt to reuse signatures in different contexts to exploit the system. Following this standard ensures that signatures are cryptographically bound to specific data structures, minimizing ambiguity in user intent and transaction details.


# Vetting Process for External Tokens

When integrating external tokens (such as ERC-20, ERC-721, or ERC-1155) with your system, it's essential to conduct a rigorous vetting process to prevent integration errors and security risks. Begin by thoroughly reviewing the token's code to ensure it complies with the relevant standard and behaves as expected. For instance, some ERC-20 tokens may have centralized controls, blacklists, or transfer restrictions that could lead to unexpected denial-of-service issues within your contract.

Additionally, certain tokens—like elastic supply tokens or fee-on-transfer tokens—may introduce balance discrepancies due to their unique mechanics, potentially breaking assumptions about balance tracking in your system. Tokens like USDT, which do not return a success value upon transfers, require special handling to ensure transaction outcomes are properly validated.

***

The following checklist outlines the key aspects to verify when reviewing an ERC-20 token contract:

## 1. **Review Security Audits**

* Ensure you read the security review of the code thoroughly. This will help identify any potential vulnerabilities or issues that have been previously discovered.
* Verify that all the issues identified in the security review have been properly addressed and mitigated before integrating the token into your DeFi platform.

## 2. **Basic ERC-20 Functionality**

* Ensure the token implements the core ERC-20 functions (`totalSupply`, `balanceOf`, `transfer`, `approve`, `allowance`, and `transferFrom`) correctly.
* Verify that the token emits appropriate events (e.g., `Transfer`, `Approval`) for all relevant actions.

## 3. **Minting and Burning Mechanisms**

* Confirm that the minting process (if allowed) is strictly controlled. There should be clear access controls to prevent unauthorized minting.
* If the token is burnable, check that the burn logic is correctly implemented and transparent.
* Verify that minting and burning are not exploited to manipulate supply or cause inflationary issues.

## 4. **Access Control and Ownership**

* Check for proper access control mechanisms, especially for functions that could alter the token supply (e.g., `mint`, `burn`, `pause`).
* Confirm that only authorized addresses (such as the contract owner or a trusted multi-sig wallet) can execute sensitive functions.
* Ensure the contract owner cannot abuse their privileges (e.g., disabling transfers or minting an excessive amount of tokens).

## 5. **Pausing Mechanism**

* Verify if the contract implements a pause function and under what circumstances it can be triggered. This should be limited to specific trusted entities and only used in emergencies.
* Ensure that the pause functionality doesn’t allow for unwanted freezing of token transfers or functionality.

## 6. **Reentrancy and Gas Limits**

* Ensure that the token contract does not have any external calls that can cause a reentrancy, especially in functions like `transfer` or `approve`.
* Check for gas heavy functions that might exceed block gas limits and cause a denial of service.

## 7. **Decimals and Precision**

* Confirm the token’s `decimals` value is set correctly. A common value is 18, but verify if it matches the expected behavior and meets your project’s needs.
* Make sure the token decimals are appropriately scaled in your system.

## 8. **Permit and EIP-2612 (Optional)**

* Check if the token supports EIP-2612 (Permit), allowing users to approve tokens via signatures rather than transactions, reducing gas costs in DeFi interactions.
* Verify that the `permit` function is implemented securely, particularly around signature handling.

## 9. **Transfer Restrictions**

* Confirm that there are no hardcoded or poorly documented restrictions on transfers (e.g., blacklists, limits on individual transfers) unless required by project rules.
* If there are any restrictions, ensure they are fully transparent and disclosed to users.

## 10. **Event Emissions and Monitoring**

* Ensure that the contract emits proper events for all critical actions, such as transfers and approvals.
* This is crucial for tracking token movements and for integrating the token into your DeFi project with accurate tracking.

## 11. **Ownership and Tokenomics Transparency**

* Ensure that the tokenomics (e.g., initial supply, distribution, and allocation) are clearly documented and reflect the intended use case of the token.
* Verify that any special minting or distribution processes are transparent and fair, without leaving room for abuse by insiders or malicious actors.

## 12. **Testing**

* Ensure the contract has passed thorough testing, including unit tests and integration tests, to catch edge cases and unexpected behaviors.

## 13. **ERC-20 Compliance vs. ERC-777 or Other Token Standards**

* Verify that the token strictly adheres to the ERC-20 standard and does not introduce unnecessary complexity or incompatibility issues with other DeFi protocols.
* If the token uses a more complex standard like ERC-777, ensure it doesn’t introduce vulnerabilities, such as reentrancy or unexpected interactions with other contracts.

## 14. **Verify Non-Standard Functions**

* Review any non-standard functions added to the ERC-20 contract, such as `pause`, `mint`, `burn`, or any custom logic. Ensure these are necessary, transparent, and properly secured.
* Make sure that non-standard functions are properly documented and do not introduce unnecessary risks.

## 15. **Check for External Dependencies**

* Confirm that the ERC-20 token does not rely on external contracts or services that could pose a security risk (e.g., external oracles or other on-chain dependencies).
* If external dependencies exist, verify that they are secure, and their failure won’t jeopardize the token’s functionality or integrity.


# Ensure Code Dependencies Are Secured

## Overview

Solidity projects rely heavily on external libraries (e.g., OpenZeppelin, Uniswap libraries). While these dependencies save development time, they **introduce potential attack surfaces** if versions are not managed carefully.

This document explains how to **pin dependencies** and ensure the version used is **exactly the one audited**, with all known issues addressed.

## 1. Pin Exact Versions

Always pin the exact dependency version in your project configuration instead of using floating versions.

**Examples:**

**Foundry:** (`foundry.toml`):

```toml
[dependencies]
openzeppelin-contracts = { git = "https://github.com/OpenZeppelin/openzeppelin-contracts", tag = "v4.9.3" }
```

**Solidity import:**

```solidity
import "@openzeppelin/contracts@4.9.3/token/ERC20/ERC20.sol";
```

**Why:**

* Prevents accidental upgrades that could introduce vulnerabilities.
* Ensures the audited code matches what is deployed.

## 2. Audit Version Verification

* Security audits **must specify the exact version** or commit audited.
* Before deployment, confirm:
  1. The deployed dependency version matches the audited version.
  2. Any known vulnerabilities from previous audits are patched.

**Tip:** Treat any code change in a dependency as **a new audit scope**.

## 3. Immutable vs Upgradeable Contracts

* **Immutable contracts:** Dependency version must be final; any fixes require redeployment.
* **Upgradeable contracts:** Dependency can be upgraded, but still pin versions and monitor for vulnerabilities.


# Testing


# Develop Comprehensive Unit Tests

Unit tests are indispensable in smart contract development, particularly for ensuring security. Unlike traditional software, smart contracts are deployed in a highly adversarial environment and, on top of this, might be immutable. Therefore, bugs can lead to irreversible financial losses.

Unit tests allow developers to validate individual components of the contract in isolation, ensuring that each function behaves as expected under both normal and edge-case scenarios. By catching logical errors early, developers can prevent vulnerabilities in a cost-effective manner.

Furthermore, the presence of thorough unit tests acts as a **safety net** during future code changes, minimizing the risk of introducing new vulnerabilities.

***

## Platforms for Unit Testing

1. [**Foundry**](https://github.com/foundry-rs/foundry)\
   A fast and flexible framework for Solidity, Foundry allows writing unit tests in Solidity itself. It's known for speed and ease of use, making it ideal for efficient and secure testing.
2. [**Hardhat**](https://hardhat.org/)\
   Hardhat is a popular Ethereum development environment that supports testing in JavaScript, TypeScript, and Solidity. It features a built-in Ethereum network for local testing and integrates with testing libraries like Mocha and Chai for comprehensive testing workflows.


# Develop Comprehensive Integration Tests

Integration tests are vital for ensuring the security and robustness of smart contracts, as they focus on the interactions between contracts and external systems. Vulnerabilities often arise from these interactions rather than isolated components, making integration testing essential for uncovering hidden flaws.

***

## Why Integration Tests Matter

Integration tests help identify:

* **Interaction Vulnerabilities:** Detect flaws in the way contracts communicate, such as incorrect function calls or data dependencies.
* **Token Handling Issues:** Uncover problems with token transfers, approvals, or compatibility across different ERC standards.
* **Permission Misconfigurations:** Validate access controls across multiple modules to ensure no unintended access is granted.
* **External Dependency Risks:** Simulate interactions with oracles, off-chain data feeds, and third-party contracts to expose edge cases or failures.

***

## Steps to Conduct Integration Tests

1. **Set Up a Local Testing Environment**
   * Use tools like [**Hardhat**](https://hardhat.org/) or [**Foundry**](https://book.getfoundry.sh/) to simulate blockchain environments.
   * Fork mainnet state for real-world data using frameworks like **Hardhat Network**.
2. **Define Critical Interaction Scenarios**
   * Focus on interactions involving multiple contracts, such as token swaps, staking mechanisms, and governance processes.
   * Test key functionalities like upgrades, rewards distribution, and withdrawal processes.
3. **Simulate Edge Cases**
   * Test interactions with incorrect inputs, unexpected state changes, or large transaction volumes.
   * Include scenarios like failing external oracle responses or reentrancy attacks.
4. **Automate Test Execution**
   * Write integration tests using tools like **Hardhat** or **Foundry**.
   * Automate test execution as part of your CI/CD pipeline to catch issues early.
5. **Monitor Logs and Events**
   * Capture and analyze contract events and logs to verify correct behavior during tests.
   * Use tools like **Tenderly** for in-depth debugging and transaction simulations.

***

## Recommended Tools for Integration Testing

* [**Hardhat**](https://hardhat.org/)\
  Provides a flexible framework for writing and executing integration tests, including mainnet forking capabilities.
* [**Foundry**](https://book.getfoundry.sh/)\
  A high-performance toolkit that supports integration testing with fuzzing and fork testing features.
* [**Tenderly**](https://tenderly.co/)\
  A platform for simulating and debugging smart contract interactions in real-time, ideal for testing complex integrations.

***

## Best Practices

* **Test Critical Flows First:** Prioritize interactions that directly impact user funds or governance decisions.
* **Combine with Unit Tests:** Use integration tests to complement unit tests by validating real-world interactions.
* **Test Against Forked Mainnet State:** Simulate scenarios using actual data and deployed contracts for higher realism.
* **Include External Dependencies:** Test interactions with oracles, tokens, and third-party contracts comprehensively.
* **Iterate Based on Findings:** Update tests continuously as new dependencies or modules are introduced.


# Develop Comprehensive Fuzzing Tests

Fuzzing is a powerful testing methodology that improves the security and robustness of smart contracts by generating and testing contracts with random or unexpected inputs. This technique helps uncover vulnerabilities that traditional testing methods may overlook, such as arithmetic errors, improper input validation, and other edge-case behaviors.

***

## Why Fuzzing is Essential

Fuzzing tests are critical for:

* **Identifying Common Vulnerabilities:** Catch issues like overflow/underflow, reentrancy, or missing input checks.
* **Stress Testing:** Observe contract behavior under extreme conditions, such as high transaction volume or invalid state transitions.
* **Mitigating Denial-of-Service Risks:** Ensure contracts remain operational during edge-case scenarios.
* **Improving Robustness:** Simulate unpredictable real-world interactions to ensure the contract withstands both accidental misuse and deliberate attacks.

***

## Steps to Implement Fuzzing Tests

1. **Integrate Fuzzing Tools**
   * Use tools like [**Foundry**](https://book.getfoundry.sh/), which has built-in fuzz testing capabilities for Solidity.
   * Explore [**Echidna**](https://github.com/crytic/echidna), a specialized fuzzer for Ethereum smart contracts.
2. **Define Properties to Test**
   * Specify invariant conditions (e.g., token balances, state transitions) that must always hold true, regardless of input combinations.
   * Include edge cases for arithmetic operations, access control, and gas consumption.
3. **Run Fuzz Tests Against Key Functions**
   * Target public and external functions exposed to users or other contracts.
   * Test scenarios involving large numbers, invalid addresses, or unexpected input lengths.
4. **Analyze Results**
   * Investigate any failed assertions or exceptions raised during fuzz testing.
   * Verify the root cause of failures and prioritize fixes for high-risk vulnerabilities.
5. **Integrate Fuzzing in CI/CD Pipelines**
   * Automate fuzz testing as part of your CI/CD workflow to ensure consistent coverage for every code change.
   * Track coverage reports to identify functions that require additional fuzz testing.

***

## Recommended Tools for Fuzzing

* [**Foundry**](https://book.getfoundry.sh/)\
  Includes native support for fuzz testing, allowing automated random input generation and invariant property testing.
* [**Echidna**](https://github.com/crytic/echidna)\
  A powerful Ethereum fuzzer that checks user-defined invariants and generates edge-case inputs.

***

## Best Practices

* **Start Simple:** Begin fuzzing critical functions with simple invariants, then expand coverage incrementally.
* **Define Comprehensive Invariants:** Ensure that invariants cover business logic, state transitions, and security properties.
* **Combine with Unit Tests:** Use fuzzing alongside unit and integration tests for comprehensive coverage.
* **Regularly Update Test Cases:** Incorporate new edge cases and vulnerabilities as the contract evolves.
* **Monitor Performance:** Keep an eye on gas usage during fuzz testing to identify inefficient code.


# Develop Comprehensive Fork Tests

Fork testing is a powerful method to ensure the security and functionality of smart contracts by replicating the state of a live blockchain, like Ethereum mainnet, into a local development environment. This allows you to test contracts against real-world data, including existing tokens, liquidity pools, and deployed contracts.

## Why Fork Testing is Essential

Testing in a forked environment helps:

* **Validate External Interactions:** Identify issues with oracles, token standards, or third-party contracts.
* **Detect Edge Cases:** Surface vulnerabilities or unexpected behaviors that may not appear in simulated environments.
* **Ensure Robustness:** Verify that your contracts handle live blockchain conditions effectively.

***

## Steps to Implement Fork Tests

1. **Set Up the Forked Environment**
   * Use tools like [**Hardhat**](https://hardhat.org/) or [**Foundry**](https://book.getfoundry.sh/) to create a local fork of the blockchain.
   * Configure the fork to sync data from the desired network (e.g., Ethereum mainnet or testnet).
2. **Write Fork-Specific Tests**
   * Interact with live contracts in your test cases (e.g., calling a Uniswap pool or querying Chainlink oracles).
   * Validate interactions with real-world data and ensure compatibility with the latest state.
   * Test edge cases like minimal liquidity, extreme slippage, or stale oracle prices.
3. **Simulate Real-World Scenarios**
   * Create scripts to simulate scenarios such as large transfers, sudden price changes, or unexpected behaviors from dependent contracts.
   * Monitor for gas efficiency, transaction reverts, or vulnerabilities in these conditions.
4. **Run Regression Tests**
   * Ensure all fork tests pass after changes to your codebase.
   * Use CI/CD pipelines to automatically run fork tests during development.
5. **Analyze Test Coverage**
   * Measure test coverage specifically for fork tests to identify any gaps in your interaction scenarios.
   * Use tools like [**solidity-coverage**](https://github.com/sc-forks/solidity-coverage) or **Foundry's coverage feature**.

***

## Recommended Tools for Fork Testing

* [**Hardhat**](https://hardhat.org/)\
  Enables seamless forking of Ethereum networks and integrates with plugins for test creation and execution.
* [**Foundry**](https://book.getfoundry.sh/)\
  Offers high-performance testing with built-in support for forking and fuzzing.
* [**Tenderly**](https://tenderly.co/)\
  Provides advanced debugging and testing capabilities with real-time transaction simulation in a forked environment.

***

## Best Practices

* **Use Real RPC Nodes:** Connect to high-quality providers like **Alchemy**, **Infura**, or **QuickNode** for accurate mainnet data.
* **Monitor Performance:** Keep an eye on gas costs and execution times in the forked environment to ensure deployability on mainnet.
* **Keep Forks Updated:** Regularly sync with the latest blockchain state to reflect current conditions.
* **Combine With Static Analysis:** Pair fork testing with tools like **Slither** or **MythX** for comprehensive security assurance.


# Track and Optimize Test Coverage

Tracking and optimizing test coverage is crucial in smart contract development, especially from a security standpoint, as it ensures that critical paths, conditions, and edge cases are thoroughly tested. Incomplete coverage can leave vulnerabilities undiscovered, which attackers could exploit once the contract is deployed.

Integrating test coverage metrics into the CI/CD pipeline using tools like Hardhat (solidity-coverage) or Foundry (forge coverage) is not just beneficial—it’s essential.

Including test coverage as a mandatory step in the CI/CD pipeline ensures that security remains a continuous, automated process rather than an afterthought, ultimately reducing the risk of deploying vulnerable contracts.

***

## Coverage Threshold Recommendations

To maintain a robust test suite, use the following thresholds:

* **Statement Coverage**: At least **95%**, ensuring most lines of code are executed during tests.
* **Branch Coverage**: No lower than **90%**, ensuring all possible branches in control structures (like `if` or `require` statements) are tested.
* **Function Coverage**: Ideally close to **100%**, ensuring all functions are invoked at least once.

While striving for high coverage, developers should balance thorough testing with practical deployment timelines, recognizing that coverage alone doesn't guarantee security—it must be coupled with quality tests targeting known vulnerabilities.

***

## Tools to Measure Test Coverage

* [**Hardhat (solidity-coverage)**](https://github.com/sc-forks/solidity-coverage)\
  A popular plugin for Hardhat that tracks statement and branch coverage in Solidity projects, providing detailed coverage reports.
* [**Foundry (forge coverage)**](https://github.com/foundry-rs/foundry)\
  Foundry's built-in coverage tool (`forge coverage`) generates test coverage reports for smart contracts written in Solidity, focusing on statement and function coverage.


# Conduct End-to-End Testing on Testnet

Testing smart contracts on a testnet is a crucial step in the development lifecycle. It provides a realistic environment to evaluate how the contracts perform under conditions similar to the mainnet, without the risk of losing real assets. Testnets allow developers to validate contract functionality, assess performance, and identify issues that might only surface in a distributed network.

***

## Why Test on Testnets?

1. **Realistic Environment**\
   Testnets replicate the mainnet environment, including network latency, gas fees, and block confirmations, offering a reliable way to observe contract behavior.
2. **Risk-Free Testing**\
   Testnets use fake tokens and resources, ensuring that no real funds are at risk during testing.
3. **Community Feedback**\
   Deploying on a testnet enables users, auditors, and collaborators to interact with the contract, providing valuable feedback and uncovering hidden issues.
4. **Validation of Deployment Processes**\
   Testing deployment scripts and procedures on a testnet helps prevent costly mistakes during the actual deployment on the mainnet.

***

## Key Steps for Testnet Testing

1. **Select the Right Testnet**
   * Use widely adopted testnets like **Goerli** or **Sepolia** for Ethereum-based contracts.
   * For layer-2 solutions or sidechains, choose testnets like **Arbitrum Goerli** or **Polygon Mumbai**.
2. **Deploy Contracts**
   * Deploy all relevant contracts, including proxies, libraries, and dependencies, to the testnet.
   * Verify that deployment scripts handle all edge cases, such as gas estimation errors or missing dependencies.
3. **Run Comprehensive Tests**
   * Perform end-to-end testing to simulate real-world interactions (e.g., user transactions, multi-contract operations).
   * Test economic scenarios, including high-frequency trading, slippage, and price manipulation.
4. **Simulate Stress Scenarios**
   * Test under high transaction loads to evaluate performance and ensure the contract remains functional.
   * Simulate gas spikes and network congestion to assess the contract's resilience.
5. **Incorporate External Integrations**
   * Validate integrations with oracles, DeFi protocols, and other external services.
   * Test for potential delays, failures, or invalid data from external systems.
6. **Gather Community Feedback**
   * Share the testnet deployment with users and stakeholders to collect real-world feedback.
   * Use their interactions to uncover usability issues or unexpected edge cases.
7. **Review and Iterate**
   * Continuously analyze testnet results, refine the code, and redeploy as needed.
   * Use tools like **Etherscan** for testnets to inspect transaction details and logs.

***

## Best Practices for Testnet Testing

* **Use Test Tokens:** Fund test accounts with faucet tokens to simulate transactions without cost.
* **Automate Testing:** Integrate testing frameworks with testnet deployments to run automated checks.
* **Monitor Activity:** Use tools to track contract activity, including events, balances, and transaction history.
* **Document Results:** Keep a detailed record of tests conducted, issues identified, and fixes implemented.
* **Final Mainnet Simulation:** Perform a "dry run" of the mainnet deployment process on the testnet, ensuring all steps are foolproof.


# Pre-Deployment


# How to Decide What Type of Security Review Your Project Needs

This guide compares different types of security reviews to help you choose the best approach for your project. The options include Private Team Security Review, Public Competition, Private Competition, Solo Review, and Formal Verification. Below is a comparison table followed by a summary of common practices and a budget-friendly alternative.

## Comparison Table

| **Metric**                                           | **Private Team Security Review**                                                          | **Public Competition**                                                                                                                                                 | **Private Competition**                                                                                | **Solo Review**                                                                          | **Formal Verification**                                                                             |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **Ability to Pick Auditors with Relevant Knowledge** | High: You can select auditors with specific expertise tailored to your project's needs.   | Low: Open to all, so expertise varies widely; you may get auditors unfamiliar with your tech stack.                                                                    | Medium: You can invite auditors with relevant skills, but pool is limited to invited participants.     | Medium: Depends on the individual auditor's expertise; limited by their knowledge scope. | High: Requires highly specialized auditors with formal methods expertise.                           |
| **Filtering Garbage Issues**                         | High: Professional auditors focus on high-quality, relevant findings with minimal noise.  | Low: High volume of submissions, many low-quality or irrelevant, requiring significant filtering effort. Employing judges to sift through submissions increases costs. | Medium: Smaller pool reduces noise, but some irrelevant submissions may still occur.                   | High: Single auditor focuses on relevant issues, but quality depends on their skill.     | High: Formal methods produce precise, verified results with minimal irrelevant findings.            |
| **Cost Efficiency to Attract Talent**                | Medium: Expensive due to hiring top-tier auditors, but targeted expertise justifies cost. | Medium: Requires large prize pools to attract skilled participants, increasing costs despite crowd-sourcing.                                                           | Medium: Moderate costs for prizes and platform fees, but less than private team reviews.               | High: Low cost (single auditor), but limited by individual capacity and expertise.       | Low: Extremely expensive due to specialized skills and time-intensive process.                      |
| **Fixes Reviews**                                    | High: Auditors often provide actionable feedback and can verify fixes post-review.        | Medium: Some platforms allow fix verification, but follow-up is less structured.                                                                                       | Medium: Similar to public competitions, with slightly better follow-up due to smaller group.           | Medium: Depends on auditor's willingness to review fixes; less formal process.           | High: Formal verification ensures fixes align with specifications, often including re-verification. |
| **"Stamp" of a Known Brand**                         | High: Reviews by reputable firms provide a trusted badge for community credibility.       | Medium: Platforms like Code4rena or Immunefi are recognized, but less prestigious than top firms.                                                                      | Medium: Similar to public competitions, but limited to invited auditors, slightly reducing visibility. | Low: No brand recognition unless the solo auditor is well-known.                         | High: Formal verification by a reputable team is highly respected in technical communities.         |
| **Scalability for Large Projects**                   | High: Teams can scale with project size, handling complex codebases effectively.          | Medium: Crowds can handle large projects, but quality control becomes harder.                                                                                          | Medium: Limited by invited participants, which may not scale well for very large projects.             | Low: Single auditor struggles with large, complex codebases.                             | Medium: Scalable for critical components, but not practical for entire large systems.               |

## Summary of Common Practices

Based on industry trends, projects often balance cost, expertise, credibility, and project size when choosing security reviews. The size of the project significantly influences the choice, as larger projects require more scalable approaches, while smaller projects can leverage simpler, cost-effective methods. Common approaches include:

* **Two Private Team Security Reviews**: Many projects, especially larger ones, opt for two private reviews by different reputable firms to maximize expertise and issue coverage. This approach ensures high-quality findings, actionable feedback, and a trusted "stamp" for community confidence, though it comes at a higher cost. It is well-suited for large, complex projects due to its scalability.
* **One Private Team Review + One Public Competition**: This hybrid approach leverages the expertise of a private team for thorough, targeted auditing and supplements it with a public competition to uncover additional issues through crowd-sourcing. It balances cost and coverage but requires effort to filter low-quality submissions from the competition. This is effective for medium to large projects where scalability and broad issue detection are needed.

## Budget-Friendly Alternative

For projects with limited budgets, particularly smaller to medium-sized projects, a cost-effective strategy is:

* **One Private Team Security Review + One Solo Review**: Combine a single private review by a reputable firm (for expertise and credibility) with a solo review by an experienced individual auditor (for cost savings). This approach maintains quality and a trusted "stamp" while reducing expenses compared to multiple private reviews or large competitions. Ensure the solo auditor has relevant expertise to maximize effectiveness. This is ideal for smaller projects where a single auditor can manage the scope effectively.


# Key Considerations for Setting the Mainnet Deployment Date

Several key factors influence the timeline for scheduling a secure mainnet deployment after smart contract development. These include:

1. **Duration of Security Reviews**: The time required for security reviews depends on the complexity of the codebase and the assessment by security researchers.
2. **Parallel or Consecutive Reviews**: Conducting reviews concurrently can save time, while consecutive reviews may extend the timeline but allow for deeper scrutiny.
3. **Adding Regression Tests**: Writing tests to verify fixes for vulnerabilities and prevent regressions adds time but is critical for long-term security.
4. **Buffer for Last-Minute Changes**: Allocating time for unexpected changes or additional fixes ensures the codebase is robust before deployment.
5. **Updating Documentation**: Revising specifications, assumptions, and logic to reflect code changes takes time but ensures clarity for future developers and auditors.
6. **Testnet Deployment and Validation**: A comprehensive testnet deployment to mirror mainnet conditions helps catch deployment-specific issues, requiring additional time.
7. **Stakeholder Communication**: Preparing and sharing transparent updates with stakeholders about review outcomes and fixes adds to the timeline but builds trust.
8. **Team Coordination and Availability**: Ensuring developers, auditors, and other team members are aligned and available can impact the schedule, especially for iterative fixes.

**Recommendation**: Plan a flexible timeline that accounts for these factors, with a buffer of at least a few weeks post-development to accommodate reviews, fixes, and validations for a secure mainnet launch.


# Conduct an Internal Security Review

Immanuel Kant, a proponent of critical thinking, famously said, *"Dare to know! Have the courage to use your own understanding."* Much like ideas, code becomes more robust when it is subjected to scrutiny and challenge. The initial group to test new code should be the development team itself.

It is highly advisable to allocate time after coding is completed for a collaborative effort aimed at identifying vulnerabilities and issues. Additionally, ensure that components are reviewed by developers who did not write the original code, as this fresh perspective can uncover hidden flaws and enhance overall code quality.

## Steps for Effective Internal Security Reviews

1. **Schedule Dedicated Review Time**\
   Allocate approximately **one week** to review \~600 lines of smart contract code, especially for unprofessional or less-experienced security reviewers, to ensure thorough analysis. For larger codebases, scale time proportionally (e.g., 2 weeks for 1200 lines).
2. **Assign Diverse Reviewers**\
   Involve developers who didn’t write the code, ideally with familiarity in smart contract security.
3. **Use a Web3-Specific Security Checklist**\
   Adopt a checklist tailored to smart contract vulnerabilities, drawing from authoritative resources like the OWASP Smart Contract Top 10, SWC Registry, and others.
   * **Example Checklist Items**:
     * Are external calls protected against reentrancy?
     * Are access controls enforced for privileged functions?
     * Are arithmetic operations safe from integer overflows/underflows?
   * **Resources**:
     * [OWASP Smart Contract Top 10 (2025)](https://owasp.org/www-project-smart-contract-top-10/)
     * [Smart Contract Weakness Classification (SWC Registry)](https://swcregistry.io/)
     * [Kadenzipfel Smart Contract Vulnerabilities](https://github.com/kadenzipfel/smart-contract-vulnerabilities)
     * [Web3 Security Resources Hub: Vulnerabilities & Attack Vectors](https://github.com/Raiders0786/web3-security-resources)
4. **Leverage Automated Security Tools**\
   Run static and dynamic analysis tools before manual reviews.
   * **Examples**:
     * **Slither** or **Mythril** for static analysis of Solidity contracts.
     * **Echidna** or **Manticore** for fuzzing to test edge cases in smart contracts.
   * **Tip**: Integrate tools into your CI/CD pipeline for automated checks.
5. **Document Findings and Remediation Plans**\
   Log vulnerabilities, their severity (e.g., Critical, High), and fixes in a tracker.
6. **Conduct Follow-Up Reviews**\
   Re-review fixed code to verify remediation, using test cases or automated tools.


# The Importance of Code Freeze Before an External Security Review

Implementing a code freeze before an external security review is a critical step in the development of smart contracts, as it ensures that the codebase remains stable and unchanged during the audit process. This practice prevents new vulnerabilities from being introduced after the review begins, maintaining the integrity of the assessment.

For smart contracts, where security flaws can lead to irreversible financial losses, a code freeze helps auditors focus on a fixed and well-understood codebase. It also eliminates the risk of miscommunication or oversight that might occur if changes are made during the audit.

By freezing the code, teams provide external reviewers with the assurance that their findings will remain relevant and actionable, ultimately leading to a more thorough and reliable security evaluation.


# Conduct an External Security Review (a.k.a. Audit)

Engaging external security experts to review the code is crucial for ensuring the robustness of smart contracts and mitigating potential vulnerabilities. Just as the three-way handshake establishes a reliable connection by exchanging critical information, the audit process similarly unfolds in stages.

The first stage, represented by the "**SYN**", corresponds to the issues identified by the security researchers during their initial review. The subsequent "**SYN-ACK**" phase involves the development team implementing fixes based on the security researchers' findings. Finally, the "**ACK**" phase signifies the security researchers verifying these fixes, confirming that the issues have been addressed effectively.

***

## How to Prepare for a Security Review

**Smart contract security is a collaborative effort**. It’s not just the responsibility of security researchers to ensure a codebase is secure—developers play a crucial role too. Both sides need to align on a shared mission: to surface and fix vulnerabilities before they make it to production.

A core principle to understand is that **the main resource in any security review is the time and focus of the researchers**. Reviews are already quite expensive. If researchers are spending their time flagging basic issues, they're not spending that time analyzing complex logic or subtle edge cases that could cause real-world financial loss. **Too many avoidable bugs eat into review time**, and each one takes time to document clearly—especially in professional settings where researchers are expected to produce detailed reports. That reduces the time available to uncover hidden, critical issues.

So how can developers help maximize the value of a security review?

1. **Pick the Right Security Researchers**\
   Choose researchers with the relevant expertise and a proven track record. It's crucial to select professionals you can trust to act ethically and transparently. Look for researchers who specialize in smart contract security and have demonstrated success in similar projects.
2. **Assess the Effort (Time and Budget)**\
   Ask the security researchers to assess the time and budget required for the review. This will ensure you have realistic expectations and resources in place to complete the review and fix any identified issues.
3. **Test Coverage**\
   A high level of test coverage is foundational. We expect at least 90%+ coverage, including statement, branch, and function coverage. But it's not just about raw percentages. You need to test both:
   * **Happy paths**—the expected flow when everything works as intended.
   * **Failure paths**—unexpected inputs, edge cases, and revert scenarios.\
     A red flag for us is when the codebase has too many bugs that could’ve easily been caught just by testing happy paths.
4. **Identify Areas of Concern**\
   Prepare a list of areas where you specifically want extra assurance. This can include complex logic, integrations with other contracts, or areas that you know may carry higher risk. By highlighting these areas, you can ensure that the review is focused and efficient.
5. **Test Variety**\
   Unit tests are essential, but not sufficient. You should also include:
   * **Integration tests** that simulate interactions between components.
   * **Fork-based tests** using live network state and real token balances.
   * **Fuzz testing**, where tools like Foundry or Echidna randomly mutate inputs to uncover unexpected behavior.
6. **Allocate Time for Fixes**\
   Pre-allocate sufficient time for addressing any issues found during the review. After the audit, there will be fixes to implement and further testing to conduct. Be sure to budget adequate time for additional tests to ensure everything works as expected before deployment.
7. **Deployment Readiness**\
   We often see projects that delay writing deployment scripts until the very end. That’s a mistake. Security reviewers should be able to review and run your deployment process—ideally in a testnet environment that mimics mainnet settings. Scripts should include:
   * Configuration options.
   * Admin setup.
   * Upgradeability logic, if relevant.\
     Also, testnet deployment and basic real-world interactions—minting tokens, transferring ownership, calling governance—should be working and demonstrable before review starts.
8. **Internal Review**\
   Before handing code over for external security review, it should go through an [internal review](/pre-deployment/internal-security-reviews) by developers who didn’t write the code. Fresh eyes often catch obvious flaws and can verify whether the design aligns with the implementation. It also shows that the team takes security seriously.
9. **Documentation**\
   Good documentation saves researchers time and leads to better results. Why? Security researchers need to look for a range of vulnerabilities, including:
   * **Well-known Solidity issues** (like reentrancy, unsafe math, unchecked return values).
   * **Common coding mistakes** (off-by-one errors, lack of access control, bad assumptions).
   * **Economic/MEV vulnerabilities** (price manipulation, oracle misuse, sandwiching opportunities).\
     But that’s not all. Researchers also look for:
   * **Application-Specific/Business Logic Vulnerabilities**.
   * **Specification Mismatch Issues**.
   * **Specification Design Issues**.\
     The better your documentation explains the intended behavior, the easier it is for researchers to catch when the code deviates from that behavior.

***

## Post Review Actions

Once the security review is complete, the work doesn’t end. The findings from the review must be acted upon promptly and thoroughly to ensure the smart contract is secure before deployment. Below are key actions to take after receiving the audit report:

1. **Add Regression Tests After Fixing Vulnerabilities**\
   Whether a vulnerability is found during a security review or after deployment, it's important to write a test that simulates the exploit attempt and verifies it fails (reverts) after the fix. This helps:
   * Prevent future regressions of the same vulnerability.
   * Document the exploit in a reproducible and testable way.
   * Strengthen long-term security through test coverage.\
     ⚠️ **Limitation**: These tests typically cover only one exploit path. Variations may still exist that trigger the same underlying flaw.\
     ✅ **Recommendations to Strengthen This Practice**:
   * Generalize the test to detect similar exploit vectors.
   * Write invariant tests to enforce critical safety conditions across a wide input space.
   * Use property-based fuzzing tools to explore unseen inputs.
   * Document assumptions (e.g., actor roles, balances, states) within the test.\
     This layered approach helps secure the fix and future-proofs the protocol against regressions of the same bug class.
2. **Plan Sufficient Buffer Time**\
   The development team needs to allocate enough buffer time for:
   * Fixing any issues identified during the review.
   * Re-reviewing those fixes by the security researchers to confirm they are effective.
   * Accommodating any “last-minute” changes that may affect core logic.\
     In other words: Don’t schedule a mainnet launch the day after your security review ends. Security reviews aren’t a checkbox. They’re an iterative process, and the timeline should reflect that.
3. **Update Documentation**\
   After implementing fixes, update the project documentation to reflect any changes made to the codebase. This includes:
   * Revising specifications to align with the updated code.
   * Documenting new assumptions or invariants introduced during fixes.
   * Clarifying any modified business logic or contract interactions.\
     Accurate and up-to-date documentation ensures that future developers and auditors can understand the codebase and its intended behavior.
4. **Conduct a Final Testnet Deployment**\
   Before deploying to mainnet, perform a comprehensive testnet deployment that mirrors the mainnet environment as closely as possible. This should include:
   * Running all tests (unit, integration, fork-based, and fuzz tests) in the testnet environment.
   * Simulating real-world interactions, such as token minting, transfers, and governance calls.
   * Verifying that deployment scripts and configurations work as expected.\
     This step helps catch any deployment-specific issues that might not have been evident during development or review.
5. **Communicate Fixes to Stakeholders**\
   If your project involves external stakeholders (e.g., investors, users, or partners), communicate the outcomes of the security review and the steps taken to address vulnerabilities. Transparency builds trust and demonstrates a commitment to security. Provide a high-level summary of:
   * The types of issues found (without exposing sensitive details).
   * The fixes implemented.
   * Any additional measures (e.g., new tests or monitoring) to ensure ongoing security.


# Implement Robust Monitoring Security Rules

Monitoring is a critical component of smart contract security. While extensive audits and formal verification help secure contracts before deployment, monitoring ensures ongoing security and operational integrity. Real-time tracking of the on-chain state helps detect anomalies, prevent exploits, and mitigate damage in case of unexpected behaviors. Additionally, code issues are sometimes discovered after deployment. For immutable smart contracts, monitoring is often the only way to mitigate these issues, making it an essential tool for maintaining security in a live environment.

Effective monitoring involves two key categories of rules: **generic security rules** and [**tailor-made security rules**](/pre-deployment/tailor-made-security-rules). Generic rules cover common security scenarios such as detecting abnormal balance changes or tracking failed transactions.

However, tailor-made rules are equally important. These custom rules address unique aspects of a specific contract’s logic and risk profile, providing more targeted protection. Security researchers play a vital role in defining these rules during the security review of the code, leveraging their understanding of the contract’s structure and potential vulnerabilities to create a monitoring strategy that complements pre-deployment security efforts.

***

## How to Implement Monitoring Security Rules

1. **Define Security Rules:** Create clear, actionable conditions to monitor. These should align with the contract’s purpose, logic, and risk profile.
2. **Use Reliable Tools:** Leverage blockchain analytics platforms, event listeners, or custom-built monitoring solutions.
3. **Automate Alerts:** Set up automated notifications for violations of predefined security rules.
4. **Regularly Update Rules:** As your contract evolves or as new threats emerge, refine your monitoring logic to stay effective.

***

## Examples of Generic Security Rules

### 1. Detecting Interactions from Suspicious Sources

**Rule**: Monitor and flag interactions originating from:

* Contracts with closed source code.
* Addresses funded by Tornado Cash or other mixers.
* Addresses identified as malicious by community threat intelligence or on-chain oracles.

**Why It Matters**: Interactions from such sources are often linked to exploit attempts. Attackers typically use mixers and anonymized contracts to obscure their tracks, making it crucial to flag these interactions for deeper investigation.

### 2. Tracking Transactions Involving Flash Loans

**Rule**: Detect and analyze transactions that involve flash loans.

**Why It Matters**: While not inherently malicious, flash loans are often used by attackers. Their use demands closer scrutiny to uncover potential threats hidden in complex transaction sequences.

### 3. Monitoring Abnormal Balance Fluctuations

**Rule**: Define thresholds for balance changes in both native assets and ERC20 tokens. Flag any transactions that result in abnormal or unexpected shifts.

**Why It Matters**: Sudden or significant changes in a contract’s balance often signal potential exploits, such as unauthorized withdrawals, minting bugs, or value-draining attacks. Real-time detection of these fluctuations enables faster remediation.

### 4. Identifying Interactions with Rarely Used Functions

**Rule**: Track calls to contract functions that are seldom invoked.

**Why It Matters**: Attackers frequently target obscure or rarely used functions that might have been overlooked during development or audits. Monitoring these interactions helps surface unusual activity and ensures these functions are not exploited unnoticed.

### 5. Detecting Spikes in Failed Transactions

**Rule**: Monitor the number of failed transactions interacting with the contract over a set time frame. Flag any spikes that exceed normal activity levels.

**Why It Matters**: A sudden increase in failed transactions can indicate deliberate DoS attacks, bugs in the contract, or malicious usage by attackers. Identifying these spikes early helps mitigate issues before they escalate.


# Leverage Security Reviews to Define Tailor-Made Monitoring Rules

Involving security researchers in defining monitoring security rules during the security review ensures a more effective and relevant monitoring system. Researchers have a deep understanding of the contract’s logic, edge cases, and vulnerabilities, allowing them to identify critical conditions that should remain true throughout the contract’s lifecycle. This helps detect issues like state inconsistencies or unauthorized actions early, strengthening the link between pre-deployment analysis and post-deployment monitoring.

Adding this step during the review also saves time and resources. Since researchers are already deeply familiar with the code, they can design monitoring logic without duplicating efforts later. Some risks identified during the review may not be directly fixable in the code but can be addressed with off-chain monitoring, such as tracking unusual access attempts.

Most standard monitoring tools lack the ability to implement custom rules tailored to a specific contract. Security researchers can fill this gap by creating bespoke rules that address unique risks, such as monitoring for interactions with high-risk addresses or tracking anomalies in critical functions. This tailored approach provides precision and coverage that generic tools often miss.

***

## Examples of Tailor-Made Security Rules

### 1. Tracking Calls to Admin Functions

**Rule**: Log and monitor all transactions involving admin functions, such as transferring ownership, pausing the contract, or upgrading logic.

**Rationale**: Admin functions have wide-reaching effects on the contract. Unauthorized or unexpected usage could lead to exploits or governance disputes.

### 2. Monitoring Certain State Variable Changes

**Rule**: Continuously validate critical state variables (e.g., owner, whitelists, or key parameters) to ensure they remain as expected.

**Rationale**: State variables are often targeted by attackers to bypass access controls or escalate privileges. Detecting unauthorized changes can prevent escalation.

### 3. Validating Oracle Price Feeds

**Rule**: Compare price feeds from oracles with market norms and redundant oracles to detect sudden deviations.

**Rationale**: Manipulated oracles can destabilize contracts, resulting in improper liquidations or inaccurate transactions. Monitoring ensures integrity.

### 4. Monitoring "Push Payments" for Potential Reverts

**Rule**: Track and flag reverts during ETH transfers to multiple recipients in a single transaction. Log the specific recipient causing the failure.

**Rationale**: While the "pull" pattern is generally advised for distributing funds due to its resilience to denial-of-service (DoS) risks, many projects opt for the "push" pattern for better user experience. In these cases, privileged users are often allowed to remove problematic recipients, but monitoring for reverts is essential to quickly identify and address potential disruptions.


# Configuration Risk Assessment for DeFi Protocols

## Overview

A **Configuration Risk Assessment** focuses on evaluating economic and operational parameters of DeFi protocols—such as collateral ratios, interest rates, and liquidation thresholds—to ensure they don't introduce unintended vulnerabilities or systemic risk.

## Why It Matters

While security reviews primarily address code-level vulnerabilities, configuration parameters drive the behavior of deployed systems. When they're misaligned or poorly calibrated, they may:

* Enable **liquidity drains**
* Trigger **mass liquidations**
* Reduce **capital efficiency**
* Erode **protocol stability**

## Pre-Assessment Checklist

* **Clear scope & documentation**: Define which parameters (e.g., LTVs, oracle refresh rates) need focus. Be explicit about the intended behavior and stress scenarios.
* **Internal audits first**: Have a fresh pair of eyes review parameter rationale and documentation before external engagement.
* **Robust testing frameworks**:
  * **Unit tests** covering edge cases.
  * **Fork-based and simulation tests** under real-world conditions.
  * **Fuzzing on inputs** to reveal unexpected behaviors.

## Core Components of the Assessment

### 1. Parameter Inventory

* Catalog all modifiable parameters: collateral factors, liquidation mechanics, protocol fees, oracle settings, etc.

### 2. Scenario Modeling & Stress Simulations

* Simulate historical and hypothetical shocks:
  * Flash crash in collateral assets.
  * Sudden oracle mispricing.
  * Liquidity shortfalls or counterparty defaults.

### 3. Risk Metrics

* Define quantitative thresholds and indicators:
  * **Collateral buffer adequacy**
  * **Liquidation slippage risk**
  * **Parameter sensitivity**

### 4. Deliverables

* **Assessment report**, outlining parameter risks and root causes
* **Recommended parameter adjustments**, with rationale and impact analysis
* **Test cases or simulation artifacts** supporting recommendations

## Post-Assessment Actions

1. **Regression tests** — Add tests verifying parameter changes prevent identified risks.
2. **Time buffers** — Allow room for revision, re-evaluation, and governance coordination before parameter updates.
3. **Documentation updates** — Ensure all changes and rationale are reflected in the docs.
4. **Testnet deployment** — Trial parameter configurations in a realistic staging environment before rolling them out live.

## Who Provides These Services

Several specialized firms have developed frameworks for configuration risk assessments in DeFi:

* **Chaos Labs** — known for risk simulations and parameter optimization.
* **Gauntlet** — pioneers in agent-based simulation and parameter recommendations.
* **RiskDAO** — community-driven risk assessment and research.
* **BlockAnalitica** — provides risk parameter analyses for lending protocols.
* **Optimism Security Council & other DAO risk committees** — increasingly, DAOs establish internal/external groups to continuously monitor and recommend parameter adjustments.


# Conduct an External Web2 Security Review

While most security reviews in Web3 focus on smart contracts, decentralized applications (dApps) also rely heavily on **traditional Web2 components** such as JavaScript/TypeScript frontends, Python or Node.js backends, and API services. A Web2 code audit reviews these off-chain components for security flaws.

## What a Web2 Code Audit Covers

* **Frontend applications**
  * Secure use of wallet integrations (Metamask, WalletConnect, etc.)
  * Handling of transaction construction logic
  * Prevention of client-side vulnerabilities (e.g., XSS, unsafe eval, DOM injection)
* **APIs and backend services**
  * Authentication and session management
  * Data validation and sanitization
  * Secure API design and rate-limiting
* **Dependency and package security**
  * Insecure npm/pip packages
  * Typosquatted or malicious libraries
  * Unmaintained dependencies with known CVEs
* **Secret and key management**
  * API keys and private keys exposed in code or `.env` files
  * Misconfigured access controls in cloud services


# Protect Against DNS Poisoning

## Description

DNS Poisoning (also called DNS Hijacking) occurs when attackers manipulate DNS records to redirect users from a legitimate Web3 project’s website to a malicious one. In these attacks, users believe they are interacting with the authentic project interface, but are instead exposed to phishing sites designed to steal **private keys, seed phrases, credentials, or funds**.

Attackers typically achieve this by:

* Compromising the registrar account controlling the project’s domain.
* Exploiting vulnerabilities or misconfigurations in DNS servers.
* Injecting malicious DNS cache entries at the resolver level.

## Why It’s Common in Web3

Web3 projects heavily rely on web frontends for:

* Wallet connections (e.g., MetaMask, WalletConnect).
* Token sales and airdrop participation.
* Project dashboards, staking platforms, and governance portals.

Unlike on-chain smart contracts, DNS remains a **centralized weak point**. A single registrar account or DNS record compromise can redirect massive amounts of traffic to an attacker’s controlled site. Because users are accustomed to trusting a project’s primary domain, these attacks are both **high-impact and high-success**.

## Impact

* **Phishing & Wallet Drains**: Users may unknowingly connect wallets to malicious contracts.
* **Credential Theft**: Login details for admin dashboards, Discord/Telegram, or analytics services may be stolen.
* **Loss of Funds**: Redirected users may approve malicious transactions or send funds to attacker-controlled addresses.
* **Reputation Damage**: Even a short DNS hijack can significantly damage trust in a project.

## Real-World Example

In **2022, Curve Finance** experienced a DNS hijacking attack. Users visiting their legitimate domain were redirected to a fake interface that mimicked Curve’s frontend. This led to users signing malicious approvals and losing funds. The incident highlighted how **DNS remains a bottleneck for Web3 security**.

## Mitigation Strategies

### 1. Domain & DNS Security

* **Registrar Account Security**:
  * Use **hardware security keys** (e.g., YubiKeys) and **2FA** for registrar logins.
  * Restrict account access to essential personnel only.
  * Regularly review registrar account activity and enable notifications for changes.
* **DNSSEC (Domain Name System Security Extensions)**:
  * Enable **DNSSEC** to cryptographically sign DNS records, reducing the risk of tampering.
  * Work with registrars and DNS providers that support DNSSEC.
* **Reputable DNS Providers**:
  * Use enterprise-grade DNS providers with strong security practices.
  * Avoid free/low-tier providers for critical domains.

### 2. Infrastructure Hardening

* **Web Hosting & CDN**:
  * Use **cloud providers with DNS-level security features** (e.g., Cloudflare, AWS Route 53).
  * Configure **DNS change alerts** and monitoring for unauthorized modifications.
* **Subdomain Protection**:
  * Audit and clean up unused subdomains to prevent subdomain takeovers.
  * Apply strict CNAME/A record controls.

### 3. Monitoring & Detection

* **Continuous Monitoring**:
  * Use DNS monitoring tools to detect unauthorized record changes.
  * Monitor SSL/TLS certificate issuance for your domains via [Certificate Transparency logs](https://crt.sh/).
* **Phishing Detection**:
  * Monitor for domains similar to your project’s (typosquatting).
  * Preemptively register commonly mistyped versions of your domain.

### 4. User-Facing Precautions

* **Official Communication**:
  * Always communicate verified official links via **multiple trusted channels** (Twitter, Discord, GitHub, etc.).
  * Pin verified contract addresses and domains in community channels.
* **Browser Security**:
  * Encourage users to bookmark your official domain.
  * Educate users about **never entering seed phrases or private keys into a website**.
* **Fallbacks**:
  * Provide IPFS-hosted or ENS-linked frontends as **decentralized access points**.
  * Example: Hosting dApp frontends on **ENS + IPFS** ensures users have a verifiable, tamper-resistant alternative.

## Summary

While smart contracts themselves may be immutable and secure, **DNS remains a centralized Achilles’ heel for Web3 projects**. A single lapse in DNS or registrar security can lead to devastating consequences, including stolen funds and loss of community trust.

**Mitigation requires a layered approach**: registrar account hardening, DNSSEC, enterprise-grade providers, proactive monitoring, and user education. For projects aiming for long-term resilience, offering decentralized frontend alternatives (ENS/IPFS) should be considered a best practice.


# Conduct a Solvency Assurance Audit

## Overview

A **Solvency Assurance Audit** evaluates whether a protocol's balance sheet and liquidation mechanisms can withstand shocks—ensuring the system remains solvent and able to honor obligations even under stress.

## Why Solvency Assurance Is Critical

Code and parameter safety alone don't guarantee viability. Protocols must also demonstrate that:

* **Assets ≥ Liabilities** under adverse conditions
* Liquidation mechanisms can act effectively and fast enough to preserve solvency

## Pre-Audit Preparation

* **Clearly define scope**: Identify pools, collateral types, leverage thresholds, and liquidity concentrations. Make assumptions explicit.
* **Run internal dry-runs**: Perform initial solvency checks before engaging external auditors.
* **Test coverage**: Prioritize fork-level and stress simulations, including edge-case modeling and fuzzed inputs.

## Audit Process and Components

### 1. Balance Sheet Analysis

* Evaluate total assets (collateral, reserves) vs. liabilities (outstanding debt, redemption obligations).
* Identify **exposure concentrations** (e.g., collateral concentration in a volatile asset).

### 2. Stress Testing Scenarios

* Simulate severe events:
  * Rapid price crashes (e.g., 50% drop in ETH in 24 hrs).
  * Liquidity shortages.
  * Correlated multi-asset failures.

### 3. Liquidation & Liquidity Dynamics

* Stress test liquidation execution paths, focusing on:
  * Market depth limitations.
  * Time-to-liquidate vs. price decay.
  * Slippage and cascading risk effects.

### 4. Risk Metrics

* **Solvency ratios** under stress.
* **Liquidation capacity**: how much collateral can be offloaded before breaching solvency.
* Early-warning indicators for escalating risk.

### 5. Deliverables

* **Solvency health report** with scenario analyses.
* **Recommendations** for:
  * Improved collateral diversification.
  * Adjusted liquidation thresholds or incentives.
  * Buffer reserves or liquidity backstops.

## Post-Audit Actions

1. **Test regression scenarios** — Ensure recommended changes fix the issues and prevent recurrence.
2. **Allocate buffer time** — Allow for testing, governance discussion, and revalidation.
3. **Update documentation** — Reflect all modifications, including new risk thresholds or monitoring protocols.
4. **Execute testnet trials** — Simulate the audit recommendations under realistic conditions.


# Establish a Contingency Plan

A contingency plan for smart contracts is a predefined strategy to mitigate risks and respond effectively to unexpected events or failures. Since smart contracts are often immutable and handle significant financial value, contingency plans help address scenarios such as bugs, security breaches, or external disruptions.

These plans may include mechanisms like pausable contracts, multi-signature controls, emergency withdrawal features, or upgrade paths. A robust contingency plan ensures that project teams can protect users and assets while minimizing downtime and reputational damage in crisis situations.

***

A robust contingency plan should include the following:

## 1. Risk Assessment and Scenario Planning

* **Identify Critical Components**: Highlight the most sensitive parts of the smart contract, such as fund-handling logic or external integrations (e.g., oracles).
* **Anticipate Failure Scenarios**: Include scenarios like reentrancy attacks, front-running, oracle manipulation, and unexpected user behaviors.
* **Define Potential Impact**: For each scenario, estimate the financial, reputational, and operational impact.

## 2. Incident Detection and Monitoring

* **Real-time Monitoring**: Implement monitoring tools to track unusual activities, such as large withdrawals, unexpected function calls, interactions from suspicious addresses and/or closed source contracts.
* **Alerting Systems**: Set up automated alerts for anomalies that could indicate a security breach.

## 3. Emergency Response Mechanisms

* **Pause/Stop Functionality**: Include mechanisms like circuit breakers or pause functions to halt operations in case of suspicious activities or detected vulnerabilities.
* **Upgradability**: If feasible, utilize proxy patterns or modular contracts to enable patching without redeploying.

## 4. Establish an Incident Response Team

* **Leadership:** The [Chief of Security](https://github.com/optimumsec/the-complete-guide-to-securing-web3-protocols/blob/main/pre-deployment/chief-of-security.md) should lead the incident response team, ensuring clear direction and accountability.
* **Core Members:** Include key personnel such as developers, security researchers, community representatives, and legal advisors.
* **Security Council Involvement:** The [Security Council](https://github.com/optimumsec/the-complete-guide-to-securing-web3-protocols/blob/main/pre-deployment/security-council.md) should be an integral part of the team, offering expertise and decision-making authority for critical situations.
* **Role Assignments:** Clearly define responsibilities such as incident commander, communication lead, and technical responders.

## 5. Access Control and Emergency Governance

* **Multi-Signature Schemes**: Require multiple trusted parties to approve critical actions, such as pausing the contract or migrating funds.
* **Emergency Committees**: Establish a governance structure for making urgent decisions. This could include key team members, external advisors, or even community stakeholders.
* **Role Definitions**: Clearly define roles and responsibilities for handling incidents, including developers, auditors, and communication leads.

## 6. Fund Recovery Strategies

* **Fallback Mechanisms**: Design contracts with withdrawal limits or time locks to reduce the risk of immediate loss.
* **Backup Wallets**: Maintain secure backup wallets to migrate funds in case of compromised contracts.

## 7. Communication Plan

* **Internal Communication**: Ensure all team members are informed and can act quickly during an incident.
* **External Communication**: Prepare templates for public disclosures to inform users, stakeholders, and the community about the issue and steps being taken to resolve it.
* **Legal and Compliance Considerations**: Work with legal advisors to handle potential liabilities or regulatory reporting.

## 8. Testing and Drills

* **Simulated Attacks**: Periodically test the contingency plan through red teaming or other simulated attack exercises.
* **Role-Playing Drills**: Conduct drills to ensure all team members are familiar with their roles during an emergency.

## 9. Post-Incident Review and Improvements

* **Incident Analysis**: After resolving an issue, analyze the root cause and the effectiveness of the response.
* **Audit and Update**: Regularly review and update the contingency plan based on lessons learned and evolving security practices.


# Deployment


# Adopt a “Soft Launch” Strategy

Launching a decentralized application (dApp) can be a high-stakes process, as any vulnerabilities or flaws could have significant financial and reputational consequences. A "soft launch" involves releasing the dApp in a controlled manner to mitigate risks and ensure robust security. Below is a guide on how to execute a soft launch effectively.

***

## Why Soft Launch?

1. **Mitigate Risks**: Reduce the impact of potential vulnerabilities or exploits.
2. **System Stress Testing**: Test the system under real-world conditions with limited exposure.
3. **Incremental Trust Building**: Gradually build trust with users as the dApp demonstrates reliability.

***

## Steps for a Soft Launch

1. **Limit Functionality**
   * Start with core features only, leaving more complex or less critical functionalities inactive.
   * Example: Allow users to deposit funds into the platform but disable withdrawals temporarily.
2. **Cap Funds and Transactions**
   * **Set Transaction Limits**: Limit the maximum value of transactions to reduce potential losses in case of an exploit.
   * **Cap Total Locked Value**: Set a ceiling on the amount of funds users can deposit.
3. **Controlled Access**
   * **Whitelist Early Users**: Restrict access to a small group of trusted participants or community members.
   * **Invite-Only Beta**: Use invitation codes to onboard users gradually.
4. **Gradual Expansion**
   * **Increase Limits Incrementally**: Slowly raise transaction and deposit caps as confidence in the system grows.
   * **Unlock Additional Features**: Enable more functionalities over time after thorough testing and validation.


# Never Deploy Code That Was Not Reviewed Externally

External code reviews are essential because they provide an unbiased, fresh perspective, often uncovering vulnerabilities or flaws that internal teams may overlook due to familiarity with the code.

Third-party auditors bring expertise, diverse experiences, and specialized tools to identify security risks, logical errors, and compliance issues. In the context of smart contracts, where flaws can lead to significant financial losses, relying solely on **internal review is insufficient**.

A rigorous, external review ensures that the code adheres to best practices and industry standards, mitigating the risk of exploits, bugs, or unintended behaviors.


# Verify Your Deployed Contracts

Deploying a smart contract to mainnet is a point of no return — any misconfiguration or overlooked mistake can lead to loss of funds or trust. A robust verification process after deployment ensures that the contract matches the audited code and behaves as expected. Below is a structured guide to verifying a smart contract deployment securely and thoroughly.

***

## Why Deployment Verification?

1. **Ensure Audit Relevance**: Confirm that the deployed contract matches the version that was audited.
2. **Prevent Silent Modifications**: Detect unauthorized or accidental changes between audit and deployment.
3. **Some Misconfigurations Are Invisible in Audit**: There are misconfiguration issues that can't be caught in an audit — they must be verified in the context of a live deployment.

***

## Steps for Deployment Verification

1. **Verify Source Code and Compiler Settings**
   * **Match Bytecode**: Ensure the deployed bytecode corresponds exactly to the audited source code.
   * **Match Compiler Version & Settings**: Confirm that the Solidity compiler version and optimization flags are identical to those used during the audit.
   * **Upload to Etherscan**: Upload the Solidity source code that matches the deployed bytecode to Etherscan for public verification. Use Etherscan’s contract verification UI or tools like `sourcify.dev` to verify the contract on-chain. Ensure the provided source code, constructor arguments, and compiler settings generate the exact bytecode deployed.
2. **Verify Final Code Version**
   * **Post-Fix Deployment**: Confirm that the deployed version contains *all* fixes and patches introduced during and after security reviews.
   * **How**: Cross-check the Git commit, release tag, or hash used for deployment against the version approved in the final audit report.
3. **Check Constructor Arguments**
   * **What to Look For**: Ensure initialization parameters (e.g., admin addresses, external token addresses, fee rates) are correctly set.
   * **How**: Decode the deployment transaction input or read constructor arguments from block explorers and compare them with audited config files.
4. **Confirm Contract Ownership and Roles**
   * **Ownership, Admin Rights & Role Setup**: Make sure privileged roles are held by the correct addresses or multisigs *and* that role permissions (`AccessControl`, `owner()`, etc.) are correctly configured and verifiable on-chain.
5. **Validate Upgradeability Setup**
   * **If Using Proxies**: Check that the proxy points to the intended implementation and that the upgrade admin is properly configured.
   * **How**: Inspect storage slots manually or use tools like `openzeppelin-upgrades` to verify the proxy pattern.
6. **Confirm Deployment Scripts Were Followed**
   * **Replay and Audit the Script**: Ensure the deployment was executed via the approved and audited scripts.
   * **Best Practice**: Automate deployment with reproducible scripts (e.g., Foundry, Hardhat) and record the transaction hashes.
7. **Match Deployed Addresses**
   * **For Multisigs, Tokens, Registries**: Confirm that all deployed contract addresses match those expected in documentation, frontends, and audit reports.
   * **Cross-check**: Ensure integrations and monitoring systems use the correct addresses.
8. **Enable Public Verification**
   * **Verified Source Code**: Publish the verified source code to public block explorers.
   * **Public README / Audit Link**: Make the audit report and deployment configuration publicly accessible to build user confidence.
9. **Tag the Commit Hash as a Release on GitHub**
   * **Why**: This provides a public, immutable reference to the exact code version that was deployed.
10. **Export Contract Addresses to Your GitHub Repo**
    * **Why**: Keeping deployed addresses in your repository (e.g., as a JSON or markdown file) improves transparency and simplifies integration for users and partners.
    * **Best Practice**: Include network name, contract name, address, and optionally, verification links.


# Launch a Bug Bounty Program

Launching a bug bounty program is a crucial step for any smart contract project aiming to achieve robust security. It leverages the collective expertise of a global community of ethical hackers and security researchers, who test the code in real-world scenarios that internal teams might not anticipate.

Unlike traditional audits, which offer a snapshot in time, bug bounties provide continuous scrutiny, incentivizing the discovery of vulnerabilities before malicious actors can exploit them. By rewarding those who identify weaknesses, projects not only enhance their security posture but also build trust with their community, showcasing a proactive commitment to safeguarding user funds.

***

Here are ten key steps to help you successfully launch a bug bounty program for your smart contracts:

## 1. Define Clear Scope and Rules

* **Specify Scope**: List the smart contracts, APIs, and systems open for testing. Exclude areas not ready for public scrutiny.
* **Set Rules**: Detail what constitutes valid vulnerabilities (e.g., reentrancy, logic errors) and explicitly exclude others (e.g., low-severity gas optimizations).

## 2. Offer Competitive Rewards

* **Reward Structure**: Create a tiered system based on severity:
  * **Low**: Minor risks with limited impact.
  * **Medium**: Vulnerabilities with moderate financial or functional risks.
  * **High**: Flaws that could lead to major exploits or loss of user funds.
  * **Critical**: Systemic risks, such as full contract compromise or massive financial losses.
* **Market Research**: Ensure your bounties are competitive with other projects in your industry.

## 3. Use Established Platforms

Leverage platforms like [Cantina](https://cantina.xyz) or [Immunefi](https://immunefi.com) to:

* Access experienced security researchers.
* Utilize built-in reporting, reward management, and analytics tools.

## 4. Provide Comprehensive Documentation

* **Technical Docs**: Include all smart contract code, architectural diagrams, and dependency libraries.
* **User Guides**: Offer detailed deployment instructions and usage scenarios for researchers to simulate real-world interactions.

## 5. Set Up Secure Communication Channels

* **Encrypted Submissions**: Provide PGP keys or use secure platforms for private vulnerability reporting.
* **Response Time**: Commit to quick acknowledgments and timely triage of submitted findings.

## 6. Transparent Reward Process

* **Evaluation Criteria**: Outline how vulnerabilities will be assessed and reward levels determined.
* **Public Recognition**: Offer the option for researchers to be publicly acknowledged for their contributions.

## 7. Implement Responsible Disclosure Policy

* Encourage researchers to report issues ethically by:
  * Guaranteeing non-retaliation.
  * Providing clear timelines for issue resolution and disclosure.

## 8. Maintain Continuous Engagement

* **Dynamic Scope**: Update the scope regularly as the project evolves.
* **Community Updates**: Share findings, fixes, and improvements made as a result of the program.

## 9. Integrate with Internal Security Measures

* Bug bounties should complement internal audits, testing, and code reviews.
* Use insights from submissions to improve your development lifecycle.

## 10. Continuous Improvement and Feedback

* **Post-Mortem Reviews**: After resolving an issue, review what went wrong and how to prevent similar issues.
* **Iterative Enhancements**: Refine bounty rules and scope based on past performance and researcher feedback.


# Ongoing Upgrades


# Handling Communications Before a Smart Contract Upgrade

Effective communication before a smart contract upgrade is critical for maintaining user trust and ensuring smooth operations. The approach differs depending on whether the upgrade is a routine enhancement or an emergency security fix. Below are actionable guidelines for both scenarios.

***

## Routine Upgrade: Adding New Features

When upgrading to introduce new features, the focus is on transparency, user readiness, and minimizing disruption.

### Key Steps:

1. **Announce Early**
   * Share the planned upgrade details well in advance through official channels (website, social media, email, etc.).
   * Clearly state the purpose of the upgrade and the benefits it brings to users.
2. **Reassure Users**
   * Emphasize that all funds are safe during the upgrade.
   * Provide clear instructions if any user action is required, such as pausing interactions or withdrawing funds temporarily.
3. **Communicate Downtime**
   * Clearly outline the expected downtime, specifying the exact time and duration.
   * Explain the impact on user interactions, such as halted transactions or disabled features.
4. **Encourage Community Feedback**
   * Allow users to ask questions or raise concerns in advance to ensure they feel engaged and informed.
5. **Post-Upgrade Updates**
   * Notify users once the upgrade is complete, summarizing the changes and reaffirming the safety of their assets.

***

## Emergency Upgrade: Fixing a Security Issue

In the case of an urgent upgrade to resolve a security vulnerability, communication must be swift and focused, with a balance between transparency and discretion.

### Key Steps:

1. **Act Quickly**
   * Announce the need for immediate maintenance without disclosing sensitive details that could enable exploitation before the fix is implemented.
2. **Reassure Users**
   * Clearly state that funds are safe and the team is acting to enhance security.
   * Avoid technical jargon; focus on user trust and the steps being taken to safeguard their assets.
3. **Explain Temporary Downtime**
   * Provide an estimated timeline for the fix and any service interruptions.
   * If the downtime is extended, provide periodic updates to reassure users of progress.
4. **Coordinate with Key Stakeholders**
   * Inform trusted community leaders, partners, and validators (if applicable) about the issue to ensure alignment in messaging.
5. **Post-Upgrade Transparency**
   * After resolving the issue, share a detailed post-mortem, explaining the vulnerability, the steps taken to address it, and any additional measures to prevent recurrence.
6. **Encourage Security Reporting**
   * Remind users and developers of the project’s bug bounty program or other mechanisms to report vulnerabilities responsibly.


# Ensure Changes Are Backwards Compatible

Upgrading a smart contract requires careful attention to backward compatibility. Any issues can disrupt operations, cause failures, or even introduce security vulnerabilities in dependent systems. To mitigate these risks, rigorous testing and communication are essential.

***

## Steps to Test Backward Compatibility

### 1. Understand Dependencies

* Map all contracts, dApps, and services interacting with the upgraded contract.
* Identify specific methods or storage patterns they rely on.

### 2. Simulate Interactions

* Deploy the upgraded contract on a testnet or local environment.
* Point dependent contracts and systems to the upgraded version and test their interactions.

### 3. Retest Old Interfaces

* Validate that all previously exposed public and external functions operate as expected.
* Ensure method signatures and expected inputs/outputs remain unchanged unless modifications were explicitly planned and communicated.

### 4. Validate Storage Layout Compatibility

* If using a proxy pattern, confirm that storage layout changes do not disrupt dependent contracts.
* Use tools like [OpenZeppelin Upgrades](https://docs.openzeppelin.com/upgrades-plugins) to detect storage layout mismatches.

### 5. Test Common Scenarios

* Simulate frequent workflows such as token transfers, staking, or withdrawals.
* Verify that these workflows produce the expected outcomes without errors.

### 6. Run Integration Tests

* Conduct integration tests involving all contracts that depend on the upgraded contract.
* Include tests for systems relying on third-party libraries or off-chain components.

### 7. Check Event Consistency

* Ensure emitted events maintain the same structure and meaning.
* This is crucial for analytics platforms, off-chain indexers, or monitoring tools.

### 8. Seek Feedback from Stakeholders

* Share the upgraded version with integrators and developers using the contract.
* Request feedback to identify overlooked dependencies or issues.

### 9. Audit the Upgrade

* Conduct a focused audit of the changes to ensure no new vulnerabilities affect compatibility.

***

## Additional Recommendations

* **Version Documentation**\
  Maintain detailed documentation outlining changes and their potential impact on other systems.
* **Deprecation Notices**\
  Clearly communicate any backward-incompatible changes and provide deprecation notices with alternatives.
* **Multistage Deployment**\
  Roll out upgrades in phases, starting with non-critical systems to monitor for issues before full deployment.


# Use Existing Unit Tests to Prevent Regression Bugs

When upgrading or modifying smart contracts, regression bugs—where previously working functionality breaks—can easily occur. Utilizing existing unit tests effectively is one of the best ways to ensure that your upgrades do not inadvertently disrupt functionality.

***

## Steps to Reuse Unit Tests

### 1. **Organize Existing Tests**

* Ensure all unit tests from the original contract are clearly documented and accessible.
* Separate tests into categories, such as critical paths (e.g., token transfers) and auxiliary features (e.g., metadata retrieval).

### 2. **Run Tests Against the Upgraded Contract**

* Execute all existing unit tests on the upgraded contract in a testing environment.
* Compare results with the original contract’s test results to confirm consistency.

### 3. **Address Failures Immediately**

* Investigate any failing tests to determine if the issue is due to:
  * A bug in the upgraded contract.
  * Intentional changes in behavior that require test updates.

### 4. **Expand Test Coverage**

* Add new unit tests to cover newly introduced features in the upgraded contract.
* Ensure the new tests integrate seamlessly with the existing suite.

### 5. **Integrate Regression Testing into CI/CD**

* Automate the execution of unit tests in your Continuous Integration/Continuous Deployment (CI/CD) pipeline.
* Require all tests to pass before allowing the upgrade to proceed.


# Handling State Migration in a Secure Way

State migration refers to the process of modifying or correcting the on-chain state of a smart contract, often necessary during an upgrade or to address issues such as bugs or vulnerabilities. Proper handling of state migration is critical to maintaining the security and integrity of the protocol, as well as ensuring user trust. Below is a step-by-step guide to handling state migration securely.

***

## Steps for Secure State Migration

### 1. **Identify and Analyze the Issue**

* **Pinpoint Affected Areas**: Identify which parts of the contract's state are incorrect or need modification.
* **Assess Impact**: Understand how the incorrect state impacts the functionality, users, and other dependent contracts.

### 2. **Plan the Migration**

* **Define the Target State**: Clearly specify the desired state after the migration.
* **Document Changes**: Maintain detailed documentation of the planned changes for review and transparency.
* **Minimize Changes**: Only modify the data that is strictly necessary to minimize risk.

### 3. **Develop and Test Migration Scripts**

* **Write Secure Scripts**: Use trusted tools like Hardhat or Foundry to write migration scripts that update the state.
* **Unit Test the Scripts**: Test the scripts thoroughly to ensure correctness.
* **Simulate in a Controlled Environment**: Test the migration in a forked mainnet environment to validate it under real-world conditions.

### 4. **Pause the Contract**

* **Prevent Further Changes**: Use a `pause` function to halt contract operations, ensuring no new transactions can affect the state during the migration.
* **Notify Users**: Communicate the downtime and the reason for the pause clearly to all stakeholders.

### 5. **Conduct the Migration**

* **Verify Before Execution**: Double-check the migration script, the target state, and all assumptions.
* **Execute in Phases**: If possible, perform the migration in smaller, incremental steps to reduce risk.
* **Monitor the Process**: Monitor logs and transactions during the migration to catch any issues early.

### 6. **Audit the Changes**

* **Independent Review**: Have the migration script and results reviewed by a third-party security expert.
* **Verify State Consistency**: Ensure the migrated state aligns perfectly with the defined target state.

### 7. **Unpause and Validate**

* **Test Post-Migration Functionality**: Conduct thorough testing of the contract after unpausing to ensure it functions as intended.
* **Monitor Activity**: Monitor the contract for unexpected behavior or issues after the migration.

### 8. **Communicate with Transparency**

* **Inform Users**: Share detailed information about what was changed and why.
* **Acknowledge Impact**: If users were affected, provide guidance or compensation where applicable.
* **Update Documentation**: Reflect the migration details in the protocol's documentation.

## Best Practices for Secure State Migration

* **Keep it Minimal**: Modify only the necessary data to reduce complexity and risk.
* **Use Access Controls**: Ensure only authorized accounts can execute the migration.
* **Maintain Transparency**: Provide public access to migration scripts and audit reports to build trust.


# Key Considerations for the Security Review of Upgrades

Ensuring the security of a contract upgrade requires a focused review process tailored to the unique risks that upgrades introduce. While it may seem tempting to focus only on the newly added code, this approach is insufficient.

A thorough security review must consider all state variables affected by the upgrade and re-examine any previously deployed code these changes interact with. Even if the original code was reviewed before deployment, revisiting it ensures that no hidden vulnerabilities are exposed by the upgrade.

***

Below are actionable tips to guide a comprehensive security review of your upgraded contract:

## 1. Confirm Compatibility with Existing Functionality

* **Test for Backward Compatibility:** Verify that all previously supported functions and interfaces behave as expected.
* **Check Dependent Contracts:** Ensure contracts or systems interacting with the upgraded contract remain functional.

## 2. Assess Changes to Storage Layout

* **Validate Storage Consistency:** If using a proxy pattern, confirm that storage layout changes do not introduce corruption.
* **Use Tools:** Employ tools like OpenZeppelin's storage layout comparison to identify potential mismatches.

## 3. Review New and Modified Code

* **Audit New Logic:** Scrutinize any newly introduced functionality for vulnerabilities or design flaws.
* **Verify Fixes:** Confirm that updates addressing previously identified vulnerabilities do not introduce new issues.
* **Revisit Touched Code:** Reassess previously reviewed code that interacts with updated state variables or new logic to ensure the upgrade doesn't expose vulnerabilities in older code.
* **Review State Migration Scripts:** Examine any scripts or mechanisms used for migrating state to ensure correctness and prevent corruption or unintended consequences.

## 4. Conduct Thorough Tests on Testnets

* **Simulate Real-World Scenarios:** Test the upgraded contract in environments similar to mainnet.
* **Integration Tests:** Ensure smooth interactions with other contracts and off-chain systems.

## 5. Review Documentation

* **Upgrade Notes:** Include detailed descriptions of changes made in the upgrade.
* **Migration Plans:** Document the state migration process and any data transformations required.

## 6. Involve External Security Researchers

* **Expert Review:** Engage third-party security researchers to evaluate the upgrade.
* **Independent Testing:** Ensure researchers independently verify your internal findings.


# Ongoing Operations


# Establish a Head of Security Role

Dedicating a **Head of Security** for a project is essential to establishing a clear, consistent approach to risk management and security strategy.

A Head of Security provides centralized leadership, overseeing security reviews, managing incident responses, and continuously assessing the threat landscape. This role ensures that security considerations are embedded at every stage of the project lifecycle—from design to deployment, and beyond.

***

## Responsibilities of the Head of Security

The Head of Security should take on the following key responsibilities:

* **Security Reviews**: Plan, coordinate, and review internal and external reviews to identify and mitigate vulnerabilities in smart contracts and infrastructure.
* **Incident Response**: Lead the response to security incidents, including identifying the root cause, minimizing damage, and coordinating with stakeholders.
* **Monitoring and Alerts**: Oversee the implementation of monitoring systems to detect and respond to suspicious activities in real-time.
* **Policy and Governance**: Develop and enforce security policies, ensuring compliance with industry standards and best practices.
* **Threat Analysis**: Continuously assess the threat landscape to identify new attack vectors and adapt security strategies accordingly.
* **Team Training**: Educate team members about security best practices, ensuring a strong culture of security awareness across all departments.
* **Post-Deployment Security**: Ensure ongoing updates and monitoring for deployed contracts, including the coordination of patching known vulnerabilities.
* **Stakeholder Communication**: Act as the primary point of contact for all security-related matters, communicating risks and strategies effectively with internal teams and external stakeholders.
* **Vendor and Third-Party Security**: Evaluate and oversee third-party tools, libraries, and dependencies to ensure they meet security standards.


# Establish a Security Council

A Security Council is essential for smart contract-based projects, providing a dedicated group to safeguard the protocol and respond to security incidents. In decentralized systems, where trust in code is critical, the council ensures rapid and organized action during emergencies, such as pausing contracts, deploying patches, or activating circuit breakers to prevent losses. Composed of trusted experts, the council supports security and stability while aligning decisions with community interests.

Many leading protocols rely on Security Councils or emergency multisigs, including **Optimism** and **Arbitrum** (12-member councils that can rapidly deploy upgrades), **Polygon** (multisig used to patch critical vulnerabilities), **MakerDAO** (emergency shutdown process), and **ENS** (root keyholders with upgrade authority). These examples show that structured, transparent security governance is a proven best practice.

## Responsibilities of the Security Council

* **Emergency Actions:** Pause contracts, deploy patches, or implement circuit breakers during crises.
* **Vulnerability Management:** Assess, prioritize, and address security vulnerabilities as they arise.
* **Governance Oversight:** Ensure protocol decisions and upgrades adhere to security best practices.
* **Regulatory Compliance:** Align security measures with legal and regulatory requirements.
* **Periodic Security Reviews:** Conduct regular assessments to evaluate contract safety and recommend immutability where appropriate.
* **Incident Response:** Lead investigations and coordinate actions in response to security breaches.
* **Community Transparency:** Engage stakeholders and communicate actions to maintain trust.


# Managing Privileged Accounts Securely

Many projects rely on externally owned accounts (EOAs) for managing privileged functions, such as pausing contracts, upgrading systems, or handling sensitive administrative tasks. However, using EOAs for such purposes introduces significant security risks, as they are susceptible to key compromise.

***

Below are actionable steps to handle these accounts securely.

## 1. Transition Away from EOAs

* **Use Multisigs:** Replace EOAs with multi-signature wallets like [**Gnosis Safe**](https://gnosis-safe.io/) to distribute control among multiple stakeholders.
* **Explore DAO Governance:** Implement decentralized governance where the community or stakeholders vote on critical decisions, ensuring long-term sustainability.
* **Consider MPC Wallets:** Leverage **multi-party computation (MPC)** wallets, which distribute key control among multiple parties without relying on a single device or location. Examples include [**Fireblocks**](https://fireblocks.com/) or [**ZenGo**](https://zengo.com/).

## 2. Secure Private Keys

* **Use Hardware Wallets:** Store private keys in hardware wallets (e.g., Ledger, Trezor) to protect them from malware and phishing attacks.
* **Backup Keys Properly:** Store encrypted backups of private keys in secure, geographically dispersed locations. Avoid cloud storage or email backups.
* **Enable Two-Factor Authentication:** When using wallet applications, ensure 2FA is enabled to add an extra layer of security.

## 3. Restrict Privileges and Access

* **Principle of Least Privilege:** Assign the minimum necessary permissions to privileged accounts. Avoid consolidating multiple critical roles under a single key.
* **Timelocks:** Introduce timelocks for high-stakes operations, allowing time for community scrutiny or intervention if suspicious activity is detected.

## 4. Monitor and Respond to Threats

* **Activity Alerts:** Set up monitoring tools to track privileged account activity. Receive alerts for any unexpected or unauthorized transactions.
* **Incident Response Plan:** Define a clear response plan for compromised keys, including pausing contracts, revoking access, and redeploying affected accounts.

## 5. Regularly Audit Privileged Functions

* **Review Access Controls:** Periodically audit the list of privileged accounts and their roles to identify unnecessary permissions.
* **Test Fail-Safes:** Ensure that the process to recover or replace compromised keys is well-documented and tested.

## Example Setup for Privileged Accounts

1. Deploy a **Gnosis Safe Multisig** for admin functions.
2. Use **Hardware Wallets** for each signer of the multisig.
3. Define a **Timelock Contract** for critical operations requiring community approval.
4. Consider transitioning governance to a **DAO Framework** like [**Aragon**](https://aragon.org/) or [**Snapshot**](https://snapshot.org/) for decentralized management as the project scales.
5. Evaluate the use of **MPC Wallets** to enhance security through distributed key management.


# Add Regression Tests After Fixing Vulnerabilities

Whether a vulnerability is found during a **security review** or after deployment, it's important to write a test that **simulates the exploit attempt** and verifies it **fails (reverts)** after the fix. This helps:

* Prevent future regressions of the same vulnerability.
* Document the exploit in a reproducible and testable way.
* Strengthen long-term security through test coverage.

> ⚠️ **Limitation**: These tests typically cover only one exploit path. Variations may still exist that trigger the same underlying flaw.

## ✅ Recommendations to Strengthen This Practice:

* **Generalize the test** to detect similar exploit vectors.
* **Write invariant tests** to enforce critical safety conditions across a wide input space.
* **Use property-based fuzzing tools** to explore unseen inputs.
* **Document assumptions** (e.g., actor roles, balances, states) within the test.

This layered approach helps secure the fix and future-proofs the protocol against regressions of the same bug class.


# Conduct a Web3SOC-Style Review

## Overview

A Web3SOC-style review evaluates your protocol's readiness for institutional interactions and identifies potential risks before deployment. Cantina pioneered the [Web3SOC framework](https://cantina.xyz/web3soc), but this guide focuses on internal implementation to ensure high standards of security, governance, and operational maturity.

## Objectives

* **Risk Identification:** Assess security, governance, financial, and operational risks.
* **Institutional Readiness:** Ensure your project is structured to meet expectations of partners and investors.
* **Continuous Improvement:** Provide actionable recommendations to enhance long-term security and reliability.

## Audit Scope

### 1. Governance

* Review decision-making processes, role assignments, and multisig controls.
* Assess community engagement and transparency mechanisms.

### 2. Security

* Conduct thorough smart contract reviews and dependency audits.
* Verify incident response and recovery plans.

### 3. Financial Integrity

* Examine treasury management, accounting transparency, and audit trails.
* Evaluate financial risk mitigation strategies.

### 4. Compliance & Legal

* Ensure adherence to applicable laws and regulations.
* Document internal compliance processes.

## Recommended Steps

1. **Initial Assessment:** Gather all relevant documentation and contracts.
2. **Gap Analysis:** Compare current practices against best-in-class standards.
3. **Remediation:** Fix identified vulnerabilities and strengthen governance/operations.
4. **Final Review:** Conduct a follow-up audit to confirm all issues are resolved.


# Secure Your Treasury

Managing a treasury in a Web3 project is one of the most critical responsibilities for founders, DAOs, and protocol teams. A compromised treasury can lead to devastating losses, damaged reputation, and loss of community trust. This document outlines key practices to **keep your treasury secure**.

***

## Principles of Treasury Safety

* **Minimize single points of failure** — no single individual should have the ability to move all funds.
* **Defense-in-depth** — combine multiple layers of security (on-chain, off-chain, operational).
* **Transparency with accountability** — the community should understand how treasury funds are safeguarded and used.

***

## Key Practices

### 1. Use Multi-Signature Wallets

* Deploy a **multi-sig (e.g., Gnosis Safe)** for treasury management.
* Require **at least 2/3 or 3/5 approvals** to move funds.
* Regularly review signers’ activity and update signer sets when members change.

### 2. Role Separation

* Separate **operational wallets** (day-to-day payments) from **treasury wallets** (long-term reserves).
* Keep treasury funds in a more secure setup with higher signer thresholds.

### 3. Access Control and Signer Security

* Signers should use **hardware wallets** (Ledger, Trezor) rather than browser extensions.
* Enable **passphrase protection and biometric/PIN locks**.
* Keep seed phrases **offline and geographically distributed**.

### 4. On-Chain Safeguards

* Consider **time-lock contracts** for large treasury actions, giving the community time to review before execution.
* Use **spending limits** for operational wallets to prevent draining in case of compromise.

### 5. Diversification of Assets

* Avoid keeping 100% of funds in a single token or chain.
* Diversify between **stablecoins, ETH, BTC, and protocol-native tokens**.
* If holding stablecoins, diversify across issuers (USDC, USDT, DAI).

### 6. Insurance and Custody Options

* For larger treasuries, explore **crypto insurance** providers.
* Consider **qualified custodians** if regulatory or institutional requirements apply.

### 7. Continuous Monitoring

* Set up **real-time alerts** (e.g., Tenderly, Forta, OpenZeppelin Defender) for unusual transactions.
* Regularly **audit treasury contracts and signers**.
* Run **internal drills** to simulate compromised keys or stolen funds.

### 8. Governance Security

* If treasury spending is controlled by governance:
  * Use **guarded launch strategies** to avoid malicious proposals.
  * Employ **veto powers or emergency pause mechanisms**.
  * Audit the governance contracts regularly.

## Emergency Planning

* Prepare a **disaster recovery plan**: what happens if a signer is compromised or unavailable?
* Ensure **backup signers** can be onboarded quickly.
* Document procedures for community communication in case of incidents.


# Securing DAOs and DAO Voting

Decentralized Autonomous Organizations (DAOs) rely heavily on **trustless governance mechanisms**. Securing both the DAO treasury and the integrity of the voting process is critical to prevent manipulation, centralization, or exploitation. Below are key measures and best practices for ensuring DAO and voting security.

## 1. Implement Token Voting Safeguards

Token-based voting is the core of DAO governance but can be vulnerable to **whale domination, temporary token manipulation, and uninformed voting**. Implementing safeguards ensures fair, resilient decision-making.

* **Quadratic or Weighted Voting**: Reduce the influence of large holders by making voting power grow sublinearly with token amount.
* **Delegated Voting**: Allow token holders to delegate votes to trusted representatives to ensure informed decisions.
* **Snapshot Voting**: Adopt off-chain voting with on-chain execution (e.g., Snapshot + Safe) to reduce costs and prevent vote manipulation during the process.

These measures **limit concentrated power, prevent short-term manipulation, and encourage informed participation**, creating a fairer and more resilient DAO governance system.

## 2. Protect Against Flash Loan Attacks

* **Vote Locking**: Require tokens to be locked for a minimum duration before they count towards voting power.
* **Voting Delay**: Introduce a buffer between the end of voting and execution to allow the community to react to suspicious activity.
* **Weight by Time**: Use time-weighted voting power, rewarding long-term holders over temporary whales.

## 3. Secure the Treasury

* **Multisig Control**: Require multiple signers for treasury actions, preferably with signers spread across jurisdictions and organizations.
* **Spending Limits**: Set daily/weekly spend caps to minimize damage from compromised wallets.
* **Timelocks**: Apply execution delays to all treasury actions so the community can review and potentially veto malicious proposals.

## 4. Improve Proposal Security

* **Proposal Screening**: Require a minimum quorum of governance token holders or a vetting process before proposals go to vote.
* **Modular Governance**: Separate routine operational decisions from critical treasury or protocol upgrade decisions.
* **Simulation & Testing**: Mandate proposal simulation on testnets or with formal verification before on-chain execution.

## 5. Strengthen Governance Processes

* **Quorum & Supermajority Rules**: Enforce quorum thresholds and higher requirements for sensitive actions.
* **Emergency Powers**: Create a security council with limited emergency powers to halt malicious or erroneous proposals.
* **Progressive Decentralization**: Begin with controlled governance, and gradually increase decentralization as the system matures.

## 6. Enhance Voter Engagement

* **Incentives for Participation**: Reward active voters or delegators with non-financial recognition or governance points.
* **Reputation Systems**: Layer voting power with non-transferable reputation to prevent pure plutocracy.
* **Education & Transparency**: Publish plain-language summaries of proposals to reduce uninformed voting.

## 7. Monitor & Audit DAO Governance

* **Continuous Audits**: Review DAO contracts and governance mechanisms regularly.
* **Real-Time Monitoring**: Set up alert systems for unusual proposals, voting spikes, or treasury movements.
* **Post-Mortems**: Document governance failures and exploits to improve resilience.


# Background Checks and Personnel Security for Web3 Projects

With the global rise of remote work, **malicious actors have increasingly targeted Web3 projects by infiltrating teams directly**. Unlike purely external attacks, insider threats are uniquely dangerous—attackers may gain access to codebases, deployment keys, and sensitive infrastructure. To minimize these risks, projects must adopt **background checks and structured personnel security measures** as part of their overall security posture.

## Why Insider Threats Matter

* **Privileged access**: Developers, DevOps engineers, and auditors often handle critical secrets.
* **Difficulty of detection**: Malicious intent may only surface after weeks or months of participation.
* **Long-term consequences**: A compromised insider can push malicious code, leak private data, or delay vulnerability disclosures.

## Recommended Measures

### 1. Background Checks

* **Identity Verification**: Require government-issued ID verification for core contributors.
* **Work History Validation**: Confirm past roles, projects, and references.
* **Reputation Screening**: Check open-source contributions, community involvement, and potential red flags.

> ⚠️ Background checks should respect privacy and comply with relevant laws (e.g., GDPR).

### 2. Access Control & Principle of Least Privilege

* Grant access strictly on a **need-to-know basis**.
* Use **role-based access control (RBAC)** for repositories, servers, and cloud services.
* Regularly review and revoke unused or outdated permissions.

### 3. Segregation of Duties

* Separate responsibilities for development, auditing, and deployment.
* Require **multi-party approvals** for critical actions like contract deployment or treasury transactions.
* Rotate roles periodically to reduce reliance on a single individual.

### 4. Security Onboarding & Offboarding

* **Onboarding**: Provide clear guidelines on handling secrets, communication tools, and reporting suspicious activity.
* **Offboarding**: Immediately revoke access when contributors leave. Audit credentials, keys, and repository memberships.

### 5. Monitoring and Detection

* Enable audit logs for GitHub, CI/CD pipelines, and infrastructure.
* Monitor for anomalous activity such as unusual commit patterns, mass data access, or sudden privilege escalations.
* Use automated alerts for sensitive actions.

### 6. Cultural and Legal Safeguards

* Establish a **code of conduct** that emphasizes security and trust.
* Use **NDAs (Non-Disclosure Agreements)** and contributor agreements to protect proprietary knowledge.
* Encourage a culture where **reporting suspicious behavior** is normalized and rewarded.


# Protect Against Social Media Takeovers (Twitter, Discord)

## Description

Social media takeovers occur when attackers gain unauthorized access to a Web3 project’s Twitter, Discord, or other community accounts. This is usually done through **phishing, credential stuffing, malware on admin devices, or compromised moderator accounts**. Once inside, attackers post malicious links, fake announcements, or false giveaways designed to trick users into connecting wallets to malicious contracts.

## Why It’s Common in Web3

* Web3 projects depend heavily on **Twitter and Discord** for direct communication with their communities.
* Announcements on these platforms are often **time-sensitive and trusted**, making it easy for attackers to mislead users quickly.
* Community members are used to seeing links to dApps, airdrops, and token claims—making it harder to detect malicious posts.

Because of this reliance, a **single compromised account** can result in widespread damage before the breach is noticed.

## Impact

* **Wallet Drains & Phishing**: Users may connect wallets to attacker-controlled contracts.
* **Scams & False Giveaways**: Fake airdrops or token claims trick users into sending funds or approving malicious contracts.
* **Community Trust Erosion**: Even after the breach is resolved, trust in the project may be permanently damaged.
* **Operational Chaos**: Security teams must scramble to warn users, restore control, and clean up reputational harm.

## Real-World Example

In **2023, Azuki’s official Twitter account** was compromised. The attackers posted a malicious link disguised as a legitimate airdrop. Community members who clicked the link and connected wallets had funds stolen. The event showed how **high-value NFT and token projects are prime targets for social media takeovers**.

## Mitigation Strategies

### 1. Account Security

* **Strong Authentication**:
  * Use **hardware security keys (FIDO2/WebAuthn)** for Twitter and Discord logins.
  * Avoid SMS-based 2FA, which is vulnerable to SIM-swapping.
* **Separate Accounts**:
  * Do not use personal accounts for project admin roles.
  * Create **dedicated, secured admin accounts** with restricted privileges.
* **Password Hygiene**:
  * Enforce strong, unique passwords stored in a **password manager**.
  * Rotate passwords after role changes or suspected leaks.

### 2. Access Controls

* **Role-Based Access**:
  * Limit admin and moderator permissions to only what is necessary.
  * Regularly audit who has elevated access to Twitter, Discord, and connected tools.
* **Offboarding**:
  * Immediately remove access from team members or moderators who leave the project.
* **API & Bot Security**:
  * Secure API tokens and bots connected to Discord/Twitter.
  * Avoid running bots from personal accounts.

### 3. Infrastructure Hardening

* **Device Security**:
  * Ensure all admins use updated operating systems and browsers.
  * Require endpoint protection (antivirus, firewall, anti-malware) on devices used for social media access.
* **Network Hygiene**:
  * Avoid logging in from shared or public networks.
  * Use **VPNs** or dedicated IPs for admin logins.

### 4. Monitoring & Detection

* **Unusual Activity Alerts**:
  * Enable login alerts for all admin accounts.
  * Monitor for changes in linked apps or integrations.
* **Continuous Monitoring**:
  * Set up automated tools to detect suspicious or unauthorized posts.
  * Encourage community reporting of suspicious activity quickly.

### 5. User-Facing Precautions

* **Verified Announcements**:
  * Maintain an **official website "announcement board"** as the ultimate source of truth.
  * Cross-post announcements on multiple trusted channels to reduce reliance on one platform.
* **Education**:
  * Train users to **never enter seed phrases or private keys into a website** linked from social media.
  * Encourage the community to verify announcements before interacting.
* **Emergency Communication**:
  * Prepare fallback communication channels (e.g., project blog, GitHub, secondary Twitter/Discord) in case primary accounts are compromised.

## Summary

Social media accounts are often the **front line of trust** for Web3 communities, making them lucrative targets for attackers. A single takeover can lead to **wallet drains, scams, and long-lasting reputational damage**.

**Mitigation requires a layered defense**: strong authentication, strict access controls, secure devices, continuous monitoring, and clear user education. Projects should also maintain **redundant, verifiable communication channels** so that even if Twitter or Discord is compromised, the community can quickly verify which announcements are authentic.


# Protect Against Phishing Attacks

## Description

Phishing attacks in Web3 involve creating **fake websites, emails, or messages** designed to trick victims into revealing sensitive information. The end goal is often to steal **private keys, seed phrases, admin credentials, or API tokens**, enabling attackers to drain wallets or compromise infrastructure.

Phishing comes in two primary forms:

1. **Against Users** – Trick community members into connecting wallets or exposing keys.
2. **Against the Project** – Target team members, admins, or service providers to gain access to project infrastructure (e.g., Discord, Twitter, cloud hosting, code repositories, or treasury funds).

## Why It’s Common in Web3

* **User Responsibility**: Users directly manage their wallets, making them prime phishing targets.
* **Centralized Weak Points**: Despite decentralization, projects still rely on centralized services (Twitter, Discord, registrar accounts, GitHub, treasury management dashboards) that can be phished.
* **Low Cost for Attackers**: Registering fake domains, setting up lookalike websites, or sending convincing DMs costs little.
* **High Trust Environment**: Communities trust announcements and quick actions (airdrop claims, mint launches), which attackers exploit.

## Impact

* **User Losses**:
  * Seed phrases or private keys stolen → wallets drained.
  * Malicious approvals signed → funds compromised.
* **Project Compromise**:
  * Admin or developer credentials stolen → infrastructure breaches.
  * Access to **code repositories, treasury funds, or cloud services** → attackers can modify contracts, drain funds, or post malicious content.
  * Social media or communication platform takeovers → widespread scams posted.
* **Reputation Damage**: Users often blame the project even when only phishing was involved.
* **Community Fatigue**: Constant scams lower engagement and trust in legitimate updates.

## Real-World Examples

* **Against Users**: Fake **MetaMask phishing sites** that prompt users to enter seed phrases, leading to complete wallet compromise.
* **Against Projects**: In **2023, several Discord admin accounts were phished** via fake “verification” bots, allowing attackers to post malicious links in official project servers. Other attacks have targeted **developer GitHub accounts or treasury management dashboards**, leading to fund losses or malicious contract deployments.

## Types of Phishing in Web3

### 1. Phishing Against Users

Attackers attempt to deceive community members directly by impersonating the project.\
**Common tactics include**:

* Fake airdrop or mint websites.
* Lookalike domains (typosquatting).
* Fake Twitter/Discord accounts impersonating the project.
* Malicious DMs from impersonated admins.

### 2. Phishing Against the Project

Attackers target the team itself to gain privileged access to **critical infrastructure or assets**.\
**Common tactics include**:

* Fake “support” or “KYC” emails to project admins.
* Phishing pages mimicking registrar, CDN, or cloud providers.
* Fake Discord/Twitter “verification” messages tricking moderators.
* Compromising third-party service accounts (analytics, monitoring tools, SaaS).
* **Access to code repositories** (GitHub/GitLab) → malicious contract deployment or backdoors.
* **Access to treasury funds** (multisigs, wallets) → direct fund theft.
* **Access to project infrastructure** (hosting dashboards, API keys, backend servers) → tampering with dApp logic or sensitive data.

## Mitigation Strategies

### 1. Protecting Users

* **Domain Security**:
  * Register lookalike domains in advance.
  * Use **DNSSEC** to secure legitimate domains.
* **Verified Links**:
  * Pin official websites and contract addresses in multiple channels.
  * Host a **single "official links" page** that always lists trusted domains.
* **Community Education**:
  * Educate users: **Never share seed phrases or private keys**.
  * Encourage bookmarking of official domains.
  * Train users to always verify transaction details before signing.
* **Monitoring & Takedowns**:
  * Monitor for fake domains and phishing sites.
  * Work with registrars and hosting providers for rapid takedowns.

### 2. Protecting the Project

* **Admin Account Security**:
  * Enforce **hardware security keys** for logins to registrar, Twitter, Discord, GitHub, cloud services, treasury dashboards.
  * Avoid SMS-based 2FA (vulnerable to SIM swaps).
* **Access Control**:
  * Use role-based permissions (least privilege principle).
  * Audit admin/moderator accounts regularly.
  * Offboard immediately when roles change.
* **Anti-Phishing Training**:
  * Educate team members on spear-phishing tactics.
  * Train admins to verify requests through a second trusted channel before acting.
* **Infrastructure Safeguards**:
  * Use dedicated project-owned accounts (not personal ones).
  * Apply strict monitoring and alerts for account logins and changes.
  * Store API keys and secrets securely (never in plaintext or public repos).

### 3. Emergency Response

* **If Users Are Targeted**:
  * Immediately warn the community via all official channels.
  * Share the malicious domains or addresses being used.
  * Provide guides for revoking malicious approvals.
* **If Project Is Targeted**:
  * Revoke compromised credentials or tokens immediately.
  * Lock down breached platforms (Twitter/Discord, cloud services, GitHub) and post warnings once access is regained.
  * Review **code repositories, treasury wallets, and backend logs** for signs of tampering.
  * Conduct a post-mortem and communicate transparently with the community.

## Summary

Phishing remains the **number one attack vector in Web3**, exploiting human trust rather than smart contract flaws. Both **users** and **projects** are frequent targets: users risk losing funds directly, while projects risk having **critical infrastructure, code, and treasury funds** hijacked to spread scams or manipulate contracts.

**Mitigation requires defense on two fronts**:

* **User protection**: education, domain security, and rapid takedowns.
* **Project protection**: strict access controls, hardware-backed authentication, and phishing-resistant team practices.

By preparing layered defenses and assuming phishing attempts are inevitable, projects can significantly reduce their community’s exposure and long-term risk.


# Protect Against Denial-of-Service (DoS/DDoS) Attacks

## Description

Denial-of-Service (DoS) or Distributed Denial-of-Service (DDoS) attacks occur when attackers **overwhelm a Web3 project’s website, API, or backend infrastructure** with traffic, rendering it slow or completely inaccessible. These attacks are often timed to coincide with **critical events** such as token sales, NFT drops, or governance actions, maximizing disruption.

Attackers achieve this by:

* Sending massive volumes of requests from a single source (DoS) or multiple sources (DDoS).
* Exploiting application-level bottlenecks (e.g., minting APIs, smart contract interactions via frontends).
* Targeting centralized hosting or CDN points to disrupt access.

## Why It’s Common in Web3

* **Centralized Hosting**: Many Web3 projects rely on centralized servers for frontend services, minting portals, or APIs, creating a single point of failure.
* **High-Value Events**: NFT launches, token sales, and airdrops are time-sensitive and generate high traffic, making them attractive targets.
* **Market Manipulation**: Attackers can disrupt access to influence secondary market dynamics or create FOMO.

## Impact

* **User Frustration**: Users cannot access minting pages, dashboards, or APIs, leading to lost participation opportunities.
* **Financial Losses**: Delayed or missed transactions during token sales or NFT drops may result in direct financial loss.
* **Reputational Damage**: Repeated outages reduce trust in project reliability.
* **Operational Strain**: Teams must scramble to mitigate attacks while monitoring community concerns.

## Real-World Examples

* Solana-based NFT projects have experienced **DDoS attacks during high-profile NFT drops**, preventing users from minting tokens and generating significant community backlash.
* Early token sales on Ethereum have occasionally been **disrupted by DoS attacks**, delaying transactions and frustrating participants.

***

## Mitigation Strategies

### 1. Network & Infrastructure Protection

* **Use DDoS-Resistant Hosting & CDNs**:
  * Deploy frontends on **CDNs with built-in DDoS protection** (e.g., Cloudflare, AWS CloudFront).
  * Consider **multi-region deployments** to distribute traffic load.
* **Rate Limiting & Throttling**:
  * Implement request limits for APIs and endpoints to reduce overload from malicious traffic.
* **Autoscaling & Load Balancing**:
  * Use cloud infrastructure capable of **auto-scaling** to handle sudden spikes in traffic.
  * Apply **load balancers** to distribute traffic evenly across servers.

### 2. Application-Level Hardening

* **Minting / Transaction APIs**:
  * Apply queueing systems or **pre-sale whitelists** to manage high traffic.
  * Validate requests and reject malformed or suspicious requests early.
* **Caching**:
  * Cache static content to reduce backend load.
  * Use **edge caching** through CDNs for high-demand assets.

### 3. Monitoring & Detection

* **Traffic Analysis**:
  * Continuously monitor traffic patterns for unusual spikes.
  * Set up alerts for **sudden increases in requests** or error rates.
* **Incident Response Plan**:
  * Predefine a DDoS mitigation playbook including:
    * Contacting the CDN/hosting provider for emergency mitigation.
    * Switching to backup infrastructure if needed.

### 4. User Communication

* **Status Pages**:
  * Maintain a public **status page** or social channel to inform users about ongoing downtime.
* **Transparency**:
  * Clearly communicate expected recovery time and mitigation actions to prevent misinformation.

### 5. Optional Advanced Mitigation

* **Web Application Firewall (WAF)**:
  * Block malicious traffic patterns or IP ranges at the edge.
* **Bot Management**:
  * Detect and challenge automated traffic to prevent scripted abuse.
* **Third-Party Anti-DDoS Services**:
  * Consider services like **Cloudflare Spectrum**, AWS Shield, or Akamai for enterprise-level protection.

***

## Summary

DoS and DDoS attacks exploit the **centralized bottlenecks** in Web3 infrastructure, particularly during high-demand events such as NFT drops or token sales. While smart contracts themselves remain unaffected, **frontend and API outages can cause financial loss, reputational damage, and community frustration**.

**Mitigation requires layered defenses**: resilient hosting/CDNs, rate limiting, autoscaling, application-level hardening, continuous monitoring, and clear user communication. By preparing infrastructure and response plans in advance, projects can reduce the impact of these attacks and maintain trust with their community.


# Protect Against SIM Swapping

## Description

SIM swapping is a form of **identity theft** where attackers convince mobile carriers to transfer a victim’s phone number to a new SIM card under their control. This enables them to intercept **two-factor authentication (2FA) codes**, reset account passwords, and gain unauthorized access to various services, including email, social media, and cryptocurrency exchanges.

In the context of Web3, SIM swapping poses significant risks to both individual users and project teams.

## Why It’s Common in Web3

* **SMS-Based 2FA**: Many Web3 projects and users still rely on SMS-based 2FA, which is vulnerable to SIM swapping attacks.
* **High-Profile Targets**: Developers, admins, and influencers are prime targets due to their access to critical accounts and platforms.
* **Lack of Awareness**: The decentralized nature of Web3 can lead to inconsistent security practices among its participants.

## Impact

* **Account Takeovers**: Attackers can hijack social media accounts to post fraudulent announcements or phishing links.
* **Financial Losses**: Access to crypto wallets can lead to significant thefts.
* **Reputational Damage**: Compromised accounts can spread misinformation, eroding trust in the affected project.

## Real-World Examples

* **Gutter Cat Gang NFT Collection**: In July 2023, the co-founder of the Gutter Cat Gang NFT project had their Twitter account compromised through a SIM swap. The attacker posted fake links to limited edition NFT sneaker airdrops, leading to users' wallets being drained.
* **Michael Terpin**: In 2017, entrepreneur Michael Terpin was a victim of a SIM swap attack that resulted in the theft of $23.8 million worth of cryptocurrency. The attackers bribed an AT\&T employee to facilitate the SIM swap.
* **FTX Heist**: In November 2022, during the bankruptcy proceedings of cryptocurrency exchange FTX, over $400 million worth of crypto was stolen. The U.S. Department of Justice indicted three individuals for orchestrating a massive SIM-swapping theft ring, allegedly responsible for the FTX heist.

## Mitigation Strategies

* **Avoid SMS 2FA**: Use hardware security keys (FIDO2/WebAuthn) instead of SMS-based authentication.
* **Secure Accounts**: Ensure email, social media, and exchange accounts have strong, unique passwords and hardware-backed 2FA.
* **Carrier Security**: Add extra PINs or passcodes with mobile carriers to prevent unauthorized SIM changes.
* **Monitor Accounts**: Regularly check for unusual login attempts and act immediately on suspicious activity.
* **User Education**: Train team members and users about SIM swapping risks and safe 2FA practices.

## Summary

SIM swapping is a high-risk attack in Web3 targeting both **users and project admins**. Compromised phone numbers can lead to account takeovers, stolen funds, and reputational damage. **Mitigation relies on using hardware-backed authentication, securing accounts, and monitoring for suspicious activity.**


# Protect Against Credential Stuffing and Account Takeovers

## Description

Credential stuffing occurs when attackers **use stolen usernames and passwords**—often from unrelated data breaches—to gain unauthorized access to accounts. In Web3, this typically targets **project admin accounts**, including email, hosting, cloud services, and social media. Once access is obtained, attackers can manipulate websites, post malicious links, or steal funds.

This attack exploits **password reuse and weak security practices**, making it a low-effort but high-reward method for attackers.

## Why It’s Common in Web3

* **Password Reuse**: Team members may reuse passwords across multiple platforms, increasing exposure when any site is breached.
* **Weak Security Practices**: Lack of hardware security keys, poor password management, and minimal account monitoring make credential stuffing easier.
* **High Impact**: Admin accounts provide access to sensitive project infrastructure, making them a prime target.

## Impact

* **Website Compromise**: Attackers can modify project websites to redirect users to phishing or scam pages.
* **Financial Loss**: Access to wallets, treasury systems, or token sales can result in direct theft.
* **Community Trust Damage**: Unauthorized posts or malicious updates erode confidence in the project.
* **Operational Disruption**: Teams must spend critical time restoring compromised accounts and mitigating damage.

## Real-World Examples

* **Web3 Project Website Takeovers**: Compromised admin email accounts have led to attackers altering official project websites, redirecting users to phishing or scam sites, and sometimes draining connected wallets.
* **Decentralized Exchange Admin Breaches**: In some cases, compromised cloud credentials allowed attackers to temporarily modify front-end content, tricking users into signing malicious transactions.

## Mitigation Strategies

### 1. Strong Authentication

* **Use Hardware Security Keys (FIDO2/WebAuthn)** for all critical accounts (email, cloud, social media, hosting).
* **Enable Multi-Factor Authentication (MFA)** wherever possible, avoiding SMS-based 2FA.

### 2. Password Hygiene

* **Unique, Complex Passwords** for every account.
* **Password Managers** to generate and securely store credentials.
* **Regular Rotation** of passwords for critical systems and services.

### 3. Monitoring and Alerts

* **Login Monitoring**: Enable alerts for suspicious logins or failed login attempts.
* **Audit Logs**: Regularly review admin account activity and changes to sensitive systems.
* **Third-Party Breach Monitoring**: Track compromised credentials using services like Have I Been Pwned.

### 4. Access Control

* **Least Privilege Principle**: Limit admin access to only the accounts and systems necessary.
* **Segregation of Duties**: Different team members handle separate critical systems to reduce risk of full takeover.
* **Immediate Offboarding**: Revoke access for departing team members promptly.

### 5. Incident Response

* **Account Lockdown**: Immediately secure or disable compromised accounts.
* **Password & Key Rotation**: Change passwords and rotate keys for all affected systems.
* **Community Communication**: Inform users of potential risks if website content or communications were altered.
* **Post-Mortem Analysis**: Determine the breach vector and prevent future recurrence.

## Summary

Credential stuffing and account takeovers are **high-risk attacks for Web3 projects**, exploiting reused or weak credentials to compromise admin accounts. By implementing **hardware-backed authentication, strong password practices, monitoring, and strict access controls**, projects can drastically reduce exposure and maintain both security and user trust.


# Periodically Revoke Permissions to Critical Assets

Maintaining tight control over access to critical project assets is a cornerstone of Web3 security. Over time, collaborators, contractors, or contributors may leave, and even trusted team members may no longer need certain privileges. Failing to revoke permissions promptly leaves your project vulnerable to insider threats, accidental misuse, or credential compromise.

This guide outlines why revocation is necessary, what assets are most at risk, and how to implement a healthy revocation and rotation process.

## Why Revocation Matters

* **Mitigate insider threats** -- Former collaborators may retain access unless permissions are actively removed.
* **Reduce attack surface** -- Exposed keys, dormant accounts, or unused permissions increase risk.
* **Compliance and accountability** -- Many industry standards (e.g., SOC2, ISO27001) require periodic access reviews.
* **Adaptability** -- Projects evolve, and so should their access controls.

## Critical Assets That Require Access Review

1. **Code Repositories**
   * GitHub / GitLab / Bitbucket organizations
   * Repository collaborators, branches, and protected branches
   * CI/CD integrations and deploy keys
2. **Smart Contract Deployment & Treasury**
   * Multisig wallets (e.g., Gnosis Safe, Zodiac, OpenZeppelin Defender)
   * Deployer accounts
   * Upgrade admin roles
   * Hardware wallets for signers
   * Custody provider accounts (exchanges, custodians)
   * Bridges and staking contracts
3. **Infrastructure**
   * Cloud providers (AWS, GCP, Azure)
   * Hosting services (Vercel, Netlify, Cloudflare, Infura, Alchemy)
   * Server access (SSH keys, Kubernetes clusters, Docker registries)
4. **API Keys & Secrets**
   * RPC providers
   * Payment processors
   * External services (analytics, monitoring, bug trackers)
5. **Operations Tools**
   * Communication channels (Slack, Discord, Telegram admin roles)
   * Project management tools (Notion, Jira, Trello)
   * Security tools (Sentry, monitoring dashboards, SOC integrations)
6. **Social & Brand Assets**
   * Twitter / X, Telegram, Discord servers, LinkedIn, Medium
   * Domain registrar accounts and DNS providers

## Best Practices for Revoking Permissions

* **Create an Offboarding Checklist** Maintain a standardized checklist to revoke all access when a collaborator leaves.
* **Use Role-Based Access Control (RBAC)** Assign access based on roles, not individuals, to simplify revocation when people change responsibilities.
* **Automate Where Possible**
  * Use tools like GitHub Actions, Terraform, or Vault to rotate keys on a schedule.
  * Employ secrets managers (HashiCorp Vault, AWS Secrets Manager, Doppler).
* **Enforce Key Rotation** Periodically rotate multisig signers, API keys, and passwords---even for active members.
* **Implement the Principle of Least Privilege** Only grant the minimum level of access required for a contributor's role.
* **Schedule Periodic Reviews** Conduct quarterly or bi-annual audits of who has access to what. Remove unnecessary permissions proactively.
* **Log and Monitor Access Changes** Keep a changelog or use services that track access revocations and permission updates for accountability.

## Treasury & Financial Assets

The treasury often represents the majority of a project's funds. Any compromise here can be catastrophic. Treat access to treasury controls with the highest level of security and enforce strict revocation and rotation processes.

### Best Practices for Treasury Access Management

* **Rotate Multisig Signers**
  * Remove signers who leave the team or change roles.
  * Replace with new trusted members or rotate periodically to limit long-term exposure.
  * Document and communicate the process for signer replacement.
* **Implement Threshold Adjustments**
  * Reevaluate signing thresholds after signers are removed.
  * Ensure the threshold still balances **security** (not too low) and **operability** (not too high).
* **Use Hardware Wallets Only**
  * Require all signers to use hardware wallets.
  * Revoke access if a signer loses their device or recovery phrase.
* **Limit Direct Access**
  * Avoid keeping funds in EOAs (Externally Owned Accounts).
  * Use smart contract wallets with granular role management.
* **Separate Treasury Layers**
  * Maintain different wallets for operational expenses, payroll, and reserves.
  * Give access only to the relevant wallet, not the entire treasury.
* **Audit Regularly**
  * Conduct quarterly access reviews of treasury signers.
  * Verify each signer is active, reachable, and still trusted.
* **Emergency Rotation Protocol**
  * Define and rehearse an emergency plan if a signer is compromised or unavailable.
  * Pre-approve backup signers to avoid governance delays in critical moments.

***

## Example Offboarding Workflow

1. Remove collaborator from GitHub organization and repositories.
2. Rotate repository deploy keys and CI/CD secrets.
3. Remove signer from multisig wallet and replace with a new trusted member.
4. Rotate API keys for critical services (RPC, monitoring, analytics).
5. Remove access to cloud providers, hosting services, and dashboards.
6. Remove admin roles from communication platforms.
7. Update internal access logs.


# Emergency Response


# Handling a Security Incident

When a security issue arises, **swift and organized action** is essential to minimize damage and maintain user trust. A well-prepared [**contingency plan**](https://github.com/optimumsec/the-complete-guide-to-securing-web3-protocols/blob/main/emergency-response/establish-contingency-plan.md), defined in advance, should guide your response to ensure consistency and efficiency.

***

Follow these steps to effectively manage a security incident:

## 1. Analyze the Incident

* **Identify the Scope:** Determine the root cause, affected contracts, and the extent of the vulnerability.
* **Consult Experts:** Bring in external security researchers if necessary to assist in the analysis.

## 2. Contain the Damage

* **Pause Operations:** Use pause mechanisms to halt withdrawals, trading, or other critical functionalities.
* **Secure Funds:** Transfer vulnerable assets to a secure address or multisig wallet to protect user funds.

## 3. Communicate Transparently

* **Notify Users:** Issue a concise and clear public statement acknowledging the issue, ensuring users understand the safety of their funds is a priority.
* **Status Updates:** Regularly update users on the progress of mitigation efforts and expected timelines for resolution.

## 4. Patch and Test Fixes

* **Develop a Fix:** Quickly create a patch to address the vulnerability.
* **Test on Testnets:** Simulate real-world scenarios to validate the fix without introducing new issues.
* **Audit the Fix:** Have security researchers review the fix independently before deployment.

## 5. Migrate Data if Needed

* **Assess Data State:** Determine if the issue has affected the integrity or accuracy of stored data.
* **Plan Data Updates:** Develop scripts or processes to repair or migrate affected data.
* **Validate Migration:** Thoroughly test data migration scripts on a testnet to confirm correctness and prevent additional errors.

## 6. Redeploy and Resume Operations

* **Roll Out Incrementally:** Deploy the patched version in stages, starting with non-critical systems to monitor its behavior.
* **Unpause Safely:** Resume operations only after verifying that the issue has been fully resolved.


# Post-Incident Actions

Once a security incident has been resolved, it is critical to conduct a thorough review and implement preventive measures to avoid future occurrences.

***

## 1. Conduct a Postmortem Review

* **Analyze the Root Cause:** Identify the technical and procedural failures that led to the incident.
* **Evaluate the Response:** Review the effectiveness of your incident handling, including areas of improvement.

## 2. Communicate the Outcome

* **Publish a Report:** Share a transparent postmortem detailing the issue, the response taken, and steps to prevent recurrence.
* **Acknowledge Community Contributions:** If applicable, credit community members or researchers who helped resolve the issue.

## 3. Strengthen Security Measures

* **Upgrade Monitoring:** Enhance detection systems to better identify similar vulnerabilities in the future.
* **Improve Code Practices:** Review and update coding standards to prevent the introduction of similar issues.
* **Expand Testing:** Include new test cases in your test suite to cover the identified vulnerability.

## 4. Reassess Protocol Design

* **Emergency Preparedness:** Revisit your incident response plan and adjust based on lessons learned.
* **Multisig Governance:** Evaluate if additional privileges or decision-making processes should involve multisigs or DAOs for enhanced security.

## 5. Update Documentation

* **Response Protocols:** Reflect any new processes or changes in your official documentation.
* **Vulnerability Registry:** Log the incident in an internal vulnerability database to track recurring patterns.

## 6. Educate Your Team

* **Team Training:** Conduct training sessions to ensure all team members understand the updated security protocols.
* **Incident Learnings:** Share key takeaways with the broader team to build awareness.


