# Unverified proxy: signature missing victim binding drains USDT

Signature only bound a 5-minute timestamp bucket and recipient, not victim or amount, letting attacker drain any approved victim's USDT via proxy.

- Payout: Real-world hack
- Severity: high
- Program: unverified
- Credited: DeFiHackLabs
- Disclosed: 2025-07-17
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-07/unverified_8fd3_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250717-unverified-8fd3
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm technique:source-review vuln:access-control vuln:signature-replay

**Target:** EVM smart contract proxy on BSC
**Root cause:** The signature verification only authenticated a 5-minute timestamp bucket and recipient address, omitting victim, token, amount, caller, proxy, chain, and nonce. The contract then used the unauthenticated victim and amount in transferFrom.
**Steps:**
1. Identify a victim with USDT allowance to the proxy (ENTRY_STATE_PROXY).
2. Obtain a valid signature for keccak256(abi.encodePacked(timeBucket, attacker)) where timeBucket = (block.timestamp / 300) * 300.
3. Call the proxy selector `0x97e76253` with (victim, attacker, signature).
4. Proxy reads victim's USDT balance and calls transferFrom(victim, attacker, balance).
**How found:** Likely from decompiling the unverified implementation and noticing the signature digest only included timeBucket and recipient, while victim and amount were separate parameters.
**Exploitation:** Attacker used a pre-existing valid signature for a 5-minute time bucket and their own address as recipient. They called the vulnerable proxy with the victim's address and the signature, causing the proxy to transfer the victim's entire USDT balance to the attacker using the victim's allowance.
**Insight:** When auditing signature-based authorization, always verify that all security-critical parameters (victim, amount, token, nonce, chain, contract) are included in the signed digest. Missing bindings allow replay with arbitrary values.
