Skip to content
This repository was archived by the owner on Oct 8, 2024. It is now read-only.
This repository was archived by the owner on Oct 8, 2024. It is now read-only.

Tracking error due to fees, and oracle may undervalue LP shares by to-be-accrued fees  #15

Open
@livnev

Description

@livnev

There might be two subtleties relating to LP fee accural in Uniswap which affect the accuracy of this oracle:

(i) for the purpose of valuing the shares, this oracle assumes that the assets in the pool will eventually be rebalanced such that the balances of the two assets represent equal value. This assumption is necessary in order for the LP price oracle to be resistant to manipulation of pair balances (by sanwiched back-and-forth trading, for example). However, the assumption is not exactly accurate due to the presence of the 0.30% taker fee (in the current Uniswap code), meaning that if "full arbitrage" occurs it will only take the balances to a ratio that is 0.30% away from "market value". This 0.30% discrepancy is always "in favour of the LPs" meaning that the oracle effectively undervalues the LP shares by up to 0.30% in these instances (and by less when the price implied by current balances is less than 0.30% away from "market value").

For an example of an oracle implementation which does not have this discrepancy, (probably) at the cost of burning more gas, see here. The tl;dr is that this implementation simulates the effects of an actual profit-maximising trade on the balances of the pool, instead of using the elegant but simplified formulas in this repo.

(ii) the effect of protocol fee accrual on the value of LP shares is not taken into account. Specifically, the implementation in this repo relies on the hypothesis that sqrt(res0 * res1) / totalSupply is invariant across trades, mints, and burns. In fact, this quantity is not quite invariant, since it can increase by the accrual of taker fees, but this growth is precisely the discrepancy described in (i) above which results in a slight undervaluation of the shares by the oracle. However, due to the presence of the _mintFee function in Uniswap, it is also possible for this invariant to decrease, when _mintFee is called from mint or burn, and a decrease in this invariant will result in an overvaluation of the shares, which is potentially more problematic for our purposes. Moreover, the magnitude of the overvaluation is not bounded by 0.30%, and can in theory be very large if mint or burn have not been called for a long time while a significant increase in sqrt(res0 * res1) / totalSupply has occured due to trading.

Explicitly, since the protocol fee is hardcoded to ~17% (while currently disabled), the oracle will overvalue the LP shares by 17% of the fee growth since the last call to mint or burn. Taking GRT/USDC, a pool with currently very high fee revenue, as an example, we see that if mint or burn have not been called for a day, then the shares will be overvalued by ~0.35%, and if no one calls it for a week they will be overvalued by 2.4%, etc. Obviously, it is very unlikely that the pool will go for so long without any mint or burn, and I am not aware of any way to stop them from being called or otherwise force this outcome, but it is still worth keeping in mind by anyone consuming this oracle, since in some cases this could be problematic.

Incidentally, the oracle implementation linked earlier, explicitly accounts for _mintFee here, avoiding this problem. Another way around it would have been to somehow call _mintFee before starting the calculations, however I don't see a way of doing that since minting or burning 0 shares is not allowed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions