BIP-37: Basin Integration

Proposed: August 23, 2023

Status: Passed

Link: Snapshot


Proposer

Brendan Sanderson, Ben Weintraub, Beanstalk Farms

Proposer Wallet: 0xf9d183af486a973b7921ceb5fdc9908d12aab440

Summary

Problem

Basin Integration

Basin is a composable EVM-native decentralized exchange protocol. Currently there is no generalized way for Wells (pools of the Basin DEX) to be easily integrated into the Silo (i.e., the Deposit, Convert and Oracle Whitelists).

Whitelist BEANETH

Currently Beans only trade against 3CRV, which is a significant centralization vector for Beanstalk. Additionally, the BEAN:3CRV pool, which is currently the sole oracle for calculating the Bean price, is not multi-block MEV manipulation resistant.

Seeds per BDV Changes

The Seeds per BDV of Bean and BEAN3CRV can be optimized given (1) the new option for providing Bean liquidity via the BEANETH Well and (2) that Unripe Depositors had accumulated Grown Stalk for about a year from Replant to the commitment of Silo V3. As a result of (2), the average Grown Stalk per BDV is excessively high for older Deposits, compared to newer ones.

Silo V3 Getters

Currently there is no way to get the total Deposited BDV or the last Mowed Stems for a particular Farmer.

Pipeline Upgrade

Pipeline v1.0.0 is unable to receive transfers of Ether, which makes it difficult to unwrap WETH as a part of a Pipeline function call. Pipeline v1.0.1 fixes this issue, but currently the Depot Facet uses Pipeline v1.0.0.

gm Incentive Reward Oracle

Currently Beanstalk uses the ratio between the USDC:ETH Uniswap V3 and BEAN:3CRV Curve pools to calculate the cost of executing the gm function in Beans. Both pools are subject to multi-block MEV manipulation and calculating the ratio between two pools is gas-inefficient.

Flood Update

Currently the implementation of Flood is not functional after the removal of the Withdrawal Freeze in BIP-36.

Disclosures

The Beanstalk DAO Disclosures can be updated to reflect the current state of Beanstalk and its risks.

Proposed Solution

Basin Integration

Provide the infrastructure for any Well LP token to be integrated into Beanstalk:

Move enrootDeposit(s) from ConvertFacet to a separate EnrootFacet.

Split up ConvertFacet into ConvertFacet and ConvertGettersFacet.

Whitelist BEANETH

Add BEANETH to the Deposit Whitelist with 1 Stalk per BDV and 4.5 Seeds per BDV. Also, support Conversions from Beans to BEANETH above peg and from BEANETH to Beans below peg.

In order for Beanstalk to calculate deltaB in the BEANETH Well, it must compare the manipulation resistant BEAN:ETH price in the Well with a manipulation resistant ETH:USD price.

Pumps are the generalized oracle component of Basin. Multi Flow is the Pump that is attached to the BEANETH Well and provides a multi-block MEV manipulation resistant BEAN:ETH price.

LibEthUsdOracle contains functionalty to fetch a manipulation resistant ETH:USD price. LibEthUsdOracle uses a greedy algorithm to return a gas efficient average price of (1) the current price returned by the ETH/USD Chainlink data feed and (2) either the ETH:USDC Uniswap V3 pool or the ETH:USDT Uniswap V3 pool depending on which is closer to (1). If the ETH:USDC Uniswap V3 price is sufficiently close (0.3%) to the Chainlink data feed price, then the oracle will not check the ETH:USDT Uniswap V3 price to save gas (i.e., be greedy). The oracle only returns a value if the price difference between the ETH/USD Chainlink data feed and either Uniswap V3 pool is less than 1%.

The BEANETH Well is added to the Oracle Whitelist by including the Well in the stepOracle and totalDeltaB functions in SeasonFacet/Oracle.sol.

Minting based on the BEANETH Well is subject to the 1% deltaB cap implemented in EBIP-2. With 2 pools on the Oracle Whitelist, the maximum amount that the Bean supply can increase each Season is 2% per the peg maintenance mechanism.

Update MetadataImage to include the BEANETH token and add the name and symbol functions to MetadataFacet to integrate Deposits with OpenSea.

Seeds per BDV Changes

Set the Seeds per BDV for Bean and BEAN3CRV to 3 Seeds and 3.25 Seeds, respectively.

After the commitment of this upgrade, the Deposit Whitelist would be the following:

Whitelisted asset Stalk per BDV Seeds per BDV
Bean 1 3
BEAN:3CRV Curve LP 1 3.25
BEAN:ETH Well LP 1 4.5
Unripe Bean 1 0
Unripe BEAN:3CRV LP 1 0

Silo V3 Getters

Add the following functions to the Silo Facet that return Deposited BDV and last Mowed Stem data for a given Farmer:

Pipeline Upgrade

Upgrade the Depot Facet to use Pipeline v1.0.1 (0xb1bE0000C6B3C62749b5F0c92480146452D15423). All updates were reviewed by Halborn.

Pipeline v1.0.1 Changelog

gm Incentive Reward Oracle

Upgrade the gm incentive reward oracle to calculate the cost to execute the gm function in Beans using the BEANETH Well.

Use getBeanEthWellPrice in LibBeanEthWellOracle to calculate the price of Ether in Beans. Remove the getBeanUsdPrice and getEthUsdcPrice functions in LibIncentive that were previously used to calculate the price of Ether in Beans using the ratio of the two return values.

Flood Update

Update handleRain in SeasonFacet/Weather.sol to reflect the removal of the Withdrawal Freeze. Beanstalk waits 1 Season after it starts Raining before Flooding.

Disclosures

The following is a list of proposed changes to the Beanstalk DAO Disclosures:

The updated Beanstalk DAO Disclosures can be read here.

BFM Signers and BIC Members

We propose the following signers for the BFM:

We propose the following members for the BIC:

Technical Rationale

Basin Integration

Integrating Basin and its components into Beanstalk in a generalized fashion makes it easier for future developers to propose BIPs that whitelist Wells.

Silo V3 Getters

Providing a way to get an individual Farmer's BDV per whitelisted token increases the composability of Beanstalk and enables protocols like Root to integrate with Silo V3.

Pipeline Upgrade

Supporting a version of Pipeline that can receive transfers of Ether improves the composability supported by the farm function.

gm Incentive Reward Oracle

Querying a single liquidity pool to calculate the price of Ether in Beans reduces the cost of calling the gm function, and thus the reward that Beanstalk pays to incentive it.

Flood Update

The Flood implementation must be updated in order to function properly.

Economic Rationale

Whitelist BEANETH

Beans currently only trade against 3CRV which is a significant centralization vector for Beanstalk. Ether is the most decentralized, censorship resistant and liquid asset on the Ethereum network. Thus, a relatively high Seeds per BDV for LP tokens of Beans paired with Ether is justified.

The Multi Flow Pump is the first Ethereum-native oracle for Ethereum-native data that offers multi-block MEV manipulation resistance in a post-Merge environment. Using Multi Flow, Beanstalk can calculate a multi-block MEV manipulation resistant BEAN:ETH price.

Uniswap V3 pools are not multi-block MEV manipulation resistant but are on-chain and permissionless. Chainlink data feeds are multi-block MEV manipulation resistant because they are off-chain and permissioned. The ETH/USD data feed is the only Chainlink feed secured by staking. Using an average of the Chainlink feed and one of the Uniswap V3 pools, Beanstalk can calculate a multi-block MEV manipulation resistant ETH:USD price at the cost of some centralization.

Therefore, Beanstalk calculates deltaB in the BEANETH Well in a manipulation resistant fashion.

Seeds per BDV Changes

Rewarding more Seeds to LP tokens than Beans

Providing liquidity for Beans is more useful to Beanstalk than Depositing Beans in the Silo, so Beanstalk should continue rewarding more Seeds to LP token Deposits than Bean Deposits. The delta in Seeds per BDV between LP tokens and Beans also minimizes upside volatility (and therefore excessive minting) as Farmers are incentivized to Convert their Deposited Beans to Deposited LP tokens above peg.

Therefore, LP tokens continue to receive more Seeds per BDV upon Deposit than Beans.

Rewarding more Seeds to BEANETH than BEAN3CRV Deposits

Prior to the April 2022 exploit, BEAN3CRV and BEANETH Deposits were both rewarded 4 Seeds per BDV. During this time, BEAN3CRV liquidity was growing rapidly and surpassed the amount of BEANETH liquidity. This is not ideal as Beanstalk should incentivize providing liquidity for Beans against decentralized assets.

Therefore, BEANETH should receive more Seeds per BDV than BEAN3CRV.

Increasing Seeds for Bean and BEANETH Deposits

Unripe Depositors had accumulated Grown Stalk for about a year from Replant to the commitment of Silo V3. As a result, the average Grown Stalk per BDV is excessively high. Increasing the Seeds per BDV for Bean and BEANETH allows for new Depositors to catch up to the average Grown Stalk per BDV faster.

With 4.5 Seeds per BDV for BEANETH Deposits, a new BEANETH Depositor would catch up to the average Grown Stalk per BDV in about 6 months. With 3 Seeds per BDV for Bean Deposits, a new Bean Depositor would catch up to the average Grown Stalk per BDV in about 9 months. A function to evaluate Seeds per BDV and time to catch up to average can be evaluated here: https://www.desmos.com/calculator/hevziu8k9y.

Additionally, decreasing the ratio of LP token to Bean Seeds per BDV reduces the incentive to not Convert from LP tokens to Beans below peg.

Therefore, the Seeds per BDV for Bean, BEAN3CRV and BEANETH are set to 3 Seeds, 3.25 Seeds and 4.5 Seeds, respectively.

gm Incentive Reward Oracle

Changing the oracle for calculating the cost to execute the gm function in Beans to the BEANETH Well that uses the Multi Flow Pump improves the censorship resistance of Beanstalk due to its multi-block MEV manipulation resistance.

Flood Update

Flood is an essential peg maintenance tool for Beanstalk.

Contract Changes

Initialization Contract

The init function on the following InitBipBasinIntegration contract is called:

Silo Facet

The following SiloFacet is removed from Beanstalk:

The following SiloFacet is added to Beanstalk:

SiloFacet Function Changes

Name Selector Action Type New Functionality
balanceOf 0x00fdd58e Replace View
balanceOfBatch 0x4e1273f4 Replace View
balanceOfDepositedBDV 0xbc8514cf Add View
balanceOfEarnedBeans 0x3e465a2e Replace View
balanceOfEarnedStalk 0x341b94d5 Replace View
balanceOfGrownStalk 0x8915ba24 Replace View
balanceOfPlenty 0x896651e8 Replace View
balanceOfRainRoots 0x69fbad94 Replace View
balanceOfRoots 0xba39dc02 Replace View
balanceOfSop 0xa7bf680f Replace View
balanceOfStalk 0x8eeae310 Replace View
bdv 0x8c1e6f22 Replace View
getDeposit 0x61449212 Replace View
getDepositId 0x98f2b8ad Replace View
getLastMowedStem 0x7fc06e12 Add View
getMowStatus 0xdc25a650 Add View
getSeedsPerToken 0x9f9962e4 Replace View
getTotalDeposited 0x0c9c31bd Replace View
getTotalDepositedBDV 0x9d6a924e Replace View
grownStalkForDeposit 0x3a1b0606 Replace View
inVestingPeriod 0x0b2939d1 Replace View
lastSeasonOfPlenty 0xbe6547d2 Replace View
lastUpdate 0xcb03fb1e Replace View
migrationNeeded 0xc38b3c18 Replace View
seasonToStem 0x896ab1c6 Replace View
stemStartSeason 0xbc771977 Replace View
stemTipForToken 0xabed2d41 Replace View
tokenSettings 0xe923e8d4 Replace View
totalEarnedBeans 0xfd9de166 Replace View
totalRoots 0x46544166 Replace View
totalStalk 0x7b52fadf Replace View
claimPlenty 0x45947ba9 Replace Call
deposit 0xf19ed6be Replace Call
mow 0x150d5173 Replace Call
mowMultiple 0x7d44f5bb Replace Call
plant 0x779b3c5c Replace Call
safeBatchTransferFrom 0x2eb2c2d6 Replace Call
safeTransferFrom 0xf242432a Replace Call
transferDeposit 0x081d77ba Replace Call
transferDeposits 0xc56411f6 Replace Call
withdrawDeposit 0xe348f82b Replace Call
withdrawDeposits 0x27e047f1 Replace Call

SiloFacet Event Changes

None.

Season Facet

The following SeasonFacet is removed from Beanstalk:

The following SeasonFacet is added to Beanstalk:

SeasonFacet Function Changes

Name Selector Action Type New Functionality
abovePeg 0x2a27c499 Replace View
curveOracle 0x07a3b202 Add View
paused 0x5c975abb Replace View
plentyPerRoot 0xe60d7a83 Replace View
poolDeltaB 0x471bcdbe Replace View
rain 0x43def26e Replace View
season 0xc50b0fb0 Replace View
seasonTime 0xca7b7d7b Replace View
sunriseBlock 0x3b2ecb70 Replace View
time 0x16ada547 Replace View
totalDeltaB 0x06c499d8 Replace View
weather 0x686b6159 Replace View
wellOracleSnapshot 0x597490c0 Add View
gm 0x64ee4b80 Replace Call
sunrise 0xfc06d2a6 Replace Call

SeasonFacet Event Changes

None.

Convert Facet

The following ConvertFacet is removed from Beanstalk:

The following ConvertFacet is added to Beanstalk:

ConvertFacet Function Changes

Name Selector Action Type New Functionality
convert 0xb362a6e8 Replace Call

ConvertFacet Event Changes

Name Change
RemoveDeposit Removed

Convert Getters Facet

The following ConvertGettersFacet is added to Beanstalk:

ConvertGettersFacet Function Changes

Name Selector Action Type New Functionality
getAmountOut 0x4aa06652 Replace View
getMaxAmountIn 0x24dd285c Replace View

ConvertGettersFacet Event Changes

None.

Whitelist Facet

The following WhitelistFacet is removed from Beanstalk:

The following WhitelistFacet is added to Beanstalk:

WhitelistFacet Function Changes

Name Selector Action Type New Functionality
dewhitelistToken 0x86b40a1b Replace Call
updateStalkPerBdvPerSeasonForToken 0xf18d9ed0 Replace Call
whitelistToken 0xd8a6aafe Replace Call
whitelistTokenWithEncodeType 0xb4f55be8 Add Call

WhitelistFacet Event Changes

Name Change
WhitelistToken stalk variable renamed to stalkIssuedPerBDV

Metadata Facet

The following MetadataFacet is being removed from Beanstalk:

The following MetadataFacet is added to Beanstalk:

MetadataFacet Function Changes

Name Selector Action Type New Functionality
imageURI 0x8f742d16 Remove View
imageURI 0xc20b8071 Add View
name 0x06fdde03 Add View
symbol 0x95d89b41 Add View
uri 0x0e89341c Replace View

MetadataFacet Event Changes

Name Change
URI Added

Depot Facet

The following DepotFacet is being removed from Beanstalk:

The following DepotFacet is added to Beanstalk:

DepotFacet Function Changes

Name Selector Action Type New Functionality
readPipe 0xdd756c4f Replace View
advancedPipe 0xb452c7ae Replace Call
etherPipe 0x6e47d07b Replace Call
multiPipe 0xcabec62b Replace Call
pipe 0x08e1a0ab Replace Call

DepotFacet Event Changes

None.

BDV Facet

The following BDVFacet is being removed from Beanstalk:

The following BDVFacet is added to Beanstalk:

BDVFacet Function Changes

Name Selector Action Type New Functionality
beanToBDV 0x5a049a47 Replace View
curveToBDV 0xf984019b Replace View
unripeBeanToBDV 0xc8cda2a0 Replace View
unripeLPToBDV 0xb0c22bb1 Replace View
wellBdv 0xc84c7727 Add View

BDVFacet Event Changes

None.

Enroot Facet

The following EnrootFacet is added to Beanstalk:

EnrootFacet Function Changes

Name Selector Action Type New Functionality
enrootDeposit 0x0b58f073 Replace Call
enrootDeposits 0x88fcd169 Replace Call

EnrootFacet Event Changes

Name Change
RemoveDeposit Moved from ConvertFacet
RemoveDeposits Copied from ConvertFacet

Beans Minted

None.

Audit

Basin Integration

The commit hash of this BIP is 76a188233917afc1db103ca64b02dab8c5280b35.

Halborn has performed an audit of this BIP up to commit hash 78d7045a4e6900dfbdc5f1119b202b4f30ff6ab8. You can view the final audit report here.

Beanstalk contract changes between the two commits:

Basin

Halborn and Cyfrin performed an audit of Basin up to commit hash e5441fc78f0fd4b77a898812d0fd22cb43a0af55. You can view the final audit report from Halborn here and the final audit report from Cyfrin here.

Code4rena performed an audit of Basin up to commit hash 8f6709ee1eeb36a452a08c591ebd3a340ea9b8c4, which included all remediations from the previous two audits.

The formal audit report from Code4rena is forthcoming, but all findings were either acknowledged or remediated by commit hash ea51be32047cbb6625232cb63b180ecfb3fd0b71, which is the commit hash of Basin code deployed on Ethereum mainnet. The changelog can be read here. All updates were reviewed by Cyfrin.

Effective

Immediately upon commitment.