# BRA token: double-tax without sync enables skim drain

BRA token double-taxed transfers to/from its LP pair without calling sync(), letting an attacker skim the imbalanced reserves for 819 BNB.

- Payout: Real-world hack
- Severity: high
- Program: - BRA
- Analysis by: DeFiHackLabs
- Disclosed: 2023-01-10
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-01/BRA_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20230110-bra
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm technique:source-review vuln:accounting-error vuln:business-logic

**Target:** BEP-20 token _transfer tax logic and PancakeSwap LP pair
**Root cause:** The BRA token's _transfer() charges a double tax when sender/recipient is the LP pair but does not call sync() on the pair, leaving reserves imbalanced relative to actual token balances.
**Steps:**
1. Flash loan 1400 WBNB from DODO DPPAdvanced `flashLoan(1400e18, 0, address(this), "xxas")`
2. Withdraw WBNB to BNB and swap 1000 BNB -> USDT -> BRA via PancakeRouter `swapExactETHForTokens`
3. Transfer all BRA to the BRA/USDT pair `0x8F4BA1832611f0c364dE7114bbff92ba676AdF0E`, triggering double tax without sync()
4. Call `IPancakePair(BRA_USDT_Pair).skim(BRA_USDT_Pair)` 101 times to collect the imbalanced excess BRA
5. Swap skimmed BRA to USDT via `pair.swap(0, usdtAmount, address(this), "")`, then USDT -> WBNB
6. Repay 1400 WBNB flash loan and transfer profit to attacker
**How found:** Reading the token's _transfer() tax logic and noticing it charges double tax to the LP pair without calling sync(), leaving pair reserves stale and skim()-able.
**Exploitation:** Attacker flash-borrowed 1400 WBNB, bought BRA, dumped it into the BRA/USDT pair to trigger the double-tax imbalance, then repeatedly called skim() to extract the excess BRA, swapped it back to USDT/WBNB, repaid the loan and kept 819 BNB profit across two txs.
**Escalation:** Repeated skim() in a 101-iteration loop to maximize extraction from the imbalanced pair.
**Insight:** For tax/fee tokens, check whether _transfer() mutates balances of the LP pair without calling sync(); any unsynced imbalance is directly harvestable via skim().

