gm β I'm 0xSpectreSec
Smart contract security researcher
Just completed @cyfrinupdraft's auditing course and starting my journey in public
What to expect from this account:
β Vulnerability breakdowns
β Audit contest journey
β EVM & Solidity deep dives
β Progress updates
Soon I'll hit 5 years in Web3 security.
This is for everyone just starting out in the space:
- people are making $100k+ from reporting a single bug. the opportunities are insane, but it's NOT easy money
- become a nerd. literally. read code, break things, put in the hours
- learn to negotiate. being great at finding bugs doesn't automatically mean you'll be great at getting paid
- be disciplined. it takes years to become genuinely good at this
- stay curious. never stop asking WHY and HOW things work
- start by finding smaller bugs. learn to walk before chasing Criticals
- be patient. skills, reputation and money don't come overnight
- adapt fast. this industry looks nothing like it did 4 years ago
- embrace new technologies, especially AI. learn to use them instead of dismissing them
- surround yourself with smart, like-minded people. you'll learn things no course can teach you
- stay up to date with exploits, research and everything happening in the space
- learn to sell yourself. your skills mean less if nobody knows about them
- build your personal brand. a good reputation opens doors you didn't even know existed
- understand what creates REAL value
- celebrate your wins, but don't get too comfortable. take a day off, then get back to work
- respect other whitehats and builders. there's always something you can learn from them
- help people without expecting anything in return. you'll be surprised where it leads
- long-term relationships > short-term benefit
- be careful what you click. even security researchers get hacked
- never think you've learned enough. the moment you stop improving, you're falling behind
- enjoy the process. this space is so crazy that it's almost impossible to get bored
π Lineage Protocol β verifiable lineage for evolving AI agents, built on @0G_labs.
β‘ Chain β lineage registry
π¦ Storage β version manifests
π§ Compute β TEE infrastructure
π ERC-7857 β Agentic ID
Live on 0G Mainnet.
GENESIS β VERSION β VERIFY
πhttps://t.co/AUNu8kcwIY
1/ How I use AI in smart contract audits (2026)
From 2023β2026, I entered 57 contests, reached top-3 30 times, won 21 and earned $627k in prizes.
109 highs + 156 mediums. 53 of them solos.
86 private audits.
This came from reading every line and building the mental model.
Challenge 18/18 of Damn Vulnerable DeFi: Withdrawalβ
Another milestone reached! π
This journey has taken me far beyond writing Solidity. I've had to deeply understand the EVM and the mechanics behind many of DeFi's core building blocks, including:
β’ ABI encoding & calldata internals
β’ Proxies, delegatecall & storage layouts
β’ CREATE2 & deterministic deployments
β’ Flash loans & governance attacks
β’ Safe wallets & Permit2
β’ Uniswap V2 & V3 (including concentrated liquidity)
β’ Oracle manipulation
β’ Cross-chain messaging & bridge security
The latest challenge (Withdrawal) was a great exercise in bridge security, authenticated messages, and withdrawal finalization.
The only challenge left is Curvy Puppet(Challenge 17)π It's been the toughest one for me so far. I've spent a lot of time experimenting with the Curve StableSwap mechanics and virtual price manipulation, but I still haven't landed the intended exploit.
I'll keep digging until I understand exactly what's happening, once Curvy Puppet falls, it'll be 18/18.
For now, it's time to shift my focus toward auditing real-world protocols and participating in competitive audits.
#Solidity #Ethereum #DeFi #BlockchainSecurity #SmartContracts #Foundry #Audit #Web3 @tinchoabbate
Challenge 16/18 of Damn Vulnerable DeFi: Shards β
Sometimes the bug isn't in the math library. It's in how you use it.
I drained funds from the marketplace by exploiting a rounding-to-zero edge case caused by FixedPointMathLib.mulDivDown().
The bug: shard purchases calculated the payment with mulDivDown(). For very small purchases, the result rounded down to 0, but the marketplace still recorded the purchase as valid.
Here's how I thought about it:
I first bought a tiny number of shards. The calculated payment was 0 DVT, yet the purchase was added to the offer's purchase list.
I immediately cancelled that purchase, returning the free shards to the offer.
Next, I bought the remaining shards normally, paying the correct amount. Finally, I cancelled this second purchase and received a full refund.
End result: I recovered every token I paid while successfully completing the purchase flow, leaving the marketplace with fewer tokens.
The interesting lesson wasn't that mulDivDown() rounds downβthat's exactly what it's designed to do. The real vulnerability was allowing a zero-cost purchase to become a first-class accounting entry. Once the protocol treated "paid" and "free" purchases identically, its refund logic became exploitable.
Rounding is part of your protocol's economics. Every mulDivDown() and mulDivUp() decision should be treated as a security decision, not just a math helper.
@CyfrinUpdraft@PatrickAlphaC@tinchoabbate
#Web3Security #Solidity #DeFi
Challenge 15/18 of Damn Vulnerable DeFi: ABI Smuggling β
I bypassed a function selector security check without touching the authorized selector at all. I just put it where the check looks β and hid the real malicious call where the EVM's ABI decoder looks.
The bug: execute() validated permissions by reading a selector at a hardcoded byte position (byte 100) in raw calldata. It never followed the ABI offset pointer β it just assumed the selector would always be there.
But ABI encoding for dynamic types like bytes uses an offset pointer to say where the actual content begins. You control that pointer. So you control what sits at byte 100 versus what actually gets executed.
Never read security-critical values from raw calldata when you already have the decoded parameter. The ABI decoder already did the hard work β just trust it.
@CyfrinUpdraft@PatrickAlphaC@tinchoabbate
#Web3Security #Solidity #DeFi
π¨ Someone lost $999,999 in USDT after signing a phishing token approval on Ethereum. π£
victim: 0x8c949361b49320c48a51f4b1c6f9f83862530f89
tx: https://t.co/54YXrwiVBi
π§΅
Challenge 14/18 of Damn Vulnerable DeFi: Puppet V3β
TWAPs are supposed to stop oracle manipulation. And they do β for single transactions. But they don't stop time.
I drained a lending pool of 1,000,000 DVT tokens using only 110 tokens and 1 ETH, in under 2 minutes.
The bug: the lending pool priced its collateral using a Uniswap V3 TWAP over a 10-minute window. Spot price manipulation in one block doesn't move a 10-minute average much. But "not much" is relative β it depends on how extreme the crash is and how long you wait.
Here's how I thought about it:
The pool had 3 days of clean 1:1 price history baked into the TWAP before my exploit even started. I dumped all 110 tokens into the pool in a single swap. The spot price collapsed to near zero. Then I waited 113 seconds.
113 seconds out of a 600-second window = ~19% weight on the crashed price. The remaining 81% was still the old 1:1 history. But the crash was so extreme that even 19% weight on "near zero" pulled the average down far enough.
Before the swap: borrowing 1M tokens required ~3M WETH in collateral. After 113 seconds: the deposit required dropped to less than 1 WETH.
The constraint that made this interesting: the exploit had to complete in under 115 seconds total from start to finish. No room to be lazy about timing.
This is why TWAP window length matters β and why thin liquidity pools make even long TWAPs vulnerable. A larger pool would have required more capital to move the price far enough to matter within the time budget.
@CyfrinUpdraft@PatrickAlphaC@tinchoabbate
#Web3Security #Solidity #DeFi
Challenge 13/18 of Damn Vulnerable DeFi: Wallet Miningβ
This one required four completely different attack surfaces chained together β and honestly, it's the most technically varied challenge I've solved so far.
I drained 20M tokens from a deposit address and 1 DVT from a wallet deployer, all without the legitimate user ever sending a single transaction.
The first bug: storage slot collision.
TransparentProxy stores `upgrader` at slot 0. AuthorizerUpgradeable stores `needsInit` at slot 0. When the proxy delegatecalls the implementation, the EVM doesn't read by variable name β it reads by slot number. So the implementation read the proxy's `upgrader` address as `needsInit`. Since upgrader is non-zero, the "cannot init" check passed. I called init() again and authorized myself.
The second bug: CREATE2 address prediction.
20M DVT was sitting at a hardcoded address waiting for a Safe wallet to be deployed there. I had to figure out which nonce would make SafeProxyFactory.createProxyWithNonce() land at exactly that address. No deployments β just pure keccak256 math in a loop until the predicted address matched.
The third bug: authorized deployment.
With myself now authorized in the registry, I called walletDeployer.drop() to deploy the Safe wallet at the exact target address β collecting the 1 DVT reward in the process.
The fourth piece: Safe transaction signing.
The wallet was deployed with `user` as the sole owner. I had the user's private key. I signed an EIP-712 Safe transaction to move the 20M tokens out β user's nonce stayed at 0 the entire time.
@CyfrinUpdraft@PatrickAlphaC@tinchoabbate
#Web3Security #Solidity #DeFi