# GDS: reward claim logic mints GDS from USDT, drains pool

GDS reward contract's pureUsdtToToken minted GDS from USDT without burning, letting attacker flash-loan, add liquidity, and drain $180k via repeated reward claims.

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

**Target:** GDS token reward contract and PancakeSwap pair
**Root cause:** The ClaimReward contract's transferToken() calls GDS.pureUsdtToToken(100e18) to mint GDS and sends it to the dead address, but the function likely converts USDT to GDS without actually taking USDT, allowing free GDS generation. The withdraw() function then transfers accumulated pair LP tokens to the owner, enabling repeated extraction.
**Steps:**
1. Attacker flash-loans USDT from SwapFlashLoan and DODO.
2. Swaps USDT to GDS and adds liquidity to the GDS/USDT PancakeSwap pair.
3. Deploys 100 ClaimReward contracts, each funded with GDS and LP tokens.
4. Each ClaimReward.transferToken() calls `GDS.pureUsdtToToken(100 * 1e18)` and transfers resulting GDS to dead address, then sends pair LP tokens to owner.
5. After 1100 blocks, attacker calls withdraw() on each contract, which transfers GDS to dead address and LP tokens to owner, then swaps remaining GDS to USDT.
6. Repays flash loans and keeps profit.
**Exploitation:** Attacker used flash loans to acquire large USDT, added liquidity to manipulate GDS price, deployed 100 reward contracts that each called pureUsdtToToken to generate GDS without cost, then withdrew LP tokens and swapped GDS for USDT, netting ~$180k.
**Escalation:** Repeated the reward claim across 100 contracts to amplify extraction.
**Insight:** Look for reward or conversion functions that mint or transfer tokens based on a calculation without actually collecting the input token; test if calling them repeatedly or from multiple contracts yields free value.

