In the constructor of FeeCollector.sol, _initializeFeeTypes()
is called. However, for fee types 6 & 7, the values set for the respective fee shares do not amount to 10000 basis points. This results in disproportionate distribution of collected fees.
In _initializeFeeTypes()
, it sets the default fee types according to protocol rules, which is denoted in basis points. Focusing on fee type 6 and 7:
As seen above, feeTypes[6] totals up to 500 + 500 + 1000 = 2000. feeTypes[7] totals up to 500 + 1000 + 500 = 2000.
Assume distributor role now distributes the collected fees via distributeCollectedFees()
.
_calculateTotalFees()
will add together all fee amounts in the respective fee types in CollectedFees
struct.
Now, _calculateDistribution()
is called.
In the code snippet above from _calculateDistribution()
, it is part of the for loop to check through every fee type and distribute the collected fee amount for the particular fee type to 4 types of stakeholders, denoted by shares[].
Simulating the scenario whereby the loop is checking for fee type 6, and feeAmount = 10_000e18. totalFees = 100_000e18:
weight = (10000e18 * 10000) / 100000e18 = 1000e18
shares[0] += (1000e18 * 500) / 10000 = 50e18
shares [1] += (1000e18 * 500) / 10000 = 50e18
shares[2] += (1000e18 * 1000) / 10000 = 100e18
shares[3] += 0
As seen above, amount distributed to the various shares do not total up to the feeAmount of 10000e18. There is 9800e18 remainder undistributed for fee type 6. Hence, referring to line 15 in the code snippet above, all remainder accumulated across every fee will be directed to shares[3], which is to the treasury.
At _initializeFeeTypes()
, it is evident that fee type 6 and 7 are not set correctly as it does not total up to 10000 basis points, and no basis points are allocated to treasury, showing that having the remainder flow to the treasury is not intentional.
These erroneous values that have been set will result in disproportionate distribution of fees, whereby a large portion of the collected fees for fee type 6 and 7 will be distributed to treasury respectively. veRAAC holders will get much lower amounts of distributed RAAC rewards.
Although fee manager admin can update the fee shares via updateFeeType()
, there is still possibility that the distributor role calls distributeCollectedFees()
with the erroneous fee shares set in the constructor.
Manual
When initializing the default fee types, ensure that the fee shares total up to 10000.
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.