HashFree Rug Pull

Reported loss $46K
Rugpull

What happened

HashFree is a BNB Smart Chain token that De.Fi's REKT database lists as rug pulled by its deployer, with the team taking 140.5 BNB in profit (listed as $46,000 lost). The verified source holds a function the deployer can use to credit tokens to any address without debiting its own balance, plus owner-set sell tax and per-address tax overrides.

De.Fi's listing gives this sequence: the deployer minted 10B HashFree tokens to itself in the deployment transaction (Tx 1 0x0134…573a); a few hours later a HashFree/BNB pair was created (Tx 2 0x557d…857f); and within about three hours a swap took a 140.5 BNB profit (Tx 3 0x96af…a8d2). The project deployer is 0xb4e31c77…89be05 (Address 0xb4e3…be05). These transactions could not be opened, so they are attributed to the listing.

The code shows the constructor mints the full 10,000,000,000 supply to the deployer and then sends 40% of it to the dead address (0x00000000…00dEaD), leaving the deployer 60%.

How it happened

  1. The constructor mints the whole supply to the deployer and immediately moves 40% to the dead address: _mtin(msg.sender, totalSupply_ * 10**decimals()); transfer(_deadAddress, totalSupply() / 10*4);. It then sets the initial sell tax and whitelists the deployer: _defaultSellfili = 4; and _release[_msgSender()] = true;. _release is written only here, so no function can add or remove an address afterwards.
  2. The public transfer has a branch for that address: if (_release[owner] == true) { _balances[to] += ambount; return true; }. The sender's balance is not reduced, no Transfer event is emitted, and _totalSupply is unchanged, so any amount can be credited to any address, including the liquidity pair or another wallet the deployer controls, without limit. The branch depends on _release, not on ownership, so renounceownership() would not remove it.
  3. Holders face a different path. transferFrom calls _recF(from, to, ambount); when to equals uniswapV2Pair the sale tax applies: tradefiliambount = _ambount.mul(tradefili).div(100);. The seller is debited the full _ambount (_balances[from].sub(tradefiliambount) plus _balances[from].sub(_ambount - tradefiliambount)), the fee goes to the dead address and the pair receives _ambount - tradefiliambount. The owner sets uniswapV2Pair with setPairList and the rate with upS(uint256 _value), which has no cap: at 100 a sale delivers nothing to the pair, and above 100 the _ambount - tradefiliambount subtraction reverts, so sales fail.
  4. The owner can also target single wallets. setSfili(address _address, uint256 _value) sets a tax of at least 3% on every transfer sent from that address (if (_Sfili[from] > 0) { tradefili = _Sfili[from]; }), and setMarketawcountfili(address _address, bool _value) exempts any transfer touching a flagged address from tax (return _marketawcount[from] || _marketawcount[_to];).
  5. What happened, per De.Fi's REKT database: the pair was created a few hours after deployment and the deployer wallet's swap three hours later took a profit of 140.5 BNB. The sources opened do not show how that profit was obtained, so whether the free-credit transfer branch, the tax setters or a liquidity removal was used is not established; the mechanisms above are what the code allows.

Protocol details

Classification Token
Protocol Type Exit Scam/Rugpull
Affected asset / contract $HashFree

Build your security review skills

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