52027 sc low whitelistrestrictions sol mint burn operations blocked when transfers disabled
#52027 [SC-Low] WhitelistRestrictions.sol: Mint & Burn Operations Blocked When Transfers Disabled
Submitted on Aug 7th 2025 at 12:00:44 UTC by @soloi for Attackathon | Plume Network
Report ID: #52027
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/restrictions/WhitelistRestrictions.sol
Impacts: Temporary freezing of funds for at least 24 hours
Description
WhitelistRestrictions.sol: Mint & Burn Operations Blocked When Transfers Disabled
Summary
The WhitelistRestrictions.sol contract contains a vulnerability where disabling the transfersAllowed flag also blocks all mint and burn operations, even for whitelisted users. This allows the admin to permanently disable core token functionality.
Vulnerability Details
Location
File:
contracts/arc/src/restrictions/WhitelistRestrictions.solLines: 95-102
Function:
isTransferAllowed()
Root Cause
The isTransferAllowed() function treats all addresses equally, including the zero address (address(0)). When transfersAllowed is set to false, the function requires both the from and to addresses to be whitelisted. However, the zero address can never be whitelisted, causing mint and burn operations to fail.
Vulnerable Code
function isTransferAllowed(address from, address to, uint256 /*amount*/ ) external view override returns (bool) {
WhitelistStorage storage ws = _getWhitelistStorage();
// If transfers are unrestricted, allow all transfers
if (ws.transfersAllowed) {
return true;
}
// Otherwise, only allow if both the sender and receiver are whitelisted
return ws.isWhitelisted[from] && ws.isWhitelisted[to];
}Technical Analysis
How Mint and Burn Operations Work
Minting:
_mint(to, amount)calls_update(address(0), to, amount)Burning:
_burn(from, amount)calls_update(from, address(0), amount)
The Problem
When transfersAllowed = false:
Mint Operation:
from = address(0),to = recipientws.isWhitelisted[address(0)]is alwaysfalse(zero address can't be whitelisted)ws.isWhitelisted[to]may betrue(recipient is whitelisted)Result:
false && true = false→ Mint blocked
Burn Operation:
from = sender,to = address(0)ws.isWhitelisted[from]may betrue(sender is whitelisted)ws.isWhitelisted[address(0)]is alwaysfalse(zero address can't be whitelisted)Result:
true && false = false→ Burn blocked
Impact Analysis
Severity: Medium
Immediate Consequences
Permanent Disabling of Mint/Burn: Admin can permanently disable core token functionality
Bricking Risk: Malicious admin could brick the token by disabling transfers
Whitelist Bypass: Even whitelisted users cannot mint or burn tokens
Functionality Loss: Core ERC20 operations become unavailable
Business Impact
Operational Risk: Inability to mint new tokens or burn existing ones
Admin Privilege Abuse: Single admin can disable critical functionality
User Experience: Legitimate users cannot perform expected operations
Compliance Risk: May violate regulatory requirements for token management
Attack Scenario
Malicious Admin: Admin with
ADMIN_ROLEcallssetTransfersAllowed(false)Permanent Disablement: All mint and burn operations are permanently blocked
No Recovery: Even if admin changes their mind, mint/burn remain blocked
Token Bricking: Token becomes non-functional for core operations
Proof of Concept
A complete proof of concept demonstrating this vulnerability is available in: my_pocs/WhitelistRestrictions_MintBurn_PoC.t.sol
Fix Recommendations
Immediate Fix
Add special handling for the zero address in isTransferAllowed():
function isTransferAllowed(address from, address to, uint256 /*amount*/ ) external view override returns (bool) {
WhitelistStorage storage ws = _getWhitelistStorage();
// Allow mint and burn operations unconditionally
if (from == address(0) || to == address(0)) {
return true;
}
// If transfers are unrestricted, allow all transfers
if (ws.transfersAllowed) {
return true;
}
// Otherwise, only allow if both the sender and receiver are whitelisted
return ws.isWhitelisted[from] && ws.isWhitelisted[to];
}Alternative Fix (More Granular Control)
If more granular control is desired:
function isTransferAllowed(address from, address to, uint256 /*amount*/ ) external view override returns (bool) {
WhitelistStorage storage ws = _getWhitelistStorage();
// Handle mint operations (from = address(0))
if (from == address(0)) {
// For minting, only check if recipient is whitelisted (if transfers are restricted)
if (ws.transfersAllowed) {
return true;
}
return ws.isWhitelisted[to];
}
// Handle burn operations (to = address(0))
if (to == address(0)) {
// For burning, only check if sender is whitelisted (if transfers are restricted)
if (ws.transfersAllowed) {
return true;
}
return ws.isWhitelisted[from];
}
// Handle normal transfers
if (ws.transfersAllowed) {
return true;
}
return ws.isWhitelisted[from] && ws.isWhitelisted[to];
}Testing Requirements
Integration Testing
ArcToken Integration: Test with actual ArcToken contract
Multiple Restriction Modules: Test interaction with other restriction modules
Upgrade Scenarios: Test behavior after contract upgrades
Security Recommendations
Immediate Actions
Audit All Instances — Check if this pattern exists in other restriction modules.
Update Documentation — Document the correct behavior for mint/burn operations.
Admin Training — Ensure admins understand the implications of disabling transfers.
Monitoring — Add alerts for when transfers are disabled.
Long-term Improvements
Role Separation — Consider separating mint/burn permissions from transfer permissions.
Emergency Controls — Add emergency functions to re-enable mint/burn if needed.
Multi-sig Requirements — Require multiple signatures for critical operations.
Timelock — Add timelock for disabling transfers to prevent immediate bricking.
Conclusion
This vulnerability represents a significant design flaw in the WhitelistRestrictions contract that allows the admin to permanently disable core token functionality. The fix is straightforward and should be implemented immediately to prevent potential abuse.
Priority: Medium — Should be fixed promptly Impact: Admin can disable core token functionality Affected: All tokens using WhitelistRestrictions module
Was this helpful?