# SQTokenStaking: missing access control on transferOwnership drains staking

SQTokenStaking's unprotected transferOwnership let an attacker seize the contract, mint stakes, unstake, and drain ~$346K in SQI swapped to USDT.

- Payout: Real-world hack
- Severity: critical
- Program: SQTokenStaking
- Credited: Defi_Nerd_sec
- Disclosed: 2026-05-12
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-05/SQTokenStaking_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260512-sqtokenstaking
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm technique:source-review vuln:access-control vuln:business-logic

**Target:** BSC staking contract
**Root cause:** The staking contract's transferOwnership (and related owner-only functions like stakeOwner, withdrawalTokens, setUintArray) lacked proper access control, allowing any caller to become owner and invoke privileged operations.
**Steps:**
1. Attacker uses EIP-7702 delegation to execute attack logic from their EOA.
2. Call `STAKING.transferOwnership(attacker)` to seize ownership.
3. Approve Pancake router for SQI and call `STAKING.bind(REFERRAL)`.
4. Set stake days array to `[0]` via `STAKING.setUintArray(1, [0])`.
5. Call `STAKING.stakeOwner(attacker, amount, 1760134760)` repeatedly with large amounts (90k, 90k, 70k, 55k, 42k, 14k, 9k, 7.5k, 4k, 3k, 2k, 100 ether).
6. Call `STAKING.unstake(1..10)` to withdraw staked SQI.
7. Call `STAKING.withdrawalTokens(address(SQI), attacker, SQI.balanceOf(STAKING))` to drain remaining SQI.
8. Swap all SQI to USDT via Pancake router, netting ~346,137 USDT.
**How found:** Not described; likely identified by reviewing the contract's public functions and noticing transferOwnership and stakeOwner lacked access modifiers.
**Exploitation:** Attacker seized ownership via unprotected transferOwnership, then used owner-only stakeOwner to credit themselves large SQI stakes, unstaked them, and drained the contract's SQI balance via withdrawalTokens, finally swapping SQI to USDT on PancakeSwap for ~$346.1K profit.
**Insight:** On staking/reward contracts, check every external function for missing onlyOwner or role checks—especially ownership transfer, stake crediting, and token withdrawal functions that can be called directly.
