Sablier

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

Claiming reward in `SablierV2MerkleLL` and `SablierV2MerkleLT` can be front-runned.

Summary

Claiming reward in SablierV2MerkleLL and SablierV2MerkleLT can be front-runned because leaf hash is generated from function arguments which are not protected and publically available.

Vulnerability Details

claim() function in SablierV2MerkleLL and SablierV2MerkleLT creates stream for user that provided valid proof with correct data (index, recipient, amount). Validating of provided data is done by hashing (index, recipient, amount) if proof is valid for generated leaf.

// 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);

If provided data is correct contract creates stream and makes sure that no one can create stream with the same data as it's already has been claimed:

// 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) })
})
);

As recipient, index and amount parameters are obtained from function arguments, any user can call this function with these parameters. Because of that malicious user can make next steps to steal other user's funds:

  • Malicius user set up front-running bot to watch pending transactions to SablierV2MerkleLL.claim() or SablierV2MerkleLT.claim()

  • If such transaction occurs, bot checks it will be successful

  • If it would make transaction with much higher gas amount to execute transaction faster than original user

Impact

Malicious user that uses front-running bot can claim other users' reward.

Recommended Mitigation Steps

Make that only user can claim their reward by using msg.sender instead of function argument recipient:

@@ -58,7 +58,6 @@ contract SablierV2MerkleLL is
/// @inheritdoc ISablierV2MerkleLL
function claim(
uint256 index,
- address recipient,
uint128 amount,
bytes32[] calldata merkleProof
)
@@ -66,6 +65,7 @@ contract SablierV2MerkleLL is
override
returns (uint256 streamId)
{
+ address recipient = msg.sender;
// 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))));
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

Support

FAQs

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