Aphrodite Protocol Rug Pull
What happened
Aphrodite Protocol (APHR) is an Ethereum reflection token with a fixed starting supply of 69,000 tokens, deployed on 2020-12-27. The deployer 0x0217f935…d2eEdc received the entire supply, and trading was locked for everyone else until the owner called enableTrading. De.Fi's REKT database lists the project as an exit scam with 97,147 USD lost and describes the sequence: the project announced a fundraising event on Telegram (archived at Source), funds were sent directly to the deployer address (transfers listed at Source), the deployer added initial liquidity in transaction 0xf0cc8a57…077bdb and later removed it in transaction 0x93245437…6d2f8d. On 2020-12-29 the Rug Detectives account flagged APHR as a scam project.
The verified code contains no function that withdraws ETH from the pool. What it does give the deployer is full initial supply, a trading lock it alone can lift, fee exemptions it controls, and uncapped fee setters; a liquidity removal needs the LP tokens, and the sources opened here do not show who held them.
How it happened
What the code allows (the sources do not show which owner functions were called):
- The constructor assigns the whole supply to the deployer:
_reflectionBalance[_msgSender()] = _reflectionTotal;with_tokenTotal = 69_000e18, and marks the deployer and the token contract fee-exempt (isExcludedFromFee[_msgSender()] = true;). - Before
tradingEnabledis set, only the owner and fee-exempt addresses can trade:require(tradingEnabled || sender == owner() || recipient == owner() || isExcludedFromFee[sender] || isExcludedFromFee[recipient], "Trading is locked before presale.");.enableTrading()isonlyOwnerand one-way; there is no function that locks trading again. - Fees are owner-adjustable with no upper bound:
setTaxFee(uint256 fee)andsetLiquidityFee(uint256 fee)assign the value directly, andcollectFeecomputesamount.mul(_taxFee).div(10**(_feeDecimal + 2))with_feeDecimal = 1, so the defaults of 5 and 5 are 0.5% each. In_transferthe sender is debitedamount.mul(rate)while the recipient is creditedtransferAmount.mul(rate), so the fee comes out of what the buyer or the pool receives; a combined value near 1000 would leave transfers with almost nothing, and a combined value above 1000 would maketransferAmount.sub(...)revert. setExcludedFromFeelets the owner exempt chosen addresses from those fees, andexcludeAccount/includeAccountchange which addresses are reflection-excluded.- Collected fee tokens sit in the contract and are swapped to ETH with
0minimum output; the ETH stays in the contract and is used to buy and burn tokens, with_rebalanceCallerFee = 500(50% of the bought tokens) paid totx.originof the transaction that triggers it. No function sends the contract's ETH to the owner. renounceOwnershipexists inOwnable; the current on-chainowner()read still returns the deployer address.
What was reported:
- De.Fi lists the sequence as a Telegram fundraising announcement, deposits sent directly to the deployer address, initial liquidity added by the deployer in transaction 0xf0cc8a57…077bdb and removed by the deployer in transaction 0x93245437…6d2f8d, with 97,147 USD lost. Rug Detectives flagged the project as a scam on 2020-12-29.
Protocol details
Evidence
- report Rug Detectives post on $APHR, 2020-12-29 (via fxtwitter mirror) twitter.com
- transaction etherscan.io transaction 0x9324…2f8d etherscan.io
- transaction etherscan.io transaction 0xf0cc…7bdb etherscan.io
- address Aphrodite Protocol verified source on Etherscan etherscan.io
- analysis Web Archive web.archive.org
- analysis Sourcify exact match for Aphrodite Protocol repo.sourcify.dev
- analysis archive.is page lrWVR archive.is
- analysis bloxy.info page 0x0217…eedc bloxy.info
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.