-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BIP-45: Seed Gauge System #722
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Brean final review
Get from storage instead of pump
Brendan review
Implement Locked Underlying fix
- fix failing event by putting it in mockSeasonFacet
for subgraph.
- removes unneeded stalk burn function.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
BIP-45: Seed Gauge System
Proposer
Safisynai
Proposer Wallet: 0x43a9da9bade357843fbe7e5ee3eedd910f9fac1e
Summary
gm
reward during the first available block from 100 to 250 Beans.Note: BIP-42 was cancelled due to a bug that was found during the Voting Period. A BCM Signer indicated that the transaction should be cancelled by signing a verified message on Etherscan. As such, BIP-42 was removed from Snapshot. The fix for the reported bug was reviewed by Cyfrin.
Links
Context
Beanstalk is a credit-based stablecoin protocol. The main goal of Beanstalk is to regularly oscillate the Bean price across $1, indefinitely. Beanstalk's primary peg maintenance mechanism, and theoretical basis for existence, is the Field (i.e., the Beanstalk credit facility). The ability for Beanstalk to borrow Beans from the open market at a reasonable interest rate is essential for long term peg maintenance.
However, with the successful addition of Conversions within the Silo in December 2021, a second peg maintenance mechanism was discovered. The ability to add and remove Beans from liquidity pools to decrease and increase the Bean price, respectively, changes the Bean price without any outflows or inflows from the system. Currently, Converts are limited in that Depositors can only Convert between Beans and LP tokens, and vice versa (i.e., not across LP tokens). Furthermore, the incentives for Converting in a given direction with respect to peg (in particular, Seed allocations to the various assets whitelisted for Deposit) are not adjusted autonomously in response to Beanstalk's state.
At the beginning of each Season, Beanstalk adjusts its parameters as a response to its position and current state in pursuit of its main goal: to regularly oscillate the Bean price across $1, indefinitely. Therefore, the two primary questions with respect to peg maintenance are:
For a thorough investigation into these questions, it is recommend that all engaged Farmers read the Beanstalk State Space presentation and listen to the recordings of the discussion. However, for the purposes of this BIP, the punchline is that to date, Beanstalk has only measured price (in practice, deltaB) and debt level (in practice, the Pod Rate) in order to determine its health and its corresponding response. With the introduction of the Seed Gauge System, now Beanstalk also measures its liquidity level (in practice, the Liquidity to Supply Ratio, or L2SR).
This represents the potential for a significant efficiency increase in terms of peg maintenance, particularly in times of very high debt levels where Beanstalk prefers peg maintenance to primarily take place within the Silo via Conversions.
The general intuition for the Seed Gauge System is as follows: Seeds generate opportunity cost for Withdrawing assets that have been Deposited for longer AND marginal benefit for holding particular assets in the Silo in the form of Grown Stalk.
There are 3 new primary tools that Beanstalk has at its disposal as a result of implementing the Seed Gauge System:
Tools 1 and 3 are relevant to the Seed Gauge System but not relevant to the general peg maintenance mechanism and can be thought of as further refinements of the model.
Tool 2 is central to the Seed Gauge System and the general peg maintenance mechanism. Up until BIP-37, the effective Bean to Max LP Ratio was fixed at 1:2 (Deposited Beans and BEAN3CRV earned 2 and 4 Seeds per BDV, respectively). Since BIP-37, the ratio has been fixed at 1:1.5, given that Depositing Beans and BEANETH earned 3 and 4.5 Seeds per BDV, respectively. With the Seed Gauge System, this ratio can now be adjusted autonomously.
Problem
Beanstalk does not currently have a way to target a particular Grown Stalk inflation rate. This means that there is no way for Beanstalk to affect the time in which it takes new Silo Deposits to catch up in terms of Grown Stalk per BDV to older Deposits. As a result of long periods without Bean mints, it is possible for older Deposits to have such a Grown Stalk advantage that it discourages newer Deposits.
Seeds per BDV for whitelisted assets are currently static and can only be changed via governance. Considering the outsized importance of Conversions within the Silo, this is a missing tool in the Beanstalk toolbox: by changing the Seeds per BDV for a pair of assets, Beanstalk can change the desirability of holding one asset over the other. In theory, dynamic Seed issuance can significantly improve peg maintenance.
The L2SR is an important indicator of Beanstalk's health, but Beanstalk currently does not measure or use it to evaluate its position and current state with respect to ideal equilibrium. Doing so requires an upgrade to the case system.
The current case system only has two different cases for price, P < 1 and P > 1. A very high P compromises utility of Bean because the potential for price spikes makes Beans less attractive to borrow and price other assets against.
Beanstalk currently changes Maximum Temperature on an absolute scale, but does not support the ability to change it on a relative scale. In instances where the Maximum Temperature is particularly high, the lack of ability to change the Maximum Temperature on a relative basis may lead to inefficiencies in the Field.
When P < 1 and demand for Soil is increasing or steady, Beanstalk is currently more aggressive in increasing the Maximum Temperature than it should be, in theory, when the debt level is high, and less aggressive than it should be, in theory, when the debt level is low.
BDV that has not been migrated to Silo V3 is not included in
s.siloBalances[token].depositedBdv
. For Beanstalk to support a LP Gauge System, it is necessary to track the total Deposited BDV for each whitelisted token.Farmers can only Chop Unripe assets by forfeiting all their associated Grown Stalk, even if they intend to leave the underlying assets in the Silo after the Chop is performed.
BEAN3CRV:
Flood is only implemented in the BEAN3CRV pool, which has low liquidity and is dewhitelisted in this upgrade.
Implementing the Seed Gauge System without any changes to Earned Bean issuance would open up potential vectors for manipulation of Deposited BDV, and thus Seed allocations for various whitelisted assets.
The
gm
function is not regularly being called in the first block in which it becomes callable due to the increased gas costs on Ethereum and the low max reward of 100 Beans.Proposed Solution
Seed Gauge System
Grown Stalk Inflation Rate
The Grown Stalk per BDV for a Deposit can be thought of as the age of that Deposit—the longer the Deposit has been in the Silo, the higher its Grown Stalk is relative to its BDV. Thus, the average Grown Stalk per BDV is a measure for how old Deposits are across the entire Silo relative to the total BDV in the Silo.
The Seed Gauge System enables Beanstalk to target an amount of Grown Stalk per BDV that should be issued each Season. In particular, Beanstalk sets the
TARGET_SEASONS_TO_CATCHUP
parameter, which determines how many Seasons it should take for a new Depositor to catch up to the average Grown Stalk per BDV. The average Grown Stalk per BDV per Season is the average Grown Stalk per BDV divided byTARGET_SEASONS_TO_CATCHUP
. We propose thatTARGET_SEASONS_TO_CATCHUP
be set to4320
, or ~6 months.Gauge Points
Gauge Points determine how the Grown Stalk issued in a Season should be distributed between whitelisted LP tokens. Only whitelisted LP tokens have Gauge Points. Gauge Points have 18 decimal precision (
1e18
).Every Season, Beanstalk calculates the new amount of Gauge Points an LP token should have by calling each whitelisted LP token's Gauge Point function.
We propose that the Gauge Points for BEANETH (the only whitelisted LP token as of this upgrade) be initialized to 100, and that BEANETH utilize the following Gauge Point function to update its Gauge Points each Season:
Thus, given that BEANETH will be the only whitelisted LP token, the BEANETH Gauge Points will remain at 100 until another LP token is whitelisted.
This function takes as input
optimalPercentDepositedBdv
, (i.e., the optimal distribution of Deposited BDV amongst whitelisted LP tokens). Put another way, this is the target distribution of liquidity for Beans to trade against. For the time being, the optimal distribution of Deposited BDV will be set and upgraded via normal governance. Given the single whitelisted LP token, we propose the optimal distribution of Deposited BDV amongst whitelisted LP tokens be set to 100% BEANETH.Bean to Max LP Ratio
Gauge Points Per BDV is the amount of Gauge Points allocated to a whitelisted LP token divided by the total BDV of that LP token Deposited in the Silo. The whitelisted LP token with the largest Gauge Points per BDV is used to determine the distribution of Grown Stalk to Beans in the Silo in order to ensure that at least 1 LP token always receives at least as much Grown Stalk as Deposited Beans (i.e., the "Max LP" in "Bean to Max LP Ratio").
The Bean to Max LP Scalar ($L$ ) is a scalar between 0 and 1 that is adjusted by Cases V2 (defined later). The Bean to Max LP Ratio has a minimum ($Y$ ) and maximum value ($Z$ ). We propose to set $Y$ and $Z$ to 1:2 (i.e., 50%, 0.5) and 1:1 (i.e., 100%, 1), respectively.
At$L = 0$ , the Bean to Max LP Ratio is at its minimum value (i.e., at 1:2, 1 Bean Deposited in the Silo receives half the amount of Grown Stalk as 1 BDV of the Max LP token), and at $L = 1$ , the Bean to Max LP Ratio is at its maximum value (i.e., at 1:1, 1 Bean Deposited in the Silo receives the same amount of Grown Stalk as 1 BDV of the the Max LP token).
Chain of Logic
Below is the series of steps that Beanstalk uses to determine how much Grown Stalk to issue each Season, and how to distribute that Grown Stalk to each whitelisted asset (Unripe assets excluded). Note that variables names listed below do not necessarily correspond to the Solidity implementation.
G
= average Grown Stalk per BDV per SeasontotalGaugeBdv
= total BDV of all Deposited LP tokens and Deposited BeansnewGrownStalk
=G
*totalGaugeBdv
(the Grown Stalk issued this Season)gaugePointsPerBdv[lpToken]
= Gauge Points per BDV for a particular tokenbeanToMaxLpRatio
=beanGaugePointsPerBdv
=max(gaugePointsPerBdv[lpToken])
*beanToMaxLpRatio
totalGaugePoints
=sum(lpGaugePoints[lpToken])
+beanGaugePointsPerBdv
grownStalkPerGaugePoint
=newGrownStalk
/totalGaugePoints
grownStalkIssuedPerSeason[lpToken]
=grownStalkPerGaugePoint
*gaugePointsPerBdv[lpToken]
grownStalkIssuedPerSeason[BEAN]
=grownStalkPerGaugePoint
*beanGaugePointsPerBdv
Cases V2
The case system is how Beanstalk evaluates its position and current state with respect to ideal equilibrium. Cases V1 measures 3 axes:
As a result, there are 24 cases that determine how to adjust the Maximum Temperature:
We propose Cases V2, which adds a fourth axis in the form of the L2SR and adds an additional case to price (excessively high price; P > Q).
With 4 cases for L2SR (excessively low, reasonably low, reasonably high and excessively high) and 3 cases for price (low, high and excessively high), Cases V2 has 144 cases. Each case determines how to change the Maximum Temperature and the Bean to Max LP Scalar.
In Cases V2, support for Beanstalk to adjust its parameters (Maximum Temperature and the Bean to Max LP Scalar) on a relative basis is added in addition to the ability to change the values on an absolute basis.
Liquidity to Supply Ratio
In the context of the L2SR, liquidity is defined as the sum of the USD values of the non-Bean assets in each whitelisted liquidity pool multiplied by their respective liquidity weights. Supply is defined as the total Bean supply minus Locked Beans (defined below).
Beanstalk can be in 4 different states in relation to its L2SR:
Locked Beans
Due to the Barn Raise and the associated Beans underlying Unripe assets, the number of tradable Beans does not equal the total Bean supply. At the time of writing, ~0.224 Beans underlying each Unripe Bean, but holders can only redeem ~0.0102 Beans per Unripe Bean. Thus, ~0.2138 Beans Per Unripe are considered not tradable. This is calculated and omitted from the Bean supply in
LibEvaluate.calcLPToSupplyRatio
viaLibUnripe.getLockedBeans
.P > Q
Currently, Beanstalk only has 2 cases for price: below and above peg. During times where the price is excessively high, Beanstalk should have the ability to adjust its parameters in a more aggressive fashion.
We propose Q to be $1.05.
Maximum Temperature and Bean To Max LP Scalar Changes
In order to adjust the Bean to Max LP Ratio, in practice Beanstalk adjusts a scalar (the Bean to Max LP Scalar) between 0 and 1, where 0 results in the minimum Bean to Max LP Ratio and 1 results in the maximum Bean to Max LP Ratio. Therefore, Cases V2 can adjust the Bean to Max LP Ratio independently of the minimum and maximum values.
Cases V2 updates the Maximum Temperature ($T$ ) and the Bean to Max LP Scalar ($L$ ) for the next Season $s + 1$ like so (where $m_T$ and $b_T$ are the relative and absolute changes to $T$ , and $m_L$ and $b_L$ are the relative and absolute changes to $L$ ):
The Maximum Temperature has a minimum of 1%, and range of the Bean to Max LP Scalar is$[0, 1]$ .
Case Data
In Cases V1, only 1 parameter was stored (the absolute change in Maximum Temperature) for each case. Cases V2 stores 4 parameters for each case:
mT
with 6 decimal precision, i.e., 100% =100e6
)bT
with 2 decimal precision, i.e., 100% =1e2
)mL
with 18 decimal precision, i.e., 100% =100e18
)bL
) with 18 decimal precision, i.e., 100% =100e18
)This is stored as a
bytes32
, which is decoded when used. 7 bytes are left unused for potential future use.144 Cases to Rule Them All
In all 144 cases,
mT
andmL
are set to 1, i.e., there are no proposed relative adjustments to Maximum Temperature or the Bean to Max LP Scalar. As a result, each cell in the following tables strictly includes [bT
,bL
], i.e., the absolute change in Maximum Temperature followed by the absolute change in the Bean to Max LP Scalar.We propose the following absolute Maximum Temperature and Bean to Max LP Scalar changes in each case:
Silo V3 Unmigrated BDV
Currently, the total Deposited BDV stored on-chain does not account for Deposits that have not been migrated to Silo V3. To fix this, a two-step process was implemented. Step one was implemented in BIP-38.
The second step is to calculate the remaining unmigrated BDV for each token at the BIP-38 migration block, and increment the total Deposited BDV by the difference of the unmigrated BDV and the migrated BDV between BIP excecution.
LibTokenSilo.incrementTotalDepositedBdv(C.TOKEN, TOKEN_UN_MIGRATED_BDV - s.migratedBdvs[C.TOKEN]);
This second step is performed as part of this BIP.
Unripe λ → λ Conversions
Add support for Conversions in the Silo from Unripe λ to λ. In doing so:
LibDataConvert
;LibConvert
to include the new Convert type;LibChop
and modifychop(...)
and_getPenalizedUnderlying(...)
to useLibChop
; andLibChopConvert
with theconvertUnripeBeansToBeans(...)
andgetBeanAmountOut(...)
functions which wrapLibChop
functions.Dewhitelist BEAN3CRV
We propose to remove BEAN3CRV from the Deposit and Minting Whitelists, and remove the BEAN → BEAN3CRV Conversion from the Convert Whitelist.
Therefore, BEAN3CRV can no longer be Deposited in the Silo or Converted to from Bean Deposits, and is no longer used in calculating a cumulative deltaB. Existing BEAN3CRV Deposits can continue to be Converted to Bean Deposits when P < 1 in the pool.
We propose to remove risks associated with BEAN3CRV from the Beanstalk DAO Disclosures.
Flood Update
Update the Flood to occur in the whitelisted Well with the most liquidity, i.e., the Flood Well.
In
Weather.sol
:handleRain
to support Cases V2 and the initialization of the Flood Well;sop
andcalculateSop
to support the Flood Well; andcalculateSop
to use the minimum of the instantaneous reserves from Multi Flow and the current reserves in the Well.Germination
Introduce a 2 Season delay for Stalk to be issued to a new Deposit. In the interim, new Deposits have Germinating Stalk. Deposits with Germinating Stalk are considered Germinating Deposits. Germinating Deposits can be Withdrawn or Transferred, but cannot be Converted.
The BDV of Germinating Deposits are not included in the calculations of Deposited BDV for the Seed Gauge System.
Deposits made in the 2 Seasons prior to the deployment of this BIP will become Germinating at the time of deployment.
Increase Max
gm
RewardIncrease the max
gm
reward in the first available block from 100 to 250 Beans.Technical Rationale
Seed Gauge System
Generalizing the function that updates the Grown Stalk inflation rate (
LibGauge.updateAverageStalkPerBdvPerSeason
) makes future parameter changes via governance more straightforward and sets the stage for the calculation of the parameter to be autonomized in the future.Calculating the Gauge Points of a given LP token by calling its
gpSelector
allows for different implementations to be used for different whitelisted LP tokens.Calculating the liquidity weight of a given LP token by calling its
lwSelector
allows for different implementations to be used for different whitelisted LP tokens.Cases V2
Cases V1 stores the cases in an
int8
array, which is too small to accommodate the new variables (mT
,mL
andbL
). Cases V2 uses abytes32
array which packs all 4 variables in one data type. It also provides space for more variables in the future without requiring another infrastructure upgrade to the Case system. For example, the case for increasingbT
by 3 and decreasingbL
by 0.50 looks like:Cases V2 decodes the
bytes32
value to getmT
,bT
,mL
andbL
.bT
has a decimal precision of 2, which corresponds to the existing Maximum Temperature changes.mL
andbL
have 18 decimal precision in order to provide greater flexibility in future changes to the cases.Reusing the Well reserves via
LibWell.getTwaReservesFromStorageOrBeanstalkPump
to calculate non-Bean liquidity and viaLibWell.getWellPriceFromTwaReserves
to calculate P reduces the cost of calling thegm
function, and thus the reward the Beanstalk pays to incentivize it.Using an if-else ladder in
LibLockedUnderlying
to approximate the number of Locked Beans is necessary due to the infeasibility of performing a Newtonian estimation on-chain.By separating the Bean to Max LP Scalar from the Bean to Max LP Ratio (see
LibGauge.getBeanToMaxLpGpPerBdvRatioScaled
), governance can more easily and independently update the scalar change in each case and the minimum and maximum Bean to Max LP Ratios. Furthermore, autonomizing the setting of these parameters in the future will be easier.Silo V3 Unmigrated BDV
Updating
totalDepositedBDV
by the amount of unmigrated BDV enables the Seed Gauge System to accurately measure the L2SR.Dewhitelist BEAN3CRV
Dewhitelisting BEAN3CRV reduces the development required to implement the Seed Gauge System, as all whitelisted LP tokens now use Wells and Pumps.
Flood Update
Generalizing the Flood, albeit to a single Well, reduces future development work associated with changing the Well in which Flood occurs.
Germination
Using Stems to denote time Deposited in the Silo reduces additional development needed for Germination.
stalkEarnedPerSeason
must be non-zero in order for Germination to denote time Deposited in the Silo. A lowerstalkEarnedPerSeason
decreases the minimum Stalk growth and reduces how much Stalk that Beanstalk needs to issue. Increasing the precision ofstalkEarnedPerSeason
by 6 (1e6
) allows for a lower minimum value that a whitelisted token needs to support Germination.Old Deposits must update their Stem precision. A Depositor's
lastStem
needs to be updated in order to properly calculate their Grown Stalk. Deposits and a Depositor'slastStem
are automatically updated upon an interaction with the Silo (i.e., no migration akin to Silo V3 is necessary).Other Misc. Technical Explanations
The Season Getters Facet is added to allow for more space in the Season Facet to implement the Seed Gauge System.
The Metadata Facet is upgraded to increase composability with current NFT marketplaces like OpenSea. Omitting the token icon from the metadata allows for whitelisting tokens without needing to upgrade the Metadata Facet each time.
LibGauge
,LibConvert
,LibLockedUnderlying
,LibIncentive
andLibGerminate
are implemented as external libraries to save bytecode space inSeasonFacet
,UnripeFacet
,ConvertFacet
andSeasonGettersFacet
.Properly emitting ERC-1155 events during Enroots makes Deposits composable with existing ERC-1155 indexers.
WhitelistStatus
allows for a non-whitelisted but Deposited token to be included ingetAverageGrownStalkPerBdv
and improves the security of whitelisting and dewhitelisting assets.Economic Rationale
Seed Gauge System
The ability to set
TARGET_SEASONS_TO_CATCHUP
as a function of time allows the linear component of Stalk growth from Seeds to be preserved while being able to toggle the slope of growth in an arbitrary fashion.Given the lack of new participation in Beanstalk it is likely that the current effective
TARGET_SEASONS_TO_CATCHUP
of ~10 months is too high. SettingTARGET_SEASONS_TO_CATCHUP
aggressively (i.e., to 6 months) compared to where it currently is in practice is a way to respond to the significant advantage older Depositors have as a result from the extended period without growth since Replant.Setting an aggressive
TARGET_SEASONS_TO_CATCHUP
is more prudent while most liquidity is still Unripe, rather than when it is mostly non-Unripe, because an aggressiveTARGET_SEASONS_TO_CATCHUP
lowers the opportunity cost of Withdrawing from the Silo.Ensuring that 1 whitelisted LP token (i.e., the LP token with the highest Gauge Points per BDV) is always allocated at least as many Seeds as Beans ensures that Beanstalk never incentivizes holding Beans over providing liquidity.
The ability to set an optimal distribution of Deposited LP BDV allows for the DAO to express a preference for the ideal distribution of Bean liquidity against various assets. Given the complexity of balancing a portfolio properly, this has not been autonomized and instead been left for infrequent changes via governance.
Cases V2
Measuring and updating the Case system to factor in the L2SR has the potential to significantly improve peg maintenance. For example, while L2SR is high, Beanstalk can be less aggressive in rewarding Seeds to LP tokens over Beans in order to encourage Conversions below peg.
By excluding Locked Beans from the Bean supply in the L2SR calculation, Beanstalk can determine its health in terms of liquidity based on only the number of Beans that can reasonably be sold. This is preferable over factoring in Beans that cannot be sold.
Price spikes makes Beans less attractive to borrow and price other assets against. Beanstalk should be more aggressive in returning the price to peg when the price reaches a particular threshold above $1. Q = 1.05 is a reasonable threshold while the Bean supply is small. It does not seem that there is a natural opposite to Q when P < 1.
By adjusting a Bean to Max LP Scalar, Beanstalk can adjust the relative incentives for holding Deposited Beans vs the Deposited LP token with the highest Gauge Points per BDV (the "Max LP").
144 Cases to Rule Them All
Although technical support for relative changes to the Maximum Temperature and the Bean to Max LP Scalar are made possible in this upgrade, more research is necessary to determine when they should be used, if at all.
When P < 1 and demand for Soil is increasing or steady, Beanstalk should be less aggressive in increasing the Maximum Temperature when the debt level is high (because the debt level is high) and more aggressive when the debt level is low (because it should be willing to sacrifice more debt at the margin in exchange for better peg maintenance). This is true for all L2SR states. Otherwise, no changes are made to the Maximum Temperature changes (in all of the proposed cases, Maximum Temperature changes in same way when P > 1 and P > Q).
No matter the L2SR, when P > Q, Beanstalk should maximally incentivize Converting to LP Deposits by aggressively decreasing the Bean to Max LP Ratio. By decreasing the scalar by 0.5 each Season, the Bean to Max LP Ratio returns to the minimum value within 2 Seasons.
When L2SR is excessively low, in all cases, Beanstalk should be similarly aggressive in incentivizing Conversions to LP Deposits by quickly reaching the minimum Bean to Max LP Ratio.
When the L2SR is reasonably low and Pod Rate is low, Beanstalk should be similarly aggressive in reaching the minimum Bean to Max LP Ratio given that, at the margin, Beanstalk would rather take on debt than lose liquidity. When the L2SR is reasonably low and Pod Rate is high, Beanstalk should gradually increase the Bean to Max LP Ratio when P > 1 (to incentivize Conversions above peg) and gradually decrease it when P < 1 (to incentivize Conversions below peg). By changing the scalar by 0.01 each Season, the Bean to Max LP Ratio can change from the maximum to the minimum value (or vice versa) within 100 Seasons.
When L2SR is reasonably high and P < 1, Beanstalk should similarly gradually increase the Bean to Max LP Ratio to incentivize Converting from LP Deposits to Bean Deposits, and vice versa when P > 1.
When L2SR is excessively high, Beanstalk should be more willing to accept a loss of liquidity rather than an increase in debt level at the margin. Therefore, it should adjust the Bean to Max LP Scalar just as it does when L2SR is reasonably high, except it can be slightly more aggressive when P < 1 and the Pod Rate is high. By increasing the Bean to Max LP Scalar by 0.02, the Bean to Max LP Ratio can change from the minimum to the maximum value within 50 Seasons.
Dewhitelist BEAN3CRV
Beanstalk is still subject to inter-block MEV manipulation at a scale proportional to the amount of liquidity in the BEAN3CRV pool. Any volume in the BEAN3CRV pool is subject to an unnecessary trading fee in the pool, which results in worse prices for Farmers and worse peg maintenance for Beanstalk. The price of 3CRV is dependent on the worst of the prices of USDC, USDT and DAI. Therefore, Beanstalk should not continue incentivizing providing liquidity to the BEAN3CRV pool.
Flood Update
Flood is an essential peg maintenance tool for Beanstalk.
Germination
Germination adds flash loan and inter-block MEV manipulation resistance to the calculation of Deposited BDV and allows the previous 10-block Vesting Period to be removed. By preventing the accrual of Earned Beans for 1 full Season, Beanstalk further disincentivizes inorganic demand.
Increase Max
gm
RewardIncreasing the max
gm
reward in the first available block from 100 to 250 Beans increases the probability that it is called as soon as possible during periods of high usage of the Ethereum network.Contract Changes
Initialization Contract
The
init
function on the followingInitBipSeedGauge
contract is called:0x6eF9cC52Eb37e0dE9592960c0c894a1000ac7dDf
Unripe Facet
The following
UnripeFacet
is removed from Beanstalk:0xAa8c44D0B89864b467C3776a7Dd367ff2aB6992A
The following
UnripeFacet
is added to Beanstalk:0xeBD6Fc0c2d4dc3Ea131d7F14aA2f617d63Dc0F1a
UnripeFacet
Function Changes_getPenalizedUnderlying
0xa84643e4
balanceOfPenalizedUnderlying
0x1acc0a47
balanceOfUnderlying
0x1be655e8
getLockedBeans
0x087d78b4
getLockedBeansFromTwaReserves
0x7caa025f
getLockedBeansUnderlyingUnripeBean
0xbfe2f3be
getLockedBeansUnderlyingUnripeBeanEth
0x208c2c98
getPenalizedUnderlying
0x6de45df2
getPenalty
0x014a8a49
getPercentPenalty
0xbb7de478
getRecapFundedPercent
0x43cc4ee0
getRecapPaidPercent
0xab434eb7
getTotalUnderlying
0xadef4533
getUnderlying
0x9f06b3fa
getUnderlyingPerUnripeToken
0xb8a04d1b
getUnderlyingToken
0x691bcc88
isUnripe
0xfc6a19df
picked
0xd3c73ec8
addMigratedUnderlying
0x787cee99
addUnripeToken
0xfa345569
chop
0x9a516cad
pick
0x13ed3cea
switchUnderlyingToken
0xa33fa99f
Metadata Facet
The following
MetadataFacet
is being removed from Beanstalk:0x8aD8dfC3303469A8c2d14763199a99363bF580cc
The following
MetadataFacet
is added to Beanstalk:0x9F5ec59d13AfDb581A383D6215b717312e875Fd2
MetadataFacet
Function ChangesimageURI
0xc20b8071
name
0x06fdde03
symbol
0x95d89b41
uri
0x0e89341c
BDV Facet
The following
BDVFacet
is being removed from Beanstalk:0xC1Bbee46EcB6445B176F7f172F91976ADF4e21D9
The following
BDVFacet
is added to Beanstalk:0xB752bfD626AD8715DE26D9bf3b3512F13632CCa1
BDVFacet
Function ChangesbeanToBDV
0x5a049a47
curveToBDV
0xf984019b
unripeBeanToBDV
0xc8cda2a0
unripeLPToBDV
0xb0c22bb1
wellBdv
0xc84c7727
Convert Facet
The following
ConvertFacet
is removed from Beanstalk:0x38Dbe7445D3C51f27E41996de5b0EA19e3E47BA6
The following
ConvertFacet
is added to Beanstalk:0x8257C2EB3265640714cCF298ad208E3054EF675F
ConvertFacet
Function Changesconvert
0xb362a6e8
Convert Getters Facet
The following
ConvertGettersFacet
is removed from Beanstalk:0x789e37096Fb0abbD4f64A86B51D720b371853a70
The following
ConvertGettersFacet
is added to Beanstalk:0x0a4121F3c4ACd9825Ed5499ACAD9fEA7a8a4eeED
ConvertGettersFacet
Function ChangesgetAmountOut
0x4aa06652
getMaxAmountIn
0x24dd285c
Enroot Facet
The following
EnrootFacet
is removed from Beanstalk:0x5CB70cf085368698198CB45D517445d4413eB695
The following
EnrootFacet
is added to Beanstalk:0x305d7c1C53817a4e5b66043e9883FB14b2005B6B
EnrootFacet
Function ChangesenrootDeposit
0x0b58f073
enrootDeposits
0x88fcd169
Migration Facet
The following
MigrationFacet
is removed from Beanstalk:0xbE73a5C684B1b53d7C7758B9a614Bcfdb24f822d
The following
MigrationFacet
is added to Beanstalk:0x5A3C138cDb894e6d200CCd350cdeE7404b1f3c9B
MigrationFacet
Function ChangesbalanceOfGrownStalkUpToStemsDeployment
0x505f43ea
balanceOfLegacySeeds
0x1be2cfd8
getDepositLegacy
0xa9be1acb
mowAndMigrate
0x1f4f3d55
mowAndMigrateNoDeposits
0xaed942e9
totalMigratedBdv
0x2b8cde0d
Silo Facet
The following
SiloFacet
is removed from Beanstalk:0xFb33Af0Cc65d5dE71399c0A395846F53Fff76D71
The following
SiloFacet
is added to Beanstalk:0x14047A7226c1e4a0dD15F69844e3771005cfa4e3
SiloFacet
Function ChangesgetSeedsPerToken
0x9f9962e4
inVestingPeriod
0x0b2939d1
claimPlenty
0x45947ba9
deposit
0xf19ed6be
mow
0x150d5173
mowMultiple
0x7d44f5bb
plant
0x779b3c5c
safeBatchTransferFrom
0x2eb2c2d6
safeTransferFrom
0xf242432a
transferDeposit
0x081d77ba
transferDeposits
0xc56411f6
withdrawDeposit
0xe348f82b
withdrawDeposits
0x27e047f1
Silo Getters Facet
The following
SiloGettersFacet
is added to Beanstalk:0xBbc36F691aBA133a214a8cb66Ab8847b8A3a5622
SiloGettersFacet
Function ChangesbalanceOf
0x00fdd58e
balanceOfBatch
0x4e1273f4
balanceOfDepositedBDV
0xbc8514cf
balanceOfEarnedBeans
0x3e465a2e
balanceOfEarnedStalk
0x341b94d5
balanceOfFinishedGerminatingStalkAndRoots
0xc063989e
balanceOfGerminatingStalk
0x838082b5
balanceOfGrownStalk
0x8915ba24
balanceOfPlenty
0x896651e8
balanceOfRainRoots
0x69fbad94
balanceOfRoots
0xba39dc02
balanceOfSop
0xa7bf680f
balanceOfStalk
0x8eeae310
balanceOfYoungAndMatureGerminatingStalk
0x0fb01e05
bdv
0x8c1e6f22
getDeposit
0x61449212
getDepositId
0x98f2b8ad
getEvenGerminating
0x1ca5f625
getGerminatingRootsForSeason
0x96e7f21e
getGerminatingStalkAndRootsForSeason
0x4118140a
getGerminatingStalkForSeason
0x9256dccd
getGerminatingStem
0xa953f06d
getGerminatingStems
0xe5b17f2a
getGerminatingTotalDeposited
0xc25a156c
getGerminatingTotalDepositedBdv
0x9b3ec513
getLastMowedStem
0x7fc06e12
getLegacySeedsPerToken
0xf5cb9097
getMowStatus
0xdc25a650
getOddGerminating
0x85167e51
getTotalDeposited
0x0c9c31bd
getTotalDepositedBDV
0x9d6a924e
getTotalGerminatingAmount
0xb45ef2eb
getTotalGerminatingBdv
0x9dcf67f0
getTotalGerminatingStalk
0x7d4a51cb
getYoungAndMatureGerminatingTotalStalk
0x5a8e63e3
grownStalkForDeposit
0x3a1b0606
lastSeasonOfPlenty
0xbe6547d2
lastUpdate
0xcb03fb1e
migrationNeeded
0xc38b3c18
seasonToStem
0x896ab1c6
stemStartSeason
0xbc771977
stemTipForToken
0xabed2d41
tokenSettings
0xe923e8d4
totalEarnedBeans
0xfd9de166
totalRoots
0x46544166
totalStalk
0x7b52fadf
Whitelist Facet
The following
WhitelistFacet
is removed from Beanstalk:0x730bfC44C8c51c469aFc133B0e445d0CC9FFc63d
The following
WhitelistFacet
is added to Beanstalk:0x47DA294946D41E90486ca8BB2adA493A6b974A2a
WhitelistFacet
Function ChangeswhitelistToken
0xd8a6aafe
whitelistTokenWithEncodeType
0xb4f55be8
getSiloTokens
0xe9522c08
getWhitelistStatus
0xd9ba32fc
getWhitelistStatuses
0x170cf084
getWhitelistedLpTokens
0x9d1d2877
getWhitelistedTokens
0xe26f7900
getWhitelistedWellLpTokens
0x76a7bc84
dewhitelistToken
0x86b40a1b
updateGaugeForToken
0xce5fb821
updateStalkPerBdvPerSeasonForToken
0xf18d9ed0
whitelistToken
0x371b5b03
whitelistTokenWithEncodeType
0x052ebc26
Gauge Point Facet
The following
GaugePointFacet
is added to Beanstalk:0x4b10DfCCD211b77671E1E01541346F0c659C681b
GaugePointFacet
Function ChangesdefaultGaugePointFunction
0xd8317c71
Liquidity Weight Facet
The following
LiquidityWeightFacet
is added to Beanstalk:0x9Aaaa79FDDEFcBbD30605F653FA440922B327c3D
LiquidityWeightFacet
Function ChangesmaxWeight
0xa8b0bb83
Season Facet
The following
SeasonFacet
is removed from Beanstalk:0x7667b52cbbe2D7CA54334C7c00F1396faF660DeA
The following
SeasonFacet
is added to Beanstalk:0xB5818dE8b02394b4300F15F61083dc3ff976EAA1
SeasonFacet
Function ChangescurveOracle
0x07a3b202
seasonTime
0xca7b7d7b
gm
0x64ee4b80
sunrise
0xfc06d2a6
Season Getters Facet
The following
SeasonGettersFacet
is added to Beanstalk:0x46d11a5076EAAD1ffA24b0C2DDF38d4Aeaa19920
SeasonGettersFacet
Function ChangesabovePeg
0x2a27c499
calcGaugePointsWithParams
0xeedc7ab9
getAverageGrownStalkPerBdv
0x7ba6cbf8
getAverageGrownStalkPerBdvPerSeason
0xeb0e1215
getBeanEthGaugePointsPerBdv
0xd1db56b8
getBeanGaugePointsPerBdv
0x69aa7e02
getBeanToMaxLpGpPerBdvRatio
0xcc88d4f9
getBeanToMaxLpGpPerBdvRatioScaled
0x673c75f0
getDeltaPodDemand
0x64b3496b
getGaugePoints
0x93523425
getGaugePointsPerBdvForToken
0x64887852
getGaugePointsPerBdvPerWell
0xb2b0556d
getGaugePointsWithParams
0x141933bf
getGrownStalkIssuedPerGp
0xf98da2de
getGrownStalkIssuedPerSeason
0x383f170f
getLargestLiqWell
0xd1943f7f
getLiquidityToSupplyRatio
0xcb2d0a3c
getPodRate
0xcce813a1
getSeedGauge
0x6af8e5a4
getSopWell
0x7d23804d
getTotalBdv
0x50539159
getTotalUsdLiquidity
0xbbf459a7
getTotalWeightedUsdLiquidity
0xf788b47c
getTwaLiquidityForWell
0xa13a3742
getWeightedTwaLiquidityForWell
0x93c9e531
paused
0x5c975abb
plentyPerRoot
0xe60d7a83
poolDeltaB
0x471bcdbe
rain
0x43def26e
season
0xc50b0fb0
sunriseBlock
0x3b2ecb70
time
0x16ada547
totalDeltaB
0x06c499d8
weather
0x686b6159
wellOracleSnapshot
0x597490c0
Event Changes
WeatherChange
TemperatureChange
UpdateAverageStalkPerBdvPerSeason
GaugePointChange
BeanToMaxLpGpPerBdvRatioChange
FarmerGerminatingStalkBalanceChanged
TotalGerminatingBalanceChanged
TotalGerminatingStalkChanged
TotalStalkChangedFromGermination
UpdateGaugeSettings
AddWhitelistStatus
RemoveWhitelistStatus
UpdateWhitelistStatus
WhitelistToken
SeasonOfPlenty
ClaimPlenty
Beans Minted
None.
Audit
The commit hash of this BIP is ac8e681c7daa7cb046c1e405b27e50e7e44c0504.
Cyfrin performed an audit of the initial version of the Seed Gauge system. The audit report can be read here.
After significant changes, such as the Germination update, an audit competition of the Seed Gauge System was held via Codehawks using commit hash a3658861af8f5126224718af494d02352fbb3ea5. The final report can be read here.
Audit remediations were committed in PRs #819, #829 and #831.
Post Audit Changes
The following changes have been made to the Seed Gauge System code, but have not been audited.
PR #836, which skips updating the Bean to Max LP Scalar if the Chainlink oracle fails.
PR #837, which updates the Germination events.
PR #843, which adds the
getLockedBeansFromTwaReserves
view function.BIP-42 Bug Fix
PR #854 fixed the Locked Bean calculation issue that was found during the BIP-42 Voting Period. The fix was reviewed by Cyfrin.
Effective
Immediately upon commitment.