DeFiHardhat
35,000 USDC
View results
Submission Details
Severity: low
Invalid

Users can claim unripe tokens beyond their entitlement

Summary

The pick function in the contract lacks validation to ensure that users cannot claim more unripe tokens than they are entitled to, potentially leading to unfair distribution and loss of tokens. Implementing additional checks to enforce entitlement limits based on specific conditions can prevent unauthorized token claims and maintain fairness in token distribution.

Vulnerability Details

The vulnerability in the pick function arises from the absence of explicit validation to ensure that the claimed amount of unripe tokens does not exceed the pickable amount, as determined by the Merkle proof. This lack of validation allows users to potentially exploit the system by claiming more tokens than they are entitled to, leading to an unfair distribution of tokens and potential loss of tokens meant for other users.

Here's a breakdown of the vulnerability:

function pick(
address token,
uint256 amount,
bytes32[] memory proof,
LibTransfer.To mode
) external payable nonReentrant {
bytes32 root = s.u[token].merkleRoot;
require(root != bytes32(0), "UnripeClaim: invalid token");
require(!picked(msg.sender, token), "UnripeClaim: already picked");
bytes32 leaf = keccak256(abi.encodePacked(msg.sender, amount));
require(MerkleProof.verify(proof, root, leaf), "UnripeClaim: invalid proof");
s.unripeClaimed[token][msg.sender] = true;
LibTransfer.sendToken(IERC20(token), amount, msg.sender, mode);
emit Pick(msg.sender, token, amount);
}
  • The pick function accepts parameters such as the token address, the claimed amount of tokens, and a valid Merkle proof. Upon receiving these parameters, the function verifies the validity of the provided token address and checks if the user has already claimed unripe tokens for the specified token.

  • The function proceeds to verify the provided Merkle proof to ensure that the claim is legitimate. It computes the leaf node from the user's address and the claimed amount of tokens and checks if the provided proof matches the Merkle root.

  • However, crucially, there's no explicit check to ensure that the claimed amount of tokens does not exceed the pickable amount based on certain conditions (e.g., time, user eligibility, etc.). This absence of validation allows users to potentially claim more tokens than they are entitled to, leading to an imbalance in token distribution and potential loss of tokens meant for other users.

Impact

The vulnerability exposes the contract to manipulation by allowing users to unfairly claim an excessive amount of tokens, disrupting the intended distribution mechanism and potentially causing financial loss or imbalance within the system.

Tools Used

Manual

Recommendations

Additional validation should be implemented within the pick function to ensure that the claimed amount of tokens does not exceed the pickable amount.

function pick(
address token,
uint256 amount,
bytes32[] memory proof,
LibTransfer.To mode
) external payable nonReentrant {
require(token != address(0), "Invalid token address");
require(!picked(msg.sender, token), "Already picked");
bytes32 root = s.u[token].merkleRoot;
require(root != bytes32(0), "Invalid token");
bytes32 leaf = keccak256(abi.encodePacked(msg.sender, amount));
require(MerkleProof.verify(proof, root, leaf), "Invalid proof");
// Additional check to ensure claimed amount doesn't exceed the pickable amount
uint256 pickableAmount = getPickableAmount(token); // Placeholder function
require(amount <= pickableAmount, "Claimed amount exceeds pickable amount");
s.unripeClaimed[token][msg.sender] = true;
LibTransfer.sendToken(IERC20(token), amount, msg.sender, mode);
emit Pick(msg.sender, token, amount);
}
Updates

Lead Judging Commences

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

Informational/Invalid

Support

FAQs

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