Skip to content
Request an audit

ViewFacet.queryAssetBalances doesn't include uncollected uniswap fees for compounded maker position

TitleViewFacet.queryAssetBalances doesn't include uncollected uniswap fees for compounded maker position
Reward$886, Unique
ContestAmmplify - 2 Sep 2025 on Sherlock
Authorpanprog
ContextMissing Logic

When ViewFacet.queryAssetBalances calculates the earnings for a compounded maker, it ignores the uncollected Uniswap fees:

solidity
uint256 fee0DiffX128 = newFeeGrowthInside0X128 - node.liq.feeGrowthInside0X128;
uint256 fee1DiffX128 = newFeeGrowthInside1X128 - node.liq.feeGrowthInside1X128;
if (data.liq.liqType == LiqType.MAKER) {
    // We just claim our shares.
    // If the sliq and shares are zero, you should fail anyways.
    // @audit-issue compounded maker should also include fee0DiffX128/fee1DiffX128 here
    data.earningsX += FullMath.mulDiv(node.fees.xCFees, aNode.sliq, node.liq.shares);
    data.earningsY += FullMath.mulDiv(node.fees.yCFees, aNode.sliq, node.liq.shares);
} else if (data.liq.liqType == LiqType.MAKER_NC) {
    data.earningsX += FullMath.mulX128(
        aNode.sliq,
        fee0DiffX128 + node.fees.makerXFeesPerLiqX128 - aNode.fee0CheckX128,
        false
    );
    data.earningsY += FullMath.mulX128(
        aNode.sliq,
        fee1DiffX128 + node.fees.makerYFeesPerLiqX128 - aNode.fee1CheckX128,
        false
    );
} else {

When the compounded maker asset is actually removed, the uncollected Uniswap fees are added to node.fees.xCFees and node.fees.yCFees and compounded as extra liquidity. If the liquidity is not increased, because the fees are below the compound threshold, they are simply added to those two fields. Either way the value reaches maker earnings — which is exactly what ViewFacet fails to do.

The reported earnings are therefore too low, and an integrator that fails to account for the fees can break its own logic and lose the difference.

The README puts the issue in scope:

Issues that lead to getting incorrect return values (i.e. deviates from the withdrawal value of the asset by more than 0.01%) from the queryAssetBalance function (even if the appropriate input is used), which will lead to issues when executing other functions, may be considered valid with Medium severity at max.

Alpha: it is very common for Uniswap fees to be missed when querying a position's value. Here the README put view functions in scope, but often the view function is also used internally by state-changing ones, and the bug matters regardless.

Conclusion

This finding would earn you $886. Always verify that Uniswap fees are tracked, compare the view function against the state-changing one, and read the README.

Full Report
Codebase

Message on Telegram All 62 posts