Parameter Discussions (Part 3) | Oracle Buffer and Initial Prices

Parameter Discussions (Part 3) | Oracle Buffer and Initial Prices

Overview

In this discussion, the R&D team will share their recommended approach to setting the Oracle Buffer and Initial Price parameters.

The aim is for the community to review these parameters, analyse R&D’s recommended approach and how it impacts the RAMM, and share any alternative recommendations for any of the above parameters during the discussion period.

Goal

At the end of the Part 3 discussion, members should have had the opportunity to review the R&D team’s recommended approach to setting the Oracle Buffer and Initial Price parameters and provide any feedback or alternative approaches during the discussion period.

At the end of the Part 3 discussion, the RAMM parameters will be in place and ready for feedback from the economic audit by Chaos Labs. Once the Engineering team has completed the RAMM’s development and the Solidity audits are complete, the final parameters will be included in the on-chain governance proposal for deploying the RAMM.

Parameters discussed in Part 3

The parameters that will be discussed are:

Parameter Description
oracle_buffer Margin to allow for oracle lag when calculating Book Value in ETH. Secondary function - create spread
spot_price_a Current price at which members can exchange ETH for NXM
spot_price_b Current price at which members can exchange NXM for ETH

*While the R&D team will share their recommended approach to setting these parameters, Chaos Labs may recommend alternative parameters to ensure the RAMM meets its goals and is secure against economic attacks. The parameters discussed thus far will be the basis of the testing and simulations performed by Chaos Labs but we will remain open to changing them if they are proven to be inadequate. The liquidity goals agreed by the members in the Stage 1 parameter discussion will remain as the target of all parameter setting.

Oracle Buffer

There is an identified need for an oracle buffer, which creates a small window around BV, where no buys or sells are allowed–this is done to allow for oracle lag when BV is calculated in ETH terms.

Oracle delays may mis-represent the BV temporarily and create arbitrage opportunities that do not benefit the mutual in any way, and this can result in value destruction for members who hold NXM.

In practice this means that, if the oracle buffer is set at B, the Below Pool will ratchet to (1-B)*BV and the Above Pool will ratchet to (1+B)*BV, meaning the two spot prices will not overlap without the book value itself changing.

Initial Prices

The Initial Prices refer to the opening spot prices used in the Above and Below pools when the RAMM is launched.

The R&D team will provide more detailed information on this parameter in their recommended approach.

Timeframe for discussion

This discussion will take place from Monday (18 September) until Monday (25 September).

At this time, there is no plan for a Snapshot signalling vote, as R&D will provide one recommended approach to setting these parameters.

  • Should members present alternative approaches to setting these parameters, a Snapshot signalling vote may be held.

Overview & Resources

We’ve outlined the scope of the Liquidity Parameters Discussion in the Overview post. You can refer to this post for an introduction to both Parts 1 & 2 of this discussion.

If you have questions about the Ratcheting AMM (RAMM) or you want to learn more about the RAMM itself, please see the Pre-Discussion Phase: RAMM Education Guide, Call for Questions post.

If you want to catch up on the Liquidity Parameter Discussions Part 1 and Part 2, see the Liquidity Parameters Discussion (Part 1) | How much ETH liquidity do we start with? and the Liquidity Parameters Discussion (Part 2) | What parameters do we need to achieve the outcome members’ signalled support for in Part 1? post on the forum, where you will also be able to find the results of the three Snapshot signalling votes.

3 Likes

Thanks @BraveNewDefi for the overview.

Suggestions on the parameters under discussion presented below. Again - please comment, pick apart, suggest changes, come up with alternatives, etc.

The following parameters are included in this part of the discussion as per the whitepaper and overview post.

Parameter Description
oracle_buffer Margin to allow for oracle lag when calculating Book Value in ETH. Secondary function - create spread.
spot_price_a Opening price at which members can exchange ETH for NXM
spot_price_b Opening price at which members can exchange NXM for ETH

Note on TWAP duration

In the original parameter discussion posts, the intention was to include the TWAP duration as a parameter in this part of the discussion.

However, the TWAP duration and implementation details are a security issue. Therefore, instead of putting a specific parameter up for community discussion at this stage, we propose that a combination of the R&D team, the Engineering team and the economic/solidity audits ensure that:

  • the implementation and parameter details are such that the mechanism can’t be attacked; and
  • these are put forward to members for the final on-chain governance vote

Oracle Buffer

Oracle Deviation

The oracle buffer’s main purpose is to prevent arbitrage opportunities resulting from oracle lag. The smart contracts use Chainlink oracles, for which the main parameter is the ‘Deviation Threshold’, i.e., the percentage value by which the reported value is different from the previous one before the value is updated. The oracles used by the Nexus Mutual smart contracts and their deviation thresholds are as follows:

Chainlink Oracle Deviation Threshold Notes
DAI / ETH 1% Impact on Book Value of ETH vs DAI/USD movements depends on the ETH/DAI split in the capital pool.
stETH / ETH 0.5% Major capital pool asset (~22%).
rETH / ETH 2% Significant capital pool asset (~11.5%).
Nexus Mutual wETH 0.3% Bespoke oracle for the Nexus Mutual Enzyme Vault

Suggest that a 1% buffer here is sufficient from an oracle delay point-of-view.

The rETH oracle is the only one that has a deviation threshold greater than 1%, but in order to have an impact on the overall book value, it’d have to form in excess of 50% of our capital pool, which is unlikely to ever be the case.

On the other hand, to future-proof the parameter, we’d want to allow for a situation where the capital pool reserves are significantly denominated in DAI (or other appropriate stablecoins), so it’s possible the capital pool/BV as a whole will deviate by close to 1% if DAI deviates by 1% from ETH.

Buy/Sell spread

The secondary purpose of the buffer is to create a buy/sell spread around book value (or future ratchet target value).

In practice, if the open market price hovers in the range ( (1 - oracle_buffer)*BV, (1 + oracle_buffer)*BV ), all trades will happen on the open market and none in the RAMM itself.

As the swaps in the RAMM are by definition value-accretive to long-term holders, it is in the interests of mutual members to keep the spread narrow in order to encourage more trades with the mutual itself.

A 1% oracle buffer (as per Oracle Deviation section above) would result in a 2% buy/sell spread. This is a 0.5% decrease on the 2.5% buy/sell spread used by the current bonding curve implementation.

Note that this buy/sell spread only applies in the range immediately around the BV - as the open market price moves away from BV only one of the RAMM pools (buys only or sells only) is likely to have active trades in it and the buy/sell spread doesn’t apply.

Therefore, putting forward:

oracle_buffer = 1%

Initial Spot Prices

Here, I’m putting forward a framework for setting the initial prices ahead of launch rather than suggesting a specific set of opening prices now.

The framework assumes that the open market price is still below Book Value at the launch of the RAMM.

spot_price_b

Description

Set the opening spot_price_b ~20% below the open market price at launch.

Rationale

In order to capture the most value for the mutual, the system should start with a sell price that’s below the open market price and allow the ratchet to move the RAMM spot price above the open market price over time. This will allow the RAMM to discover an optimum price at which members start selling their NXM to the system. The assumption is that the initial sellers will be arbitrage bots buying up open market liquidity and redeeming via the RAMM, while individuals will wait to redeem at prices closer to BV.

The opening price will need to be significantly lower than the current open market price, as it needs to be locked in ahead of the governance process, so should allow for some market movements in the meantime.

The current suggestion for the ratchet speed at launch is 50% of BV/day, so a 20% gap to the wNXM price will likely be closed in less than half a day.

spot_price_a

Description

Set the opening spot_price_a, after setting spot_price_b, at a value where opening internal_price == current bonding curve price.

Rationale

The initial price of the above pool is back-solved to allow the smoothing out of the impact on staking resulting in cover capacity, which uses the internal price.

This means the spot_price_a likely has to open higher than the current bonding curve price. However, using the ratchet speed of 4% of BV/day, the above pool is likely to reach Book Value in about 15-20 days. This timeframe also corresponds to the internal system price moving from the bonding curve value to the new RAMM internal_price value.

Example Using Current Values

Using the current system and market conditions, the framework would produce the following:

  • As the current open market price is 0.018 ETH, we’d set spot_price_b for the governance process equal to 80% of that, or 0.0144 ETH
  • The current bonding curve price is 0.02869 ETH
  • To derive spot_price_a, we need internal_price = 0.02869 ETH
    • internal_price = min(twap_a, spot_price_a) + max(twap_b, spot_price_b) - BV, which simplifies at opening to spot_price_a + spot_price_b - BV
  • The BV is currently 0.02164 ETH
  • spot_price_a solves to 0.03593 ETH

To be clear, these are not the proposed values, but rather a representation of what the proposed framework would produce currently.

Next Steps

Similarly to the Stage 2 parameter discussions, please suggest alternatives, happy to go further investigate any concerns/scenarios raised by the community.

If sufficiently robust alternatives emerge from that process, we can have a snapshot vote at the end of the week to get a view as to which set of parameters the community would prefer.

4 Likes

Thanks Rei - all of this makes sense to me.

There might be an argument to lower the spot_price_b a bit more than ~20%, eg ~50%, as it only takes a day for the ratchet to catch up and there could be volatility between setting the proposal and it actually executing (it would take roughly 1 week). This is a minor point though, in all likelihood 20% would be fine.

2 Likes

I’d also be in favour of a setting the spot_price_b param lower. Thank you for your detailed explanation Rei and Brave.

1 Like

Thanks @Rei not a tech guy - but a 1% oracle buffer haircut seems quite large to me. I feel it should be in a lower range from .02-.05%.

To expand on my first post:

  1. An oracle buffer of 1% seems like overkill. Starting from first principles, if 100% of funds were ETH, there would of course be no need for an oracle buffer. So from that perspective it makes sense to take an approximate weighted average that can be manually updated by governance. Separately I suggest you consider whether Uniswap oracles may be appropriate here in figuring out the correct weighting. Particularly with respect to liquid staking tokens - the market views these as stable pairs - and accordingly the chainlink buffers seem unreasonably wide.

Some rough math:

2.Separately I suggest you consider whether Uniswap oracles may be appropriate here in figuring out the correct weighting. Particularly with respect to liquid staking tokens - the market views these as stable pairs - and accordingly the chainlink buffers seem unreasonably wide.

The above post makes sense to me - assuming more sensitive oracles are not available/secure enough, it looks like 0.4% or 0.5% would be sufficient to protect the mutual from fluctuations within the oracle’s range with extra room in case the asset constitution changes. This additional spread would be captured by the mutual as a redemption fee.

One other point to note for discussion is that a buffer of 1% allows a realized spread in excess of 1%, as the underlying spot prices can move to just under the amount needed to trigger an oracle update. With a fixed buffer, this always resolves against the trader. For example, assume the entire pool were DAI with a 1% deviation threshold. This would allow a realized spread of up to 1.99% before the oracle updated. Thus the realized spread is in the range (1, 1.99%).

1 Like

Hey all, thanks for the thoughts and analysis.

Oracle Buffer

@NxmMaxi :

The analysis is valid for the current state, and there’s certainly value in having a tighter buffer (e.g. members getting a closer exit price; mutual capturing capital earlier on swings above BV), but I don’t think just looking at the current state of the assets is enough.

Based on the Stage 1 votes & discussion, there is likely to be a chunk of capital wishing to exit upon launch.

Assuming 15% of the Capital Pool exits via ETH, the updated picture of the analysis is this (and I’m assuming investments remain fixed in value):

The figure is up to 0.42%.

At 30% exits, the figure becomes 0.51%. Let’s say at this point we have to convert an extra $10m of DAI to pay claims - the Max Deviation would become 0.57%

If, say, in a year’s time, 50% of the Capital Pool has exited the figure is 0.71%. Here we’d probably also start moving some of the investment assets out of the bigger positions, but in all likelihood that’ll be to diversify into other assets rather than convert directly back to ETH.

Admittedly, we can react to gradual changes and change the oracle buffer down the line through governance, but I personally wouldn’t be comfortable setting the initial value at anything less than 0.75%. The less we have to manually update parameters, the better.

Overall, would much rather be conservative and see how things play out instead of being aggressive, cutting it close to the line and getting arbitraged. Not sure the benefits outweigh the potential downside.

On the Uniswap oracles point - appreciate the pairs are usually stable, but in my view it’s reasonably likely any LST could move 2% in a day relative to ETH (e.g. like stETH did in June 2022).

@ngmi :

Wouldn’t the spread be (0.01%, 1.99%)?

Assuming the Capital Pool is 100% DAI, If ETH price goes up by 0.99% and the oracle hasn’t yet updated, the BV has gone down by 0.99% to 99.01% of the original BV, but the pool still allows sells at 99% of the original BV.

Side note is that RAMM pools work on ETH only so there would need to be some ETH in the pool to trade anyway :slightly_smiling_face:

Initial Discount

@Hugh - happy to set it at 50% discount to open market price at start to ensure price doesn’t move against us in the week before, especially as indeed it would close in just under a day. Unless there are any other comments, happy to change it to 50%.

3 Likes

Thx for response-you are correct.

Separately, @Rei, agree with yours and Hugh’s take that the 50% discount seems completely fine - I only see upside/sensible risk mitigation there.

1 Like

Agree with the general consensus around other parameters, but I wanted to share my thoughts on the oracle buffer parameter discussion.

Core Purpose for the Oracle Buffer

If we’re setting the Oracle Buffer parameter at launch, we should err on the side of caution and be conservative.

I’m in favor of the 1% buffer. Setting it lower would create a benefit to members who want to exit, but it could also lead to potential arbitrage if large market movements happen, given ETH will flow out of the capital pool as members redeem and exit. As Rei highlighted, that means the LST and DAI holdings have a larger impact on the pool.

25 bps Difference

Ultimately, the difference is 25 bps between 1% and 0.75%. In total, 43,750 ETH will be allocated for initial liquidity in the RAMM, which is $69,594,000 with the price of ETH at the time of writing.

  • A difference of 0.25% represents $173,985 for the entire amount of initial liquidity in the RAMM

Given the impact is small, relatively speaking, it doesn’t justify the risk that would be passed on to members who plan to remain in the mutual if the oracle buffer were to be reduced lower than 1%.

The RAMM will close the gap between the current market value and BV. The 1% buffer will be the same as the fee members and non-members would incur if they traded on the open market, given the Uniswap pool fee tier is 1%.

3 Likes

Hi all,

Unless anyone has further objections to the points raised by myself and Brave on the oracle buffer in the last two posts regarding security/materiality vs. the benefit of having a lower value, suggest that we proceed with putting a 1% buffer forward in the on-chain vote (subject to any further analysis from e.g. Chaos Labs).

Parameters put forward in the on-chain governance vote would be:

  • oracle buffer = 1%
  • opening spot_price_b = 50% of wNXM price at time of putting forward the on-chain governance vote
  • opening spot_price_a backsolved such that internal_price = old bonding curve price

Open invite to please speak up if you strongly believe we should continue this discussion and put forward alternative values for the oracle buffer at this time. If there are no further comments, will consider this discussion, and the initial parameter discussions as a whole to be complete.

3 Likes