The Market::receiveWethReward function incorrectly updates wethRewardPerVaultShare, leading to an over-allocation of WETH rewards to vaults. Instead of distributing WETH rewards proportionally based on delegated credit, the function adds the entire reward amount to wethRewardPerVaultShare. The wethRewardPerVaultShare represents the amount of weth reward accumulated by the market per vault delegated credit (share). Instead of adding weth reward per credit, receiveWethReward adds the whole amount causing miscalculation. As a result, multiple vaults receive more rewards than they are entitled to, causing an imbalance in the reward distribution.
The receiveWethReward function is invoked by FeeDistributionBranch::_handleWethRewardDistribution.
This function accepts receivedVaultsWethRewardX18 as an argument and directly updates wethRewardPerVaultShare without considering the total delegated credit.
Since the reward is not divided by the total delegated credit, it is stored in full, causing over-rewarding across vaults.
Consider receiveWethReward is called with receivedVaultsWethRewardX18 = 10e18
Market::wethRewardPerVaultShare will add 10e18
When Vault::recalculateVaultsCreditCapacity is called, it will calculated the change of wethRewardPerVaultShare. It will deduct lastVaultDistributedWethRewardPerShare from Market::wethRewardPerVaultShare and return the result. So the return will be 10e18
After that recalculateVaultsCreditCapacity will call self.wethRewardDistribution.distributeValue(vaultTotalWethRewardChangeSD59X18); to update value per share. Since vaultTotalWethRewardChangeSD59X18 is 10e18, the valuePerShare will be 10e18/2e18 = 5e18
The reward for the users of this vault becomes: totalShares * (valuePerShare - lastValuePerShare). This will be 10e18.
If there are more than one vault connected to the market, the vaults will be drained off WETH. If users from one vault claims reward, other users from other vault won't be able to claim anything as due to lack of WETH and vault will be in shortage of WETH
The system may drain WETH liquidity, as vaults will continuously withdraw more than what is available for rewards
Protocol funds will be at risk, as excessive WETH withdrawals may leave the system insolvent.
Manual code review
Modify Market::receiveWethReward, such that the receivedVaultsWethRewardX18 is divided by total delegated credit. This division will ensure vaults will get only their share.
When vault retieves the weth reward, it should be multiplied with vault shares to get the correct amount
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.