We do not have a reliable USD price for the recorded assets yet.
0xc7647406542f8f2473a06fea142d223022370aa5722c044c2b7ea030b8965dd00x8b7218cf6ac641382d7c723de8aa173e98a80196BSC0x7fdc0d8857c6d90fd79e22511baf059c0c71bf8bBSCAn unprivileged BSC account drained CFToken from the CF/USDT liquidity pair by calling a public token function that accepted an arbitrary from address. In transaction 0xc7647406542f8f2473a06fea142d223022370aa5722c044c2b7ea030b8965dd0 at block 16841995, the caller invoked CFToken._transfer(pair, attacker, 1000000e18) against 0x8b7218cf6ac641382d7c723de8aa173e98a80196. The pair at 0x7fdc0d8857c6d90fd79e22511baf059c0c71bf8b lost 986000 CF net, the attacker received 930000 CF, and the remaining 70000 CF fee was split across the pair, foundation, and callback addresses.
The root cause is a broken authorization invariant in CFToken. The contract exposed _transfer(address from, address to, uint256 amount) as a public function and, when useWhiteListSwith was false at block 16841994, it allowed any external caller to debit arbitrary holders without checking ownership or allowance.
CFToken is a fee-on-transfer token deployed at 0x8b7218cf6ac641382d7c723de8aa173e98a80196. The relevant trading venue in this incident is the CF/USDT pair at 0x7fdc0d8857c6d90fd79e22511baf059c0c71bf8b. The pre-state snapshot taken at block shows that the pair held raw CF units, the token whitelist switch was disabled, and the foundation and callback fee recipients were already configured.
168419941293324982465647953742866When CFToken transfers tokens out of a configured pair, it applies a 7% buy-side fee. The verified source and observed balance changes show this fee is split 20% back to the pair as LP reward, 30% to foundation 0xa9056272ca777a63ae3a275d7aab078fd90a1691, and 50% to callback 0x3ecffccc4c35ccd71a7c61446c90117fb7995fb1. That fee logic explains why a 1000000e18 arbitrary debit yields 930000e18 to the attacker but only 986000e18 net loss to the pair.
This is an authorization failure in a token accounting primitive, not a pricing bug or flash-loan pattern. CFToken exposed its internal balance-moving routine as an externally callable public method instead of keeping it internal to ERC20 entrypoints. The function accepts caller-supplied from, to, and amount values and enforces only zero-address, positive-amount, and optional whitelist checks. At the exploit block, the whitelist gate was disabled, so no sender authorization remained. As a result, any EOA could choose a token-rich source address such as the CF/USDT pair and move tokens to an attacker-controlled recipient. The explicit invariant violated here is: a holder balance should decrease only when that holder calls transfer or an approved spender calls transferFrom within allowance. The concrete breakpoint is the subtraction from _tOwned[from] inside _transfer without any msg.sender == from or allowance check.
The verified CFToken source contains the vulnerable entrypoint:
function _transfer(
address from,
address to,
uint256 amount
) public {
require(from != address(0), "ERC20: transfer from the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
if (useWhiteListSwith) {
require(msgSenderWhiteList[msg.sender] && fromWhiteList[from] && toWhiteList[to], "Transfer not allowed");
}
...
_tOwned[from] = _tOwned[from].sub(amount);
_tOwned[to] = _tOwned[to].add(acceptAmount);
}
Two properties matter. First, _transfer is public, so it appears in the ABI and is callable directly by any external account. Second, the only policy gate is useWhiteListSwith; there is no ownership or allowance validation for the from address. The pre-state snapshot at block 16841994 records "useWhiteListSwith": false, so even that whitelist check was inactive before the exploit transaction.
The seed transaction metadata confirms the attacker used this surface exactly as exposed. The calldata targets the token contract and encodes selector 0x30e0789e, which corresponds to _transfer(address,address,uint256), with parameters:
from = 0x7fdc0d8857c6d90fd79e22511baf059c0c71bf8b // CF/USDT pair
to = 0xee0221d76504aec40f63ad7e36855eebf5ea5edd // attacker EOA
amount = 1000000000000000000000000 // 1,000,000 CF
The on-chain trace ends with the direct call:
CFToken::_transfer(
0x7FdC0D8857c6D90FD79E22511baf059c0c71BF8b,
0xee0221D76504Aec40f63ad7e36855EEbF5eA5EDd,
1000000000000000000000000
)
The same trace emits four Transfer events that match the fee logic in code: 14000e18 back to the pair, 21000e18 to foundation, 35000e18 to callback, and 930000e18 to the attacker. The balance-diff artifact independently confirms the resulting state: the pair decreases from 1293324982465647953742866 to 307324982465647953742866, foundation increases by 21000000000000000000000, callback increases by 35000000000000000000000, and the attacker increases from zero to 930000000000000000000000. Those post-state deltas are the direct consequence of the missing authorization check inside _transfer.
The adversary flow is a single transaction. Before block 16841995, the attacker only needed publicly observable state: the token address, the pair address, the fact that _transfer was public, and the fact that useWhiteListSwith was disabled. No privileged role, signature, contract deployment, or allowance setup was required.
In the exploit transaction, EOA 0xee0221d76504aec40f63ad7e36855eebf5ea5edd called the token contract directly. It set from to the CF/USDT pair and to to itself, choosing 1000000e18 as the debit amount. Because the pair was marked as a buy-side source, the function executed the pair fee logic, then wrote the new balances on-chain. The attacker therefore realized the ACT predicate in one step: an unprivileged caller caused the pair's CF balance to decrease and an attacker-controlled balance to increase without pair authorization or allowance.
The measurable token loss is 986000000000000000000000 raw CF units, or 986000 CF at 18 decimals, from the CF/USDT pair. The attacker received 930000000000000000000000 raw CF units, while 56000000000000000000000 raw CF units were redistributed by the token's built-in fee paths. The affected parties are the liquidity pair and any LPs relying on the pair's CF inventory. This transformed a public token method into a permissionless liquidity-pool drain.
0xc7647406542f8f2473a06fea142d223022370aa5722c044c2b7ea030b8965dd0 on BSC, including raw calldata and sender/recipient metadata.0x8b7218cf6ac641382d7c723de8aa173e98a80196, especially _transfer and the whitelist switch state variables.16841994, showing useWhiteListSwith=false, pair balances, and configured fee recipients._transfer(pair, attacker, 1000000e18) call and emitted Transfer events.-986000e18, attacker +930000e18, foundation +21000e18, and callback +35000e18.