Sample report: The DAO
The DAO was a crowdfunded investment contract on Ethereum. In June 2016 an attacker used a reentrancy bug in its split function to drain about 3.6 million ETH, and the community answered with the hard fork that split Ethereum and Ethereum Classic. Below is the unedited automatic report scau.pro produced for the contract's verified source code.
- Network
- Ethereum
- Language
- Solidity
- Contract
- 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413 (Etherscan)
Automatic first pass, shown without edits. The findings are generated by AI and are not verified by an auditor: some may be false positives, and some issues may be missed.
12 findings
-
Critical: 1
-
High: 3
-
Medium: 6
-
Low: 1
-
Info: 1
-
Reentrancy in DAO.splitDAO(): external call to newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) occurs before the caller's balance/totalSupply are zeroed, allowing recursive split calls to move funds multiple times. This is the classic DAO vulnerability pattern.
-
Reentrancy in TokenCreation.refund(): msg.sender.call.value(weiGiven[msg.sender])() is performed before totalSupply, balances and weiGiven are updated, allowing repeated refunds during fallback reentry.
-
executeProposal() performs arbitrary external call p.recipient.call.value(p.amount)(_transactionData). Although proposal is closed afterwards, this enables arbitrary code execution/reentrancy into DAO functions during execution and should be guarded.
-
DAO.newContract() can transfer the entire DAO balance to an allowed recipient if invoked via a passed proposal to address(this). This intentional upgrade path is highly privileged and can drain all funds if governance/allowed-recipient control is compromised.
-
Reentrancy risk in ManagedAccount.payOut(): uses _recipient.call.value(_amount)() before returning. Callers relying on post-call accounting may be exposed; prefer checks-effects-interactions or withdrawal pattern.
-
Potential arithmetic underflow in divisor(): closingTime - 2 weeks / closingTime - 4 days can underflow when closingTime is less than those durations, producing incorrect pricing logic in Solidity <0.8.
-
Multiple arithmetic operations use unchecked uint math in Solidity <0.8, e.g. token = (msg.value * 20) / divisor(), balance additions, totalSupply additions, minQuorum calculations. Overflows/underflows can corrupt token balances and voting math.
-
ERC20 approve race condition: approve() directly changes allowance from a non-zero value to another non-zero value, allowing a spender to front-run and spend both old and new allowance.
-
Unchecked low-level call in TokenCreation.createTokenProxy(): extraBalance.call.value(msg.value - token)() return value is ignored, so ETH forwarding failure is not handled and accounting can diverge.
-
DoS risk from push payments: executeProposal() throws if p.creator.send(p.proposalDeposit) fails, so a proposal creator contract with reverting fallback can prevent successful proposal execution.
-
Unchecked return value of send() when refunding proposal deposit if recipient is no longer allowed: p.creator.send(p.proposalDeposit) return value is ignored and proposal deposit can become stuck/lost in accounting.
-
Info SWC-703 Contract.sol, line 1
Use of deprecated Solidity 0.4-era constructs: throw, constant, sha3, unnamed fallback functions, and low-level call.value. These reduce maintainability and lack modern safety features such as automatic overflow checks.
Need more than a first pass?
A tool can't sign off on your contract. Our auditors can: a manual smart contract audit with a report you can show investors and exchanges.
Created by H-X Technologies. Security audits and penetration tests for banks, energy companies, exchanges, etc.
Need more than a first automatic pass or a report you can show investors and exchanges? Our experts can audit your smart contract manually. Request a thorough audit.
Trusted by:
More free tools from H-X: ISO 27001 and TISAX self-assessment, IT/OT audit cost calculator.
Building software for clients? Manage infrastructure? Need pentest or compliance? Partner with H-X.