-
Notifications
You must be signed in to change notification settings - Fork 3
[KIP-001] - Prioritize Kolibri Liquidity Pool for Liquidations #1
base: master
Are you sure you want to change the base?
[KIP-001] - Prioritize Kolibri Liquidity Pool for Liquidations #1
Conversation
Fixing under and over collateralization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At a high level, I agree that we should incentivize pool based liquidations in some way.
Some thoughts:
- 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?
- It is unclear to me why we need private users at all - the pool is open to everyone and introducing a 2 phased approach adds technical complexity
- I'm curious about playing with the reward on the liquidity pool. If there's a portion of folks writing liquidation bots today, then they are taking on (1) currency risk by holding kUSD and not earning on it and (2) technical risk that their bot wins. The potential returns make this a tradeoff that is worth it to some people today. A higher reward on the pool eliminates risk 1 (because the liquidator bot doesn't need to hold currency) but decreases their returns (the pool reward is less than a full on liquidation). I'm interested if there's an equilibrium here.
|
||
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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. | ||
|
||
### Details |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 resolve this issue, I propose to give the KLP a X block priority for the liquidations. | ||
|
||
### Details | ||
In order to make an onchain executable procedure, I propose to make the Liquidation a 2 step process, Preliquidate and Liquidate. |
There was a problem hiding this comment.
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.
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 newOven
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 callsliquidate()
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.
There was a problem hiding this comment.
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.
### Details | ||
In order to make an onchain executable procedure, I propose to make the Liquidation a 2 step process, Preliquidate and Liquidate. | ||
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 ...) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)?
In order to make an onchain executable procedure, I propose to make the Liquidation a 2 step process, Preliquidate and Liquidate. | ||
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 ...) | ||
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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)?
The prioritization expiry block height is X blocks higher than the current block. (Can be 5 or 10 or ...) | ||
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. | ||
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. |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
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. | ||
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. |
There was a problem hiding this comment.
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).
So this is a great KIP1 @ffallah - huge thanks for writing it up :). I think it has some refinement to actually figure out what needs to change and where we can get creative with solutions, but this is a good start that captures the spirit of what we're trying to accomplish! I left some comments in-line, hopefully this won't be too crazy to implement! |
@keefertaylor thanks for taking the time to comment on this as well! As the architect of these contracts you definitely know best about how to go about things, so ultimately I'll defer to your expertise here, but I've tacked on some thoughts in-line (and below).
I think tracking block heights is pretty straight forward with a little state management. Cleaning things up is key to all of it though (if we use a map keeping it clean when things transition to various states).
I do think private users really does add a level of safety to this whole endeavor assuming it's not too gross to implement - there's a few ways that the current LP fails and at that point we're in a situation where things are unstable: It's probs a good idea to pull in the quipu folks to better understand the risks associated with the pool, or upgrade the LP so that it's not a hard requirement on Quipuswap (or fails gracefully) to liquidate ovens. I'm sure folks would be OK getting XTZ + kUSD for their QLkUSD tokens, but I'm unsure how easy it is to gracefully recover from a failed inter-contract call 🤔. |
I'd just like to comment I am greatly in favor of this proposal as I think it makes the process more fair for all participants. I think it makes sense that private users should be able to liquidate after a certain amount of time for reasons listed by others, what the correct delay should be, I'm not sure. 5 blocks seems long enough that it would, in theory be impossible for someone to bribe a baker not to include the operation, but idk. Also, since I believe this proposal would be so favorable, I'd also be in favor of a small percentage of the liquidation going to the stability fee/treasury/dev fund as well but that could be up for debate. |
Prioritize Kolibri Liquidity Pool for Liquidations