Tall Burgundy Nightingale
High
The direct transfer of blacklisted user's tokens to msg.sender will cause complete loss of funds for users as any BLACKLISTER_ROLE can claim tokens for themselves, allowing malicious blacklisters to steal user funds through the blacklisting process.
In Stablecoin.sol in the _onceBlacklisted function, the choice to send tokens to msg.sender instead of a controlled treasury or the contract itself is a mistake as it enables direct theft of user funds by any address with BLACKLISTER_ROLE.
User needs to have a token balance greater than 0
Attacker needs to have BLACKLISTER_ROLE
User must not be currently blacklisted
None
Malicious actor notices User A has 1,000,000 tokens
Malicious actor with BLACKLISTER_ROLE calls addBlackList(userA)
_onceBlacklisted is triggered
All 1,000,000 tokens are transferred directly to the malicious actor (msg.sender)
Malicious actor now owns all of User A's tokens
Malicious actor can immediately transfer these tokens to another address or sell them
Even if User A is later unblacklisted, their tokens remain stolen
Users suffer 100% loss of their token holdings when blacklisted. The attacker gains immediate ownership of all seized tokens, effectively turning the blacklist feature into a mechanism for direct theft by any address with BLACKLISTER_ROLE.
No response
Transfer to treasury or contract instead of msg.sender
contract Stablecoin is ERC20PermitUpgradeable, Blacklist {
address public immutable TREASURY;
function _onceBlacklisted(address user) internal override {
uint256 balance = balanceOf(user);
if(balance > 0) {
// Transfer to treasury or contract instead of msg.sender
_transfer(user, TREASURY, balance);
// OR
_transfer(user, address(this), balance);
}
}
}