Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Valid

Vault WETH Rewards Not Proportional to Delegated Credit

Summary

The getVaultAccumulatedValues function fails to multiply the change in WETH rewards by the vault’s share of total delegated credit, resulting in a non‑proportional reward distribution.

Vulnerability Details

The function calculates wethRewardChangeX18 as follows:

wethRewardChangeX18 = ud60x18(self.wethRewardPerVaultShare).sub(lastVaultDistributedWethRewardPerShareX18);

The calculation for wethRewardChangeX18 subtracts the last distributed WETH reward per share from the current value without considering the vault's share of the total delegated credit. This omission allows all vaults to receive the full change in WETH rewards, regardless of their actual contribution. Consequently, a single vault could claim the entire WETH reward meant to be distributed proportionally among all vaults. This flaw breaks the security guarantee of fair and proportional reward distribution, leading to potential financial imbalances and dissatisfaction among vault participants.

Impact

Medium because it can lead to unauthorized enrichment of individual vaults and disrupt the intended reward distribution mechanism. By failing to distribute rewards proportionally, the system risks financial imbalances and potential exploitation by vaults with smaller credit shares.

Likelihood is medium, since it requires a vault to have a smaller share of the total delegated credit, the absence of proportional distribution makes it feasible for any vault to claim a disproportionate share of the rewards. The risk is higher in systems with multiple vaults and varying credit shares.

Tools Used

An attacker could exploit this vulnerability by operating a vault with a minimal share of the total delegated credit. When the getVaultAccumulatedValues function is called, the vault would receive the full change in WETH rewards, regardless of its actual contribution:

// Assume vault A has a minimal credit share
uint256 wethRewardChangeX18 = ud60x18(self.wethRewardPerVaultShare)
.sub(lastVaultDistributedWethRewardPerShareX18);
// Vault A receives the full reward change, leading to unauthorized enrichment

This configuration would result in vault A receiving a disproportionate share of the WETH rewards, disrupting the intended distribution mechanism.

Recommendations

Modify the calculation of wethRewardChangeX18 to incorporate the vault’s credit share. For example:

wethRewardChangeX18 = ud60x18(self.wethRewardPerVaultShare)
.sub(lastVaultDistributedWethRewardPerShareX18)
.mul(vaultCreditShareX18);

This correction ensures that each vault receives a reward proportional to its contribution, preserving the intended economic balance.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

`wethRewardPerVaultShare` is incremented by `receivedVaultWethReward` amount which is not divided by number of shares.

Support

FAQs

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