# MetaPoint: unrestricted approve() drains victim wallets via transferFrom

MetaPoint token's public approve() let anyone grant themselves allowance over 11 victim wallets, then transferFrom drained ~$820k in POT.

- Payout: Real-world hack
- Severity: high
- Program: MetaPoint
- Analysis by: DeFiHackLabs
- Disclosed: 2023-04-12
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-04/MetaPoint_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20230412-metapoint
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** BEP-20 token contract (POT) with public approve() function
**Root cause:** The POT token exposed an unrestricted approve() callable by anyone, which set an allowance from the caller's perspective over victim balances, enabling arbitrary transferFrom.
**Steps:**
1. Fork BSC at block 27264383.
2. For each of 11 victim addresses, call `IApprove(victim).approve()` to establish allowance.
3. For each victim, read `IERC20(pot).balanceOf(victim)` and call `IERC20(pot).transferFrom(victim, address(this), amount)`.
4. Swap drained POT to USDT then USDT to WBNB via PancakeSwap router.
**Exploitation:** Attacker called the public approve() on each victim to grant allowance, then transferFrom pulled all POT balances to the attacker contract, swapped to USDT and WBNB for ~2500 BNB (~$820k).
**Insight:** On BSC tokens, check for approve()/transferFrom helpers that lack msg.sender binding to the token owner; a public approve() that sets allowance over arbitrary holders is a direct drain primitive.

