The SablierV2Lockup::withdrawMultiple
function reverts if one of the recipient addresses is blacklisted, particularly when using USDC
or USDT
tokens as the asset.
The SablierV2Lockup::withdrawMultiple
function iterates over the array of streamIds
and calls withdraw
from each stream to the recipient:
Then the withdraw
function calls the internal _withdraw
function:
And at the end the _withdraw
function calls the safeTransfer
function to transfer the amount
to the to
address:
In the documentation is written that the protocol will work with any ERC-20 compatible token:
It is important to know that:
Some tokens (e.g. USDC, USDT) have a contract level admin controlled address blocklist. If an address is blocked, then transfers to and from that address are forbidden.
https://github.com/d-xo/weird-erc20#tokens-with-blocklists
The problem is that USDC
and USDT
tokens have built-in compliance mechanisms that prevent transfers to blacklisted addresses. When attempting to transfer these assets to a blacklisted address, the transfer will fail, causing the entire withdrawMultiple
transaction to revert.
If one of the recipient addresses is blacklisted and the asset used is USDC
or USDT
, the withdrawMultiple
function will revert and nobody will be able to receive the expected amount. The token transfer to these users will fail and will also brick the withdrawn system because the blacklisted user is never cleared.
The withdrawn distribution is handled in a loop, causing the recipient unable to receive the expected amount, the transfer will not be cleared and the contract will be left DOS'd. A malicious recipient can also use this as a point of attack by intentionally getting himself blacklisted.
Also, the assets can be pausable tokens:
Some tokens can be paused by an admin (e.g. BNB, ZIL).
Similary to the blocklist issue above, an admin controlled pause feature opens users of the token to risk from a malicious or compromised
token owner.
https://github.com/d-xo/weird-erc20?tab=readme-ov-file#pausable-tokens
If the asset that is used is pausable token and is paused, then the transfer of this token from and to the protocol will be impossible.
In the considered withdrawMultiple
function that means again the withdrawn functunality will be broken and the recipients will be unable to receive their expected amount.
Manual Review
To prevent the withdrawMultiple
function from reverting when one of the recipient addresses is blacklisted, you can implement a pre-check mechanism to identify and skip blacklisted addresses before attempting the withdrawal.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.