52393 sc low burns blocked by both sides whitelist with zero address exclusion when restrictions are enabled
Submitted on Aug 10th 2025 at 12:08:27 UTC by @Khay3 for Attackathon | Plume Network
Report ID: #52393
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
Summary
When transfersAllowed == false, WhitelistRestrictions::isTransferAllowed requires both from and to to be whitelisted. Because the zero address cannot be whitelisted, any burn (to == address(0)) is permanently disallowed under restriction. This blocks protocol flows that depend on burning (supply reduction, redemption, bridging, fee-burning) whenever restrictions are active.
Vulnerability Detail
The isTransferAllowed function enforces a strict “both-sides must be whitelisted” rule under restriction:
WhitelistRestrictions::isTransferAllowed():
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];
}The whitelist admin/manager cannot add the zero address, making to == address(0) (burn) impossible under restriction:
WhitelistRestrictions::addToWhitelist():
function addToWhitelist(address account) external onlyRole(MANAGER_ROLE) {
if (account == address(0)) {
revert InvalidAddress();
}
...
}The batch variant also refuses to add zero (silently skipping it):
WhitelistRestrictions::batchAddToWhitelist():
for (uint256 i = 0; i < accounts.length; i++) {
address account = accounts[i];
if (account == address(0)) {
continue; // Skip zero address
}
...
}In short: isTransferAllowed enforces both from and to whitelisted while the zero address cannot be whitelisted, therefore any burn to address(0) can never satisfy the condition when restrictions are enabled.
Impact
Burns are impossible whenever restrictions are active. This prevents supply reduction, fee-burning, redemption flows that rely on burn-to-zero, and common bridge patterns that require token burns on the origin chain. Operations such as emergency redemptions or compliance-driven supply adjustments are blocked, potentially freezing required lifecycle actions and creating governance and operational risks.
If burn gating is not intended, users and integrators will experience unexplained failures in legitimate burn calls during periods when restrictions are toggled on, degrading protocol reliability.
Recommendation
Proof of Concept
Was this helpful?