# ETH contract handling errors

Nested revert in ETH contract execution let an attacker credit their Coinbase account without transferring funds; delegatecall was also mishandled.

- Payout: hidden
- Severity: critical
- Program: Coinbase
- Found by: ambisafe
- Disclosed: 2018-04-04
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/328526
- Library page: https://bugbountylibrary.com/r/h1%3A328526
- Tags: area:web3 domain:web3 impact:funds-loss kind:bounty platform:hackerone sev:critical tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** ETH deposit contract handling / account crediting logic
**Root cause:** The ETH contract handling code credited a user account based on contract execution state without verifying funds were actually transferred, and mishandled nested revert and delegatecall semantics.
**Steps:**
1. Deploy `InternalAttacker` contract with `internalAttack(address)` payable and `dive(address)` functions.
2. `internalAttack` calls `address(this).call(bytes4(keccak256("dive(address)")), _target)` then transfers balance to msg.sender.
3. `dive` transfers balance to `_target` then calls `revert()`.
4. Invoke via web3: `eth.contract(...).at('<address>').internalAttack(depositAddress, {gas: 300000, value: web3.toWei('0.2')})`.
5. Nested revert causes Coinbase to credit the account though funds were not transferred.
6. Second issue: deploy `InternalDelegateAttacker2` whose `internalAttack` calls `_target.delegatecall()` then transfers balance to msg.sender.
**How found:** Researcher analyzed Coinbase's ETH contract handling and identified that nested revert and delegatecall semantics were not correctly accounted for, allowing balance manipulation.
**Exploitation:** Attacker deploys a malicious contract and calls internalAttack against their Coinbase deposit address with value; the nested revert path tricks the handler into crediting the account while the contract retains/returns funds to the attacker.
**Insight:** When a custodial exchange credits deposits by simulating contract calls, test nested revert and delegatecall paths: a revert inside an inner call can leave the outer call's state inconsistent with actual fund movement.

