DAI:ETH UNI-V1 Oracle Discussion

Based on a few different lines of communication I have seen, it seems that our main holdup on adding UNI-V1 as a collateral type is a lack of clarity on how the oracle itself would function.

Given my impression of interest in seeing it as MCD collateral, I thought I would start a conversation about that to hash out the details of a potential oracle.

To that end, I will add a PoC implementation that I threw together just to demonstrate what I think might be a decent approach, but please don’t think of this as a definitive solution. I like to think of it as the 1st proposed pricing model in this thread.

As part of this discussion, I think it would be great to hear any possible approaches to pricing UNI-V1 tokens and any concerns about the proposed solutions.

If you have any ideas please add your thoughts.

8 Likes

In the above solution, we are connecting to an ETH node to poll the uniswap contract. In that solution we get the DAI and the ETH balances that the contract holds. Using the ETH:USD price from some oracle (in my case coin gecko) I am able to arrive at a price by dividing the USD value of the liquidity pool by the total number of issued liquidity tokens. That instantaneous number is then used to compute the 1-minute moving average which you see outputted in that program.

After doing some digging into the oracles source code. I reached out to nick to suggest a few ways that we might be able to adapt the approach above to fit into the current oracle architecture.

It seems based on nick’s comments that there are a couple of concerns with the proposed approach. Namely, that there are some scalability concerns around connecting to ETH nodes. This could potentially be worked around by providing this data via an HTTP endpoint similar to how we get pricing data today, but that raises trust concerns around the HTTP endpoint itself.

Based on this it seems that the foundation is not interested in incorporating on-chain data for oracle purposes at this time. Probably leaving our uniswap tokens dead in the water unless they see a HUGE uptick in trading activity or a change in heart coming from the foundation. He mentioned that they plan to address this in the future, but that won’t be released until the Oracle-V3 architecture is completed :slightly_frowning_face:

1 Like

Well call me stubborn but I’m back to comment on this. I was a little unimpressed by the comment coming from the foundation stating that uniswap tokens could not be supported at this time, so I did some digging. The TLDR of that is I’ve looked through the oracle code a good bit and, having done that, I think this can be supported by the current V2 architecture.

Let’s talk a bit about the oracles-v2. Basically the whole thing is powered by this program called Omnia. Omnia is the program that is reading prices from coinbase/biance/etc and then publishing the median of those prices to an ethereum contract such that it can be used the protocol. However, Omnia itself can kind of be thought of as two separate programs as it has two different modes that it can run in. A “FEED” program and A “RELAYER” program. Now while these two programs are written in the same code base they don’t actually talk to each other directly. They use a distributed gossip protocol called scuttlebutt to relay messages from the feed program to the relayer program. So here is how it works. you have a process running the omnia-feed program it fetches prices from 3p APIs and then it publishes that price to scuttlebutt simple as that. Separate from that, you have a process, the relayer, reading the scuttlebutt feeds. Once the relayer has found a price from enough of the feeds it takes the median of those prices and then publishes it to the DSValue contract, but it is important to note the relayer doesn’t know anything about the feed program. The relayer is just reading JSON messages off of scuttlebutt. It has NO IDEA how the price number that is contained in that JSON message got there. It just reads the latest message off a few topics and publishes the median of those to the blockchain. So if we want to introduce a novel oracle to the system all that we need to do is have that oracle publish pricing information to a scuttlebutt feed and update the relayer’s config file such that it will read from that feed.

Having learned all that. I’ve updated the POC oracle to do exactly that. Every time that a new block is posted it fetches the DAI and ETH balances, eth price, and token supply to arrive at a price. It then takes that price and finds the 5 minute moving average. Every time that it updates this moving average it publishes a JSON message to scuttlebutt. Now, as long as we have matched the format used by the feed program the relayer shouldn’t have any trouble reading our message, and if it can do that it can publish it on-chain. Criticisms are welcome here, but I think this is the rough idea.

Now just for completeness sake, I will also take a moment to argue that the scalability concerns are also a bit overstated. There are plenty of high throughput / hosted eth interfaces out there that you could connect to such as https://infura.io/. If you had concerns about the scalability of infura.io itself you could just connect to a second hosted eth node for instance https://alchemyapi.io/. This would mitigate concerns by ensuring that if one of the ETH interfaces that you were using was down you would still have prices coming in from the second.

This is where I’ll leave things off though. I can’t be the only person advocating for this thing as collateral, and I cannot make further progress on the PoC without the foundation giving me more information about their ssb server. We need buy in from the foundation. So if you want to see this idea explored further I would suggest putting some comments in this thread and stating as such.

5 Likes

I would like to propose an alternative way of calculating the price of a UNI-V1 ETH share. Rather than take a moving average, we can take use the market price of ETH-DAI to calculate the “fair value” of the collateral.

Uniswap works off of an invariant. This is the result of SHARE_DAI * SHARE_ETH. This invariant will grow as LPs earn fees but it will remain unaffected by exchange rate changes (and thus frontrunning / sandwich attacks).

To calculate the fair market value for the share, you would calculate the fair balance of assets and price those:

INVARIANT = CURRENT_DAI_BAL * CURRENT_ETH_BAL
DAI_FAIR_BAL = INVARIANT / ETHDAI
ETH_FAIR_BAL = INVARIANT / DAIETH
UNI_V1_PRICE = DAI_FAIR_BAL * DAIUSD + ETH_FAIR_BAL * ETHUSD

DAIETH and ETHDAI would be prices taken externally, not from uniswap, to counteract temporary uniswap market inefficiencies and/or manipulation attacks.

This method avoids manipulation attacks but makes an assumption around arbitrage and efficient markets (which is already made elsewhere within makerdao).

.
EDIT:

The initial formula was off by one magnitude because I didn’t properly derive the expected balances from the invariant and exchange_rate. Here is the updated, hopefully correct, formula for the fair value of a UNI-V1 share:

BAL_A = SQRT(INVARIANT / PRICE_A:B)
BAL_B = SQRT(INVARIANT / PRICE_B:A)
SHARE_VALUE = (BAL_A * ORACLE_PRICE_A) + (BAL_B * ORACLE_PRICE_B)

In the context of UNI-V1-ETHDAI it would look like this:

BAL_ETH = SQRT(INVARIANT / ETHUSD)
BAL_DAI = SQRT(INVARIANT / (1 / ETHUSD))          // (USDETH === 1 / ETHUSD)
SHARE_VALUE = (BAL_ETH * ETHUSD) + (BAL_DAI * 1)  // Value in USD
2 Likes

There might a problem in the formulas here. I plugged some numbers in for these values based on the contract balances and exchange rates and come up with a uniswap price ~2e15 :money_mouth_face:. It seems a little high to say the least.

Maybe check my math here and see what’s up?

Thanks for taking the time to test out the maths, you were right and there were a few issues:

  1. Balances (and thus invariant) are meant to be calculated on a per-share basis to calculate the value of each share and not the total value of the pool.
  2. Calculating balances using invariant and an external market price (e.g. Coinbase) is not as simple as INVARIANT / PRICE because INVARIANT is one order of magnitude bigger than PRICE. This is because INVARIANT = BAL_A * BAL_B where PRICE = BAL_A / BAL_B. This is addressed by taking the square root of the previous result: SQRT(INVARIANT / PRICE).

Hopefully my copy of your example doc makes the process more clear:

In my sheet I also highlight how using this formula allows us to completely ignore the current exchange rate of the uniswap market, making this process resistant to price manipulation attacks.

I’m a highschool dropout so definitely welcoming of more eyes on the maths laid out here.

1 Like

Ahh that is starting to look much more reasonable.

A couple of thoughts:

1 Like

Addressing those points:

  1. I guess the more correct way of looking at this is that this system introduces the need for a DAI/USD oracle/input. We can either make the assumption that 1 DAI = ~1 USDC (or the system shuts down), or we will need to track the price of DAI (if we are going to use it as a collateral to back more DAI, this will be unavoidable).

  2. If we prefer Uniswap as a DAI/USD oracle, we can use ETH/DAI price on Uniswap moving average. As mentioned above, it’s unavoidable to track DAI/USD if we want to use DAI as collateral for more DAI.

Addressing 3 in long form:

UNI_V1_PRICE represents the share price after adjsuted for in my formula. Thanks to arbitrage and efficient markets, the theoretical value of the UNI-V1 share and the actual value of the share should always be within <0.3% (Uniswap’s fee level). What my formula addresses is the risk of temporary mispricings of the uniswap ETHDAI markets resulting in dramatic swings of the underlying collateral price.

NAIVE_V1_PRICE is calculated by multiplying the assets backing each share by their market value.
UNI_V1_PRICE is calculated by using the current market price to calculate the “fair balances” if arbitrageurs were efficient. It then takes this “fair balance” and miltiplies it by the market price.

Otherwise, I could:

  1. Shift Uniswap ETHDAI exchange rate
  2. Balances backing UNI-V1 share change.
  3. UNI-V1 market price inflates/deflates.
  4. I leverage this to open undercollateralized CDPs, OR liquidate CDPs unfairly.

Sheet updated to contast naive share value with the “actual / theoretical” share value:

2 Likes

Your sheet really helped clear things up on why this would be preferable. I’ll update my PoC to calculate the price of the token using this method. Will leave the moving average in there for now though but open to discussion on if this is a good idea as well.

As far as the DAI/USD inputs go: I personally would be in favor of just making the assumption that 1 DAI == 1 USD and then modify our maths from there. Reason being that it allows us to just use the ETH/USD markets to calculate our price. Those markets are much larger that any ETH/DAI or DAI/USD markets in terms of 24h volume so they should be more resilient to tampering.

2 Likes

I would be really interested in seeing this as a collateral type. Do you find the suggested MIP6 process too much admin to take on alone, or is there some further blocker now that the PoC you wrote is mostly up and running? I also have my doubts about using on-chain data tbh, and - though I think that using two different http APIs could be a possible solution - I am obviously less risk-averse (and experienced!) than Nick.

1 Like

I think the blocker here is getting buy in from the Oracle team to pursue this further :slightly_frowning_face:

Personally I would love to hear a rebuttal from the oracles team regarding my assessment on oracles-v2, so I think we should wait a few days to see if @NikKunkel and co have anything to say.

Depending on if we get that rebuttal and what is said within, a few days from now I would suggest someone put up a poll to see if we want to pursue this price oracle on the Oracles-V2 architecture or If we prefer to wait for Oracles-V3. That way we can give a bit of signal from the community regarding the tech direction.

FWIW I would love it if someone else took point on that polling front. I think I may be a bit biased here and worry that if I wrote up a poll my biases might be represented in the polling options.

1 Like

To provide some context on the oracle team, recently Nik has been working on creating possibly the most comprehensive MIP10 imaginable, which covers basically all the oracle processes in MIP form.

Just to highlight that if he doesn’t get to this immediately it’s most likely not because you’re being deliberately ignored, but rather because people are super busy.

Happy to answer any open questions here but I recommend waiting for Uniswap V2 (~2 weeks)

https://forum.makerdao.com/t/uni-v1-dai-uniswap-dai-liquidity-token-collateral-application/1966/24

Will uniswap v2 materially impact the pricing model proposed above? I.E. is the approach being outlined here valid for both versions of the protocol.

The launch of V2 will have zero bearing on V1 but it might impact MKR holder priorities if V2 is more widely adopted than V1.

V2 also follows the 1:1 split between Asset A and Asset B, so for the V2 DAIETH pool, it should function the same as the V1 pool for pricing. Is that correct @haydenadams?

That said, I think V2 would be the more risky collateral as V1 has been around longer