Morteza Khedri
August 13, 2025
6 min read

Security isn't just a phase in building a Web3 protocol, it's the foundation.
At Nex Labs, we’re building a decentralized index provider protocol that bridges crypto and real-world assets. Through our platform, users can invest in index tokens that track various sectors or asset classes. But behind the simplicity of clicking "buy" lies a complex stack of smart contracts, automation, and decentralized infrastructure that must work flawlessly and securely.
In this blog, we want to take you behind the scenes of our security journey, how we approached auditing our code, why it was important, the steps we took before even calling in external experts, and what we learned along the way. We hope our experience helps other teams, especially those just starting out, to treat audits not as a checkbox, but as a mindset.
If you're building in Web3, your contracts are likely open by design. Anyone with a wallet can interact with your system. That’s the beauty of permissionless finance, but it also makes you a target. Any vulnerability, even in an edge case, can be exploited, and the consequences could be devastating: drained vaults, frozen assets, or permanent loss of trust.
At Nex Labs, our protocol relies on fully on-chain vaults that manage real assets. These vaults are orchestrated by factory contracts, which also handle minting and burning of our index tokens. These tokens are not just numbers, they represent real user funds. A flaw in our token logic or asset management system wouldn’t just be a technical hiccup; it could be catastrophic for our users.
So we knew from day one: security wasn’t optional, it had to be embedded into every layer of our development lifecycle.
We didn’t want a one-and-done audit. In Web3, where threats evolve quickly, that’s simply not enough. Instead, we committed to a multi-layered audit strategy, combining:
This approach gave us multiple perspectives on our code. The AI tools could catch early patterns and coverage gaps. Human auditors could spot logical flaws and attack vectors. Our community could stress-test our contracts in unpredictable ways.
Each layer helped make the next one more efficient, and together, they made our code far more resilient.
Before we even brought external auditors on board, we rolled up our sleeves and got to work internally. We treated the pre-audit phase as seriously as the audit itself. The goal was simple: make sure that by the time external auditors looked at our code, they were dealing with high-quality, well-documented, and tested contracts.
We started by increasing our code coverage to over 80%, not just to hit a number, but to ensure that all critical paths, including edge cases, were accounted for. We also used fuzz testing tools like Foundry, which generate random inputs to simulate unpredictable user behavior. This uncovered bugs that we hadn’t thought of, and let us fix them early.
Tooling is your silent partner in audit readiness. We ensured that our test environment was stable and reproducible. This meant resolving things like StackTooDeep errors, which can frustrate even seasoned Solidity devs, and making sure all scripts (like Forge coverage reports) ran smoothly. When your tools are reliable, your audits run smoother.
Next, we stepped into the mindset of a hacker. We reviewed fallback mechanisms, stress-tested exception handling, and tried to anticipate what might happen under unusual conditions, like a user submitting malformed data or hitting contract limits. This helped us plug potential logic holes before they became real problems.
External libraries can be convenient, but they’re also potential attack vectors. We audited every dependency in our stack, removed unused code, and upgraded libraries to the most secure versions. This was tedious but critical. Why secure your own code if you’re importing vulnerabilities from others?
Documentation is often overlooked, but in an audit, it’s gold. We created clear architecture diagrams, explained how each contract interacted with others, and mapped out all high-privilege functions. This didn’t just help our auditors, it helped us onboard new engineers and stay aligned as a team.
We didn’t rely on "one engineer checks the other" and call it a day. We set up a structured peer review workflow, encouraged questions, and ran sessions where multiple engineers reviewed critical functions together. These conversations led to some of our most important fixes.
With all of that in place, we tagged a clean version of our codebase and created an internal audit readiness report. We had one last internal review meeting where we aligned on what we wanted to achieve from the audit, and where we expected the biggest risks might be.
We were finally ready.
After evaluating several firms, we chose QuillAudits for our main audit. Their experience with DeFi protocols, strong technical team, and reputation in the space made them an excellent fit.
The process was surprisingly collaborative, and we learned a lot about how to work with auditors, not just wait on them.
The first step was to provide detailed documentation. We shared whitepapers, architectural diagrams, and design notes so the audit team could understand our system as a whole before diving into the code.
We also filled out a comprehensive contract breakdown form, explaining the logic and function of each major contract in the repo. This helped Quill’s team understand not just what we built, but why.
One of the best decisions we made was to create a private chat channel with the audit team. This allowed for real-time back-and-forth, answering questions, clarifying design decisions, and addressing concerns as they came up. It made the process much more efficient and far less opaque.
After the initial review, Quill delivered an audit report with a detailed breakdown of findings categorized by severity. For each one, they explained the impact and suggested fixes. We immediately got to work.
Once we had implemented the fixes, we submitted the updated codebase for a second round of review. This back-and-forth gave us confidence, not just that issues were resolved, but that the auditors had validated each change.
In the end, we received a final audit report confirming all critical issues had been addressed, with detailed commentary for each resolution. We published the report publicly to ensure full transparency.
This journey taught us more than just how to pass an audit. It changed how we think about security.
Auditing isn’t a final boss you beat once. It's an ongoing practice. As we expand Nex Labs and launch new indexes, we’ll continue using the same multi-layered approach to security, AI tooling, rigorous testing, expert reviews, and community-driven validation.
We’re proud of what we’ve built so far, and even more excited about what’s ahead. If you're building something in Web3, we hope our journey helps you build safer, more resilient systems.
Because at the end of the day, security isn’t just for protocols, it’s for the people who trust us with their capital.