Obedient Lava Monkey
Medium
A miscalculation in the fee allocation logic in executeBackUnbacked
will cause incorrect fee distribution for the protocol treasury as rounding errors in fee.percentMul(protocolFeeBps)
can lead to a portion of the fee being lost.
In BridgeLogic.sol, the fee is split into protocol fees and liquidity provider (LP) fees using percentage math:
uint256 feeToProtocol = fee.percentMul(protocolFeeBps); // Calculates protocol's share of the fee
uint256 feeToLP = fee - feeToProtocol; // Remainder allocated to LPs
However, percentMul
truncates results due to integer division, leading to rounding errors. This causes the feeToProtocol + feeToLP
to be slightly less than the total fee
, resulting in a small portion of the fee being lost. percentMul
**, defined in Aave’s math libraries, performs multiplication followed by integer division ((a * b) / 10_000
), which inherently truncates fractional results. This truncation ensures the sum of feeToProtocol
and feeToLP
is slightly less than fee
due to the discarded remainder.
- The
protocolFeeBps
is set to a valid value (e.g., 10_000 BPS = 100%). executeBackUnbacked
is called with a non-zerofee
.
- The caller interacts with the contract, triggering
executeBackUnbacked
. - Dependencies (e.g.,
percentMul
) are assumed to be functional but subject to truncation.
- A user backs unbacked tokens via
executeBackUnbacked
with a specifiedfee
. - The protocol calculates
feeToProtocol
andfeeToLP
. - Due to rounding in
percentMul
, the total of these values is slightly less than the originalfee
. - The difference is effectively "lost" as it’s not allocated to the protocol or LPs.
The protocol treasury and LPs collectively lose a small fraction of the fees due to rounding errors, leading to potential financial inefficiency over many transactions. While each transaction's impact is minimal, the cumulative effect could result in significant losses.
Adjust the calculation to ensure no fees are lost by assigning the rounding error to the LPs or the protocol.
uint256 feeToProtocol = fee.percentMul(protocolFeeBps);
uint256 feeToLP = fee - feeToProtocol; // Handles remainder implicitly
assert(feeToProtocol + feeToLP == fee); // Ensures all fees are accounted for