Stabilizing the soft peg

I often clarify to folks that RP doesn’t have a hard peg. Instead, it has a ratio of existing rETH to ETH backing the rETH, which also serves as our mint/burn ratio. When the deposit pool (DP) is neither empty nor full, market rate must follow the mint/burn ratio, because otherwise it’s trivial to arbitrage until it does (buy on market, burn on RP; or mint on RP, sell on market). However, once the DP is full/empty, we rely on a very long arb process to keep us near the peg.

Current slow arb process

Let’s start simple. No gas/swap fees, you can create or exit minipools instantly, there are no queued minipools. I’m also simplifying by talking like there’s a single pool (DP) for both mint/burn and minipool creation/exit.

Scenario 1
DP is empty; the mint/burn ratio is 1.1, but on the market it’s trading at 1.05. You exit N minipools, which means you receive 16*N ETH+rewards and DP gets 16*N ETH+rewards. You swap your 16*N ETH for rETH, which happens to be exactly enough to move the market price to 1.1 (your overall buy has a 1.075 ratio). You burn your rETH at the full 1.1 rate. You pocket 16*N*.025, and the peg is restored.

Ok. So what’s the issue once we stop allowing instant execution? Gas/fees aren’t that big a deal - they limit how tight to the peg we’d arb, but they don’t change how quick it is or the overall feedback loop. The real pain point is that someone else might burn rETH before you. Your exit does help repeg, but it’s not necessarily you that gets the reward. Note that prebuying rETH before the exit doesn’t ensure you get the arb opportunity - it’s till just a race to burn.

Scenario 2
DP is full; the mint/burn ratio is 1.1, but on the market it’s trading at 1.15. If you could mint rETH, that’d be instant profit… but the DP is full. No problem. You make a new minipool and then you use the 16ETH of free space in the DP to realize your instant profit.

Again – the pain point without instant execution is someone else taking advantage. When you make the 16ETH of space in the DP, anyone can mint, and they will get the profit.

Conclusion
Arbing is still probably going to happen despite the above, but it won’t be by small players. If you open 2000 ETH of space, it’s very likely you have time to take advantage of the arb opportunity you created (at least for part of it). If you open 16 ETH of space, you probably won’t get that lucky. Potentially better, as a whale, you might be able to long/short, then move the market by exiting/creating minipools to repeg.

Suggested arb process
When DP is empty (and market price is below burn/mint ratio):

  • We would like minipools to exit to reduce the overall supply of rETH to move the price up
  • Flow
    • When you exit, you are allowed to provide up to 8 ETH worth of rETH (at the burn/mint rate).
    • Your exit will give you your ETH+rewards, as well as 8 ETH from burning the provided rETH at the full rate (#profit).
    • This allows the exiting NO to profit from the arbitrage opportunity without getting into a race.

When DP is full (and market price is above burn/mint ratio):

  • We would like minipools to be created to increase the overall supply of rETH to move the price down
  • Flow
    • When you create a minipool, you are allowed to provide up to 8 additional ETH.
    • In addition to getting a minipool, you will get 8 ETH’s worth of rETH (at the burn/mint rate).
    • If desired, that rETH can be immediately sold on the market (#profit).
    • This allows the NO creating a minipool to profit from the arbitrage opportunity without getting into a race.
A few more thoughts:
  • I’m not really sure about the 8 ETH limit I wrote in. It seemed a way to have the community get to arbitrage as well… but potentially it would just be arb bots and it’s better to allow NO arbitrage for the full 16 ETH in both cases.
  • This is a significant change to actual contracts, not just a front end thing. That said, it benefits NOs by providing arb opportunities, so I think they’ll wish to upgrade.
  • The options to provide additional rETH/ETH when exiting/creating a minipool are only beneficial in the situations above. This is nice because it means the contract can always have those options instead of needing to check the state of the DP or the market or anything like that.
  • One downside is that this requires extra capital to pull off. In these examples, you need 24 ETH (assuming your RPL levels are fine) instead of just 16. An alternative would be to “earmark” some ETH/rETH for you instead, so you could exit-then-arbitrage or arbitrage-then-start-minipool. I think this adds too much complexity though, so the extra capital might be the lesser evil.
  • This whole topic is considering postmerge and exits being available. I don’t think it’s materially affected by reward skimming existing or not.
4 Likes

This can already be achieved by bundling the minipool creation/distribution of minipool balance with rETH mint/burn through flashbots. No contract changes should be necessary. To make it more accesible to node operators, we could consider developing a smartnode addon that simplifies the process.

edit: misremembered how distribution works, see below

2 Likes

That’s awesome - if it can already be done, that’s great!

I’d love to see these as a commands on the smartnode (or a separate thing to install alongside the smartnode).

If it’s not too difficult, could you write a little guide? Would be great to be able to reference a link or pinned post in discord when folks ask about the ratio vs market rate (several times a week).

For the rETH mint side:
The deposit transaction (that can be exclusively done by the node operator) is what triggers transfer of ETH from the deposit pool to the minipool. As soon as space is created in the dp, rETH can be minted. See: https://github.com/rocket-pool/rocketpool/blob/24e7a6e14e70e17e5a434a3234505cf1001f0ce5/contracts/contract/node/RocketNodeDeposit.sol#L60

For the rETH burn side:
I was wrong. The distributeBalance call is what tranfers ETH from the minipool contract to rETH and makes it available for burns. I thought I remembered that the node operator has 14 days were only they can call distributeBalance, but that’s only the case if minipool balance is below 16 ETH. In the normal case, anyone can call distributeBalance on the minipool and do the arb. See: https://github.com/rocket-pool/rocketpool/blob/24e7a6e14e70e17e5a434a3234505cf1001f0ce5/contracts/contract/minipool/RocketMinipoolDelegate.sol#L287

Just confirming my new understanding:

When creating a minipool (arb with rETH mint)
assignDeposits() gets called, which is the function that will actually “create space” in the deposit pool by assigning it to a particular minipool.

I think I had conflated the “creating space” idea with the part where RP actually deposits its share, but for arb we only care about when the space is created. Looks like it should work :thumbsup:.

When exiting (arb with rETH burn)
I’m a little less clear here.

My first read (I’m a solidity and RP contract newb) looks like distributeBalance has a different effect when staking (status==MiniPoolStatus.Staking) vs when the validator has exited (status==MiniPoolStatus.Withdrawable). It looks like the 14-day check is in place if status==MiniPoolStatus.Withdrawable?

If I’m understanding those statuses right, I think flashbots would work for this arb need.

Update: knoshua explained and showed me that this wouldn’t work, because the oDAO sets the state to Withdrawable. So it’ll be an open race with everyone :frowning:

Posted a pull request that would enable arbing on exit with flashbots bundles.

Update: and a pull request for another variant after discussing with Kane in #smart-contracts on discord

2 Likes