DEFIBase Rug Pull

Reported loss $379K
Ethereum
Rugpull

What happened

DEFIBase (DEFIB) is a rebasing token whose code starts with all transfers paused and gives the owner control over who may move tokens and over which address can rebase or mint shares. initialize() sets transfersPaused = true with only the owner on transferPauseExemptList, and the owner can later change the flag, add exemptions, and point monetaryPolicy at any address, which can then call rebase, mintShares and burnShares. The live record, drawing on the De.Fi listing, says DEFIBase is a fork of the Base project, that an error in calling the rebase function returned the current token price instead of the initial one, that a manual call to the price rebase method failed 280 transactions for the developers, that the Telegram chat was muted for the community, and that 696 ETH was withdrawn from the general pool in a series of transactions; victims' negative comments are listed at the Etherscan comments page of 0xfda2dca8…bac1a3.

The pool and the price logic are in contracts outside the supplied token source, and the proof tweet was not retrievable, so those events are attributed to the listing and not independently confirmed.

How it happened

  1. initialize() gives the whole supply to the owner and starts the token locked: _shareBalances[owner()] = _totalShares;, transfersPaused = true;, transferPauseExemptList[owner()] = true;. Initial supply is 5,000,000 tokens (INITIAL_SUPPLY = 5000000 * 10**DECIMALS).
  2. While paused, transfer, transferFrom, approve, increaseAllowance and decreaseAllowance all begin with require(!transfersPaused || transferPauseExemptList[msg.sender], "paused");. The check is on the caller, so a non-exempt holder cannot even approve a router and a non-exempt contract cannot pull tokens with transferFrom.
  3. The owner controls the lock: function setTransfersPaused(bool _transfersPaused) public onlyOwner, function setTransferPauseExempt(address user, bool exempt) public onlyOwner. The code allows a state where chosen addresses (for example a pool pair, as caller of transfer on buys) can move tokens while ordinary holders cannot approve or sell; whether that state existed during the incident is not shown by any opened transaction.
  4. The owner can also set the monetary policy address to any account: function setMonetaryPolicy(address monetaryPolicy_) external onlyOwner { monetaryPolicy = monetaryPolicy_; ... }. That address alone may call rebase, which changes _totalSupply by any signed supplyDelta (limited only by MAX_SUPPLY) and recomputes _sharesPerDEFIBASE = _totalShares.div(_totalSupply), rescaling every holder's balance.
  5. The same address may mint shares without limit: function mintShares(address recipient, uint256 amount) public { require(msg.sender == monetaryPolicy, "forbidden"); _shareBalances[recipient] = _shareBalances[recipient].add(amount);. balanceOf divides shares by _sharesPerDEFIBASE, so minted shares appear as a balance, and rebasesPaused (owner-set) can freeze rebases.
  6. Per the De.Fi listing, the rebase call misbehaved, the developers' manual price rebase failed 280 times and 696 ETH left the general pool; those steps run in the external policy and pool contracts and are not visible in this token's code.

Protocol details

Classification Yield Aggregator
Protocol Type Exit Scam/Rugpull
Affected asset / contract DEFIB
Protocol links Website

Build your security review skills

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