BIP-21: Replant Beanstalk
Proposed: July 29, 2022
Status: Passed
Link: Snapshot
Proposer
Beanstalk Farms
Quorum
50%: 106,664,659.23 Stalk
Two-thirds supermajority: 142,219,545.64 Stalk
Summary
- Execute a series of transactions to Replant Beanstalk.
- Commit a series of upgrades to Beanstalk.
- Unpause Beanstalk.
Note: Any bugs found during testing will continue to be fixed throughout the BIP-21 Voting Period such that
the Replant may not be delayed.
Problem
BIP-21 addresses the following issues:
1. Beanstalk must be Replanted, which involves
several steps.
- New ERC-20 tokens: The new Bean, Unripe Bean and Unripe BEAN:3CRV LP ERC-20 Tokens
have not yet been deployed.
- New BEAN:3CRV pool: There is currently no liquidity pool in which the new Bean
token can be traded.
- Remove old tokens from the Deposit Whitelist: The Deposit Whitelist still has the
old Bean token and its associated LP Tokens. Leaving the old tokens on the Whitelist would pose security
concerns to Beanstalk.
- Add new tokens to the Deposit Whitelist: The new Bean token, new BEAN:3CRV LP
Token, Unripe Bean token and Unripe BEAN:3CRV LP Token have not yet been added to the Deposit Whitelist.
- Minting Pool: The Oracle still uses the old BEAN:ETH liquidity pool when
calculating deltaB.
- Minting Schedule: It is unclear how the market will value Bean initially, and the
deltaB will be significantly above peg upon Replant.
- Flood: Flood is still based on the old BEAN:ETH liquidity pool.
- Deposit Earned Beans: Pre-exploit Earned Beans are not currently Deposited in any
Season, which complicates accounting for them during the Replant.
- Stalk and Seed balances: Stalk and Seed balances are still in their pre-exploit
state and must be updated to reflect the Barn Raise structure.
- Barn: Support for the Barn Raise as described in BFP-72
has not yet been added to Beanstalk.
- Ratio at which Fertilizer sales add liquidity: Liquidity from Fertilizer sales
must be added to the BEAN:3CRV pool at a particular ratio.
2. Beanstalk has improvements to the issues that have been audited for inclusion in the Replanted version of
Beanstalk.
- Oracle Whitelist: The current architecture to facilitate Bean/Soil minting each
Season is not generalized or flexible. From a technical perspective, it should be straightforward to add and
remove liquidity pools from the list of pools that facilitate Bean/Soil minting.
- Convert Whitelist: The current architecture to facilitate Conversions within the
Silo is not generalized or flexible. From a technical perspective, it should be straightforward to add and
remove Conversions from the list of possible Conversions within the Silo.
- Sub-optimal Conversion: Currently, when a Stalkholder Converts a Deposited LP
token to a Deposited Bean, Grown Stalk from Seeds can be lost if the current BDV of the Deposit is lower
than at the time of Deposit due to impermanent loss. This makes Converting unattractive when Beanstalk wants
to encourage Conversions.
- Soil issued when P > 1: When P > 1, Beanstalk is currently willing to issue
enough Soil such that if demand for Soil remains high, the total number of Pods stays the same from Season
to Season, independent of the Pod Rate. A more sophisticated Soil supply schedule should account for the Pod
Rate.
- FarmFacet and Internal Balances: Currently there is no flexible way to compose
multiple interactions with Beanstalk together into a single transaction.
- Depot and Curve Pipeline: Beanstalk previously supported complex transactions with
Uniswap and Beanstalk in a single transaction. The architecture to support these types of transactions is
not generalized to also be able to interact with other protocols.
- Withdrawal Freeze: The current 4 Season Withdrawal Freeze is an economic
inefficiency that creates a supply overhang when there are Withdrawn assets.
- Deposit transferability: Deposits currently cannot be transferred from one address
to another.
- Ownership transfer process: Ownership transfer of the Beanstalk contract is
currently a one-step process and doesn’t require a claim by the receiving address.
- Division of Silo Reward Claiming: Silo Members cannot currently Mow Grown Stalk
and Plant Plantable Seeds in separate transactions, even when it may be gas-efficient to do so.
- Minting of Plantable Seeds: Plantable Seeds are currently minted before being
Planted, which is a suboptimal accounting practice.
- Contract ownership: Publius currently custodies ownership of the Beanstalk and
Fertilizer contracts, and must transfer ownership of Beanstalk to the BCM and transfer ownership of the
Fertilizer contracts to Beanstalk.
3. Beanstalk must be Unpaused.
- Unpause Beanstalk: A
sunrise()
function call is currently not
accepted by Beanstalk.
Proposed Solution
The following solutions are proposed to the issues listed above:
1. Execute a series of steps to Replant Beanstalk.
- New ERC-20 tokens: Deploy and distribute new Bean, Unripe Bean and Unripe
BEAN:3CRV LP ERC-20 Tokens.
- Holders of Beans at the end of the block prior to the exploit received Unripe Beans at a 1:1 ratio.
- Holders of LP Tokens on the Deposit Whitelist that were not Deposited at the end of the block prior
to the exploit received Unripe Φ at a ratio of 1 Unripe Φ per BDV of LP Tokens on the Deposit
Whitelist held at the end of the block prior to the exploit.
- Holders of LP Tokens on the Deposit Whitelist that were Deposited at the end of the block prior to
the exploit received Unripe Φ at a ratio of 1 Unripe Φ per the maximum of the BDV of the Deposit at
the end of the block prior to the exploit and at the time of Deposit, per Deposit.
- New BEAN:3CRV pool: Deploy a new BEAN:3CRV metapool with an A parameter of 1 per
BFP-77.
Mint 100 Beans and add the 100 Beans and 100 USDC to the pool as initial liquidity.
- Remove old tokens from the Deposit Whitelist:
- Remove the old Bean token.
- Remove the old BEAN:3CRV LP Token.
- Remove the old BEAN:ETH LP Token.
- Remove the old BEAN:LUSD LP Token.
- Add new tokens to the Deposit Whitelist: For the BDV function, please refer to the
appendix in the attached whitepaper.
- Add the new Bean token with 1 Stalk and 2 Seeds per BDV Deposited.
- Add the new BEAN:3CRV LP Token with 1 Stalk and 4 Seeds per BDV Deposited.
- Add the Unripe Bean token with 1 Stalk and 2 Seeds per BDV Deposited.
- Add the Unripe BEAN:3CRV LP Token with 1 Stalk and 4 Seeds per BDV Deposited.
- Minting Pool: Remove the old BEAN:ETH liquidity pool from the calculation of
deltaB.
- Minting Schedule: Replant Beanstalk with a ramped minting schedule for Soil and
Beans—deltaB will be equal to deltaB * R, where R starts at 0% and increases by 1% at the start of each
Season for 100 Seasons after Replant.
- Flood: Remove the old BEAN:ETH liquidity pool from the Flood.
- Deposit Earned Beans: Distribute Earned Beans as Deposited Unripe Beans in Season
6074 upon Replant.
- Stalk and Seed balances: Recompute all Stalk and Seed balances.
- A Stalkholder’s Stalk upon Replant is the percentage of Fertilizer sold prior to Replant times their
Stalk at the end of the block prior to the exploit.
- A Stalkholder’s Seeds upon Replant is the percentage of Fertilized sold prior to Replant times the
sum of their Seeds at the end of the block prior to the exploit and their Plantable Seeds at the end
of the block prior to the exploit.
- Old BEAN:LUSD LP Token holders are credited as if they had more Seeds, as Unripe BEAN:3CRV LP
receives 4 Seeds for Depositing in the Silo.
- Barn: Implement the full specifications of the Barn. For a full writeup of the
Barn, please refer to the Barn section in the attached whitepaper.
- Ratio at which Fertilizer sales add liquidity: Add liquidity from Fertilizer sales
to the BEAN:3CRV pool at a ratio of 1:0.866616.
2. Implement a series of improvements to Beanstalk.
- Oracle Whitelist: Move the Oracle to mint based on the Oracle Whitelist (the
whitelist of liquidity pools whose deltaB’s are summed to calculate a cumulative deltaB), which upon Replant
will consist solely of the new BEAN:3CRV metapool.
- Convert Whitelist: Introduce the Convert Whitelist, the generalized whitelist that
determines which Conversions within the Silo are permitted under certain conditions. For full details on the
Convert Whitelist, please refer to the appendix in the attached whitepaper. The following Conversions are
whitelisted upon Replant:
- Deposited Beans to Deposited BEAN:3CRV LP Tokens, when the Bean price in the BEAN:3CRV pool is
greater than $1.
- Deposited BEAN:3CRV LP tokens to Deposited Beans, when the Bean price in the BEAN:3CRV pool is less
than $1.
- Deposited Unripe Beans to Deposited Unripe BEAN:3CRV LP Tokens, when the Bean price in the BEAN:3CRV
pool is greater than $1.
- Deposited Unripe BEAN:3CRV LP Tokens to Deposited Unripe Beans, when the Bean price in the BEAN:3CRV
pool is less than $1.
- Sub-optimal Conversion: When a Stalkholder Converts a Deposit, they update its
Season of Deposit to retain its Grown Stalk from Seeds, and BDV only if it is higher than when it was
Deposited.
- Soil issued when P > 1: Change the definition of S_t^{min} to:
- FarmFacet and Internal Balances: Introduce the FarmFacet and Internal (Farm)
Balances that allow Farmers to compose transactions within Beanstalk together.
- Depot and Curve Pipeline: Add the Depot to the Farm. Add the Curve Pipeline to the
Depot to enable interactions with Curve through Beanstalk.
The Curve Pipeline allows anyone to call functions in any pool registered in any of the following Curve
registries.
The following functions to interact with Curve pools can be called through the Curve Pipeline:
function exchange(
address pool,
address registry,
address fromToken,
address toToken,
uint256 amountIn,
uint256 minAmountOut,
LibTransfer.From fromMode,
LibTransfer.To toMode
) external payable nonReentrant;
function exchangeUnderlying(
address pool,
address fromToken,
address toToken,
uint256 amountIn,
uint256 minAmountOut,
LibTransfer.From fromMode,
LibTransfer.To toMode
) external payable nonReentrant;
function addLiquidity(
address pool,
address registry,
uint256[] memory amounts,
uint256 minAmountOut,
LibTransfer.From fromMode,
LibTransfer.To toMode
) external payable nonReentrant;
function removeLiquidity(
address pool,
address registry,
uint256 amountIn,
uint256[] calldata minAmountsOut,
LibTransfer.From fromMode,
LibTransfer.To toMode
) external payable nonReentrant;
function removeLiquidityImbalance(
address pool,
address registry,
uint256[] calldata amountsOut,
uint256 maxAmountIn,
LibTransfer.From fromMode,
LibTransfer.To toMode
) external payable nonReentrant;
function removeLiquidityOneToken(
address pool,
address registry,
address toToken,
uint256 amountIn,
uint256 minAmountOut,
LibTransfer.From fromMode,
LibTransfer.To toMode
) external payable nonReentrant;
- Withdrawal Freeze: Change xi from 4 Seasons to 0.
- Deposit transferability: Make Deposits transferable.
- Ownership transfer process: Implement a 2-step ownership transfer process.
- Division of Silo Reward Claiming: Introduce division of Silo Reward claiming. Mow
claims Grown Stalk and Plant claims Plantable Seeds, Earned Stalk and Earned Beans.
- Minting of Plantable Seeds: Change Plantable Seeds to only be minted once Planted.
- Contract ownership: Transfer ownership of Beanstalk from Publius to the BCM and
ownership of Fertilizer from Publius to Beanstalk.
3. Unpause Beanstalk.
- Unpause Beanstalk: The BCM will Unpause Beanstalk on August 6th, 2022 around 16:00
UTC.
Rationale
The following are Beanstalk Farms’ rationale for the proposed solutions above:
1. Beanstalk must be Replanted, which involves
several steps.
- New ERC-20 tokens: The new Bean token and Unripe assets must be deployed, per BIP-20.
They are distributed in accordance with BFP-72.
- New BEAN:3CRV pool: The Beanstalk DAO approved BEAN:3CRV for the Replant Liquidity
Pool in BFP-75
and an A parameter of 1 in BFP-77.
- Remove old tokens from the Deposit Whitelist: The tokens on the old Deposit
Whitelist used the exploited Bean token. Upon Replant, Beanstalk will use a new Bean token. Therefore,
liquidity pools that utilize the old Bean token should be removed.
- Add new tokens to the Deposit Whitelist: In order for Farmers to be able to
interact with the Silo, the new Bean token, new BEAN:3CRV LP Token, Unripe Bean token and Unripe BEAN:3CRV
LP Token must be added to the Deposit Whitelist.
- Minting Pool: The old BEAN:ETH liquidity pool uses the old Bean token, and is
therefore not relevant for the calculation of deltaB.
- Minting Schedule:This minting schedule is conservative but with a quick ramp-up.
The regular minting schedule of 100% will resume about 4 days after Replant. A ramped minting schedule
allows time for Bean to price itself post-exploit.
- Flood: The old BEAN:ETH liquidity pool uses the old Bean token, and is therefore
not relevant for the Flood.
- Deposit Earned Beans: The expectation for Silo Members is that they can always
remain passive and earn Beans from Earned Stalk. Depositing Earned Beans in the current Season makes
accounting for them during the Replant less complicated. Thus, Earned Beans are Deposited for pre-exploit
Silo Members in the current Season.
- Stalk and Seed balances: Stalk and Seed balances should be haircut in accordance
with BFP-72.
Depositors of old BEAN:LUSD LP tokens at the end of the block prior to the exploit were credited as having
had 4 Seeds per BDV Deposited for the sake of simplicity.
- Barn: Please refer to BFP-72
for the rationale behind the implemented Barn mechanics.
- Ratio at which Fertilizer sales add liquidity: Liquidity that is recapitalized by
the Barn Raise will be added to this pool at the ratio that would cause the deltaB to trend towards the
pre-exploit deltaB in the Replant pool per BFP-77.
2. Commit a series of upgrades to Beanstalk.
- Oracle Whitelist: Moving the Oracle to mint based on the Oracle Whitelist is
significantly more generalized and flexible than the previous minting architecture.
- Convert Whitelist: Moving to a Convert Whitelist is significantly more generalized
and flexible than the previous Convert architecture.
- Sub-optimal Conversion: When the value of Beans goes down, LP Token holders with
Bean exposure realize impermanent loss, coinciding with the opportunity to Convert Deposited LP Tokens to
Deposited Beans. Minimizing the cost for Stalkholders to Convert Deposited LP Tokens to Deposited Beans will
minimize downside Bean price volatility.
- Soil issued when P > 1: By issuing more Soil when the Pod Rate is excessively
low and less Soil when the Pod Rate is excessively high will improve Beanstalk’s ability to return the Pod
Rate to its optimal level.
- FarmFacet and Internal Balances: The FarmFacet and Internal (Farm) Balances
realize the full benefits of composability within Beanstalk.
- Depot and Curve Pipeline: The Depot is an extension of the composability of the
FarmFacet to the rest of the Ethereum network. The Curve Pipeline is the first integration of this
functionality between Beanstalk and another protocol.
- Withdrawal Freeze: The Withdrawal Freeze creates a supply overhang when there are
Withdrawn assets, which creates a market inefficiency. By lowering the Withdrawal Freeze to 0, assets are
still Frozen until the beginning of the next Season. Therefore, the benefits of the Withdrawal Freeze are
retained while the supply overhang is minimized.
- Deposit transferability: Deposits being non-transferable is an inefficiency for
Silo Members and provides no benefit to Beanstalk.
- Ownership transfer process: A 2-step ownership transfer process is safer than a
1-step ownership transfer process.
- Division of Silo Reward Claiming: Introducing the Mow and Plant functions allows
for more customization for Silo Members when interacting with the Silo.
- Minting of Plantable Seeds: It is not good accounting to include Plantable Seeds
in the
balanceOfSeeds()
function.
- Contract ownership: Per BFP-73,
ownership of Beanstalk is being transferred to the BCM. Once Beanstalk is Replanted, it can own the
Fertilizer contract.
3. Unpause Beanstalk.
- Unpause Beanstalk: Allow Beanstalk to accept
sunrise()
function
calls.
Post Audit Changes
The following changes have been made to Beanstalk, but have not been audited.
All relevant changes with the exception of CurveFacet
and LibUnripeSilo
can be viewed
here.
File Name |
Changes |
Type |
C.sol |
Changed constants. |
Parameter Change |
CurveFacet.sol |
Most functionality—some were audited, but all have been heavily tested. |
Bug Fix |
FertilizerFacet.sol |
Renamed variable; added getCurrentHumidity() . |
Refactor / Usability |
FieldFacet.sol |
Moved burn token logic to LibTransfer's burnToken() function. |
Refactor |
PauseFacet.sol |
Removed 2 unnecessary lines of code. |
Clean Up |
Silo.sol |
Fixed an issue with the BDV of Earned Beans; removed unused variables. |
Bug Fix |
TokenFacet.sol |
Removed an unnecessary variable. |
Clean Up |
UnripeFacet.sol |
Renamed ripen() to chop() ; renamed claimUnripe() to
pick() ; added Internal Balance support for pick() and chop() ;
added picked() function.
|
Refactor |
LibWhitelist.sol |
Removed BEAN_LUSD variables. |
Clean Up |
LibTransfer.sol |
Added generalized burnToken() function with Internal Balance support. |
Refactor |
LibUnripeSilo.sol |
Most functionality—some were audited, but all have been heavily tested. |
Updated to account for Barn Raise changes |
LibCurveConvert.sol / LibMetaCurveConvert.sol /
LibBeanMetaCurve.sol / LibCurve.sol
|
Change the lpToPeg() function to account for Curve exchange fee. |
Bug Fix |
FertilizerFacet.sol |
Added getFertilizers() function. |
Usability |
LibCurveOracle.sol |
Added MetapoolOracle event. |
Usability |
SeasonFacet.sol |
Moved Sunrise event call to the start of the sunrise() function instead of
the end. |
Refactor |
Weather.sol |
Added the Season number to Weather related events. |
Refactor |
SiloFacet.sol |
Changed the updateUnripeDeposit() and updateUnripeDeposits() functions to
enrootDeposit() and enrootDeposits() , respectively.
|
Refactor |
Effective
After either:
- A two-thirds supermajority is reached; or
- The Voting Period ends and more than half of the total outstanding Stalk votes in favor of the BIP,
Publius will:
- Execute the remainder of the Water Treatment approved by BIP-20;
- Transfer ownership of Beanstalk to the BCM;
- Deploy BIP-21 related facets and initialization script;
- Propose the BIP-21 Diamond Cut to the BCM;
- Propose the approve transaction to use the BCM’s USDC; and
- Propose the addFertilizer transaction that adds the BCM’s USDC to the new BEAN:3CRV pool.
After that, the BCM will:
- Execute the BIP-21 Diamond Cut, which removes all existing function selectors and adds the new ones;
- Initialize Beanstalk;
- Execute the approve transaction to use the BCM’s USDC; and
- Execute the addFertilizer transaction.
The BCM will Unpause Beanstalk thereafter on August 6, 2022 at around 16:00 UTC.
After the Unpause transaction and thus BIP-21 is fully executed, the BCM shall follow the
process for verifying proposed BIPs moving forward.