Bistroo Hack

Reported loss $47K
Other

What happened

On May 7, 2022, around 21:20 UTC, an attacker drained Bistroo's BIST single-asset staking contract on BNB Smart Chain with a re-entrancy attack. BIST reached BSC through pNetwork's bridge, which issues the bridged token as a BEP-777 (ERC-777-style) token. The staking contract's emergencyWithdraw() sent tokens before it zeroed the user's balance, and the token's tokensReceived() recipient hook let the attacker's contract call back in.

According to Bistroo, the attacker withdrew 1,711,569 BIST (about $47,000) from other stakers' deposits in a single transaction. The tokens were dumped right away, which crashed the BIST price. Part was swapped to BNB on BSC. Part was bridged to Ethereum and sold on Uniswap V2 for about 10.975 ETH. Bistroo said its other staking contracts were not at risk. It promised to repay affected BSC stakers their deposited BIST, plus the rewards they would have earned, on a voluntary basis, and to relaunch BSC staking with a new contract.

Attack transaction (BSC): 0x8c96b3314e30cf62bdfd4f94df38a2f040e171e849208b328dcd4ac2cdbcb748

Bridge transaction (BSC): 0x01beb9667d3b91d201d6a9e2e9c0bdbf481dfd34a2314d96a2431a1886308632

Swap transaction (Ethereum): 0xb6994245bc1a0121b89cf3ec0ce7cf0b0e55b70302acc9272d5af5d1150e99f2

Attack contract (BSC): 0x70b31bb9859e88ddb3ac04bc205575992edad3fa

Attacker wallet (BSC): 0xba31058357ea2f474a2ed0d1b3f9183904ebd38a

Attacker wallet (Ethereum): 0x6ea72d536c8842646daa95d14a2fd622c258b610

How it happened

  1. The attacker deployed a contract registered as an ERC-777 token recipient, so it has a tokensReceived() hook, and used it as a staker in Bistroo's BSC single-asset staking contract. Its recorded stake (user.amount) is what emergencyWithdraw() pays out.
  2. The attack contract called emergencyWithdraw(). That function reads user.amount, sends it with pool.lpToken.safeTransfer(), and only then sets user.amount to zero.
  3. Wrapped BIST is a BEP-777 token, so the transfer calls the recipient's tokensReceived() hook before the staking contract clears the balance.
  4. From that hook the attack contract called emergencyWithdraw() again, so the same recorded balance was paid out more than once. The attacker repeated this within one transaction until 1,711,569 BIST had left the contract.
  5. The attacker sold part of the BIST for BNB on BSC, bridged the rest to Ethereum, and sold about 1,075,305 BIST for about 10.975 ETH on Uniswap V2.

Protocol details

Classification Token
Protocol Type Exploit/Other
Affected asset / contract BIST
Protocol links Website @BistrooIO

Build your security review skills

Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.