Skip to content

Protocol Design #1

@norswap

Description

@norswap

Here's the MVP approach from the README:

Users can create an order, or can take the opposite side of an existing order. An order consist of the expiry date for contract and the order, contract "value" (i.e the collateral, and max amount to loose), if the position is long or short, and asset (ETH/ERC20).

Order matching is done inside the contract. For the MVP version all orders are 1:1, but in the future support for difference ratio based on market conditions would make sense (if the entire market is crashing going long should yield higher payout than going short).

Both user has to deposit the value of the contract as collateral. To make things a bit simpler, I think it makes sense to value all contracts in ETH. At the expiration of the payout is done based on changes in the underlying asset against ETH. We will use ChainLink for price history. Users can also never loose more than what they put up as collateral.

So this design has a few issues (entirely my fault, since I suggested it):

  • Taking the long position is less attractive than buying the real asset, because the max upside +100%.
  • Shorting is generally unattractive in crypto because of high volatility and the max profit while shorting is 100% while the max loss is unlimited. Some stopgaps can be taken to sweeten the pot, like letting the contract price fluctuate above the asset price, but that further reduces the upside of the long side.
  • The contract must be "settled" at some point (i.e. both sides paid according to the current asset price). This means that either we need expiry dates, which fragment liquidity, or you must allow for both party to break the contract at any time (not great).

But fear not, I have an alternative design that I'm super exicted about. It's based on a protocol-issued stablecoin (or at least pseudo-stable), which acts a bit like a poker chip (let's call it $C for the purpose of this explanation). To enter any position, a user has to enter it with $C.

So if an asset has price 100$, the long side must enter with 100 $C, and so does the short side. The protocol mints $C on demand in exchange for 1$. In exchange they receive one synthetic token. Imagine the asset is ETH, they would receive one $cfdETH (long) or one $scfdETH (short). In the contract, their $C would be locked in two distinct pools: the long pool and the short pool.

When an oracle update comes in, saying that the price of ETH increases 10%, then 10% of the $C locked on the short side is transferred to the long side. And vice-versa when the price decreases.

The synthetic assets give a claim to the underlying pool. So if there the total supply of $cfdETH is 100, and you own one, then you have a claim on 1% of the $C locked on the long side of the pool, which you can redeem at any time.

This works perfectly well when the long side and the short side are perfectly balanced (i.e. the same amount of $C locked on each side), but that's unlikely to be the case. First because of the long bias (although there could a short bias when the market dumps), and second because this equilibrium is constantly shifting.

Take the 10% ETH price increase as an example. It leaves the pool unbalanced at 110 $C vs 90 $C.

The solution is to mint $C out of thin air to make everybody whole. Of course, this is an inflation and stability concern, because we're now minting unbacked $C.

One thing we can do is to encourage users to naturally balance the pools. One way we can do that is to claim less than our fair share of the pool.

Let's take an extreme example. The price of ETH is 100$. There are 10 people on the long side, but only one person on the short side. We thus have a 1000/100 $C imbalance. The protocol has to "mint" 900 $C on the short side to make the pool balanced.
One way to conceptualize this is that the protocol takes the role of a normal user on the short side, excepted it gets all its $C for free. So in this case, it would get 9 $scfdETH.

Imagine the price goes down to 90$. The protocol would normally be entitled to a gain of 9*10 = 90$C. What if instead, we credited an disproportional amount of this gain to the lone shorter?

There's many formulas we could use to this, and figuring this out is future work, but for now let's assume the protocol only claims 30% of the gains. So it gains 9*0.3*10 = 27$C while the lone shorter gets 10 + 9*10*0.7 = 73 $C. More than 7x his "normal" 10$C payout!

The risk/reward imbalance should cause people to rush in to balance the pool until the "premium" (730% in the example above) is a fair risk premium for the risk of shorting. This should be especially true since there is a way to hedge and arbitrage: long the asset (possibly by buying it on another chain, but possibly on this protocol), short it on the protocol. If the asset goes up, you're neutral, but if the value goes down, then you're making more on the short side than you're losing on the long side. Risk-free profit!

So in practice, since the protocol backstops the value with newly minted $C, and assuming the presence of smart arbitrators, the pools should be pretty balanced, which minimizes the emission of new $C, which should remove the concern about runaway inflation.

There is still a concern about the stability of $C price: will it keep peg to 1$? How do you redeem your $C for other stables?

The basic idea is that as long as demand for $C exceeds supply (i.e. people redeeming), the price will remain a 1$ (it will never exceed 1$ since the protocol is willing to mint for 1$). If it ever goes in the other direction (which is inevitable over the lifetime of a project, then there is a risk of depeg).

My suggestion here would be to implement an "exit queue": anybody can queue their $C to be sold, and in this case, the protocol will use this pool of $C to supply to new users instead of minting new $C. (Note we can't use the protocol treasury for the same purpose, since some $C was minted out of thin air — the total $C supply is only partially backed.)

This can still be a big problem if the queue grows too much or too fast. I'd fix this via a protocol token (let's call it $CFD for now). If the queue grows beyond a certain threshold, people that own $C can mint $CFD at a small discount to the market price. This allows them to exit by acquiring the token at a discounted price (and potentially dumping it immediately). Because this creates an arbitrage, the effect should be that arbitrageurs should start acquiring $C in order to purchase discounted $CFD and make a profit. So this should move the queue along.

(Alternatively, and this is probably a better approach, we could avoid minting $CFD, and just offering a discount on a $C-$CFD AMM purchase. This would have the stabilizing benefit that if the exit queue gets too full, demand for $CFD will be stimulated. It goes without saying that this all requires more thinking / modelling.)

This means that $CFD will go down in value when the TVL decreases. However, $CFD holders benefit when the TVL increases: when the queue is empty, the protocol mints $C in exchanged for other stablecoins, and those go straight to the protocol's treasury. And the treasury essentially provides a floor on the $CFD price.

In addition, the protocol should probably take some small fees (0.3%?), probably when entering and exiting synthetic positions.

Addendum: we also need to think about MEV — in particular, a user should only be allowed to effectively enter a pool following an oracle update. Otherwise, users could front-run oracle updates, piling into a position when they already know that the price will increase, and exit immediately after.

Addendum 2: the minting model means that the pools need to be permissioned — we can't allow an asset whose price could be too easily manipulated, because that creates an obvious attack to extract $C from the system. This is not too great: the initial idea was to enable to long/short ANY asset, and now we need to assess the reputability of the assets we allow. I think there are things to be done here, which is basically to create permissionless mini-copies of the protocol for specific assets (so they would have their $Cprime stable), and bridge them to the main one with something that can act as a breaker (e.g. an AMM pool that the deployer of the new asset supplies initial liquidity for). But that's FUTURE work.

Addendum 3: we can't really long/short ANY asset, because we're limited with things covered by oracles (Chainlink list here). In the future, it will be possible to read the L1 state from Optimism, so I think we'll be able to use that to get more price feeds and even things like Uniswap TWAMM, etc...

Would love feedback on this. Anybody to poke holes in the design?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions