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

Precision Loss in Redemption Fee Calculation #49

Open
hats-bug-reporter bot opened this issue Sep 4, 2024 · 1 comment
Open

Precision Loss in Redemption Fee Calculation #49

hats-bug-reporter bot opened this issue Sep 4, 2024 · 1 comment
Labels
Invalid - lead auditor invalid This doesn't seem right

Comments

@hats-bug-reporter
Copy link

Github username: --
Twitter username: --
Submission hash (on-chain): 0xd38ace7a59b96a6a751d0d711b6b9e87f00c57952e28def3bc373346c8bce244
Severity: high

Description:
Description
The previewRedeem function in the Minter contract experiences precision loss due to integer division when calculating fees for small redemption amounts. This can result in inconsistent fee application and potential exploitation through multiple small redemptions.

Attack Scenario
The current implementation of previewRedeem uses integer division to calculate the fee amount. For small redemption amounts, this can result in rounding down to zero, effectively allowing fee-free redemptions. This inconsistency in fee application could be exploited by users to minimize or avoid fees by splitting larger redemptions into multiple smaller ones.

  1. Proof of Concept (PoC) File
    function previewRedeem(uint256 amount) public view virtual returns (uint256) {
    uint256 feeAmount = amount*redeemFee/FEE_DENOMINATOR;
    uint256 netAmount = amount-feeAmount;
    return netAmount;
}

Illustration

Assuming redeemFee = 100 and FEE_DENOMINATOR = 10000 (1% fee):

Redemption of 1000 tokens: feeAmount = 10, netAmount = 990
Redemption of 10 tokens: feeAmount = 0, netAmount = 10
Redemption of 1 token: feeAmount = 0, netAmount = 1

  1. Revised Code File (Optional)
    function previewRedeem(uint256 amount) public view virtual returns (uint256) {
    uint256 feeAmount = (amount * redeemFee + FEE_DENOMINATOR - 1) / FEE_DENOMINATOR;
    uint256 netAmount = amount - feeAmount;
    return netAmount;
}

The revised code uses the "ceiling" division technique to ensure that even small redemptions incur at least a minimal fee when applicable. This approach maintains consistency in fee application across all redemption amounts.

Additionally, consider implementing a minimum redemption amount to further mitigate the impact of this issue

@hats-bug-reporter hats-bug-reporter bot added the bug Something isn't working label Sep 4, 2024
@0xRizwan
Copy link

0xRizwan commented Sep 5, 2024

Duplicate of #7 and #48

@ilzheev ilzheev added the invalid This doesn't seem right label Sep 5, 2024
@0xRizwan 0xRizwan added Invalid - lead auditor and removed bug Something isn't working labels Sep 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Invalid - lead auditor invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

2 participants