Sablier

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

Anyone can deposit ERC20 to Airstream, allowing early claim and start of grace period

Summary

When an Admin deploys an Airstream, they have the option of funding it at a later time. This could be to allow organising of funds, waiting for some special event period, etc. When the Airstream is deployed, all of the necessary MerkleProof data is already present to allow claims, however there are no funds at this time, meaning no one can claim successfully.

However there is no function within the Airstream that only the Admin can call to provide the funding and mark the Airstream as started. Any user is able to directly transfer ERC20 tokens to the vault and call claim(). This would start the 7 day grace period, and the Admin may not notice this happening. This can ruin the whole deployment of the Airstream as the admin may want to fund it themselves and then have 7 days afterwards to monitor engagement and have the ability to use clawback() if needed (This is core functionality for admins).

Vulnerability Details

SablierV2MerkleLL::claim()

function claim(
uint256 index,
address recipient,
uint128 amount,
bytes32[] calldata merkleProof
)
external
override
returns (uint256 streamId)
{
// Generate the Merkle tree leaf by hashing the corresponding parameters. Hashing twice prevents second
// preimage attacks.
bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(index, recipient, amount))));
// Check: validate the function.
_checkClaim(index, leaf, merkleProof);
// Effect: mark the index as claimed.
_claimedBitMap.set(index);
// Interaction: create the stream via {SablierV2LockupLinear}.
streamId = LOCKUP_LINEAR.createWithDurations(
LockupLinear.CreateWithDurations({
sender: admin,
recipient: recipient,
totalAmount: amount,
asset: ASSET,
cancelable: CANCELABLE,
transferable: TRANSFERABLE,
durations: streamDurations,
broker: Broker({ account: address(0), fee: ud(0) })
})
);
// Log the claim.
emit Claim(index, recipient, amount, streamId);
}

The claim() function has no checks for any Admin controllable variable that starts the claim process. The only action preventing claiming and the start of the grace period is the lack of funds within the Airstream.

SablierV2MerkleLockup::clawback()

function clawback(address to, uint128 amount) external override onlyAdmin { // @audit-ok
// Check: current timestamp is over the grace period and the campaign has not expired.
if (_hasGracePeriodPassed() && !hasExpired()) {
revert Errors.SablierV2MerkleLockup_ClawbackNotAllowed({
blockTimestamp: block.timestamp,
expiration: EXPIRATION,
firstClaimTime: _firstClaimTime
});
}
// Effect: transfer the tokens to the provided address.
ASSET.safeTransfer(to, amount);

As seen, if the grace period has passed then the Admin is unable to clawback any funds.

Impact

A malicious user can start the grace period early by donating funds to the Airstream directly and calling claim(). This will start the grace period and denies the Admin the use of the clawback function if this action goes unnoticed.

Likelihood: Medium
Any user who has earned a small amount of funds from a giveaway can call this function, suffering minimal losses, e.g. 1 DAI. If this happens on an L2, which will be the case as Sabier is planning on deploying to 8+ chains, then the gas fees are minimal. Meaning any griefing user can perform this grief attack with minimal funds.

Impact: Medium
This can deny the Admin's use of the clawback function from the Airstream if the grief attack goes unnoticed. If an Admin notices this attack, then they could redeploy however if an Admin does not notice this and transfers funds after the grace period is over, then they will lose clawback functionality permanently, or until expiration period is ended. An Admins can save the address of the Airstream after deployment and transfer funds directly to it to start the Airstream, there is no requirement to monitor the contract or use the UI from Sabier for funding/ starting of claiming.

Therefore this has a Medium impact as Admin will be unable to utilise the clawback function due to this grief attack, which breaks core functionality of an airstream whilst also having the possiblity of the Admin losing funds due to not being able to clawback if the grace period is already finished when funding the airstream.

Tools Used

Manual Review

Recommendations

Add an Admin only function that allows the Admin to fund the Airstream, and only allow this function to mark the Airstream as started, allowing claims. This means any donations to the Airstream will not allow early claiming and start of the grace period.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Info/Gas/Invalid as per Docs

https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity

Grace started early by donate + claim

0xnevi Judge
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Grace started early by donate + claim

Support

FAQs

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