-
Notifications
You must be signed in to change notification settings - Fork 80
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-49: Misc Improvements #802
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
Contributor
Brean0
reviewed
Mar 23, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review I
Brean0
reviewed
Apr 10, 2024
✅ Deploy Preview for beanstalk-ui ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ Deploy Preview for basin canceled.
|
Brean0
approved these changes
Aug 5, 2024
This was referenced Aug 11, 2024
Closed
Closed
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-49: Misc. Improvements
Proposer
Beanstalk Farms, Brendan Sanderson, Ben Weintraub
Proposer Wallet: 0x4a24e54a090b0fa060f7faaf561510775d314e84
Summary
gm
to be the minimum of (1)Links
Problem
Currently, Fertilizer metadata (the SVG image, traits, etc.) is hosted on centralized infrastructure. In addition to being fundamentally misaligned with the ethos of Beanstalk, any data hosted on centralized infrastructure requires maintenance and is subject to downtime.
Beanstalk is prone to overissuing Soil at$|\Delta B_{\overline{t-1}}|$ .
gm
call because Soil issuance below peg is solely based onCurrently, the Recorded BDV of a Deposit is not necessarily equal to its Current BDV. For example, if a user Deposits BEANETH into the Silo and the USD price of ETH falls significantly (and thus the BDV of BEANETH decreases), the Recorded BDV does not decrease. In practice this means Farmers "lock in" the higher BDV at the time of Deposit such that Beanstalk is over crediting BDV to Deposits relative to their value being contributed to it. Beanstalk only supports Convert types that do not decrease the BDV of the Deposit making it impossible for the BDV associated with a Deposit to ever be corrected.
Currently, Beanstalk offers a conservative Chop Rate of ~1.33% (22.49% recapitalization * 5.9012% of debt repaid to Fertilizer) to Unripe holders. Chopping is beneficial to Beanstalk as its obligations and the amount needed to fully recapitalize Unripe assets decreases. Although the current model is likely to result in the least volatility as Beanstalk is recapitalized (as a result of Unripe holders Chopping later on average), Beanstalk can be more aggressive given its healthy position in terms of L2SR.
Locked Beans are calculated under the extremely conservative assumption that all Unripe LP is Chopped within a single Season.
Currently, when Unripe LP holders Chop,
s.recapitalized
is unchanged as demonstrated in BIR-14. As a result, the Barn Raise ends earlier than intended, i.e., Beanstalk will not sell enough Fertilizer to fully recapitalize all Unripe LP.Proposed Solution
On-Chain Fert Metadata
We propose to migrate the Fertilizer metadata hosted at fert.bean.money on-chain.
Specification
FertilizerImage.sol
to dynamically assemble the SVG image for Active, Used and Available Fertilizer; anduri
inInternalizer.sol
to (1) assemble the required on-chain data, (2) generate the correct Fertilizer image URI usingimageUri
fromFertilizerImage.sol
and (3) return the final metadata URI to be consumed.Soil Issuance Update
We propose to change Soil issued at$\Delta B_{\overline{t-1}} < 0$ to be the minimum of (1) $|\Delta B|$ calculated using the instantaneous reserves from Multi Flow and (2) $|\Delta B_{\overline{t-1}}|$ .
gm
whenSpecification
In
SeasonFacet/Sun.sol
:setSoilBelowPeg
, which calculates the cumulative deltaB across all whitelisted Wells using the instantaneous reserves in Multi Flow (stepSun
to usesetSoilBelowPeg
.BDV Decrease
Implement a new
ANTI_LAMBDA_LAMBDA
Convert type, callable by anyone, that Converts on behalf of a Farmer and can decrease a Deposit's BDV.Specification
account
inLibConvert.convert(…)
;ANTI_LAMBDA_LAMBDA
Convert case to the Convert ladder inLibConvert
;LibConvert
so that more frequently used Converts appear first;convertData
types, update them to return 0, and add a check that ensures proper use ofmsg.sender
instead ofaccount
when applicable;ConvertFacet.convert(…)
, replacemsg.sender
in other Convert helper functions withaccount
;ANTI_LAMBDA_LAMBDA
Convert is called inConvertFacet.convert(…)
, and when it is, update the input Deposit with the Current BDV; andconvertParams
inLibConvert
for readability and extensibility.Chop Changes
We propose to:
Specification
LibUnripe.getRecapPaidPercentAmount(…)
(the percentage paid back to Fertilizer holders) from the Chop Rate calculation;LibUnripe.getPenalizedUnderlying(…)
to calculate the Unripe λ → λ Conversion using the new formula;getTotalRecapitalizedPercent(…)
to get the US dollar denominated percentage recapitalized by Beanstalk;getLockedBeansUnderlyingUnripeBean(…)
to account for the percent recapitalized percentage instead of the amount paid back to Fertilizer;LibChop.chop(…)
to useLibUnripe.removeUnderlying(…)
instead ofLibUnripe.decrementUnderlying(…)
when decreasing the available Ripe underlying amount for the Unripe token after a Chop.Technical Rationale
The Fertilizer Facet must be updated due to changes to the ERC-1155 token metadata. Hosting the metadata on-chain instead of on centralized infrastructure eliminates any risks associated with uptime.
The Season Facet must be updated due to changes to the deltaB calculation introduced by the Soil issuance change below peg.
The Convert Facet must be updated due to the introduction of
ANTI_LAMBDA_LAMBDA
.The Unripe Facet must be updated due to changes to the
chop
function.Economic Rationale
Soil Issuance Update
Consider an example where Beanstalk is at -300k deltaB for the first 58 minutes of a Season. At the 58th minute, i.e., 10 blocks before the next
gm
call, a Farmer buys and Sows 200k Beans, bringing the current deltaB to -100k.Assuming no other trades in the final 2 minutes of the Season, the Soil issued at
gm
will be slightly less than 300k, despite Beanstalk only needing 100k Beans to be bought to return to peg. Before Multi Flow, this was necessary for sufficient manipulation resistance. However, thanks to Multi Flow it is now possible for Beanstalk to issue less Soil in these instances without being subject to manipulation.In general, Beanstalk does not need to be particularly aggressive when issuing Soil—it does not want to issue debt if it doesn't have to and would prefer to spend an extra Season below peg over issuing a lot of excess Soil.
Thus, using the inter-block MEV manipulation resistant instantaneous reserves in Multi Flow to calculate deltaB below peg is preferred.
BDV Decrease
The ability to decrease a Deposit's BDV is necessary to prevent Beanstalk from over crediting BDV to Deposits relative to their value currently being contributed to the system. There is no incentive for a Farmer to decrease their own BDV. Thus, the Anti λ → λ Convert is callable by any user.
Chop Changes
Beanstalk can be more aggressive given its healthy position in terms of L2SR. Chopping is beneficial to Beanstalk as its obligations and the amount needed to fully recapitalize Unripe assets decreases.
The Locked Beans calculation must be updated to account for the new Chop Rate calculation. Changing the assumption from 100% to 75% of Unripe assets Chopping within a single Season is still conservative but more realistic.
Ensuring the
chop
function is implemented as intended is essential to the structure of the Barn approved by the DAO.Contract Changes
Initialization Contract
The
init
function on the followingInitBipMiscImprovements
contract is called:0x2d130cEfa0bf9D1a3e0445c9478503c326F2F8E9
Unripe Facet
The following
UnripeFacet
is removed from Beanstalk:0xD64BB5c2dBf12fEBeFc6397926A3c0aA6f8b6535
The following
UnripeFacet
is added to Beanstalk:0xb52af7889b05eF652468E98D249700415a9F587D
UnripeFacet
Function Changes_getPenalizedUnderlying
0xa84643e4
getRecapitalized
0xe68a543a
addMigratedUnderlying
0x787cee99
addUnripeToken
0xfa345569
balanceOfPenalizedUnderlying
0x1acc0a47
balanceOfUnderlying
0x1be655e8
chop
0x9a516cad
getLockedBeans
0x087d78b4
getLockedBeansFromTwaReserves
0x7caa025f
getLockedBeansUnderlyingUnripeBean
0xbfe2f3be
getLockedBeansUnderlyingUnripeLP
0x33f37f27
getPenalizedUnderlying
0x6de45df2
getPenalty
0x014a8a49
getPercentPenalty
0xbb7de478
getRecapFundedPercent
0x43cc4ee0
getRecapPaidPercent
0xab434eb7
getTotalUnderlying
0xadef4533
getUnderlying
0x9f06b3fa
getUnderlyingPerUnripeToken
0xb8a04d1b
getUnderlyingToken
0x691bcc88
isUnripe
0xfc6a19df
pick
0x13ed3cea
picked
0xd3c73ec8
switchUnderlyingToken
0xa33fa99f
Convert Facet
The following
ConvertFacet
is removed from Beanstalk:0xEb1b833D3E81cb3d390514cabB9b809E6170626C
The following
ConvertFacet
is added to Beanstalk:0x2604D728D8c6918b8C427bF42aa2ed07ceB5cf23
ConvertFacet
Function Changesconvert
0xb362a6e8
Convert Getters Facet
The following
ConvertGettersFacet
is removed from Beanstalk:0x8ABa09526dc6EB6Ea44eE3f8745dD8bc9EF744E2
The following
ConvertGettersFacet
is added to Beanstalk:0x09D466663586292F5f0c1D99e9547A7A81E887f5
ConvertGettersFacet
Function ChangesgetAmountOut
0x4aa06652
getMaxAmountIn
0x24dd285c
Season Facet
The following
SeasonFacet
is removed from Beanstalk:0x92458b7ade7798c45E5ff583c353F70F950d66Cf
The following
SeasonFacet
is added to Beanstalk:0x51F74C024936E296132c6F4E59b9EEd677eb3B1c
SeasonFacet
Function Changesgm
0x64ee4b80
seasonTime
0xca7b7d7b
sunrise
0xfc06d2a6
Season Getters Facet
The following
SeasonGettersFacet
is removed from Beanstalk:0x5A1675f3156c9e73D7eA20eb58470A0002865E85
The following
SeasonGettersFacet
is added to Beanstalk:0x9fd4daD032324bC569decC3795731aEC309c2923
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
Fertilizer Facet
The following
FertilizerFacet
is removed from Beanstalk:0x729672c68134E2DF0CdD36D3296841A2993534c7
The following
FertilizerFacet
is added to Beanstalk:0x9586878Ea437CBB6D4b6381Bde7B064f531CfB77
FertilizerFacet
Function ChangesgetTotalRecapDollarsNeeded
0x12cb5eab
_getMintFertilizerOut
0x94daa221
balanceOfBatchFertilizer
0x304ec65d
balanceOfFertilized
0xb6f42085
balanceOfFertilizer
0x1799b3b2
balanceOfUnfertilized
0x1edb6be1
beansPerFertilizer
0x9bb4e35a
beginBarnRaiseMigration
0xe3d4e44c
claimFertilized
0x83e08888
getActiveFertilizer
0xdc6ba285
getBarnRaiseToken
0xf255da60
getBarnRaiseWell
0x93a39bea
getCurrentHumidity
0x39448802
getEndBpf
0xc85951a1
getFertilizer
0x9c45a1d5
getFertilizers
0x34af5416
getFirst
0x1e223143
getHumidity
0x29130a66
getLast
0x4d622831
getMintFertilizerOut
0x69744dd0
getNext
0xf4a057e2
isFertilizing
0x6ae1c014
mintFertilizer
0x363591d0
payFertilizer
0xd47aee59
remainingRecapitalization
0x4a16607c
totalFertilizedBeans
0x4f9a9678
totalFertilizerBeans
0xf9c4ebde
totalUnfertilizedBeans
0xa3ef48c9
Event Changes
None.
Beans Minted
None.
Audit
The commit hash of this BIP is 10c50916acdd1a2ea8c3699217779cbbe549389e.
An audit competition of this upgrade was held via Codehawks using commit hash 662d26f12ee219ee92dc485c06e01a4cb5ee8dfb. The final report can be read here.
Audit remediations were committed and documented in PR #943. All changes were reviewed by Cyfrin.
Post Audit Changes
The following changes have been made to the BIP-49 code, but have not been audited:
LibLockedUnderlying
to reflect the change in the Locked Beans calculation;Fertilizer/Internalizer.sol
used by the Fertilizer SVGs; andSeasonGettersFacet.getTotalDeltaB()
to calculate the cumulative deltaB across all whitelisted Wells.Effective
Immediately upon commitment.