
Announcements
December 1, 2025What Is The Mentorship Series The Mentorship Series will track the progress of mentees under my...November 28, 2025What Is The Bug Deep Dive Series In the first place, check out the post on my introduction, if...November 26, 2025Since 2022, I’ve climbed from an anonymous contestant to top-2 on Sherlock and on Code4rena 90...Mentorship Series
January 16, 2026We finished the Panoptic contest on Code4rena. Lesson Summary: Verify pool ID packing...January 16, 2026We continued the Panoptic contest on Code4rena. Lesson Summary: Simulate full sequences ...January 16, 2026We continued the Panoptic contest on Code4rena. Lesson Summary:## Notes When the user doesn't...January 16, 2026We continued the Panoptic contest on Code4rena. Lesson Summary: There seems to be enough...January 16, 2026We continued the Panoptic contest on Code4rena. Lesson Summary: Downcasting cuts the number,...January 16, 2026We continued the Panoptic contest on Code4rena. Lesson Summary: Entry point for UniswapV4 is...January 16, 2026We continued the Panoptic contest on Code4rena. Lesson Summary: Offset is the byte position in...January 16, 2026We continued the Panoptic contest on Code4rena. Lesson Summary: Master bit manipulation first ...January 16, 2026We started the Panoptic contest on Code4rena. Lesson Summary: OZ multicall had a bug when...December 17, 2025We finished the Mento V3 contest on Cantina and went over the submitted findings. Lesson...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: When you have contracts like the...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: Do the math on the whole...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: Roundings should happen in...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: expectedAmountIn comes from...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: Whenever you see a division by a...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: Even if you found a lead/issue...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: Simao somehow smelled where...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: When fetching a price, a...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: Can Chainlink return absurd...December 17, 2025We continued the Mento V3 contest on Cantina. Lesson Summary: In such protocols, depending on...More PostsBug Deep Dives
January 18, 2026Read more...Jackpot enforces pool cap as the following: This is to ensure the following: bonusBallMax + normalBallMax <= MAX_BIT_VECTOR_SIZEPool cap does not exceed governance pool cap Otherwise, TicketComboTracker cannot properly store purchased Ticket on max bonus ball, since the following will revert...January 4, 2026Read more...The Factory.deploy function uses create2 to deploy a wallet but reverts (CreateCollision) if address already exists. Per ERC-4337, factories that use deterministic creation must return the account address even if the account was already created (eip-4337) so bundlers and entryPoint...January 3, 2026Read more...Sequence wallets support ERC‑4337 by validating signatures inside validateUserOp() in ERC4337v07. The function enforces that msg.sender is the entrypoint and then performs signature verification via an external self‑call: this.isValidSignature(userOpHash, userOp.signature). Because of this...December 27, 2025Read more...When a session call with BEHAVIOR_REVERT_ON_ERROR behavior fails, the entire execution reverts but the signature remains valid, since nonce is not yet consumed. Attackers can forge a valid partial signature from failed multi-call session, executing partial calls that were never intended to run...December 25, 2025Read more...Consider a scenario where (1) the wallet is behind the checkpointer and (2) a chained signature is used; however, bit 6 (0x40 - the checkpointer usage flag) is zero. As a result, when BaseSig.recover is called the below if-block on BaseSig.sol:88-106 will be skipped: We can see that this will...December 24, 2025Read more...Due to insufficient safeguards against price drops, liquidators receive less collateral than expected from the vault and pool, resulting in financial losses. Suppose: F-asset = FXRP1 XRP = 1 USDVault’s collateral is USDC1 NAT = 1 USDLiquidation factor = 1.05 Based on the above assumptions,...December 23, 2025Read more...Rewards obtained from FSTO through the delegation of voting power to signal providers can be stolen by the agent’s owner due to a discrepancy between the reward token’s address and WNAT’s address in the collateralPool contract, leading to the forfeiture of rewards for CPT holders. Users...December 22, 2025Read more...A collateral token may become invalid following a governance decision. In such a case, the agent is expected to switch it to another valid collateral token. However, there is a scenario where the vault owner has no incentive to perform this switch at least temporarily. During liquidation, if the...December 21, 2025Read more...To protect users against bricked positions by malicious subscriber contracts, Uniswap V4 notifier allows recovery of a reverting notifyUnsubscribe call: Conversely, in order to protect subscriber against forced failure due to insufficient user gas limit, outer call reverts if less than...December 20, 2025Read more...When ViewFacet.queryAssetBalances calculates the earnings for compounded maker, it ignores the uncollected uniswap fees: When the actual compounded maker asset is removed, the uncollected uniswap fees are added to node.fees.xCFees and node.fees.yCFees and compounded as additional liquidity. If...December 19, 2025Read more...View::queryAssetBalances is used to query how much assets an user would receive if they were to withdraw their funds at the moment. However, the value returned will be wrong as it does not account for potential JIT penalties that the position might incur. When a user removes their maker position...December 18, 2025Read more...The protocol uses the TransferHelper.safeTransferFrom(token, _currentTokenRequester, msg.sender, uint256(change)); for its token transfers. But this does not work if the token returns false for all the operations. Tokens like Tether gold will cause the transfer to always revert. Thus such...December 17, 2025Read more...When there is not enough liquidity in the node, it borrows liquidity from the parent. Since parent's liquidity equals liquidity of both children, borrowing liquidity increases the liquidity both of the current node and its sibling. This is done in solveLiq: Notice, that sibling's liquidity is...December 16, 2025Read more...Each segment in the Ammplify protocol functions as vault for compounded Makers. This makes the classic first deposit share inflation attack possible for any range which doesn't have liquidity yet: User wants to deposit liquidity into some range;There is no Ammplify Maker liquidity in some...December 15, 2025Read more...The borrow fee rate returned by the smooth rate curve is an annual percentage yield (APY), but the implementation multiplies it directly by elapsed seconds without annualizing. This treats an annual rate as if it were a per-second rate, inflating fees by roughly 31,536,000x over the intended...December 14, 2025Read more...When takers pay their fees, they pay their taker rate using the amounts of token0 and token1 based on the geometric mean price of the interval (in Data.computeBorrows): For example, if there is 1e18 taker liquidity in the [-122880..245760] range, the borrow amounts for this interval should be: ...December 13, 2025Read more...PoolLib.getInsideFees calculates inside fees when current price is inside the position range as: The issue is that this code doesn't handle uninitialized ticks. poolContract.ticks returns correct lowerFeeGrowthOutside amounts only for initialized ticks. For uninitialized ticks it returns 0....December 12, 2025Read more...When any user adds maker liquidity (via newMaker or adjustMaker), the amounts of token0 and token1 required from the user are calculated in the data.xBalance and data.yBalance, however the actual amounts spent to mint the required liquidity are never checked, the contract simply sends whatever...December 11, 2025Read more...The minimum order size check for ASK orders during order creation is ineffective, allowing the creation of a large number of economically insignificant ImmediateOrCancel (IOC) orders. During the cron-based auction, these orders are canceled and refunded, which can consume excessive execution time...December 10, 2025Read more...The XYK reflect_curve algorithm that generates passive orders is unfavorable to the pool, computing more unfavorable prices than what the actual AMM algorithm would give. The reason for this is that for instance, for bid orders, the function uses the following to determine the order size at...More Posts

