UnlimitedBase Finance Rug Pull
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
- 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. - 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.
- 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 hastransferOwnershipand otheronlyOwnerfunctions), it does not change_totalSupply, and it has no once-only guard.balanceOfreturns_vOwned[account]and_transfermoves_vOwnedbalances, so the credited tokens are as spendable as any others. - 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). - At 10:27:51 UTC the deployer called
swapExactTokensForETHon 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
Evidence
- report De.Fi REKT database listing for UBASE (proof: X post by CaptainJackAPE) twitter.com
- report UbaseToken source (Sourcify, exact match) repo.sourcify.dev
- transaction Etherscan tx: renounceOwnership() call by deployer etherscan.io
- transaction Etherscan tx: swapExactTokensForETH of 99,897,470 UBASE etherscan.io
- transaction Etherscan tx: addLiquidityETH 43 ETH + 99,000 UBASE etherscan.io
- address UbaseToken verified source (Etherscan) etherscan.io
- analysis Web Archive web.archive.org
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.