TRT Rug Pull
What happened
TRT (contract 0x52f56100…C4F668) is a BEP-20 token on BNB Smart Chain. On 2023-04-05 CertiK's Skynet alert reported a large liquidity removal, with 99% slippage, saying the deployer removed liquidity in four transactions for a profit of about 93,000 USD and that the token appeared to be a honeypot. De.Fi's listing describes the same event as a liquidity-removal scam by the team managing liquidity, with the deployer removing a large share of the LP and dumping the token, which fell by about 90% from its initial price. The verified source mints the whole supply to the deployer, who is also granted the admin role at construction, and its _transfer blocks wallet-to-wallet transfers while an admin-set _usdtPair address controls which trades are allowed, so the admin role can both stop ordinary holders from selling and tax every transfer; no opened transaction shows those functions being called.
Deployer named by De.Fi: 0x4de9ff82…3f49ce. Liquidity-removal transactions listed by De.Fi: 0x2e845ee2…69a832 and 0xf6505fe6…269358.
How it happened
- The constructor mints the full supply to the deployer and makes it the admin:
_mint(creater_,totalSupply_*10**decimals());and_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());. On-chaintotalSupplyis 100,000,000 TRT, so the deployer can supply the pool and keep the rest. _transferonly lets a transfer through when the sender has an admin-granted quota, is a contract, or one side is_usdtPair:}else if(isTxt(from)){...}else if(from==_usdtPair||to==_usdtPair){...require(false,"Block is busy, please try again");. Ordinary wallet-to-wallet transfers revert, and trades with the pair pass only while_usdtPairpoints at the real pool.- The admin can repoint that variable at any time:
function setUsdtPair(address Pair_) public onlyRole(DEFAULT_ADMIN_ROLE){ _usdtPair=Pair_;. If it is set to another address, a sell from a wallet to the real pool matches none of the allowed cases and reverts withBlock is busy, while buys still pass because the pool is a contract andisTxt(from)is true.setBotHMDArrcan grant chosen addresses a transfer quota that bypasses the check. - The admin can also set an uncapped tax:
_scale=scale_;withsuper._transfer(recipient, _destroyAddress, tAmount.div(100).mul(_scale));andtAmount = tAmount.div(100).mul(100-_scale);. The sender is debited the full amount and the recipient loses_scalepercent to the dead address; at 100 the recipient keeps nothing, and above 100 the subtraction underflows and every such transfer reverts. - The token contract has no liquidity lock, so whoever holds the LP tokens can remove the pool at any time. CertiK reports that the deployer removed liquidity in four transactions, a 99% slippage event and roughly 93,000 USD profit, and De.Fi lists the same removal as a rug pull with the token falling about 90%. Whether the pair switch or the tax was used before or during the removal is not shown by any opened source.
Protocol details
Evidence
- report @CertiKAlert incident report twitter.com
- report CertiK Alert post on TRT liquidity removal (via fxtwitter) twitter.com
- transaction bscscan.com transaction 0x2e84…a832 bscscan.com
- transaction bscscan.com transaction 0xf650…9358 bscscan.com
- address BscScan verified source for TRT bscscan.com
- address bscscan.com address 0x4de9…49ce bscscan.com
- analysis Sourcify repository entry for TRT repo.sourcify.dev
- analysis De.Fi REKT database listing for TRT de.fi
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.