BoobsDefi Rug Pull
What happened
This is the yield-farming contract for the BOOBS token on BNB Smart Chain. Stakers deposit LP tokens into MasterChef and receive BOOBS rewards. Its setMigrator function (owner only) can point the farm at any contract, and migrate(uint256 _pid) (callable by anyone) then approves that contract for the farm's entire LP balance and accepts whatever token it returns, as long as the farm's balance of the new token equals the old balance.
A malicious migrator could take the LP tokens and hand back a worthless token, leaving stakers' deposits unbacked. The deposit fee is also owner-adjustable up to 100% per pool. De.Fi's REKT database lists the project as an exit scam / rug pull dated 2021-08-25 with no loss figure; the code shows what the owner can do, not what the owner did.
How it happened
- Users call
deposit(_pid, _amount), andMasterChefholds their LP tokens whileuserInforecords each balance. - The owner calls
setMigrator(IMigratorChef _migrator) public onlyOwner, which stores any address asmigratorwith no timelock or limit. The owner read on 2026-09-30 is 0x6e3c7b74…465b15, the same address as the deployer. migrate(uint256 _pid)ispublicwith no access check. It readsuint256 bal = lpToken.balanceOf(address(this));, runslpToken.safeApprove(address(migrator), bal);and callsmigrator.migrate(lpToken), so the migrator receives an allowance over every staked LP token in that pool and can move them withtransferFrom.- The only guard is
require(bal == newLpToken.balanceOf(address(this)), "migrate: bad");. A migrator that returns a token it controls and credits to the farm with the same balance passes this check, after whichpool.lpToken = newLpTokenreplaces the real LP token. - After that,
withdrawandemergencyWithdrawpay stakers throughpool.lpToken.safeTransfer(...)from the replacement token, not from the original LP tokens. This is what the code allows; no transaction showing a migrator being set was opened. - A second control is
set(...) public onlyOwner, which accepts_depositFeeBPup to 10000 (100%);depositthen computesdepositFee = _amount.mul(pool.depositFeeBP).div(10000)and sends it tofeeAddress. - The reward token also carries a hard-coded 20% cut:
BoobsToken.mintsends_amount * 1/5todevAddress0x6e3c7B74…465B15 and only_amount * 4/5to the recipient, whileupdatePoolcredits stakers on the full reward (accEggPerShareusesboobsReward), so the farm is minted less than it accounts for andsafeEggTransferpays out only up to its balance.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.