sherlock-audit / 2024-04-titles-judging

9 stars 6 forks source link

threadmodeling - The full `msg.value` Ether amount is sent to the `feeManager` without refund even when fee amount is zero #232

Closed sherlock-admin3 closed 4 months ago

sherlock-admin3 commented 4 months ago

threadmodeling

medium

The full msg.value Ether amount is sent to the feeManager without refund even when fee amount is zero

Summary

When calling TitlesCore.createEdition, there's a collectCreationFee() function being called on feeManager.

Whether the feeAmount there is zero or a certain amount: any msg.value from the user will always be fully sent to the feeManager without any refunds.

Vulnerability Detail

On TitlesCore.createEdition, we reach the following line: TitlesCore.sol#L138

File: TitlesCore.sol
138:         feeManager.collectCreationFee{value: msg.value}(edition_, tokenId, msg.sender);

The implementation of collectCreationFee actually receives the funds on the FeeManager contract but doesn't give anything back in the event of an amount sent while fee is 0:

File: FeeManager.sol
166:     function collectCreationFee(IEdition edition_, uint256 tokenId_, address feePayer_)
167:         external
168:         payable
169:     {
170:         Fee memory fee = getCreationFee();
171:         if (fee.amount == 0) return; 

Also, in the event of an excess sent, the exact fee.amount is forwarded but the excess stays stuck in the FeeManager contract:

Nowhere in the call flow is there an automatic refund mechanism for the user here.

While it could be argued that the admin can call withdraw() for each user, this is still not a viable solution, whereas the solution is simple to implement

Impact

Funds are stuck, very often.

Case by case withdraw can be made by the admin, but the mistake can easily be avoided with a code fix.

Code Snippet

Manual Review

Recommendation

Implement a function refunding the excess