The contract defines a TokensWithdrawn event whose indexed parameters are ordered as (token, to, amount). However, when emitting the event inside withdrawTokens, the arguments are passed in the reversed order (to, token, amount). This mismatch causes the indexed topic for "token" to contain the recipient address and the indexed topic for "to" to contain the token address, rendering all off-chain indexing permanently incorrect.
function withdrawTokens(address token, address to, uint256 amount) external onlyOwner {
IERC20(token).transfer(to, amount);
emit TokensWithdrawn(to, token , amount);
}se in the codebase with @> marks to highlight the relevant section
https:
Risk
Likelihood:
Impact:
Etherscan, The Graph, Dune, Covalent, and every subgraph show garbage data (token address displayed as recipient and vice versa)
Frontends, analytics dashboards, tax tools, and monitoring bots become unusable or misleading
Proof of Concept
address token = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address to = 0xDeaD000000000000000000000000000000000000;
uint256 amount = 1000e6;
emit TokensWithdrawn(to, token, amount);
Recommended Mitigation
- remove this code
+ add thfunction withdrawTokens(address token, address to, uint256 amount) external onlyOwner {
IERC20(token).transfer(to, amount);
- emit TokensWithdrawn(to, token , amount);
+ emit TokensWithdrawn(token, to, amount);
}