In this issue of Full Stack, we’ll explore one of the most exciting audits we’ve performed this year: Cube!
Cube is a trading platform which aims to provide users with the security of a Decentralized Exchange (DEX) and the execution quality of a Centralized Exchange (CEX).
Cube achieves this by applying their cutting edge expertise in Multi-Party Computation (MPC). In this article, we’ll share some insights from our audit for builders interested in constructing complex exchange products, and for those interested in the Sec3 audit process.
While Sec3 has a relatively small team, our auditors punch well above their weight in practical experience and academic expertise. Several in our team specialize in the field of cryptography, (both in Zero-Knowledge applications and MPC), with one even having won a national cryptography championship.
Relatively few projects in Web3 are working on MPC, so we don’t get to field these skills as often as we’d like. Understandably, we were very excited to bring our abilities to bear with Cube.
(Want help with your ZK or MPC project? Reach out to a member of the team here!)
The significance of structure: building with long-term vision
Builders often rush their product to market, cutting corners for faster delivery. Sometimes this is due to funding constraints (short runway); other times, they feel pressured to deliver an MVP to appease the short-attention spans of their community, or feel FOMO during a bull market to capitalize on the favorable conditions.
The most dangerous element of this approach is that it increases the chances of security vulnerabilities being overlooked, potentially leading to the demise of the project and harm to users.
But rushing development can reduce a project’s longevity in other ways as well. For a Web3 project to weather the test of time, it needs to be structured in such a way that it is simple to improve and test. Ironically, building with this in mind is not simple, requiring time and prudent strategy.
Cube has followed this approach to the letter, being built with long-term reliability in mind. Immediately obvious upon examining the codebase was its modular architecture: rather than one broad blob of code to iterate and improve upon, Cube’s infrastructure is split into separate modules. This makes maintenance of each element easier and testing more effective, ultimately contributing to stronger security.
Building modularly is not easy of course, and comes with its own potential vulnerabilities. But these can be dealt with, as Sec3 security researcher Chengxu notes:
Initially, we had concerns that adopting a modular design approach might introduce a range of intricate challenges in authentication and authorization design. As a result, we used this as our entry point to actively seek out potential issues and conduct in-depth scrutiny.
However, we are pleased to report that the Cube project has implemented notably robust isolation strategies across various functional modules and network configurations. The successful implementation of these strategies has not only heightened the overall system security but has also enhanced the feasibility of the authentication and authorization design.
Cube's architecture not only performs excellently in its current state but also provides a solid foundation for future expansion and maintenance, making it easier to add new features or modules while reducing the risk of interference with existing code. Furthermore, thanks to Cube's excellent architecture design, we can conduct incremental audits more easily without worrying about impacting the development progress of Cube. In summary, Cube's software architecture design fully embodies the essence of professional software engineering, providing strong support for the system's performance, maintainability, and scalability.
While a modular approach may not be best for every Web3 project, it represents a ‘gold-standard’ for complex projects with multiple functions. Budding builders, take note!
New territory, old risks
Cube’s hybrid mix of centralized trading and decentralized custodianship provide unique benefits to users. But every foray into uncharted territory comes with its own risks, both new and old.
For senior Sec3 security researcher Q7 (who just returned from winning the Sui track of the MetaTrust CTF), one should always begin with the mathematics:
Based on my extensive auditing experience, whether for exchanges or DeFi contracts, mathematical computation modules form the foundation of a project's security. Any minor errors, precision loss, or overflow issues in these calculations can pose significant security threats to the project. As a result, I focused first on Cube’s "uint" module.
As I delved deeper into this section of the code, I was pleasantly surprised by its high quality. This module boasts a comprehensive suite of unit tests, and not only are there almost no security issues, but the code has also undergone numerous optimizations. For instance, it utilizes the Karatsuba algorithm for multiplication.
Given our extensive experience in Rust development and auditing, we paid particular attention to code blocks related to "unsafe" during audits. Cube has excelled in this regard as well. We did point out that some portions of "unsafe" code violated the experimental stacked borrows rules, although this potential undefined behavior currently does not pose any issues. The Cube project promptly addressed these issues, implementing fixes and adding corresponding Miri tests to detect similar issues.
Compared to other traditional blockchain exchange projects, Cube, which is built upon MPC (Multi-Party Computation), is more sensitive to on-chain data. On-chain data serves as a new data entry point without standard validation patterns. Therefore, we focused on analyzing Cube’s processing flow for on-chain data during the audit and made some targeted recommendations.
Seeking a perfect match…ing engine
Key to any Central Limit Order Book (CLOB) is its matching engine: the system that connects buy and sell orders together to create market equilibrium.
Following our previous in-house experience auditing other exchanges, matching engines should be examined from two perspectives, as Sec3 security researcher Liriu explains:
1. Matching Model
As a trading matching engine based on the order book model, Cube has implemented three types of order types: limit price, market limit price, and market price with protection.
These three matching modes require different ‘sanity-check’ items. We started by examining the consistency between the matching mode and submit parameters to audit the core business logic of Cube’s matching engine.
Based on our experience auditing blockchain exchange projects, in order to improve query efficiency, matching engines generally implement two layers (or even more) of storage and cache. Cube is no exception; it implements snapshots for fast querying of order status and uses position and book storage to store position data and order data respectively.
The risk of using snapshots is that inconsistencies or exceptions during the update process can lead to serious consequences like system crashes. Recognizing this, Cube has built safeguards against this at the foundational level, co-ordinating the update process between storage and cache across multiple global semaphores.
2. Data Flow
Cube's architectural design decouples the matching engine into a separate module that provides APIs externally. Starting from the interface data flow assumption that assumes complete control over interface parameters, we examine unexpected actions in control flow.
We found that Cube uses both flatbuffers and SBE as serialization protocols for inter-module communication. This approach takes into account both the maintainability of the project and the special requirements of financial projects for program execution speed. We also paid special attention to the synergy between these two serialization methods during the audit.
Referring back to the modular design architecture mentioned earlier, the matching engine is its own module in Cube’s architecture, allowing it to be tested and updated independently of other modules. The auditing team were impressed by how such a fundamental element of the architecture can be kept isolated, as Chengxu explains:
One element of the matching engine that impressed the team was the use of the EventBus design pattern in the price matching module, web backend, and database. This event-driven architecture not only achieves loose coupling between various modules but also enables the system to efficiently handle multi-threaded asynchronous dispatching issues. This elegant design allows data to be transmitted between different components in an efficient and reliable manner, ensuring data consistency and integrity.
Audit conclusions
Cube presents a novel synthesis of blockchain technologies, which brings security challenges both old and new. However, one key-takeaway for builders from our audit is to focus on one of the most basic aspects of software development: structure.
While a simple concept to grasp, building with long-term robustness in mind can be hard to execute for teams short on time or runway. However, it will ease the process of improving your product, and allow you to secure it more efficiently as well. These are compounding effects which will increase your chances of success and stability after launch.