NeedForSpeed Finance Rug Pull
What happened
NeedForSpeed.Finance (RFI-NFS, Ethereum contract 0x77b97372…eb44db) is a Reflect (RFI) fork that takes a 3% holder fee and a 3% burn on every transfer. Its transfer-blocking control is _setMaxTxAmount: the owner can set the per-transfer cap to any value, including zero, and the cap applies to every transfer where neither side is the owner. De.Fi's REKT database describes the token as a custom ERC20 with logic that allows blocking token transfers.
De.Fi's listing says the project ran a fundraising event through the Token Sale contract 0x21c76e2a…18d0b0, that the funds were sent to the contract deployer (transaction 0x4f71d08f…1f8d0a), that all 125 ETH was used to add initial liquidity (transactions 0x1286d6c6…2fc01a, 0xfbe58652…9c472e and 0x2f5a1600…14ea6f), and that the deployer then removed the liquidity (transactions 0x8ecb6bd2…09de99, 0x874091d6…d34124 and 0x2775cd7f…9cb262).
Etherscan's page for 0x874091... shows the deployer 0xD3f001a9…41a2bF removing liquidity through Uniswap V2 Router 2 on 2021-04-27 at 12:31:58 UTC and receiving about 30.48 ETH (about $82.8K at Etherscan's valuation), in line with the $82,091 loss. The pages for 0x8ecb... and 0x2775... show other activity: a removal of about 14.45 ETH on 2020-12-13 at 13:22 UTC, before this contract was deployed that day at 17:02 UTC, and a removal from a TFL/ETH pair on 2021-05-27.
On-chain owner() reads the zero address (2026-09-30), so ownership was renounced at some point; the source cannot show what the cap was set to before that.
How it happened
- The constructor gives the whole supply to the deployer:
_rOwned[_msgSender()] = _rTotal;. The supply is_tTotal = 1 * 10**6 * 10**7base units with 8 decimals, which is 100,000 tokens. - A per-transfer cap starts at
uint256 private _maxTxAmount = 2000e8;(2,000 tokens) and_transferenforces it unless one side is the owner:if(sender != owner() && recipient != owner())followed byrequire(amount <= _maxTxAmount, ...)._transferalso requiresamount > 0. - The cap has no lower bound.
function _setMaxTxAmount(uint256 maxTxAmount) external onlyOwner()assigns_maxTxAmount = maxTxAmount;, while the fee setter next to it is bounded byrequire(taxFee >= 1 && taxFee <= 10, ...). With the cap at 0, every transfer between non-owner addresses reverts: a holder's sell through the router (transferFrominto the pair) and a buy out of the pair both fail, while transfers to or from the owner still pass. renounceOwnership()sets_owner = address(0);. After thatowner()is the zero address, no transfer qualifies for the exemption and_setMaxTxAmountcan no longer be called, so the last cap value stays for good. Renouncing does not undo a cap set earlier.- What was reported: De.Fi's listing says the deployer removed the liquidity, and the opened Etherscan page for 0x874091... shows the deployer removing liquidity on 2021-04-27 for about 30.48 ETH. No opened transaction shows a call to
_setMaxTxAmount, so the listing's transfer-blocking claim is matched to this code control but not traced to a transaction.
Protocol details
Evidence
- report Report needforspeed.finance
- transaction Etherscan transaction 0x874091d6...6d34124 (removeLiquidityETH, 2021-04-27) etherscan.io
- transaction Etherscan transaction 0xc5ec66f3...ed14d05d (contract creation, 2020-12-13) etherscan.io
- transaction Etherscan transactions 0x8ecb6bd2...509de99 and 0x2775cd7f...96cb262 etherscan.io
- transaction etherscan.io transaction 0x1286…c01a etherscan.io
- transaction etherscan.io transaction 0x2775…b262 etherscan.io
- transaction etherscan.io transaction 0x2f5a…ea6f etherscan.io
- transaction etherscan.io transaction 0x4f71…8d0a etherscan.io
- transaction etherscan.io transaction 0xfbe5…472e etherscan.io
- address RFINFS (NeedForSpeed.Finance) verified source on Etherscan etherscan.io
- address etherscan.io address 0x21c7…code etherscan.io
- analysis RFINFS on Sourcify (exact match) repo.sourcify.dev
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.