After minting rETH there is a period of 5760 blocks (~21 hours) where the minting wallet is not able to transfer any of its rETH tokens. This lock was implemented to mitigate Finding 6.2 of the Consensus Diligence Audit. In short, it was possible to sandwich the price update and extract value from rETH holders.
It turns out that this mechanism has some issues:
Since a token lock is a very rare mechanism in the current ecosystem, it has caused confusion for users. Seeing wallets attempt to transact multiple times with freshly minted rETH is not uncommon.
BrassLion on Discord pointed out that it made their life difficult when trying to build a Yearn vault for rETH.
Langers mentioned that some wallets have asked for a referral fee model to integrate Rocket Pool. It’s my understanding that with the lock in place, this would require contract upgrades.
I believe there is an alternative solution to the sandwich issue that removes these concerns. To see how it works, we can look at sandwiching attacks of token swaps on DEXes, which are very similar in principle. There, the price of a token is updated according to some AMM whenever a user swaps one token for another and MEV bots are often taking advantage of that price update by sandwiching it with two swaps of their own. But not every DEX swap is sandwichable. Only large swaps are susceptible, because the price movement needs to be big enough to make up for the trading fees (and gas) that the sandwicher incurs on their swaps.
Similarly, a fee when minting rETH would make sandwiching the rETH price update unprofitable, as long as fee > price_delta. Assuming that price updates happen daily and remain constant over time, a 0.05% fee would be sufficient to prevent sandwiching in a world where rETH has a 18.25% APR (0.05% * 365). Finding the correct fee value would require some analysis of historical price update data and the increased APR after merge needs to be considered, but at first glance a relatively minor fee seems to suffice.
My suggestion is to distribute the proceeds of this fee to rETH holders. It’s also worth noting that this can only be a soft solution, in that price_delta > fee could happen at times. I think that a price sandwich every few months would have a neglible impact overall and the negatives of the current solution aren’t justified.
Impact on rETH stakers
For rETH stakers, this fee acts as a zero sum game. No value is taken away from them overall, it’s just a redistribution mechanism. Stakers that hold rETH for a shorter duration than average would incur a loss, while long term holders would gain from this system. As long as the fee is low, the impact would be marginal overall.
network.reth.deposit.delay can be set to 0, effectively removing the time lock from rETH.
RocketDepositPool.sol can be upgraded to add a fee on deposit
As an alternative idea, wouldn’t setting the rETH lock timer to something arbitrarily small (1 block) prevent the sandwich attack as well? Or if not 1 block, we could figure out the minimum-viable-locktime. I agree in principle that removing it entirely would be better, but that would almost certainly require audits and therefore be post-merge.
If we can get something “good enough” out sooner, I wonder if that might be a better solution for the time being.
@Marceau The lock time needs to be around the same length as the updates for it to work as intended. So lowering the lock time is a trade-off between protection and UX. It also doesn’t really solve the problem of integrations as any lock time at all, even a single block, is the problem.
I am personally in favour of @knoshua idea here. I think it is a simple but clever solution to the problem and will make integrations easier and UX much better. From the users’ perspective, they will lose a single day’s worth of rewards which I think is an acceptable trade-off for the above benefits. Implementation is also very simple.
Another approach - Do we even need a lock with a small deposit pool cap. In the current model, RP has essentially been living with a 200 ETH deposit cap imposed by the 20% range (1800 - 2000 ETH) already. (Meaning that NO have not been forming minipool until the commission is in this range and thus there is only a 200 ETH band in the dp that considers to a 20% commission.) If let’s say we set the deposit pool capacity to 500 ETH (2.5 times what the realistic capacity is ATM) when we set the NO commission at 15% we might be able to disable the time lock as there is not enough leverage capacity to make the arb profitable off the daily price adjustment.
For example, if an arb bought yesterday 500 rETH at 1.017867 = 491.22 rETH and then cashed out at the end of the block after the ON price update 491.22 * 1.017955 = 500.04 ETH Yes its 0.04 ETH gross arb profit but the arb would have to pay for the staking gas, the unstaking gas, and the flashbot fees. Seem like this amount of ETH profit might not be worth the squeeze. This change would require no audits.
I’ve also been thinking about this recently. However, in the future the deposit pool will be larger and there’s no guarantee that it will be consistently full. So it creates a situation where a botter can just wait for days where there is enough capacity to perform the attack. Solving the issue all together with this deposit fee instead of relying on uncontrollable factors such as deposit pool capacity and current gas prices to make it uneconomical is the better approach IMO.
I like this idea! It’s very simple and gets rid of the UX painpoints from failed transactions and from potential price mismatch on secondary markets – any mismatch like the ones we’ve seen recently could have been arbitraged more quickly without the lock, leading to fewer people overpaying for rETH on Uniswap (with the added benefit that a small part of the value gained by arbitrage bots would be taxed and effectively redistributed to holders) of course the bottleneck is still new minipools so price mismatches would not be fully solved but it’s gonna be a diminishing problem as DeFi liquidity increases anyway.
Also, could the effect on “real” rETH holders could be further mitigated by splitting the 0.05% fee into a 0.025% fee on minting and 0.025% fee on burning? It’s still the same total fee for sandwich attacks, but someone who intends to mint and hold rETH would only pay half.
The issue with adding a fee on burn is that this would have to be part of the rETH contract and that one is not upgradeable. We would get around that limitation for mint by adding it to the deposit pool contract (when ETH is deposited to mint rETH), because deposit pool is upgradeable.
Indeed, the rETH lock is a technical pain that affects both UX and integration. If we can implement your proposal it would be a win for everyone’s quality of life.
As you mention, choosing the right fee amount is going to require some analysis. Particularly post-merge where the rETH APR will be much more variable (fees and MEV). It may be worth having this implemented but dormant in the contract code, a little after The Merge, so analyse the trend and dial in an appropriate fee amount. The exact amount is probably not important as long as we close the gap enough to make it not profitable most of the time, but it would help us get to the right ball-park.