Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Users will lose funds when they call claim() and send bigger msg.value than required #202

Closed
howlbot-integration bot opened this issue Sep 6, 2024 · 4 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-109 🤖_04_group AI based duplicate group recommendation satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality

Comments

@howlbot-integration
Copy link

Lines of code

https://github.com/code-423n4/2024-08-phi/blob/8c0985f7a10b231f916a51af5d506dd6b0c54120/src/PhiFactory.sol#L264-L305

Vulnerability details

When users call the claim() function in Cred.sol, they are required to pay a mintFee, which is determined by the artId and quantity through the getArtMintFee() function:

return IPhiRewards(phiRewardsAddress).computeMintReward(quantity_, arts[artId_].mintFee)
+ quantity_ * mintProtocolFee;
}

This function first calculates the reward value using computeMintReward(), and then adds quantity_ * mintProtocolFee to determine the total mintFee. This total is the amount users must pay when executing the claim() function.

The calculated mintFee is passed as msg.value to the merkleClaim() function, or to signatureClaim() depending on art.verificationType. Both of these functions ultimately call _processClaim() with msg.value as one of its parameters. _processClaim() attempts to handle any surplus by recalculating the mintFee. The issue arises because claim() initially accepts msg.value, but only passes the mintFee to merkleClaim() or signatureClaim(). As a result, the following check in processClaim() will always result in zero since msg.value and mintFee are the same:

if ((etherValue - mintFee) > 0) {
msgSender().safeTransferETH(etherValue - mintFee);
} 

Impact

Users will be not able to get refund amount if mintFee is less than msg.value that was sent. Mark as high, because anytime when msg.value is not exact same as mintFee, users will lose the funds from the difference between msg.value and mintFee.

Proof of Concept

https://github.com/code-423n4/2024-08-phi/blob/8c0985f7a10b231f916a51af5d506dd6b0c54120/src/PhiFactory.sol#L264-L305
https://github.com/code-423n4/2024-08-phi/blob/8c0985f7a10b231f916a51af5d506dd6b0c54120/src/PhiFactory.sol#L352-L383
https://github.com/code-423n4/2024-08-phi/blob/8c0985f7a10b231f916a51af5d506dd6b0c54120/src/PhiFactory.sol#L723-L758

Consider the following scenario:

  1. Alice calls claim() with msg.value set to 100.
  2. The claim() function calculates mintFee as 40.
  3. claim() passes the mintFee (40) to merkleClaim().
  4. merkleClaim() processes the 40 and calls _processClaim() with 40 as the final parameter.
  5. _processClaim() tries to handle any surplus by recalculating mintFee, but the comparison between mintFee and msg.value results in zero.

As a result, Alice loses the surplus 60.
Keep in mind that the same scenario is possible not only with merkleClaim(), but also with signatureClaim().

Tools Used

Manual review

Recommended Mitigation Steps

Implement a check within claim() to refund any redundant amount that exceeds the calculated mintFee.

Assessed type

ETH-Transfer

@howlbot-integration howlbot-integration bot added 3 (High Risk) Assets can be stolen/lost/compromised directly 🤖_04_group AI based duplicate group recommendation bug Something isn't working duplicate-11 sufficient quality report This report is of sufficient quality labels Sep 6, 2024
howlbot-integration bot added a commit that referenced this issue Sep 6, 2024
@c4-judge
Copy link
Contributor

fatherGoose1 changed the severity to 2 (Med Risk)

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Sep 10, 2024
@c4-judge
Copy link
Contributor

fatherGoose1 marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Sep 12, 2024
@c4-judge c4-judge reopened this Sep 23, 2024
@c4-judge
Copy link
Contributor

fatherGoose1 marked the issue as not a duplicate

@c4-judge
Copy link
Contributor

fatherGoose1 marked the issue as duplicate of #109

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-109 🤖_04_group AI based duplicate group recommendation satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

1 participant