Sablier

Sablier
DeFiFoundry
53,440 USDC
View results
Submission Details
Severity: low
Invalid

```SablierV2MerkleLT``` and ```SablierV2MerkleLL``` constructors can revert for some tokens

Summary

Smart contracts that interact with ERC20 tokens often require setting allowances for other addresses to manage tokens on behalf of the token owner. A practice is to set a very high allowance (e.g., type(uint256).max) to avoid having to repeatedly approve smaller amounts. This is done in the SablierV2MerkleLT and SablierV2MerkleLL constructors for max approval the Sablier contract to spend funds from the MerkleLockup contract.

However, certain ERC20 tokens, such as UNI and COMP, implement special logic in their approve function to handle large approval values differently. Specifically, they revert if the value passed to approve or transfer is larger than uint96. This revert leads to the failure of the smart contracts deployment.

Vulnerability Details

SablierV2MerkleLL.sol
constructor(
MerkleLockup.ConstructorParams memory baseParams,
ISablierV2LockupLinear lockupLinear,
LockupLinear.Durations memory streamDurations_
)
SablierV2MerkleLockup(baseParams)
{
LOCKUP_LINEAR = lockupLinear;
streamDurations = streamDurations_;
// Max approve the Sablier contract to spend funds from the MerkleLockup contract.
@> ASSET.forceApprove(address(LOCKUP_LINEAR), type(uint256).max);
}
SablierV2MerkleLT.sol
constructor(
MerkleLockup.ConstructorParams memory baseParams,
ISablierV2LockupTranched lockupTranched,
MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages
)
SablierV2MerkleLockup(baseParams)
{
LOCKUP_TRANCHED = lockupTranched;
// Since Solidity lacks a syntax for copying arrays of structs directly from memory to storage, a manual
// approach is necessary. See https://github.com/ethereum/solidity/issues/12783.
uint256 count = tranchesWithPercentages.length;
for (uint256 i = 0; i < count; ++i) {
_tranchesWithPercentages.push(tranchesWithPercentages[i]);
}
// Max approve the Sablier contract to spend funds from the MerkleLockup contract.
@> ASSET.forceApprove(address(LOCKUP_TRANCHED), type(uint256).max);
}

Impact

The constructors in the SablierV2MerkleLT and SablierV2MerkleLL set a very high allowance (type(uint256).max) for approving the Sablier contract to spend funds from the MerkleLockup contract. However some ERC20 tokens, such as UNI and COMP, implement special logic in their approve function to handle large approval values differently. Specifically, they revert if the value passed to approve or transfer is larger than uint96.

For reference:

Attempts to deploy the contracts with token like UNI and COMP will lead to a failure. These tokens can't be used in the airstream (for example: airdrop).

Tools Used

Manual review

Recommendations

Set the approval with the proper value or manage this behaviour separately.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

ERC20 UNI and COMP Revert on Large Approvals

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.