Inconsistent Share Calculation in calculateShareByAddress for the Last Beneficiary
calculateShareByAddress uses (totalAmount * weight) / totalWeight uniformly for every beneficiary, but distribute() sweeps the rounding remainder into the last beneficiary. The view function returns a value that does not match the on-chain payout.
Description
The function calculateShareByAddress in FeeDistributionVault.sol calculates the share of a given beneficiary based on their weight relative to totalWeight:
(totalAmount * beneficiary.weight) / totalWeight;
However, this logic diverges from the actual distribution logic implemented in the distribute function, specifically for the last beneficiary.
In distribute, the remaining balance (remainingAmount = balance - distributedAmount) is transferred to the last beneficiary to avoid dust (small leftover tokens caused by rounding errors):
uint256 remainingAmount = balance - distributedAmount;matToken.safeTransfer(beneficiaries[beneficiaries.length - 1].addr, remainingAmount);
As a result, when calculateShareByAddress is called for the last beneficiary, it may return a value that does not match what will actually be transferred during distribution.
This discrepancy can mislead frontends, indexers, or other off-chain systems relying on calculateShareByAddress to predict actual payout amounts. Specifically, the last beneficiary might see a computed value that underestimates or overestimates their real share.
Impact
Off-chain consumers display the wrong payout estimate for the last beneficiary in the list. The on-chain distribution is unaffected, but UIs and integrators may show stale or incorrect numbers.
Recommendation
Update calculateShareByAddress to mirror the behavior of distributing for the last beneficiary. This could involve:
- Summing the calculated shares for all previous beneficiaries.
- Returning
totalAmount - sum(previousShares)for the last beneficiary.
This change will ensure consistency between the view logic and the actual on-chain distribution, eliminating confusion or mismatches in expected payouts.

