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

Unlclaimed pickable unripe tokens might be locked in the `pick` function

Summary

The UnripeFacet:pick function allows users to claim their pickable Unripe Tokens. Users provide a Merkle proof along with the amount of tokens they want to claim. The function first verifies that the Merkle root for the Unripe Token is not empty, ensuring that the token is valid and exists in the system.
It checks whether the user has already claimed tokens for the given Unripe Token. If they have, the function reverts to prevent double claiming. The function validates the Merkle proof provided by the user to ensure that the claimed amount is legitimate.

Vulnerability Details

The issues arises as pick doesn't verify whether the amount user wants to claim is less than or equal to the actual amount available for the user to claim. This can lead to a situation where a user claims fewer tokens than expected, which will set s.unripeClaimed[token][msg.sender] to true. Now subsequent attempts to claim the remaining tokens will fail due to the assumption that they've already claimed their entire allocation.

See the following code:

/**
* @notice Picks a Farmer's Pickable Unripe Tokens.
* @dev Pickable Unripe Tokens were distributed to all non-Deposited pre-exploit Bean and Bean LP Tokens.
* @param token The Unripe Token address to Pick.
* @param amount The amount of Unripe Tokens to Pick.
* @param proof The merkle proof used to validate that the Pick is valid.
* @param mode The destination balance that the Unripe Tokens are sent to.
*/
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);
}

Impact

Users may face inconsistencies in claiming their Unripe Tokens, leading to potential loss of unclaimed unripe tokens and loss of trust in the system. It can also result in a waste of gas fees for users attempting to claim the remaining tokens after an incomplete claim.

Tools Used

Manual Review

Recommendations

To address this issue, you should implement a verification step in the pick function to ensure that the amount being picked matches the actual available amount for the user.

Updates

Lead Judging Commences

giovannidisiena Lead Judge over 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.