Pinned Tweet
Thanks to @flipkeygg for trusting me to audit your project. It was a pleasure working with you.
Always focused on delivering the highest-quality security service and helping clients build more secure projects.
EVMbench from @OpenAI reports the following results for agents:
Detect: ~46%
Patch: ~42%
Exploit: ~72%
This is very interesting. It suggests that agents are significantly better at exploiting vulnerabilities than detecting them in the first place.
You might ask: Isn't the real challenge detecting the vulnerability, rather than exploiting it?
But what if we took a different approach?
What if we pointed agents toward acknowledged vulnerabilities and asked them to exploit them?
Since agents perform better at exploitation than detection in this benchmark, it could be worth testing whether this approach helps uncover deeper issues in real world codebases.
Instead of asking agents to find a needle in a haystack, give them a known weakness and see how far they can go.
Good morning, guys.
This weekend, I spent a lot of time reading past exploits and new EIPs, and I realized something: the more I learn, the less I feel I know.
Web3 is one of the fastest moving industries, and staying up to date requires constant learning. It's also highly technical, with an enormous amount of information to absorb.
So don't get discouraged. You're working in one of the most challenging industries, and mastering it takes time.
Keep learning, keep working, and trust the process. The results will come.
Have a happy Monday.🫡
I really like Sundays. It's the day when I work less, recharge my batteries, and prepare my goals for the next week.
And today, it's raining, which makes it even more relaxing. 🌧️
What do you usually do on Sundays?
KyberSwap Elastic lost ~$48M in 2023 because one tick crossing was skipped.
To get it, you need 1 idea from Uniswap V3 style pools:
Each LP position adds liquidity L only inside its range.
The pool marks the edges:
+L at the lower tick
−L at the upper tick
When a swap moves the price across a tick, the pool applies that marker.
That's how it knows how much liquidity is active right now.
The attack:
1. Add liquidity L in a very narrow range.
2. Swap so the price lands just past the upper tick.
3. A rounding issue in the swap math → the pool does NOT register the crossing → L should be removed, but stays active.
4. Swap back down across the same tick
→ the pool applies the marker again → active liquidity = 2L
Now the pool prices swaps as if it had 2L.
But only L is backed by real tokens.
More liquidity = more tokens out per swap.
The extra came from the other LPs.
Auditor lesson for concentrated liquidity forks:
Check every place the price can end exactly on or just past a tick boundary.
"Price moved past the tick" and "tick was crossed" must always agree.
Solidity security lesson: never pay users with send() or transfer().
One of Ethereum's first "funds stuck" bugs came from exactly this.
King of the Ether Throne, February 2016:
1. A new king paid ETH to take the throne.
2. The contract sent compensation to the previous king with send().
3. send() forwards only 2,300 gas.
4. Some kings used Mist contract wallets, which needed more than 2,300 gas to receive ETH.
5. send() failed and returned false.
6. The contract never checked the return value.
7. The king lost the throne and his payout. The ETH stayed in the contract.
Two bugs in one line:
- a hard-coded gas limit
- an unchecked return value
Why it still matters in 2026:
- a Safe needs more than 2,300 gas to receive ETH (proxy + delegatecall)
- EIP-7702 EOAs can run code on receive
- gas costs change with forks (EIP-1884 broke 2,300-gas receivers in 2019)
The fix:
Use call, check the returned value, and always follow the CEI pattern.
Or better: let users withdraw (pull) instead of pushing payments to them.
Solidity security tip: never give a transient storage slot two jobs.
SIR trading lost its entire $355K TVL to exactly this.
How the Vault worked:
1. mint() does a Uniswap V3 swap.
2. Uniswap calls back uniswapV3SwapCallback() on the Vault.
3. Anyone can call that function, so the Vault must check the caller.
The check:
mint() stores the pool address in transient slot 1
the callback runs: require(msg.sender == tload(1)).
The bug:
At the end of the callback, the Vault wrote the minted amount into the same slot 1.
Transient storage lives for the entire tx, not for a single call. So after mint(), slot 1 no longer held the pool. It held a number the user controls.
The attack, in one tx:
1. Brute-force a CREATE2 salt until the contract address, read as a number, is an amount you can mint.
2. Call mint() with inputs that mint exactly that amount → slot 1 = your address.
3. From that address, call uniswapV3SwapCallback() directly.
4. msg.sender == tload(1) passes.
5. The callback trusts you and pays out the Vault.
An address is just a 20-byte number.
If a user can write a number into the slot you use for auth, they can become "the pool".
What I check now in every audit with tstore/tload:
- one slot = one meaning.
- clear the slot right after use.
- never auth with a value the user can influence later in the same tx.
- treat everything in transient storage as alive until the tx ends.
EIP-1153 saves gas. Used wrong, it loses the bag.
Big news for Web3 security today: OpenAI is reportedly in early talks with @trailofbits about a potential acquisition.
This highlights the growing importance of security across the tech industry, especially in Web3, where security is fundamental to building trust and protecting users.
That’s one small step for man, one giant leap for Web3 security.
Yesterday, we had a talk with @BowTiedDravee at the @yAuditDAO fellowship.
You need to check this out. He shared a ton of alpha, explaining how attackers think and covering different techniques for finding the most valuable bugs.
yBorg - Week 3 Day 2
Today’s speaker: @BowTiedDravee on “Thinking Like an Attacker.”
Use attack trees: start with the goal, work backward, and challenge assumptions until attacker control reaches something breakable.
🌶️ Hot take: AI is a gun. You still need to aim.
Watch 👇
The key to finding issues in BB is to start from the end.
Identify the impact you want to achieve, then work backward to find the paths that could lead to it and figure out how they can be exploited.
I've watched interviews, joined calls, and spoken with some of the best bug hunters. One thing that consistently stands out in their methodologies is that they start from the end and work backward.
Impact → Attack path → Root cause.
Instead of asking, "What can go wrong?", ask yourself, "How can I achieve this impact?"
I'm trying different strategies to find issues using only LLMs and manually verifying their outputs.
So far, the best approach for finding deeper issues is to take the valid impacts accepted by the BB/Contest and use them as goals for an agent, asking it to break the system using the /goal command.
At @yAuditDAO fellowship, shadow audits are being conducted to evaluate how LLMs perform in real world audits. These are the results from Sentinel's first run.
What can we learn from them?
Sentinel's precision looks promising, but recall remains the main challenge.
When Sentinel reports an issue, its findings appear reliable. However, it's still missing too many issues.
Recall could improve significantly in the second run by reviewing the leads, guiding the system with the auditor's knowledge and experience to uncover deeper issues, and adding these insights to the system's knowledge base.
The goal is to combine AI's capabilities with the auditor's expertise to find what AI would otherwise miss.
This week, I found a valid High severity issue by simply guiding the AI and asking the right questions.
I wanted to run an experiment: could AI find a valid issue with me only guiding it, reviewing its output, and asking the right questions?
The answer is yes. It found a valid High severity issue that was confirmed.
What workflow did I follow?
1. Build the context
I ran x-ray from @pashov’s skills to understand the protocol.
2. Spawn a swarm of agents
I used one agent per invariant, each with the goal of breaking its assigned invariant. An orchestrator coordinated the entire swarm.
3. Judge the findings
I validated the final findings using two independent judges.
4. Report the issue
The issue that survived validation was manually reviewed, confirmed to be valid, and reported.
I’m genuinely surprised by how capable AI is at finding a valid issue when you focus on guiding it rather than controlling every step.
Remember: It’s not the arrow, it’s the Indian.
Module 3 of @asen_sec’s series on building your own agent is here.
The judging phase is one of the most important steps. If it’s not done correctly, you can lose a true positive, which can be catastrophic.
Your judge needs to be strong enough to filter out false positives without missing true positives.
Super interesting talk by @0xFireFist. Took some notes and got some new ideas to implement on Sentinel. Thanks, boss!
🚨 2 FREE AI skills have helped hunters earn more than 5 figures in bug bounties.
In front of @yAuditDAO's yBorg Fellowship, I showed exactly how we built them and how to get the best results from them. All the ALPHA in the video below👇
I want you🫵 to be the next to earn 5 figures in bounty with pashov/skills!
I’m auditing a new and difficult codebase, and I’m trying a new approach.
I use AI to ask questions whenever I don’t understand something about the code. One time, the AI answered my question and also pointed out what could go wrong, even though I didn’t explicitly ask for it.
That gave me an idea:
Why not have the AI scan the code for potential issues while I’m using it to understand the code?
That’s what I’m doing now. Whenever I ask a question, I get the answer + a potential lead about what could go wrong. I save these leads in a Markdown file to review later.
While you’re learning and understanding the code, you’re also collecting leads that can later be turned into real issues.
2x1.
This is one of the best articles on the most common attack vectors in Uniswap v4 Hooks.
You can use it to expand your knowledge, and each section can also be used as a goal for your AI to find issues in new Uniswap implementations.
Give it a try.
santiagoib.medium.com/common…
Today I was testing the two versions of Sentinel, the old and the new, on the same codebase.
The first run with the new version showed a big improvement, but the second run surprised me with the issues it was able to find.
Stay tuned. I’ll share a comparison soon to see exactly where the new version improves.







