Solidstate in 2024: Retro

As we close out 2024, it feels like the perfect moment to reflect on the security landscape of the ICP and share what Solidstate has accomplished this year.

In this article, we’ll walk through some key statistics, our general sentiments, concerns, and our wish list for the coming year.

2024 in Review

This year, we focused on strengthening the security of the following projects:

Currently, we’re reviewing projects from Liquity and ICPanda. These projects have ranged from DeFi protocols to user-facing wallets, each pushing us to innovate and refine our approach to auditing within the ICP ecosystem.

Some statistics

Let’s dive into the numbers to see how we did! All the figures are based on our 2024 audits.

Findings by Severity:


We identified 123 issues, averaging about 31 findings per audit. Nearly a third of these were high or very high severity.

These can be grouped into the following main categories:

  • Concurrency: Issues from async operations that cause inconsistent states.
  • Access Control: Problems with unauthorized access or improper permission settings.
  • Arithmetic: Errors in numerical calculations, such as precision loss or overflow.
  • Resource Management: Flaws in handling system resources like memory or storage, leading to leaks or exhaustion.
  • Data Integrity: Concerns about maintaining accurate and consistent data, primarily related to canister upgrades.
  • Other: Findings that don’t fit into the above categories.


Resource Management Takes the Lead: This area stood out as the largest cluster of findings by a significant margin. Interestingly, arithmetic issues were less prevalent than we initially expected, highlighting the effectiveness of our current practices in that domain.

Although the “Other” category appears large in the chart, it’s important to note that most very high, high, and medium severity findings are not included there.

But patterns!
Over the past year, we’ve observed several recurring patterns across the audited codebases. These patterns might help explain why certain categories have been more challenging to identify bugs in during production.

Concurrency

Testing multi-canister setups in an asynchronous environment is challenging. Many of the concurrency issues we found could have been detected with a more thorough set of tests that cover edge cases, particularly those related to timing. These projects often handle numerous incoming messages, increasing the likelihood of messages encountering unusual scenarios.

Unlike the EVM, where transactions are executed synchronously and the state resets if a revert occurs, the Internet Computer Protocol uses a concurrent execution engine that queues incoming messages. A single call or transaction can be split into multiple messages. Each message begins and ends with asynchronous calls, and if any message fails, the state reverts to the previous asynchronous checkpoint (the end of the last message in the same larger call).

We strongly recommend that developers consider how each message affects the state, anticipate potential inconsistencies, and implement fail-safe methods to prevent corrupted states. In short, calls are not executed atomically, even though messages are. We strongly recommend reading these (1, 2) pages. (See SS-ICROUTER-004).

Resource Management

If you haven’t already, integrating cycle drain protection and maintaining stable storage archives for your logs is crucial. This safeguards your application against potential economic vulnerabilities inherent in the ICP’s reverse gas fee model. (See SS-NFID-001)

Additionally, while the ICP allows for a substantial amount of stable storage per canister, be cautious of repetitive operations that can lead to unexpected state growth. Even if the state doesn’t reach storage limits, certain calls that interact with large data structures can exceed instruction resource limits. For example, query calls have an instruction limit of 5 billion, which is relatively easy to reach if you’re accessing and iterating through large data structures within the query method.

Arithmetic

Design choices play a significant role in managing arithmetic operations. By opting for fixed-point arithmetic calculations and deciding on the number of decimals to use, you can completely avoid the pitfalls of problematic floating-point numbers.

Fortunately, Candid supports Nat (a wrapper for big integers), allowing you to perform fixed-point arithmetic with up to 18 decimals without much concern. While it’s theoretically possible to use more decimals, 18 has become a standard for most use cases.

HTTPS Outcalls and Chain Fusion

When dealing with HTTPS Outcalls or making request calls to the EVM RPC canister, be cautious of the maximum response size and avoid hardcoding any limits. Response sizes can vary due to external factors, and hardcoding anything can cause your code to break if the response sizes change. HTTPS calls are not as reliable as you may be expecting, as servers can arbitrarily change the response size by modifying the headers or the body. There is a hard limit of 2 MiB for ingress message payloads. (See SS-ICROUTER-002)

Funding

This year, we had the chance to work with DAOs to fund audits in a pretty straightforward way. The core team kicks things off by requesting an audit and working with us to define the scope and budget. Once that’s set, we submit the proposal to the DAO for a vote.

It’s a practical, transparent approach that fits well in the ICP ecosystem. One great example is how ICLighthouse DAO funded the ICRouter audit—you can check out the details here: Accept Delivery & Completion of ICRouter Audit by Solidstate.

Looking Ahead to 2025

As we wrap up 2024, it’s hard not to get excited about what the next year might bring. There are a few areas we’re particularly eager to explore and see evolve in 2025:

Improved Documentation and Best Practices

One thing we’d love to see is better-documented code that’s compliant with best practices. Good documentation makes life easier for everyone, it streamlines onboarding for new developers and helps prevent misunderstandings that could lead to security issues. Let’s aim for clarity and consistency in our codebases.

Enhanced Testing Environments and Developer Tools

Having robust testing environments and developer tools is a game-changer. Tools similar to Foundry for Ethereum have made a significant impact, and it would be fantastic to see something like that for the ICP ecosystem. Better tools mean we can catch bugs early and improve the overall quality of our projects. Fortunately, we can do fuzz testing on Rust code but it’s hard to write PoCs for bugs that involve many async functions and different canisters.

Leveraging tECDSA Signatures and HTTPS Outcalls

We’re also looking forward to more projects on the IC making use of the tECDSA signature scheme and HTTPS outcalls. These features open the door to building chain-agnostic protocols securely, which is a big step toward greater interoperability in the blockchain space.

Wrapping Up

To everyone we’ve worked with this year: thank you for trusting us with your projects. We’re looking forward to 2025, supporting even more teams to build safer, more robust applications.

If you’re building something and want to ensure it’s secure—or if you’re passionate about blockchain security and would like to join our team—don’t hesitate to reach out. You can find us on X (@SolidStateSec)! Let’s continue making the IC ecosystem stronger together.

Nima

8 Likes