DittoETH

Ditto
DeFiFoundryOracle
55,000 USDC
View results
Submission Details
Severity: medium
Invalid

Unsafe downcasting in arithmetic operation

Summary

Unsafe downcasting in arithmetic operation

Vulnerability Details

Value is unsafely downcasted and truncated from uint256 to uint96 .

Impact

The unsafe downcasting in claimDittoMatchedReward() for Vault.dittoMatchedReward at line 175 will result in loss of rewards for user.

function claimDittoMatchedReward(uint256 vault) external nonReentrant {
STypes.Vault storage Vault = s.vault[vault];
STypes.VaultUser storage VaultUser = s.vaultUser[vault][msg.sender];
// User's shares total
uint88 shares = VaultUser.dittoMatchedShares;
// Implicitly checks for a valid vault
if (shares <= 1) revert Errors.NoShares();
// Decrease by 1 wei to account for 1 wei gas saving technique
shares -= 1;
// Total token reward amount for limit orders
uint256 protocolTime = LibOrders.getOffsetTime() / 1 days;
uint256 elapsedTime = protocolTime - Vault.dittoMatchedTime;
uint256 totalReward =
Vault.dittoMatchedReward + elapsedTime * 1 days * Vault.dittoMatchedRate;
// User's proportion of the total token reward
uint256 sharesTotal = Vault.dittoMatchedShares;
uint256 userReward = shares.mul(totalReward).div(sharesTotal);
// Only update dittoMatchedTime when totalReward increases
if (elapsedTime > 0) {
Vault.dittoMatchedTime = uint16(protocolTime); // @dev(safe-cast)
}
// Update remaining records
Vault.dittoMatchedShares -= shares;
if ((totalReward - userReward) > type(uint96).max) revert Errors.InvalidAmount();
175: Vault.dittoMatchedReward = uint96(totalReward - userReward);
VaultUser.dittoMatchedShares = 1; // keep as non-zero to save gas
if (userReward > type(uint80).max) revert Errors.InvalidAmount();
VaultUser.dittoReward += uint80(userReward);
emit Events.ClaimDittoMatchedReward(vault, msg.sender);
}

The loss is due to broken accounting if the value exceed uint96 , resulting in overflow and impacting rewards.

Tools Used

Manual code review.

Recommendations

The recommendation is made for using uint256 or apply Openzepplin’s SafeCast library.

Updates

Lead Judging Commences

0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.