Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

[KIP-001] - Prioritize Kolibri Liquidity Pool for Liquidations #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions kips/KIP01 - Prioritize Kolibri Liquidity Pool for Liquidations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Kolibri Improvement Proposal #01

### Preface
Hello everyone :)
I am honored to present the first Kolibri Improvement Proposal. I feel like Satoshi in some sense right now.
Kidding aside, I welcome and encourage everyone to participate in this and other proposals.
Lets not forget that as kDAO holders and as a community, we are in the control of the future and success of Kolibri.
I should also thank the Kolibri dev team for their hardwork and support.

### Summary
An onchain executable procedure to priorotize the Kolibri Liquidity Pool for oven liquidations.

### Motivation
The Kolibri Liquidity Pool (KLP) is an important and integral part of the kUSD algorithmic stable coin.
It serves at least the following purposes :
1. Makes sure that big ovens that may not be liquidable by individuals, can be liquidated by the pooling the resources of individual kUSD investors.
2. Provides a fair return for the investors who are willing to help the kUSD ecosystem stability.


The current implementation doesnt prioritize the KLP and individual investors compete for the liquidation of the under-collaterized ovens using high fees.
Such implementation is not healthy for the ecosystem and will discourage the pool investors and may lead to disintegration of KLP due to small or no returns of their investment into KLP.
In order to resolve this issue, I propose to give the KLP a X block priority for the liquidations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a high level - why not just let the KLP always liquidate?

The only scenario I can think of is that:

  • An oven with $X in value is liquidatable
  • KLP has <$X in value
  • A private market participant has >$X in value

In this scenario, the private investor could always contribute to the KL, and they'd receive a ratable share of the liquidation reward. Their share of the reward is split among folks in the pool, so it would be less if they were allowed directly, but should still be profitable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, "time" is hard to measure on the blockchain. I wonder if "time" is the wrong metric. Perhaps we should use collateralization percentage or otherwise?

Do you mean the 5 block priority time ? the block height is easy to measure on the blockchain which roughly translates to time. although it may not be 100% precise.

I'm curious about playing with the reward on the liquidity pool.

I dont think this resolves the issue, because the gain to users who liquidate the ovens individually are enormous, compared to anyone participating in the pool and hoping someone else would pay a 1000 XTZ fee to beat the others who are trying to liquidate an oven.
Competing to liquidate the ovens by the fees and hoping miners will pick it up, just does not sit right with me.

At a high level - why not just let the KLP always liquidate?

It is a proposal which I think should be considered seriously and be discussed.
From a technical point of view, it is much easier to implement and has less complexity but aside from that, I think letting both private users and KLP have access to Liquidate entry point brings more trust and stability into system.
If giving KLP priority in someway is hard to implement, probably it is the way to go.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a high level - why not just let the KLP always liquidate?

I think there's real risk to this since with the LP as it is it may fail through a number of mechanisms, potentially destabilizing Kolibri overall. Having individuals still being able to liquidate things means we get to have our cake (prioritize/incentivize the LP) and eat it to (not worry about the negative consequences to the LP being the only liquidator). If Quipu doesn't have enough funds or there's some bug in the interaction there it could be catastrophic.

I do think the reward needs to be higher (probably min 10%, possibly more like 25%), but that's a separate thing.


### Details
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One point I think we should clarify is that today, the in-protocol stability fund KT18wngSoTUqEJiNaYuhcrfYCtsczLUVVkTp may always liquidate an undercollateralized oven [1].

In this future, would they be able to liquidate in the preliquidate phase? Or the liquidate phase?

[1] This is regardless of if the oven is underwater. The fund is currently controlled by a 1/3 msig, held by Hover Labs. Hover Labs has promised to never liquidate anything that isn't underwater. A future KIP to govern control of the fund / give it to a decentralized set of holders may be useful.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this future, would they be able to liquidate in the preliquidate phase? Or the liquidate phase?

If an oven is underwater, I think the in-protocol stability fund should be able to liquidate it immediately and KLP should NOT be allowed to liquidate it because it would lose value. the purpose of the in-protocol stability fund was to manage underwater ovens from the start, not to gain from liquidating undercollateralized ovens.
It is a very rare and edge case that I hope never happens, but it is good that you brought it up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One point I think we should clarify is that today, the in-protocol stability fund KT18wngSoTUqEJiNaYuhcrfYCtsczLUVVkTp may always liquidate an undercollateralized oven [1].

Right now it looks like there's an admin check for the stability fund, so only the breakGlass contract can now do that (which would require a DAO proposal, which surely is way too long a time to wait).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I think you're right in that it's a multisig and not the DAO/gov stuff.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an oven is underwater, I think the in-protocol stability fund should be able to liquidate it immediately and KLP should NOT be allowed to liquidate it because it would lose value. the purpose of the in-protocol stability fund was to manage underwater ovens from the start, not to gain from liquidating undercollateralized ovens.
It is a very rare and edge case that I hope never happens, but it is good that you brought it up.

I think this is reasonable, having the stability fund be able to liquidate immediately is a general characteristic we're looking for for the stability fund's role, so if someone triggered the block timeout, and the stability fund liquidated it (or the stability fund were to just liquidate without kicking off the block timer) then that all holds logically IMO.

In order to make an onchain executable procedure, I propose to make the Liquidation a 2 step process, Preliquidate and Liquidate.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a quick high level view of how this works today.

Kolibri Diagram

I think at a technical level to implement your proposal:

  • We'd need to design a new oven contract, which holds a these new bits of information (at the very least, isPreliqudate. I suspect we may need more, see below)
  • We'd need to update OvenFactory to issue new Oven contracts
  • New APIs to accommodate pre-liquidate should be created in Minter and we'll need to change the minter contract.
  • A new OvenProxy will need to shim the new ovens to the new minter.

So we'd end up with:

  • A set of Oven v1s (these will always liquidate like normal)
  • A set of Oven v2s
  • Oven Proxy v1 and Oven Proxy V2, which shim calls to the Minter
  • Minter V2 (Minter V1 is completely deprecated)

Note: I've architected this system but I welcome debate on if there's a better technical design - I'm not an infallible engineer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally understand my proposal needs updating contracts and adds complexity, I am not a blockchain engineer so I dont comment on the design.
But if it is not worth implementing technically, probably only allowing the KLP to liquidate the ovens is the way to go.

Copy link
Member

@Fitblip Fitblip Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@keefertaylor wouldn't we be able to gate/manage this entirely at the minter?

I feel like we might be able to actually hoist this into the existing system by upgrading the minter and rewriting the %liquidate function and adding a simple map (or bigmap) to the minter that tracks liquidation request states.

Then from the different roles:

  • Liquidity pool would be able to just liquidate underwater ovens no matter what (no complicated timer needed)
  • Stability fund would be the same deal
  • Arbitrary liquidators on first call to liquidate() would just be added to an internal map of liquidation requests along with the block they requested, the oven is not liquidated (but if liquidated by the LP, some cleanup occurs to clear the map), but if that same liquidator comes along and after 5 blocks have passed calls liquidate() on the oven again, it's able to go through without issue.

Unless I'm missing something, I'm not sure there's anything else that needs updated but that one function. Benefits are minimal overhaul to the system, gives us the timeout mechanism we want to allow for the LP to liquidate things, and allows for individuals to liquidate as a last resort with a large economic incentive to keep on top of it.

Copy link
Member

@Fitblip Fitblip Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, if after 5 blocks (well N blocks) pass the oven is no longer liquidatable, the %liquidate entrypoint should just clean things up.

If an oven gets under-collaterized and is not in Preliquidation state, The Preliquidate entrypoint should be called which sets the Preliquidation state and prioritization expiry block height in the oven storage.
The prioritization expiry block height is X blocks higher than the current block. (Can be 5 or 10 or ...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely add this as a constant in the minter's storage, which governance can update.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How complicated would it be to get this data though? Does the DAO contract need to be updated (which would be...complicated lol)?

If an oven is in Preliquidation state and block height is less than expiry block height, only the KLP can execute the liquidate entry point.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you deal with the case where (Assuming a buffer of 5 blocks):

  • At block n an oven is liquidatable
  • At block n+1 the oven is marked for preliquidate
  • At block n+2 the oven is unliquidatable, but no one unmarks it
  • At block n+6 a private user liquidates the oven

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an oven is in Preliquidate state, it doesnt mean that it is liquidatable. It only means that KLP has the priority to exercise Liquidate procedure for X blocks from the time that flag is set.
so at n+6 if the oven is still in Preliquidate state but not undercollaterized, no one can liquidate it anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're over-complicating this a bit, why not just make the LP able to liquidate as long as ovens are under-collateralized (same with the stability fund), and then manage the individual actor path as its own case (with the block level tracking)?

If an oven is in Preliquidation state and block height is higher or equal to expiry block height, meaning the prioritization duration has expired, anyone including KLP can execute the liquidate entry point.
If an oven is in Preliquidation state but has become over-collaterized without liquidation for any reasons the ResetLiquidate entrypoint can be called which resets the Preliquidation state and expiry block height in the oven storage.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who would be calling ResetLiquidation? Liquidators are incentivized to liquidate anything they can, so it's unlikely (IMHO) that the masses would generously try to keep folks from being liquidated against their interest.

I think there's the possibility that we automatically reset the state if it is called m blocks in the future, but this has its own set of thorny issues (ex. What if the oven was actually liquidatable for m blocks)

Copy link
Author

@ffallah ffallah Aug 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should provide economical incentives to the users who help the govern and run the whole ecosystem. for example rewarding anyone who successfully executes Preliquidate, Liquidate for KLP and Resetliquidate entrypoints on ovens with 1 kUSD from the KLP because it is a service to the KLP and its investors.

In order to make sure these procedures are followed and executed by the community, the proper economic incentives are provided by the Kolibri DAO and users executing these procedures are awarded accordingly.
The award can be kDAO tokens or a percentage of the successful KLP liquidations or etc.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with a sufficiently large LP reward rate (10%-50%) folks would retool to compete for having the LP do its thing, and then the individual liquidators can be used as a last resort (in case Quipu pauses the pool, or there's some other issue like 0 liquidity in the quipu pool).