Often projects do not carry out cross-checks due to the limited budget and the high cost of an audit - but there is a way.

Audit costs can vary anywhere from $8,000 to even as much as $100,000+ depending on the amount of code, its complexity, the number of engineers engaged, the company that conducts the audit, etc.

Now let's imagine that we want the same code to be checked by 2-3 independent companies to minimize the risk of missing vulnerabilities. The cost might triple.

An audit with an example cost $25,000 with 2 additional cross-checks could cost $75,000.

This is not a solution that can be afforded at an early stage of the project. Especially now, when it is not easy to raise the funds.

Smart contract audit

The audit has the key advantage that it most often checks the entire code and all integrations. During the service, we not only look for vulnerabilities but also think about how to do something better to improve security and minimize the risks.

Tincho summarized this really well in a few points:

  • An audit is more than whether or not you find all the bugs
  • An audit should provide value regardless
  • Every auditor on the planet who is worth their salt doesn't have a perfect track record

When auditing, you should be not only finding bugs but:

  • Teaching best practices
  • Helping them understand attack vectors
  • Showing effective testing practices

An audit should add value to the team regardless of the number of vulnerabilities found. This is the time when knowledge and thoughts are exchanged. The project has a chance to increase its security awareness and become better at designing future features.

However, the cross-checks goal is different. It aims primarily to minimize the likelihood of significant vulnerabilities being missed. If it can be in the form of an audit – great.

But if the budget does not allow us to do it - should we not carry them out?

Key threat based cross-checks

There is a cheaper way to cross-check within a predetermined budget and it can still be very effective. How? By focusing on key threats and scenarios that allow them to be realized.

After the first audit, you should find a section in the report that contains the attacker's key objectives. It may look like this:

Potential attackers’ goals:

  • Steal collateral from the pool.
  • Exceed the established rules to get bigger rewards, fees.
  • Exceed the established rules to unleash tokens earlier.
  • Steal tokens from Vault.
  • DoS protocol.
  • Give the protocol a bad reputation.
  • Steal protocol fees.
  • Take control of the protocol.
  • Lock users’ funds in the contract.

Based on this, the documentation provided, and conversations with the team, we are able to create a list of attack scenarios focusing on the most significant risks. The list should contain very detailed and verifiable scenarios such as:

Example verifiable attack scenarios:

  • Verify that it is not possible to "withdraw more than deposited" by '"re-entering the Vault and rebalancing during withdrawal".
  • Verify that it is not possible to obtain larger shares by front-running and transferring funds to the address of the pool that is being created.
  • Verify that it is not possible to "DoS the distribution of income" by "reverting on withdrawals".
  • Verify that it is not possible to steal protocol funds via withdraw function with reentrant behavior by specifying the malicious input parameters.

Changing the way we define the scope of tests from components to specific scenarios brings many benefits. Auditors stop focusing on a comprehensive approach for which there is a time during the audit. They focus all their attention on key threats.

This significantly increases the flexibility and possibilities of adapting the offer to the customer's needs. We can not only prepare a list of scenarios that are worth covering within a predetermined budget but also choose which of them are to be verified and which the team will cover themselves to reduce the final cost.

However, this is not the end of the advantages of this approach. In addition to the fact that you have full control over the price, you also gain: full control over what is actually verified, ready to use scenarios for unit tests (abuser stories), and great input for further property-based security (fuzzing, formal verification).

The differences summarized

Audit cross-checkKey threat based cross-check
Costfull audit pricepredetermined budget
Price range$8 000 - $100 000+$4 000 - $10 000+
ScopeWhole codebaseSelected scenarios
ResultsAll kinds of vulnerabilities and recommendations. Increasing security awarenessVerification of high-impact scenarios
GoalRisk minimization and a comprehensive approach to increasing securityReducing the likelihood of missing high-impact vulnerability
When to use itLarge TVL, reasonable security budget, lack of upgradeability
  • Before the release
  • Significant changes
  • Cross-check
Small TVL, upgradeable smart contracts, relatively small budget
  • Significant changes
  • Cross-check
DisadventagesPriceLimited scope

If you are still wondering what is the best solution in your situation, let us help.

  • Did you like this article? Be sure to share it on social media!

Composable Security 🇵🇱⛓️ is a Polish company specializing in increasing the security of projects based on smart contracts written in Solidity. Examples of projects that have trusted us are market leaders such as FujiDAO, Enjin, or Tellor. We are creators of the Smart Contract Security Verification Standard. Speakers at various conferences such as EthCC, ETHWarsaw, or OWASP AppSec EU. Authors of numerous publications on DeFi security. Experienced auditors operating in the IT Security space since 2016.

If you need support in the field of security or auditing smart contracts do not hesitate to contact us.

Paweł Kuryłowicz

Paweł Kuryłowicz

Managing Partner & Smart Contract Security Auditor

About the author

Co-author of SCSVS and White Hat. Professionally dealing with security since 2017 and since 2019 contributing to the crypto space. Big DeFi fan and smart contract security researcher.

View all posts (9)