Manual Smart Contract Code Review: Step-by-Step Guide

Andre Costa
Published on:
Jun 8, 2025
Cryptocurrency
Smart contracts power billions of dollars in blockchain transactions, but they’re vulnerable. Over $5 billion has been lost to DeFi hacks, with $2.3 billion stolen in 2024 and $2 billion already gone by Q1 2025. Automated tools only catch 8–20% of bugs, leaving critical vulnerabilities - like logic errors and access control flaws - undetected. Manual reviews are essential to prevent these losses.
Key Takeaways:
25% of smart contracts have critical vulnerabilities, often missed by automated tools.
Reentrancy attacks and access control flaws are the most exploited weaknesses.
Manual reviews catch subtle issues, build user trust, and reduce financial risks.
Steps to Conduct a Manual Review:
Prepare: Gather documentation, understand the contract’s goals, and set up testing tools like Hardhat or Foundry.
Review Code Line-by-Line: Check for access control flaws, arithmetic errors, and external call risks.
Test Thoroughly: Simulate attacks (e.g., reentrancy), test edge cases, and deploy on testnets to validate functionality.
Report and Fix: Document findings, collaborate with developers on fixes, and verify changes.
Manual code reviews save projects from catastrophic losses and establish credibility. Regular audits, especially after updates, are a must for long-term security.
Smart Contract Audits, Security, and DeFi FULL Course | Learn smart contract auditing
Preparing for a Manual Smart Contract Code Review
Getting ready for a smart contract review requires careful preparation. This groundwork lays the foundation for a thorough and effective manual review, ensuring that the process addresses all critical security aspects of the project.
Gathering Documentation
Good documentation is the key to understanding a project's goals, structure, and audit scope. Start by collecting all technical materials that explain what the contract is designed to achieve. This should include the project's whitepaper, which outlines the business model and tokenomics, as well as architectural diagrams that show how the contract's components work together. Make sure to include an audit scope document that specifies the repository link, branch, and paths to the contracts under review.
Your documentation should also cover:
Functional and non-functional requirements
Assumptions or design choices made by the development team
Any non-standard practices used in the code
Unit tests are especially helpful because they reveal what the developers consider most important. Additionally, provide clear instructions for running the test suite, including any necessary configurations. With this documentation in place, you’ll be better equipped to understand the contract's logic and purpose.
Understanding Contract Goals and Logic
A clear understanding of what the contract is supposed to do helps in identifying potential vulnerabilities or inconsistencies. Start by reviewing the documentation to fully grasp the audit scope and the business logic behind the project. Compile the contracts and interact with them to ensure they operate as intended. If anything is unclear, consult with the development team to resolve ambiguities, especially regarding architectural decisions or trade-offs between security and functionality.
It’s also important to identify stakeholders and their objectives to uncover potential areas of conflict. Think about the long-term behavior of the contract, such as its upgrade path or how it might perform under changing market conditions. Lastly, analyze the test suite to pinpoint any gaps in coverage that could leave vulnerabilities undetected.
Setting Up the Development Environment
A properly configured development environment is essential for a seamless review process. Use tools like Hardhat or Foundry for compilation and testing. Hardhat offers extensive plugin support and flexible integration, while Foundry is known for its fast unit testing and compatibility with multiple blockchain platforms.
Incorporate both static and dynamic analysis tools into your workflow:
Static analysis: Tools like Slither help identify vulnerabilities and suggest optimizations, such as declaring certain variables as constants to save gas.
Dynamic analysis: Tools like Mythril simulate runtime scenarios to detect vulnerabilities.
For example, during the Geisted project review, the team at H-X Technologies used Ganache to simulate transactions without incurring gas costs. This approach uncovered an "Unchecked CALL Return Values" vulnerability. Additionally, Slither was used to recommend gas-saving changes.
Integrate tools like Solhint into your CI/CD pipeline to catch style and security issues early. Make sure your environment matches the target deployment platform, whether it’s Ethereum mainnet, Polygon, or Binance Smart Chain. Each platform has unique characteristics, such as differences in gas costs and block times, that need to be accounted for.
As Sanjiv Maewall, CTO of blockchain and digital assets at Deloitte Consulting, notes: "Each platform has its unique offerings and tradeoffs, so choose one that best aligns with your project's requirements".
Finally, set up diverse test scenarios to simulate various market conditions, user behaviors, and potential attack vectors. A well-prepared environment and a solid understanding of the contract’s goals pave the way for a meticulous and effective code review.
Step-by-Step Manual Code Review Process
With your tools ready and documentation in hand, it's time to dive into the review process itself. Following a structured approach ensures you can spot vulnerabilities while keeping the audit efficient and thorough.
Initial Assessment and Scope Definition
Start by clearly defining the scope of your audit. List the specific contracts, files, and commit details that you'll be reviewing. This not only prevents unnecessary work but also ensures you can allocate time effectively across the components.
Pinpoint the exact code to analyze. Identify the repository location, branch, and commit hash to guarantee you're working with the correct version. If you're not reviewing the entire codebase, spell out which files or folders are included, and note any exclusions to avoid misunderstandings later.
"Understanding project scope is crucial for the successful execution of any project. It defines the boundaries and deliverables of the project, ensuring that all stakeholders have a clear understanding of what is included and what is not".
Next, map out the contract's architecture and dependencies. Identify any external libraries, imported contracts, or third-party integrations that might influence security. This step helps you uncover potential vulnerabilities that could arise from how these components interact.
Create a checklist of system elements that need extra scrutiny. This could include areas like token transfers, access control mechanisms, or complex calculations. Flagging these in your audit scope document ensures auditors focus on high-risk components.
Also, document the key stakeholders and their roles within the system. Understanding who has what permissions can help you identify risks like privilege escalation. Note any assumptions or design choices, such as reliance on external price feeds or specific user behaviors, as these may introduce vulnerabilities.
Once the scope is clearly defined, you're ready to dig into the code itself.
Line-by-Line Code Analysis
Carefully review each line of code to uncover vulnerabilities and logical errors. This step demands patience and precision, but it's often where the most critical issues are found.
Start by examining state variables and their visibility settings. Confirm that variables are correctly marked as private, internal, or public, depending on their intended use. Watch for uninitialized variables, as they can lead to unexpected behaviors or security flaws.
Move on to functions, reviewing them one by one. Pay close attention to access control modifiers. Check that functions have the correct visibility settings and ensure sensitive operations can only be executed by authorized users. Missing or incorrect access control could allow unauthorized actions.
Scrutinize arithmetic operations for issues like overflow, underflow, and rounding errors. While Solidity 0.8.0 and later versions provide built-in overflow protection, older contracts or those using unchecked blocks still require manual checks. Be cautious with division operations, as they can lead to precision loss or rounding issues.
External calls are another common area of concern. Verify that the contract handles failed calls appropriately and check for vulnerabilities like reentrancy attacks.
Lastly, analyze gas usage patterns. Look for loops or operations that might consume excessive gas or hit gas limits. These checks are critical to avoid performance bottlenecks and potential denial-of-service scenarios.
After completing this detailed review, move on to testing and simulations.
Manual Testing and Simulations
Testing the contract under various scenarios often reveals issues that static analysis might miss.
Set up a local testing environment using tools like Ganache or Hardhat. These platforms let you interact with the contract in a controlled setting, avoiding concerns about gas costs or network delays. A local blockchain environment, such as Ganache or Hardhat, is ideal for thorough testing without significant overhead.
Create test cases that explore edge conditions. For example, test with zero values, maximum values, and boundary inputs. Push the contract into unusual states or call functions in unexpected sequences. Many bugs only appear under these extreme conditions.
Simulate potential attack scenarios manually. For instance, test for reentrancy by building malicious contracts that attempt to exploit your contract during execution. Check for front-running vulnerabilities by simulating transactions with varying gas prices and timings. A well-known example is the Rubixi ponzi game incident, where a naming error allowed anyone to claim ownership of the contract and withdraw funds - a mistake that could've been avoided with proper testing.
Deploy the contract on testnets like Goerli or Sepolia to evaluate its full functionality under realistic blockchain conditions. These environments let you test the contract's business logic and user interactions without risking real funds.
Verify the integration of external systems and contracts. Ensure price feeds work as expected, governance mechanisms are functional, and upgrade paths don't introduce new risks. Pay close attention to how the contract handles failures or unexpected values from external dependencies.
Finally, document all findings with detailed reproduction steps and impact assessments. This documentation helps developers address issues effectively and serves as a reference for future audits.
Identifying and Addressing Common Vulnerabilities
When reviewing code and conducting tests, pinpointing vulnerabilities is critical to ensuring a secure audit. Smart contract vulnerabilities can lead to massive financial losses and erode trust. In 2024 alone, losses from these weaknesses topped $3 billion, with valid vulnerability reports rising by 147%, of which 24% were classified as high or critical. Shockingly, around 70% of decentralized applications have been compromised due to avoidable coding flaws.
Below, we examine some of the most pressing vulnerabilities that demand attention during manual reviews.
Reentrancy and External Call Risks
Reentrancy attacks remain one of the most common and devastating threats, accounting for over 65% of recent Ethereum hacks. Nearly half of all identified vulnerabilities are tied to this issue.
These attacks occur when a malicious contract repeatedly calls back into a vulnerable contract before the initial function execution is complete. This recursive behavior allows attackers to manipulate the contract or drain its funds.
For instance, in April 2022, Rari Capital suffered an $80 million loss due to a reentrancy exploit in its borrow function, which lacked the proper Checks-Effects-Interactions pattern. Similarly, the Orion Protocol faced a reentrancy attack in February 2023, resulting in a $3 million loss across Ethereum and the BNB Chain.
To address this, during manual reviews, focus on functions that make external calls before updating internal states, such as withdrawal functions or token transfers. The Checks-Effects-Interactions pattern is a key defense - ensure checks are conducted, and internal states are updated before interacting with external contracts. Adding reentrancy guards, like modifiers or mutexes, can further protect against recursive calls.
"Reentrancy attacks remain a significant threat to the security of Solidity smart contracts. Developers must exercise caution and adhere to security best practices to mitigate these vulnerabilities."
– Ismail, CoinsBench
Another effective strategy is adopting a pull-over-push approach for fund transfers. Instead of automatically pushing payments, require users to request withdrawals explicitly. This reduces the attack surface by eliminating automatic external calls during critical operations.
Arithmetic and Logic Errors
Arithmetic errors may seem trivial but can lead to disastrous outcomes. A survey revealed that 90% of smart contracts encounter arithmetic issues, such as overflow or underflow, at least once in their lifecycle.
Integer overflow and underflow are the most frequent culprits, with over 50% of vulnerabilities linked to arithmetic errors. While Solidity 0.8.0 and later versions include built-in protection against these issues, many contracts still run on older versions or use unchecked blocks, bypassing safeguards.
One notable example is the MonoX hack in December 2021, where a logic error allowed the native MONO token to be exchanged for itself, resulting in a $31 million loss.
During manual reviews, scrutinize all mathematical operations, particularly those involving user inputs or external data. Be wary of division operations that might cause rounding errors and multiplication or subtraction operations prone to overflow or underflow. Calculations involving percentages, fees, or token distributions deserve extra attention, as subtle errors can emerge under specific conditions. Implement range checks and use data types with sufficient capacity to minimize risks. Alarmingly, 70% of contracts lack proper safeguards against these vulnerabilities.
Access Control and Authorization Flaws
Access control weaknesses are among the most exploited vulnerabilities in smart contracts, contributing to over 40% of blockchain failures.
The infamous 2017 Parity Multisig Wallet attack is a prime example. An access control flaw allowed an attacker to exploit a publicly exposed initialization function, altering the ownership state to include only their wallet address. This enabled the unauthorized transfer of over 150,000 Ethereum, worth roughly $30 million at the time.
To mitigate such risks, review critical functions for proper access control mechanisms, such as onlyOwner
modifiers or role-based restrictions. Pay close attention to initialization functions, upgrade processes, and emergency controls, as these often carry the highest privileges. Role-based access control (RBAC) systems require precise implementation to ensure roles are assigned correctly and cannot be escalated. For multi-signature wallets, ensure signature validations and threshold requirements are robust to prevent bypass attempts.
Adhering to the principle of least privilege is essential - functions should only have the permissions they absolutely need. Contracts without audits are 3.5 times more likely to suffer breaches.
"Effective access control mechanisms are an important part of blockchain security. By implementing robust controls like RBAC, ownership roles, modifiers, and multisig wallets, smart contracts can greatly reduce the risk of unauthorized access."
– VibraniumAudits
Reporting and Collaboration
Once your manual review is complete, the next step is to document the vulnerabilities and work with developers to address them. This phase builds on the findings from the code review process, emphasizing the importance of clear documentation and teamwork to ensure a thorough and effective audit.
In 2023, auditors identified over 74,000 security issues in smart contracts, with critical vulnerabilities making up about 10% of the total findings. But identifying these issues is only part of the challenge - proper documentation and collaboration are crucial for resolving them effectively.
Creating an Audit Report
An audit report serves as a roadmap for developers, helping them address security concerns in a structured way. To achieve this, your report should include several essential components that combine technical detail with actionable guidance.
Start with an executive summary that highlights the most critical vulnerabilities and provides an overview of the system's security posture. This section should be accessible to non-technical stakeholders while emphasizing the urgency of addressing high-severity issues. Follow this with an assessment overview, which explains the methodologies used during the audit and notes any limitations encountered.
The system overview should outline the smart contract's architecture, key functions, and business logic. This context is critical for helping developers understand how identified vulnerabilities could impact the system as a whole.
The heart of your report lies in the audit findings. Each vulnerability should be detailed, including its location, potential impact, and recommended fixes. Be specific - include references to exact lines of code where the issues are found. This level of precision removes any ambiguity, allowing developers to address problems quickly and effectively.
To keep the report organized, categorize findings by severity: Critical, High, Medium, Low, and Informational. For instance, critical issues might involve reentrancy vulnerabilities that could lead to drained funds, while informational findings might suggest optimizations or adherence to best practices.
For each issue, go beyond generic advice. Instead of simply stating "fix the reentrancy vulnerability", provide clear instructions, like implementing the Checks-Effects-Interactions pattern or adding specific reentrancy guards. This actionable guidance ensures developers understand how to resolve vulnerabilities effectively.
Your report should also make a convincing case for the severity of each issue. Include proof-of-concept scenarios when possible to demonstrate how an attacker could exploit a vulnerability and the potential consequences.
Verifying Fixes and Final Documentation
Collaboration doesn’t stop once the initial report is handed over. Ongoing communication between auditors and developers is key to ensuring fixes are implemented correctly without introducing new risks.
Set up a dedicated communication channel, such as a Slack workspace, regular video calls, or shared project management tools, to facilitate discussions. Encourage the development team to provide feedback on the findings and discuss the proposed solutions.
After developers implement fixes, conduct a thorough fix review to confirm that the changes resolve the original vulnerabilities without causing new issues. This step is critical - address high-severity bugs immediately. Test each fix against the original vulnerability scenario and perform additional tests to rule out unintended side effects. This review completes the cycle, ensuring the solutions are effective.
"Collaboration between developers and auditors during this phase ensures fixes are properly implemented without introducing new risks." - Blockchain App Factory
During the fix review, classify each issue as "Fixed", "Mitigated", "Acknowledged", or "Unresolved". Fixed issues are fully resolved, mitigated ones have acceptable workarounds, acknowledged issues are risks the team has chosen to accept, and unresolved issues need further attention.
Document all changes, including the rationale behind them and how the fixes address the vulnerabilities. Use version control to track these modifications, ensuring a clear record of what has been done.
For high-stakes projects, consider recommending a follow-up audit or peer review to validate the fixes and reassess the system’s security. This extra step can catch anything missed during the initial review.
Finally, update your audit report to include the status of all findings and deliver the final version to the project team. This document serves as a comprehensive record of the security review and provides a foundation for future audits.
The collaboration doesn’t end here. Encourage development teams to prioritize security as an ongoing practice, staying informed about emerging threats and evolving best practices. Regular monitoring and updates will help address new vulnerabilities as they arise, tying together the entire audit process into a continuous cycle of improvement.
Conclusion
Manually reviewing smart contract code is a key step in protecting against financial losses in the Web3 space. Billions have already been lost due to vulnerabilities in smart contracts, highlighting the need for a thorough review process.
While automated tools are useful for spotting common issues, they can't replace the depth of understanding that comes with human analysis. Manual reviews dig deeper, uncovering subtle logic errors and violations of business rules that automated scans might miss. This hands-on approach forms the backbone of trusted audit services, which are essential for securing Web3 projects.
The cost of audit services typically ranges from $5,000 to $15,000 - a small investment compared to the potential losses from an exploited vulnerability.
Take My Web3 Startup, for example. They specialize in smart contract and DApp code reviews, offering end-to-end solutions for Web3 projects. With experience in launching over 127 Web3 projects - including NFT platforms, staking DApps, and gaming applications - they understand the unique security challenges of blockchain technology. Their services include free initial code reviews and comprehensive audits, helping projects identify and address vulnerabilities before going live.
A manual code review not only enhances security but also builds trust. As the blockchain industry grows, users and investors are increasingly prioritizing projects with strong security measures. A thorough audit acts as a badge of trust, demonstrating your commitment to both security and professionalism.
It’s important to remember that security isn’t a one-and-done task. Smart contracts should be audited regularly, especially after significant updates, and ideally by multiple independent experts. Investing in manual code review today can prevent catastrophic losses down the road.
"In the rapidly evolving world of Web3, smart contract auditing isn't just a best practice - it's a critical necessity that protects digital assets, builds trust, prevents costly exploits, and ensures long-term project sustainability." - Blockchain App Factory
FAQs
Why are manual reviews of smart contract code often more reliable than automated tools for finding vulnerabilities?
When it comes to reviewing smart contract code, manual audits often prove to be more dependable because they tap into human expertise and the ability to interpret context. Skilled auditors can uncover subtle issues like complex logic flaws or specific security vulnerabilities that automated tools might miss entirely. While these tools are great at detecting known patterns of vulnerabilities, they can sometimes flag false positives or fail to catch more nuanced problems.
Manual reviews also go beyond just spotting vulnerabilities. They take a closer look at the contract’s overall functionality to ensure it aligns with the project’s goals and requirements. This level of in-depth analysis can uncover risks that automated tools might overlook, making manual audits an essential part of securing and validating smart contracts.
What are the most common vulnerabilities in smart contracts, and how can developers address them?
Smart contracts come with their own set of vulnerabilities, including reentrancy attacks, access control flaws, integer overflows/underflows, and price oracle manipulation. Tackling these issues head-on is key to building secure and reliable contracts.
Reentrancy attacks happen when external calls are made before updating the contract’s state, allowing attackers to exploit this gap and re-enter the contract maliciously. To guard against this, developers can adopt the checks-effects-interactions pattern and implement reentrancy guards.
Access control flaws occur due to poorly set permissions, which can lead to unauthorized actions. Using role-based access control (RBAC) and following the principle of least privilege can help tighten security.
Integer overflows and underflows result from calculations that exceed the limits of a data type. With Solidity 0.8.0 and later versions, these issues are automatically checked. Alternatively, libraries like SafeMath can be used for older versions.
Price oracle manipulation involves tampering with external data feeds, potentially skewing calculations such as collateral values. To mitigate this, rely on secure oracles and implement robust data validation methods.
By addressing these vulnerabilities during development, smart contract creators can enhance both the security and trustworthiness of their projects.
What steps can teams take to maintain the security of their smart contracts after completing a manual code review?
To keep smart contracts secure after an initial manual code review, it's essential to take a forward-thinking approach. Start with regular security audits and updates to tackle any new vulnerabilities that might surface due to changes in the ecosystem or updates to your code. These audits help ensure your contracts remain resilient over time.
Using automated monitoring tools is another critical step. These tools can flag unusual activity and spot potential threats early, giving you a chance to act before issues escalate.
You might also want to explore bug bounty programs. These programs invite external security experts to uncover and report vulnerabilities, adding an extra layer of protection by tapping into a wide range of expertise.
Lastly, prioritize ongoing developer training. Keeping your team up-to-date on the latest security practices and trends ensures they're ready to handle new and evolving threats with confidence.