superfluid-finance / superfluid-sentinel

MIT License
24 stars 13 forks source link

Priorization and timing of liquidations #165

Closed d10r closed 1 year ago

d10r commented 1 year ago

The current sentinel implementation has no concept of the cost and profitability of a liquidation. It's limited only by the token selection and MAX_GAS_PRICE config item. There's several problems / sub-optimalities we could address:

1. non-PIC liquidations shouldn't delay PIC liquidations

If a sentinel handles a mix of PIC- and non-PIC-tokens, it should put liquidations of the PIC-token in front of the queue.

2. no concept of how much a liquidation costs

The cost of a liquidation is

cost = gas_price * gas_limit

Gas price can be highly volatile depending on fee market conditions, gas limit can vary greatly if SuperApp hooks are involved. This cost can be approximately calculated before and precisely after a liquidation. As a first step, we should log the cost.

3. no concept of profitability of a liquidation

Non-PIC liquidations should occur only if the liquidation is expected to be profitable:

reward > cost

The reward is calculated as

reward = remaining_deposit - (flowrate * (t_now - t_became_critical))

during the liquidation period. After the liquidation period, the reward becomes reward = deposit for non-PIC liquidations while it turns negative according to the above formula for PIC liquidations - that negative reward is taken from the PIC bond and applied lazily as soon as the liquidation happens (regardless of who triggers it).

For a start, this calculation could already be implemented for the native token wrapper SuperToken (SETH), such that unprofitable liquidations remain in queue, just as if the gas price cap were exceeded. Together with logging. We can also define a basket of "stable assets" with price information, as no high precision is needed here.

In order to test for all tokens, the reward amount needs to be converted to the native token unit of account. Possible implementation: use Uniswap V2 (or its dominant clone on that chain). E.g. provide the sentinel with a mapping of chain-id / UniV2 factory address, from there it should be possible to figure out the price of the SuperToken underlying.

4. no concept of high vs low gas prices

Liquidation cost can fluctuate wildly with gas prices. While non-PICs can just not do unprofitable liquidations, PICs need to eventually take care of them, otherwise their cost eventually eats up the bond. They could however minimize the cost by avoiding time windows of high gas prices. In order to implement this, we basically need to have a gas price predictor which allows to probabilistically predict if a liquidation should be delayed. This may be the case especially for streams with small reward during congestion periods. We need something like

get_predicted_price(current_price, t)

In order to implement this calculation, some kind of price history data is needed. The sentinel could build its own price history by persisting prices it observes (especially on EIP-1559 enabled chains). To be figured out: what kind of formula best implements such a predictor?

Two hypothetical scenarios for how the profitability could evolve over time. Here in both cases the profit is always negative, thus non-PICs would (should) just ignore them. But PICs could try to minimize their losses by timing the liquidation. The smaller the flowrate is, the more sense it will make waiting for the gas price to come down. image

ngmachado commented 1 year ago

This is more a discussion than one specific issue. @Didi can we migrate to a specific discussion?

d10r commented 1 year ago

moved to https://github.com/superfluid-finance/protocol-monorepo/discussions/1295