
AuditWeb3 SecuritySolidity
A Zealynx intern's 3-Step process to a Top 10 finish in a Sherlock Audit
20 de junio de 2025•M3D
In the fast-paced world of competitive security auditing, every new project is a test. My journey had been paved with audits of a manageable scale, typically hovering around the 500 non-comment Source Lines of Code (nSLOC) mark. They were challenging, yet digestible. Then, the Burve Protocol contest appeared on Sherlock, and the landscape shifted dramatically. It was a 4,192 nSLOC giant with an 80,500 USDC prize pool to match. The scale was intimidating, but the opportunity was undeniable.
I'm proud to say I finished in 8th place, identifying 3 of the 9 total findings. But this success story isn't about a lone auditor wrestling with a complex codebase in isolation. It's a testament to a powerful combination: a systematic personal methodology, modern tooling, and—perhaps most importantly—the invaluable guidance I received through mentorship. The support from my mentor, Carlos (bloqarl) at Zealynx Security, was absolutely fundamental to this achievement, turning potential roadblocks into stepping stones.
This article is a breakdown of that journey. It's less about the vulnerabilities themselves and more about the process—the strategies, the tools, and the collaborative spirit that made this result possible.
Part 1: Taming the Beast - A Strategy for Large Codebases
Facing a codebase eight times larger than anything I'd previously tackled, the first hurdle was purely psychological. The "divide and conquer" strategy is well-known, but applying it effectively requires a deep understanding of the system's architecture. This is where I hit my first major learning curve and where mentorship proved to be a game-changer.
Demystifying the Diamond with a Guiding Hand
Burve is implemented using the EIP-2535 Diamond Standard. This was my first direct contact with a diamond contract, and frankly, the initial complexity was daunting. I could see that the standard used a single proxy contract to delegate calls to multiple logic contracts ("facets"), but understanding the nuances of its storage, its upgrade patterns, and its potential attack surface felt like a steep hill to climb.
This is where the power of mentorship became crystal clear. Carlos (bloqarl) from Zealynx Security, provided crucial insights and resources that demystified the Diamond Standard. Instead of spending days piecing it all together from documentation and articles alone, his guidance accelerated my understanding of how the proxy worked and how to approach auditing its facets. This support was fundamental; it transformed what could have been a multi-day roadblock into a strategic advantage.
With this newfound clarity, the path forward was clear:
- Understand the Core Diamond: Guided by Carlos's insights, I first focused on the proxy logic itself—how facets were managed and how storage was shared.
- Isolate the Facets: I then treated each facet as its own mini-protocol. The
VaultE4626
facet, the swapping logic, and other components could be analyzed in near isolation. This masterstroke, enabled by mentorship, turned the 4,192 nSLOC monster into a series of smaller, more familiar ~500 nSLOC audits.
That initial time investment, supercharged by expert guidance, was invaluable. The next time I face a Diamond contract, I'll be ready to dive straight into the security research, armed with confidence and a proven methodology.
Part 2: The "Research" in Security Researcher - Finding the Critical Hit
The single biggest payout came from a finding that wasn't discovered by staring at the code for hours, but by researching the components the code was built upon. The job title is Security Researcher, and this experience hammered home the importance of that first word.
The Power of Knowing Your ERCs
I have a fascination for Ethereum Request for Comments (ERCs). They are the building blocks of DeFi, and understanding their nuances, features, and, most importantly, their common pitfalls is a superpower for an auditor. The Burve protocol utilized an ERC4626 vault, a standard I had previously studied.
One particular vulnerability associated with ERC4626 had always stuck with me: the first deposit/inflation attack. My research process was simple:
- Identify the core, standardized component:
ERC4626
. - Actively recall and research known vulnerabilities associated with that standard.
This led me back to an exceptional three-part series by Arbitrary Execution on Medium, which I consider required reading for anyone working with tokenized vaults:
- Shared Vulnerabilities Between ERC-4626 Vaults And Vault-like Contracts (Deep Dive Part 1)
- Shared Vulnerabilities Between ERC-4626 Vaults And Vault-like Contracts (Deep Dive Part 2)
- Shared Vulnerabilities Between ERC-4626 Vaults And Vault-like Contracts (Deep Dive Part 3)
Armed with the knowledge from these articles, I wasn't just reading code; I was actively hunting for a specific pattern. I checked if the Burve implementation of the wrapper around the underlying vault had mitigations for this known inflation attack. It did not.
The Finding: Attacker can steal user funds via ERC4626 inflation attack on underlying vault The wrapper contract calculated shares to mint based on thetotalAssets
of the underlying vault. An attacker could directly transfer assets to the underlying vault, artificially inflating thistotalAssets
value without minting any new shares. When a victim then deposited, their funds would be valued against this inflated total, causing them to receive far fewer shares than they should (often zero). The attacker could then withdraw their small initial stake, claiming a disproportionate amount of the underlying assets, including the victim's funds.
This discovery reinforced a core principle: You don't have to find every bug from first principles. Stand on the shoulders of giants by studying the research of others. My curiosity now leads me to investigate if standard implementations, like those from OpenZeppelin, have since integrated default mitigations for this well-known issue.
Part 3: Hands-On Discovery - Finding Logic Flaws with Modern Tooling
While off-chain research landed the critical find, two other medium-severity findings were unearthed through a more hands-on, interactive approach to the code. For this, I heavily relied on two powerful techniques: LLM-assisted code exploration and high-verbosity testing with Foundry.
Using LLMs as a "Vibe Check" and Test Generator
I use AI tools like Cursor and Windsurfer not as automated bug finders, but as incredibly fast assistants that help me "vibe test" the code. My process looks like this:
- Isolate a complex function: I'll find a function with intricate logic, like the
commit
function in the vault facet. - Ask the LLM to explain it: I'll prompt it with, "Explain this function to me step-by-step, as if I were a junior developer."
- Generate a test stub: I'll then ask, "Write a basic Foundry test function that calls this
commit
function with a deposit and a withdrawal."
The generated code isn't always perfect, but it's a starting point that saves me minutes of boilerplate. It makes the code less abstract and more tangible, showing me exactly how to interact with it. It was during this process that an LLM helped me spot a subtle but critical logic flaw.
The Finding: Contract logic flaw will mismatch internal and external vault shares, potentially trapping user funds. In thecommit
function, when withdrawals were greater than deposits, the code was supposed to calculate the net withdrawal amount. However, it incorrectly zeroed out theassetsToDeposit
variable before subtracting it fromassetsToWithdraw
. This meant the contract always withdrew the gross amount from the external vault, burning more external shares than its internal accounting tracked, leading to a slow desynchronization that would eventually trap user funds.
The Power of High-Verbosity Tracing with Foundry
For the final vulnerability, the credit goes to Foundry's powerful logging capabilities. After using an LLM to quickly stub out a test, I run it with maximum verbosity:
foundry test -vvvv
. This command provides a full execution trace, showing every single state change, variable assignment, and internal call.The Finding: Zero Tax Exploitation in Withdrawal Function The trace showed the contract correctly calculating the tax amount to be deducted from a withdrawal. However, in a subsequent step, this calculated tax was never actually subtracted from the final amount sent to the user. They received their full, pre-tax withdrawal amount, effectively draining the protocol of funds that should have been collected as fees. The flaw was plain as day in the-vvvv
output.
This method transforms auditing from a static analysis of code into a dynamic analysis of its execution, often revealing logical errors that are easy to miss when just reading.
Part 4: Lessons from the Shadows - What the Missed Vulnerabilities Taught Me
Placing 8th was a great result, but a crucial part of my growth process is to humbly review the final audit report and analyze the vulnerabilities I didn't find. These misses are not failures; they are invaluable lessons that forge new mental models and become foundational "breakpoints" to check for in every future audit.
New Breakpoint #1: The Silent Killer of Cumulative Precision Errors
One missed finding involved a silent rounding attack in the reserve's share calculation. Small, seemingly insignificant rounding errors in a function that could be called repeatedly (
trimBalance
) could be exploited to gradually inflate a share counter, eventually leading to an overflow and destabilizing the entire reserve's accounting.- The Lesson: My focus on math-related bugs has often been on single-transaction overflows or glaring division-by-zero errors. This taught me to look for a more insidious class of bug: the cumulative precision error. From now on, any proportional arithmetic, especially involving division within a function that can be called repeatedly, is a major red flag. My new mental checkpoint is: "What happens if this calculation is off by just one wei? Can an attacker repeat this action a thousand times to turn dust into a fortune?"
New Breakpoint #2: Questioning Oracles and When External Dependencies Fail
Another vulnerability I missed stemmed from a flawed assumption about an external dependency. The protocol logic assumed that a
withdraw
and subsequent deposit
to an underlying vault would always net out perfectly. However, it didn't account for the scenario where the underlying vault might temporarily disable withdrawals. In this "unhappy path," the protocol's internal logic would proceed incorrectly, leading to protocol fees being wrongly sent to users.- The Lesson: A contract can be perfectly secure in isolation but dangerously flawed in its interactions. This taught me to rigorously audit the seams between contracts. My new mental checkpoint is to treat every external call as potentially hostile or unreliable. I will now systematically ask: "What happens to my protocol's state if this external call reverts? If it's paused? If it returns 0? If it returns an unexpectedly high value? Does my contract handle every one of these edge cases gracefully?"
New Breakpoint #3: Thinking Like an Economist to Uncover Flawed Value Models
The most insightful miss was a high-level economic design flaw. The protocol used a single, fungible
ValueToken
to represent ownership across multiple, separate liquidity pools ("closures") that held different assets and had different valuations. This created a massive arbitrage opportunity: an attacker could mint cheap ValueToken
shares from a low-value or crashed pool and then use them to redeem valuable assets from a healthy, high-value pool, draining it at the expense of other LPs.- The Lesson: This vulnerability wasn't in a single line of Solidity; it was in the protocol's fundamental economic model. It taught me that I must periodically zoom out from the code and analyze the system as an economist. My new mental checkpoint is to challenge the very concept of value within the protocol: "Is this token that represents value truly fungible? Can value be illicitly transferred between pools that are supposed to be separate? Am I auditing the code, or am I auditing a tiny piece of a complex financial machine with incentives I haven't fully mapped out?"
Final Thoughts: The Road Ahead
This audit was a significant milestone, reinforcing that success in this field is a blend of individual skill and community strength. My key takeaways are now richer:
- Embrace Large Codebases with Strategy: Break down monoliths using their own architecture.
- Seek Guidance When Needed: Mentorship isn't a crutch; it's an accelerator. The support from Carlos and Zealynx Security was instrumental in overcoming the initial technical hurdles.
- Research Is Your Highest ROI Activity: Know the standards and their weaknesses.
- Get Your Hands Dirty with Tooling: Use modern tools to dynamically test the code's execution path.
- Build Your Library of Breakpoints: Treat every missed vulnerability as a lesson.
While individual effort is crucial, this experience taught me that growth in this field is rarely a solitary pursuit. The support from communities like Zealynx Security and mentors like Carlos is a force multiplier, turning daunting challenges into achievable milestones and profound learning experiences.