Coming Soon

DeepThreat Review

Catch what linters miss.

AI code review built for smart contract security. Understands cross-contract interactions, provides fix suggestions, and goes beyond pattern matching into semantic understanding.

Join Waitlist → See Demo →

See it in action

DeepThreat Review analyzes your PRs line-by-line, catching vulnerabilities that traditional tools miss.

contracts/Vault.sol +42 −8
 24      mapping(address => uint256) public balances;
 25      bool public locked;
 26  
 27  +   function withdraw(uint256 amount) external {
 28  +       require(balances[msg.sender] >= amount);
 29  +       (bool success, ) = msg.sender.call{value: amount}("");
 30  +       require(success);
 31  +       balances[msg.sender] -= amount;
 32  +   }
 33  
 34  -   function setOracle(address _oracle) external {
 35  -       oracle = _oracle;
 36  -   }
 37  +   function setOracle(address _oracle) external onlyOwner {
 38  +       require(_oracle != address(0));
 39  +       oracle = _oracle;
 40  +       emit OracleUpdated(_oracle);
 41  +   }
 42  
 43  +   function flashLoan(uint256 amount) external {
 44  +       uint256 balBefore = address(this).balance;
 45  +       IFlashBorrower(msg.sender).onFlashLoan(amount);
 46  +       require(address(this).balance >= balBefore);
 47  +   }
DeepThreat Review 3 findings
CRITICAL Reentrancy in withdraw() Lines 29–31

External call via msg.sender.call is made before state update balances[msg.sender] -= amount. An attacker can re-enter withdraw() and drain the contract.

💡 Suggested Fix
-   (bool success, ) = msg.sender.call{value: amount}("");
-   require(success);
-   balances[msg.sender] -= amount;
+   balances[msg.sender] -= amount;
+   (bool success, ) = msg.sender.call{value: amount}("");
+   require(success);

Apply checks-effects-interactions pattern. Consider adding a nonReentrant modifier for defense in depth.

HIGH Flash loan price manipulation vector Lines 43–47

The flashLoan function only checks address(this).balance after callback. If the Vault's pricing depends on oracle, a flash loan borrower can manipulate the oracle during the callback, then interact with other Vault functions at manipulated prices.

💡 Suggested Fix

Add a reentrancy guard and snapshot oracle prices before the callback. Use TWAP oracles or validate price deviation bounds.

MEDIUM Missing event emission in withdraw() Line 27

The withdraw function does not emit an event. This makes it difficult to track withdrawals off-chain and may impact monitoring/alerting systems.

💡 Suggested Fix

Emit a Withdrawal(address indexed user, uint256 amount) event after the state update.

Why DeepThreat Review

🔗

Cross-Contract Analysis

Understands interactions between contracts, catching flash loan attacks and cross-contract reentrancy that single-file tools miss.

🎯

Semantic Understanding

Goes beyond regex patterns. Understands intent, data flow, and business logic to find real vulnerabilities.

🔧

Fix Suggestions

Every finding comes with actionable fixes and explanations. Not just "there's a bug" — here's exactly how to fix it.

GitHub App

Install once, get security reviews on every PR. Line-specific comments right in your workflow.

🌐

Multi-Language

Solidity, Vyper, Move — all first-class citizens. Built for the multi-chain future.

🏷️

Severity Classification

Critical, High, Medium, Low, Info — every finding is classified so you know what to fix first.

Get early access

DeepThreat Review is coming soon. Join the waitlist to be first in line.

Join Waitlist →