BlackHartBlackHart
Hacks Feed/DxSale

DxSale

May 28, 2026·BNB Chain·Privileged owner-key drain of a liquidity locker
$1.7M
total loss
StatusConfirmed
View current DxSalescore →

An attacker who controls the owner key of DxSale's old liquidity locker on BNB Chain has been draining LP tokens that more than 1,400 projects locked up as far back as 2021, including SafeMoon-linked liquidity. Around $1.74 million has been pulled out so far and roughly $2.91 million more is still exposed, out of about $7.3 million of affected positions. The locker keeps working exactly as coded. The problem is that whoever holds its owner key can move the locked funds, and that key is now in hostile hands. Proceeds were swapped into BNB and moved through more than 80 wallets, so they are effectively gone.

New DxSale products and current token toolingsafe(The drain targets the old locker, not newer DxSale products.)
Liquidity locked in the old DxSale lockerdrained(More than 1,400 positions; about $1.74M pulled so far, roughly $2.91M still exposed.)
Holders of tokens whose LP was locked heredrained(Removing locked liquidity can crash the price of the affected tokens.)
Recovery of drained fundsunknown(Funds swapped to BNB and spread across 80 or more wallets; no recovery announced.)
What the score saw

DxSale is not one of the protocols we publish a live safety score for, so we had no prior reading on it. The weakness here is the kind our model weighs heavily wherever it does apply: a contract that custodies user funds while a single live owner key, with no renounce and no timelock, can change the rules and pull the funds out. A liquidity lock is only as safe as the key that controls the locker.

Exploit anatomy

The drain runs against DxSale's liquidity locker, whose owner is now an attacker account. That account set its own code to point at a purpose-built drainer contract using a new account-delegation feature, so the locker sees every call as coming from its rightful owner. For each batch of positions the drainer drops the lock fee to one unit, creates lock records with the unlock date backdated to 1970 so they count as already expired, restores the fee, then withdraws the freed LP in a loop and routes it through wrapped BNB into BNB. The cash-out moved through a pass-through wallet and a years-dormant wallet tied to the DxSale team before fanning across 80 or more hops.

FUND FLOWROOT CAUSE / ENABLERS
Stage 1 · SOURCE
Attacker account
owns the locker
0xC4574DDE...aaFA69
delegated to the drainer
Bybit withdrawal
104 BNB gas
~ $67K, ~20h prior
Live owner key
0xC457...FA69
no renounce
Ownership takeover
owner moved to attacker ~269 days earlier, unnoticed
no timelock
EIP-7702 self-delegation
attacker account sets its own code to the drainer, so the locker sees every call as its rightful owner
Stage 2 · TAKEOVER
DxSale liquidity locker
1,400+ positions
0xEb3a9C56...53e449
~ $7.3M affected, ~$2.91M still exposed
Owner-only fund-moving functions
*changeFees*, *createLocker*, *unlockToken* gated only by onlyOwner; no multisig over user LP
Stage 3 · MONETIZATION
Withdraw LP, swap to BNB
fee set to 1, unlock backdated to 1970
0xc2efbd94...1e4718
withdraw in a loop, route through wrapped BNB
Backdated unlock accepted
lock records created with unlockTime = 68s after 1970, so positions register as already expired
Stage 4 · LAUNDERING
Pass-through + 80+ hops
1,200+ BNB, ~$763K
0x47F80D09...1F66bf
team-linked dormant wallet in the flow
No ownership-change monitoring
the quiet owner move sat undetected ~269 days; no alert on outflow either
missing control
Untouched

Safe. New DxSale products and current token tooling were not affected.

Mechanism

A single live owner key over the old locker was never renounced and not behind a timelock or multisig. With the key in hostile hands, the owner called changeFees, createLocker with unlock backdated to 1970, then unlockToken to pull the LP. Not a contract bug.

Source
blackhart.io/hacks/dxsale-locker-owner-key-drain
verified on-chainswapped to BNB, across 80+ wallets
Full forensic detail

Step-by-step reconstruction, root cause, counterfactuals, remediation, and disclosure timeline.

Exploit anatomy

1.
DxSale's liquidity locker is a single contract that has custodied LP tokens for thousands of BNB Chain projects since 2021. It still exposes owner-only functions that can change fees, create lock records, and withdraw locked tokens.
2.
Roughly 269 days before any funds were touched, ownership of the locker was quietly moved to the attacker account. On-chain the locker now reports that account as its owner. This long gap is why the takeover went unnoticed.
3.
About 20 hours before the drain, the attacker account was funded with 104 BNB (about $67K) from Bybit to cover gas.
4.
The attacker deployed a drainer contract that hardcodes the victim locker and wrapped BNB, then used a new account-delegation feature to set the attacker account's own code to that drainer. From then on the account runs the drainer logic as itself, which is why the locker accepts the calls as owner actions.
5.
For each batch of positions the drainer drops the lock fee to one unit, creates lock records with the unlock time set to 68 seconds after 1 January 1970 so they register as already expired, then restores the fee.
6.
The drainer then withdraws the freed LP tokens in a loop, pulling them out of the locker, and sells them through wrapped BNB into BNB.
7.
Proceeds move through a pass-through wallet that forwarded 1,200 or more BNB (about $763K) to the attacker, then across more than 80 wallet hops. A years-dormant wallet that researchers tie to a DxSale team wallet appears in the flow.

Root cause

DxSale's old liquidity locker is a single contract that custodies LP tokens for thousands of projects. It kept owner-only functions that can change the lock fee, create lock records, and withdraw locked tokens. That owner key was live, never renounced, not behind a timelock, and not behind a multisig. Ownership over the key moved to an attacker, who then used the normal owner functions to convert locked deposits into a withdrawable balance and pull them out. The contract did exactly what it was written to do. The failure is that a single key was allowed to keep that much authority over other people's funds. Whether the key was always the team's or was acquired by an outsider is not independently proven; the load-bearing fact either way is the live privileged key.

// Owner-only functions on the locker that move user funds
function changeFees(uint256 newFee) external onlyOwner { ... }
function createLocker(address token, uint256 amount, uint256 unlockTime, string memory logo) external { ... } // unlockTime = 68 -> 1970, already expired
function unlockToken(uint256 lockerId) external { ... } // withdraws the position

Prevention analysis

Similar incidents

Merlin DEX (2023)

A privileged role on a DeFi product was used to withdraw user-supplied liquidity, with insider or key-control attribution. Same shape: legitimate authority turned against the funds it was meant to protect.

Multichain (2023)

Custodial admin authority over locked assets was exercised to drain them. Identical risk class at the architecture level: a privileged custodial role over user funds without enough operational hardening.

EIP-7702 account drainers (2025 onward)

Same delegation primitive used here: an account sets its own code to a drainer and self-executes. Usually pointed at victim wallets; here it is pointed at a protocol locker.

Remediation

1.No public incident statement from DxSale at the time of analysis.
2.The locker is still owned by the attacker address, so there is no user-side withdraw path that bypasses the hostile owner.
3.If you have LP sitting in the old DxSale locker, treat it as at risk now; the key controlling it is hostile.
4.Recommended for any locker operator: renounce ownership after locks are configured, or place it behind a multisig with a timelock.
5.Recommended: treat fee setters, lock creators, and unlock functions on custodial lockers as fund-moving authority and gate them the same way you would a treasury.

Timeline

~2021DxSale locker accumulates LP-token locks for thousands of BNB Chain projects, including SafeMoon-linked liquidity.
~269 days Locker ownership quietly transferred to the attacker account.
~2026-05-2Attacker account funded with 104 BNB (about $67K) from Bybit.
~2026-05-2Drainer contract deployed and the attacker account delegates its code to it via account delegation.
2026-05-28Drain executed across 1,400 or more positions: fee set to 1, lock records backdated to 1970, fee restored, LP withdrawn in a loop and routed through wrapped BNB to BNB. About $1.74M pulled so far.
2026-05-28Proceeds move through a pass-through wallet (1,200 or more BNB) and 80 or more hops; a team-linked dormant wallet appears in the flow.
2026-05-28Coinsult Audits and Tahax publish on-chain analyses. Blackhart verifies the address-level facts on BNB Chain and publishes this report.
Continuous adversarial monitoring

Get your protocol scored across 12 dimensions, or request ongoing coverage.