Lucene search

K
code423n4Code4renaCODE423N4:2023-11-SHELLPROTOCOL-FINDINGS-ISSUES-279
HistoryDec 08, 2023 - 12:00 a.m.

Unwrap Fee Rounding Down: Revenue Loss, User Unfairness, and Reduced Confidence

2023-12-0800:00:00
Code4rena
github.com
5
revenue loss
user unfairness
reduced confidence
integer division
truncation
minimum fee
unwrap fee divisor
smart contract

7.2 High

AI Score

Confidence

Low

Lines of code

Vulnerability details

Impact

The issue with the unwrap fee rounding down can have several detrimental impacts on the Ocean protocol:

  1. Revenue Loss: Due to rounding down, the contract loses out on potential unwrap fees, particularly for smaller unwrap amounts. This can significantly reduce the protocol’s revenue and limit its ability to operate and maintain its services.

  2. Unfairness to Users: Smaller users who unwrap smaller amounts are disproportionately affected by the rounding down, leading to a sense of unfairness and potentially discouraging them from using the platform.

  3. Reduced User Confidence: The presence of this issue can erode user confidence in the protocol’s accuracy and fairness, potentially leading to decreased user engagement and adoption.

Proof of Concept

Scenario:

  • User attempts to unwrap 100 units of a token.
  • Current unwrap fee divisor is 2000 (0.05%).
  • Calculated unwrap fee: 100 / 2000 = 0.05
  • Actual unwrap fee charged: 0 (due to rounding down)

Code:

function calculateUnwrapFee(uint256 unwrapAmount, uint256 unwrapFeeDivisor) public pure returns (uint256) {
  return unwrapAmount / unwrapFeeDivisor; // Integer division causes rounding down.
}

This code snippet demonstrates how the integer division in the calculateUnwrapFee function results in rounding down the fee, leading to potential loss.

Test:

  • Deploy the Ocean smart contract with a specific unwrap fee divisor.
  • Send multiple unwrap transactions with different small and large amounts of tokens.
  • Verify the actual unwrap fee charged for each transaction.
  • Compare the actual fees with the expected fees calculated without rounding down.
  • Analyze transaction logs to identify instances of fee rounding down and quantify the potential revenue loss.

Significant Code Traces:

  • Focus on the calculateUnwrapFee function, specifically the line where unwrapAmount is divided by unwrapFeeDivisor. This line uses integer division, inherently causing the rounding down issue.

Tools Used

  • Solidity Compiler
  • Manual Review

Recommended Mitigation Steps

  1. Implement Truncation:

Modify the calculateUnwrapFee function to use truncation instead of integer division.
This ensures the fee is always rounded towards zero, eliminating revenue loss for smaller unwrap amounts.

Code:

function calculateUnwrapFee(uint256 unwrapAmount, uint256 unwrapFeeDivisor) public pure returns (uint256) {
  return truncate(unwrapAmount / unwrapFeeDivisor);
}
  1. Set Minimum Unwrap Fee:

Define a minimum unwrap fee that applies regardless of the unwrap amount.
This guarantees the contract always collects some fee, even for very small unwrap transactions.

Code:

function calculateUnwrapFee(uint256 unwrapAmount, uint256 unwrapFeeDivisor) public pure returns (uint256) {
  uint256 fee = unwrapAmount / unwrapFeeDivisor;
  if (fee < minimumUnwrapFee) {
    fee = minimumUnwrapFee;
  }
  return fee;
}
  1. Adjust Unwrap Fee Divisor:
  • Increase the unwrap fee divisor to reduce the rounding down effect.
  • This results in smaller unwrap fees for all users but minimizes revenue loss.

Assessed type

Error


The text was updated successfully, but these errors were encountered:

All reactions

7.2 High

AI Score

Confidence

Low