UnlimitedBase Finance Rug Pull

Reported loss $6K
Ethereum
Rugpull

What happened

UnlimitedBase.Finance (UBASE) has a renounceOwnership function that does not renounce anything. It is owner-only, never touches _owner, and instead adds a hard-coded 99,896,470 UBASE (_feetokens) to the caller's balance every time it is called, with no change to _totalSupply and no event. The token's whole supply was 100,000 UBASE, so one call credited roughly 999 times everything that existed.

The deployer added 99,000 UBASE and 43 ETH of liquidity at 10:05:14 UTC on 2020-12-15 (tx 0x2728c826…b4111e), called renounceOwnership() from the deployer address at 10:26:41 UTC (tx 0x16326c6e…cfb26a), and 70 seconds later swapped 99,897,470 UBASE for about 53.66 ETH on Uniswap V2 (tx 0x6188200a…86c31f). De.Fi's REKT database lists the incident as an exit scam / rug pull with $6,283 lost and describes the hidden minting as living under the renounceOwnership() function.

How it happened

  1. The constructor calls initialize(100000000000000), which sets _vOwned[_msgSender()] = initialSupply; for the deployer and makes the deployer the owner through __Ownable_init(). The token uses 9 decimals (DECIMALS = 9, passed to _setupDecimals), so the supply is 100000000000000 / 10^9 = 100,000 UBASE, all held by the deployer at the start. The contract was deployed at 00:22:20 UTC on 2020-12-15.
  2. At 10:05:14 UTC the deployer added 99,000 UBASE and 43 ETH to a new Uniswap V2 pool (tx 0x2728c826…b4111e). That left about 1,000 UBASE in the deployer's balance, assuming nothing else moved.
  3. What the code allows: function renounceOwnership() public virtual onlyOwner { _vOwned[_msgSender()] = _vOwned[_msgSender()].add(_feetokens); } with _feetokens = 99896470 * 10 ** DECIMALS. That is 99,896,470 UBASE, about 999 times the 100,000 UBASE supply. The function does not clear _owner, so the deployer stays owner (the contract still has transferOwnership and other onlyOwner functions), it does not change _totalSupply, and it has no once-only guard. balanceOf returns _vOwned[account] and _transfer moves _vOwned balances, so the credited tokens are as spendable as any others.
  4. At 10:26:41 UTC the deployer address called renounceOwnership() and the transaction succeeded, so by the code above it credited 99,896,470 UBASE to the deployer (tx 0x16326c6e…cfb26a).
  5. At 10:27:51 UTC the deployer called swapExactTokensForETH on Uniswap V2 Router 2, sending 99,897,470 UBASE into the pool and receiving about 53.66 ETH, against the 43 ETH it had added 22 minutes earlier (tx 0x6188200a…86c31f). The sold amount equals the credited 99,896,470 UBASE plus the roughly 1,000 UBASE left after the liquidity add.

Protocol details

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

Build your security review skills

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