Smart Contract Auditor | Application Security Researcher
Twitter | Github | LinkedIn | Hackenproof | Email
Protocol Name | Platform | Total Bugs Reported | High | Med | Low |
---|---|---|---|---|---|
OrderBook | Codehawks | 2 | 1 | 0 | 1 |
Beatland Festival | Codehawks | 4 | 1 | 1 | 2 |
Last Man Standing | Codehawks | 2 | 0 | 2 | 0 |
Totals | Codehawks | 8 | 2 | 3 | 3 |
- Dates: July 3–10, 2025
- Scope: 217 nSLOC
- Role: Independent auditor
- Rank: Top 25 globally
- Contest: https://codehawks.cyfrin.io/c/2025-07-orderbook
- LeaderBoard: https://codehawks.cyfrin.io/c/2025-07-orderbook/results?lt=contest&page=3&sc=xp&sj=reward&t=leaderboard
- Full Report: Reports
Root + Impact
Normally, once an order has expired (past its deadline), it should be possible to remove the order and return tokens to the seller, freeing up storage and preventing locked funds. In the current implementation, only the original seller can cancel their expired order. If the seller becomes inactive or loses access, the expired order cannot be cancelled by anyone else, resulting in tokens being locked in the contract and permanent storage bloat.
function cancelSellOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
if (order.seller == address(0)) revert OrderNotFound();
if (order.seller != msg.sender) revert NotOrderSeller();
if (!order.isActive) revert OrderAlreadyInactive();
order.isActive = false;
IERC20(order.tokenToSell).safeTransfer(order.seller, order.amountToSell);
emit OrderCancelled(_orderId, order.seller);
}
Risk
Likelihood: High, due to seller inactivity over time Impact: Tokens permanently locked + gas/storage bloat
PoC
orderBook.createSellOrder(...); // seller loses access
// time passes...
orderBook.cancelSellOrder(orderId); // reverts for anyone except seller
Mitigation
- if (order.seller != msg.sender) revert NotOrderSeller();
+ if (order.seller != msg.sender && block.timestamp < order.deadlineTimestamp) revert NotOrderSeller();
This allows anyone to cancel expired orders and return tokens to sellers.
Root + Impact
The getOrderDetailsString()
function is meant to display order data including token symbol, but tokenSymbol
is declared and never initialized. This causes the string to always return an empty token field.
function getOrderDetailsString(uint256 _orderId) external view returns (string memory) {
Order memory order = orders[_orderId];
string memory tokenSymbol; // uninitialized
string memory status;
if (!order.isActive) {
status = "Cancelled";
} else if (order.isActive && block.timestamp >= order.deadlineTimestamp) {
status = "Expired";
} else if (block.timestamp < order.deadlineTimestamp) {
status = "Active";
}
return string(abi.encodePacked(
"Order ID: ", Strings.toString(_orderId),
", Token: ", tokenSymbol,
", Amount: ", Strings.toString(order.amountToSell),
", Price: ", Strings.toString(order.priceInUSDC),
", Status: ", status,
", Deadline: ", Strings.toString(order.deadlineTimestamp)
));
}
PoC
string memory details = orderBook.getOrderDetailsString(1);
// Output: Token field is empty
Mitigation
string memory tokenSymbol = "UNKNOWN";
try IERC20Metadata(order.tokenToSell).symbol() returns (string memory symbol) {
if (bytes(symbol).length > 0) {
tokenSymbol = symbol;
}
} catch {
tokenSymbol = Strings.toHexString(uint160(order.tokenToSell), 20);
}
This ensures meaningful output even if symbol()
fails.
- Dates: July 15–22, 2025
- Scope: 283 nSLOC
- Role: Independent Auditor
- Rank: Top 17 globally
- Contest: Beatland Festival Codehawks Page
- Submitted Full Reports:
- High
- Medium
- Rank: Top 92 globally
- Contest: (Last Man Standing Page)
- Submitted Full Reports:
- Medium
- Medium
- Repored a vulnerability in web platform for Codehawks Acknowledged by Patrick Collions Sir
- Disclosed responsibly during live contests.
- Ranked 23rd globally on Codehawks amongst Top 100 contest category for July 2025
- Cyfrin Web3 Wallet Security Mastery Course
- BlockChain Basics Course from Cyfrin Updraft
- Reported vulnerabilities in: Airtel, NASA, DRDO, Huawei, Nykaa, Blackberry, Siemens and lot more
- Platforms: Bugcrowd, HackerOne, Hackenproof, TryHackMe
- CVEs published: CVE-2025-25758, CVE-2025-25688, CVE-2025-25595
- Featured in NCIIPC Jan 2024 Newsletter (Top 15 security researchers)
- Google Hacking Database dork: https://www.exploit-db.com/ghdb/8105
- AIR 2 in FOSSx India (IIT Bombay)
- BlackHat Asia Bugcrowd CTF rank: 143
- Speaker at TenguCon Japan 2024
- CFP accepted at BSides Bloomington USA 2024