DeFiHardhat
21,000 USDC
View results
Submission Details
Severity: medium
Invalid

Ensuring Correct Token Distribution with Balance Checks in the pick Function

Summary

The pick function allows users to claim their pickable unripe tokens by verifying their eligibility using a Merkle proof and then transferring the corresponding amount of tokens to their specified account. This report highlights the importance of implementing balance checks before and after critical operations to ensure the correctness and security of the token distribution process.

Vulnerability Details

The original implementation of the pick function does not include explicit balance checks before and after the critical operation of transferring tokens. This oversight can lead to potential discrepancies in token accounting, resulting in incorrect token transfers. Without verifying the balances, the function may not guarantee that the expected amounts are correctly processed, potentially causing a loss of funds or an inconsistent token state.

Impact

Incorrect Token Transfer: If the transfer operation does not credit the correct amount of tokens to the user, it could result in a loss of funds for the user.
State Inconsistency: Without verifying balances, the function might leave the contract in an inconsistent state, affecting the overall integrity of the token ecosystem.

Tools Used

Manual review

Recommendations

Implement Balance Checks: Add explicit balance checks before and after the transfer operation to ensure that the correct amounts are processed.
Ensure Successful Transfer: Verify that the user’s balance of the claimed tokens is increased by the correct amount after the transfer operation.

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;
// Check initial balance of the token for the sender
uint256 initialBalance = IERC20(token).balanceOf(msg.sender);
// Transfer the tokens
LibTransfer.sendToken(IERC20(token), amount, msg.sender, mode);
// Ensure the transfer was successful
uint256 finalBalance = IERC20(token).balanceOf(msg.sender);
require(finalBalance == initialBalance + amount, "Pick: Transfer amount mismatch");
emit Pick(msg.sender, token, amount);
}
Updates

Lead Judging Commences

giovannidisiena 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.