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.