MCCP 21: Stake BPT staked in mStable into Balancer Staking contracts

Big thanks to @derc for initiating this proposal and to @naddison to be on top of the implementation already!

Simple Summary

It is proposed to upgrade mStable’s staking contracts to support staking MTA/ETH BPT tokens currently staked on mStable into Balancer’s new staking contracts for continued BAL LM rewards

Abstract

Balancer has launched veBAL with a new set of staking contracts where Balancer LPs must now stake their LP Tokens (BPTs, Balancer Pool Tokens) to continue to receive liquidity mining incentives.

mStable governors staking the 80/20 MTA/ETH BPT tokens in the staking contract do not enjoy new BAL emissions, which the mStableDAO is currently voting for the pool from the rewards from the token swap previously announced with Balancer and other veBAL holders voting for MTA/ETH pool.

It is proposed to upgrade the staking contracts to support BPT tokens currently staked in mStable to be further staked into Balancer’s new staking contracts for liquidity mining incentives, currently with fully automated BAL minting and inflation schedule locked.

Note that mStable’s MTA/ETH pools on Balancer currently receive ~0.8% of voting power rewards, and possibly more in future when Convex-esque platforms like Aura Finance launch and bribes are implemented in future.

Motivation

MTA/ETH stakers taking part in mStable’s governance can continue receiving BAL LM rewards which have transitioned into a staking model. Furthermore, continued LM rewards will support or increase buy pressure to support MTA’s token price, and upside to MTA secondary market price would support our own LM incentives and ecosystem.

Specification

Instead of the mStable MTA/WETH Staking BPT (mBPT) being held in the Staking Token BPT (stkBPT) contract, it would be deposited into the new Balancer mBPT Gauge Deposit (mBPT-gauge).

Detailed functional changes to the StakedTokenBPT contract:

  • Add immutable balancerGauge variable that contains the address of the new Balancer mBPT Gauge Deposit (mBPT-gauge) and implements the new IBalancerGauge interface.

  • As balancerGauge is immutable, it must be set in the constructor.

  • A new function added to

  • approve the new Balancer gauge contract to transfer mBPT from the StakedTokenBPT contract.

  • Migrate all the mBPT held in the StakedTokenBPT contract to the new Balancer gauge.

  • Modify the setBalRecipient function so the default rewards receiver is set on the new gauge instead of the old balRecipient storage variable.

  • Modify the convertFees function so

  • the mBPT balance of the StakedTokenBPT contract is retrieved from the new gauge rather than the StakedTokenBPT's mBPT balance.

  • pending mBPT fees are withdrawn from the gauge before the balancer pool is used to swap mBPT for MTA.

  • Modify the internal _transferAndStake function so mBPT is transferred to the new gauge after mBPT is transferred into the StakedTokenBPT contract.

  • Modify the internal _withdrawStakedTokens function so mBPT is withdrawn from the gauge before mBPT is transferred to the withdrawal recipient.

  • Add a new internal _balanceOfStakedTokens function that gets the mBPT balance staked in StakedTokenBPT from the new Balancer gauge.

Functional changes to the parent StakeToken contract:

  • Make internal function _transferAndStake virtual so it can be overridden by StakedTokenBPT.

  • Add a new internal _withdrawStakedTokens function that transfer’s mBPT to the recipient by default but can be overridden by StakedTokenBPT to withdraw mBPT from the new Balancer gauge.

  • Add a new internal _balanceOfStakedTokens function that

gets the balance of the staked MTA or mBPT tokens. By default it gets

the balance of the staked tokens held in the staking contract but can be overridden by StakedTokenBPT which gets the balance from the new Balancer gauge.

A new IBalancerGauge interface with the following functions is added:

  • deposit

  • withdraw

  • set_rewards_receiver

The changes to implement this were a lot more complicated than expected. The functional changes were relatively straight forward. The problem was the contract was already at its size limits so adding the new features pushed it over the limit. Getting it back under the limit was tricky.

I’ve documented the functional and non-functional changes in the PR Deposit mBPT in Staked Token BPT (stkBPT) in Balancer's new mBPT Gauge (mBPT-Gauge) by naddison36 · Pull Request #350 · mstable/mStable-contracts · GitHub

I have moved this reply to the current MCCP 21 thread to make it more consistent and easier to follow @naddison, I hope you don’t mind :sunglasses:

On the topic of MCCP 21, I am in full support and many thanks for navigating this super tricky terrain and being able to cram it all into the contract Nick!

1 Like