-
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-50: Reseed Beanstalk #909
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
✅ Deploy Preview for basin canceled.
|
❌ Deploy Preview for beanstalk-ui failed.
|
This was
linked to
issues
Aug 11, 2024
Closed
Closed
Closed
Closed
BeanstalkFarmsOperations
approved these changes
Oct 10, 2024
BeanstalkFarmsOperations
approved these changes
Oct 10, 2024
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-50: Reseed Beanstalk
Proposer
Beanstalk Farms, Ben Weintraub, Brendan Sanderson
Proposer Wallet: 0xf9d183af486a973b7921ceb5fdc9908d12aab440
Summary
TokenTransferred
event with data on sender and receiver addresses of Farm balance transfers;Links
Problem
Secure Beanstalk
Since Replant in August 2022, there have been 5 bugs that could have led to a loss of funds (fixed in EBIPs 1, 4, 5 (only Circulating assets were at risk), 10 and 12). In particular, the bugs that were mitigated in EBIPs 1, 10 and 12 could have led to losses of nearly all value in the Beanstalk contract.
Since the creation of the Immunefi Bug Bounty Program in BIP-26, the DAO has paid 1,530,350 Beans in bounties, 1,322,100 of which was for bug reports concerning funds in the Beanstalk contract that were at risk.
Generalized Convert
The effectiveness of the LP component of the Seed Gauge System is highly limited due to excessive friction between LP Converts. Currently, in order to Convert LP → LP, the source pool(s) must have negative deltaBs and the destination pool must have a positive deltaB (effectively a Pipeline LP → BEAN → LP Conversion). This is both inefficient from a gas perspective and limiting for Farmers' choices given that the effect from a peg maintenance perspective is neutral.
Generalized Flood
Currently, Flood is only implemented to take place in a single Well. The effectiveness of Flood is substantially decreased with the introduction of several whitelisted Wells.
Shipments
Currently, the distribution of Bean mints (allocated to the Silo, Field and Barn) is not sufficiently generalized such that it can be upgraded by changing parameters (i.e., facet changes are required).
Tractor
Maintaining and optimizing a position in Beanstalk requires manual intervention (Mowing, Planting, Harvesting Pods and Depositing the Beans, etc.). Smaller Farmers do not necessarily have the resources to automate the execution of their Beanstalk transactions.
Existing peer-to-peer transaction marketplaces (such as Seaport) are limited in the scope of the functionality that they support. Existing generalized function call systems (i.e., smart contract accounts, Depot + Pipeline) only support the use of assets from the sender of the transaction.
QoL Improvements
Solidity Version v0.8.20
As a result of Beanstalk using Solidity v0.7.6, many QoL tools are not available to the Beanstalk development community, such as:
Whitehats and auditors are generally more familiar with Solidity v0.8.0 and higher.
Whitelist Upgrades
Whitelisting a Well requires new code changes to the Beanstalk contracts, which increases the friction associated with whitelisting a Well (via audits, etc.). Ideally, the DAO can whitelist a Well in the Silo without any facet changes.
Morning Auction Adjustment
Currently, the Temperature increases excessively fast in the first few blocks of the Morning. For example, Soil can never be purchased at a Temperature below ~27% of the Maximum Temperature given the current parameters.
New Default Gauge Point Function
Currently, the default Gauge Point function increments or decrements the Gauge Points for each whitelisted LP token by 1 based on whether the current BDV distribution for the LP token is greater than or less than the optimal BDV distribution. Given the maximum and minimum Gauge Point values of 1000 and 0, respectively, it can take up to 20 days ((1000/2) Gauge Points / 24 Seasons ~= 20.833 days) for the Gauge Points to "catch up" such that the Seed rewards reflect the new current vs. optimal distribution.
For example: BEANwstETH and BEANETH currently have 1000 and 0 Gauge Points, respectively. If sufficient amounts of BEANETH Converts to BEANwstETH such that the current distribution of BEANwstETH is higher than optimal, Beanstalk will keep rewarding more Seeds to BEANwstETH than BEANETH for ~20 days even though it is no longer necessary.
Minimum Bean to Max LP Ratio Upon Rain
Currently, it's possible for Beanstalk to Flood before the Bean to Max LP Ratio has reached its minimum value, i.e., before Beanstalk has created the maximum incentive for Converting downwards.
Technical Improvements
Some Farmer balances can only be calculated by indexing events since Beanstalk deployment, resulting in either (1) thousands of calls to RPC providers each time the Beanstalk UI loads (which often gets rate limited), or (2) reliance on infrastructure like the subgraphs. Both have historically resulted in downtime for Farmers trying to view their balances.
Beanstalk currently has a number of variables set as constants in order to save gas. This increases the friction of upgrading Beanstalk by needing to redeploy the facets with only constants changed.
The current App Storage structure is difficult to extend and develop with.
Currently, Beanstalk's reentrancy protection system does not support Pipeline and Depot.
Micro Stalk can sometimes be lost during certain Silo interactions due to the current Stalk precision relative to the Seed precision. This introduced a rounding error where users had slightly less Stalk than the amount needed to Withdraw.
Within Beanstalk, Farmers can transfer assets to and from their Circulating and Farm balances. When a Farmer transfers an asset from their Farm Balance to another address' Farm Balance, the emitted events make it difficult to trace the origin of the assets.
L2 Migration to Arbitrum
Beanstalk is a gaseous protocol. While the costs of interacting with Beanstalk at the time of writing in September 2024 are reasonable, activity on Ethereum L1 is currently low. In the past when Gwei has spiked, interacting with Beanstalk has cost tens or hundreds of US dollars. This prices out smaller Farmers and reduces the efficacy of Beanstalk's peg maintenance mechanism.
Upgrades like Secure Beanstalk, the new view functions, etc. increase the cost of interacting with Beanstalk across the board.
New Whitelist
Opportunities for Bean liquidity providers to receive Stalk and Seed rewards are currently limited. A wider variety of options increases utility for Silo Depositors, particularly with the combination of the Seed Gauge System and Generalized Convert.
Process Updates
Hypernative, the Immunefi Bug Bounty Program and the Beanstalk DAO Disclosures can all be updated to reflect the new state of Beanstalk.
Proposed Solution
Secure Beanstalk
We propose the implementation of system-wide invariants that are checked on every write call to Beanstalk. The invariants are indicative of a healthy state of Beanstalk's internal accounting and must always be maintained. These invariants ensure that the Beanstalk contract contains enough assets to cover all of its user obligations, ERC-20s are not being transferred unexpectedly and that the Bean supply is not being manipulated.
The Invariable contract defines several invariant modifiers that are used across the code base.
Specification
The invariants fall into three different categories:
The
fundsSafu
modifier checks every whitelisted ERC-20 token. If the balance of the token in the Beanstalk contract is lower than the amount of the token that users can claim (through Withdrawals, Harvests, Claims, etc) then the invariant will fail and the call will revert. This ensures there are always enough tokens in the contract for Beanstalk to pay its existing obligations. Excluding diamond management functions, this invariant can be placed on every write function in Beanstalk.The
noNetFlow
,noOutFlow
, andoneOutFlow
invariants track the balance of ERC-20 tokens inside Beanstalk and fail if there is an unexpected movement of assets. This ensures that there are not any withdrawals of unexpected assets in the modified functions, however, it does not set any limits on the amounts withdrawn.noNetFlow
requires that Beanstalk token balances are the same at the end of the call as they were at the beginning,noOutFlow
requires that all Beanstalk token balances are the same or higher at the end of the call andoneOutFlow
allows for only one asset to decrease in amount during the call. These three modifiers cover the vast majority of use cases and one of the three can be put on almost every write function in Beanstalk. Notable exceptions are diamond management, Convert andfarm
-like functions.The
noSupplyChange
andnoSupplyIncrease
invariants keep track of the total supply of Bean at the beginning and end of the call to ensure that the Bean supply was not unexpectedly modified.noSupplyChange
prevents both minting and burning, whereasnoSupplyIncrease
only prevents minting. One of these two modifiers can be placed on every write function in Beanstalk that is not intentionally minting or burning Beans (such as Sowing andgm
). Notable exceptions are diamond management andfarm
-like functions.We also propose to remove various dead code such as the Pod Market V2 pricing functions.
Generalized Convert
We propose a Generalized Convert implementation with support for LP → LP Converts, a Stalk penalty system to enable Converting against peg and a per-block Convert cap mechanism to protect against flash loan attacks.
The PipelineConvertFacet exposes the new
pipelineConvert
function and Stalk penalty logic has been applied to the existing ConvertFacet. The existing ConvertFacet retains support for Unripe Converts, which are not supported by the new PipelineConvertFacet.Specification
The Pipeline Convert function is defined as:
Usage of the first four parameters is the same as the existing
convert
function (specify the input crates using the Deposited Stem and amounts, as well as the input and output tokens to Convert from and to). TheadvancedPipeCalls
parameter is new.The
pipelineConvert
function withdraws the corresponding whitelisted tokens from Beanstalk and passes them to the Pipeline contract. The supplied Pipeline calls should call other contracts to swap (the total input token amount available to swap can be calculated by summating all the amounts passed in viaamounts
).Example Pipeline Calls for Convert
A typical series of Pipeline calls might follow these steps (using Solidity):
The previous user of the Pipeline contract may not have setup an approval for spending the input token used to Convert, so an approval call verifies the ERC-20 can be sent to the
TARGET_ADDRESS
(in some cases, perhaps a Well).This example adds liquidity to a Well (assuming this is a Bean → Well convert). Note that this action is performed from the Pipeline contract itself, and thus, the recipient is the Pipeline contract. The swap call does not have to use Wells—other DEXs (Uniswap, Curve, etc) or aggregators (0x, 1inch, etc) can be used.
The above encoded calls are then wrapped in
AdvancedPipeCall
so that the target contract and Clipboard data can be specified. The final array of these calls are inserted into the Convert function. Note these calls may want to check available Convert capacity first if a MEV protection RPC is not used (see Convert Capacity below).After the final Pipeline call is performed, the
pipelineConvert
function calls the ERC-20balanceOf
function on the Pipeline contract and removes all of the ERC20 token of theoutputToken
type. Any other ERC-20's remaining in Pipeline after the Convert must be removed by the user.Stalk Penalty
Generalized Convert introduces the ability to Convert against peg and a Stalk penalty for doing so. The penalty applies a 100% reduction in Grown Stalk of the Converted Deposit based on the amount that was Converted against peg.
For example, if 20 BDV is Converted, and only 10 of the BDV Converted is against peg, then 50% of the Grown Stalk associated with Deposit will be burned. No penalty is applied if the Convert brings the cumulative deltaB closer to 0.
Convert Capacity
To prevent flash loan attacks that allow Converting against peg without incurring the Stalk penalty, a Convert capacity mechanism is introduced.
Every Convert updates the amount of BDV Converted per block on a per Well and overall basis. The total capacity available before a penalty applies is based on deltaB for each corresponding Well and the overall deltaB.
View functions are exposed to read the remaining capacity for a block in order to ensure that the Pipeline function can revert if conditions become unfavorable to the user over the course of the block.
Convert Capacity View Functions
Two functions are available to view available Convert capacity for the block, the first being the overall capacity remaining:
And the second being the capacity available on a per Well basis:
If the available Convert capacity of either is less than the BDV of the amount being Converted, then the Stalk penalty will apply.
Generalized Flood
We propose a Generalized Flood implementation that supports Flooding in the highest deltaB Wells until the cumulative deltaB is 0.
While previously the entire Pod Line became Harvestable upon Flood, we propose that only 0.1% of the Bean supply worth of Pods become Harvestable.
Shipments
We propose a dynamic system for distributing Bean mints to the different outputs within the system—the Silo, Field and Barn. The system is sufficiently generalized such that it can change between different configurations without requiring contract changes. It can support multiple Fields and is expandable to handle unknown output types that can be implemented in future upgrades.
Specification
Each distribution stream for new Bean mints is defined by two different structures: a
ShipmentRoute
and aShipmentPlan
.Shipment Routes define where a portion of the Bean mints will be sent to and how the associated Plan is retrieved. The Routes are stored in Beanstalk state. They can be modified via owner-restricted write functions. The Route contains an enum indicating which output stream the mints are associated with—the Silo, Field or Barn. Implementation of streams that do not fall into these categories require modification to the Beanstalk contracts.
Shipment Plans specify the ratio and the maximum Beans that a Route can receive for the current mint. This configuration is dynamic, based on current state and arbitrary logic. Shipment Plans are retrieved by calling standardized Plan getter functions. The functions can live internal or external to Beanstalk. Externalizing these functions allows for them to be updated without modifying Beanstalk contracts.
Each Plan assigns points to its associated route. The Route receives the ratio of minted Beans equal to the ratio of Route points / all points. In this way, there are not circular dependencies for each Plan to know about the other Plans.
If Beans to a route exceed the maximum Beans that Route can handle the excess Beans will be distributed to the other routes, in proportion to their points. The Silo Route should never have a cap.
Both Shipment Routes and Plans can be updated via the
setShipmentRoutes
function, in conjunction with an external contract that contains the associated Shipment Plan getters.Tractor
We propose Tractor, a peer-to-peer transaction marketplace that allows third party operators to perform Beanstalk actions on behalf of a Farmer.
Blueprints are off-chain data structures that are EIP-712 signed to verify the intent of the publishing Farmer. Blueprints allow Farmers to define arbitrary sequences of on-chain function calls, which can be executed permissionlessly by other Farmers known as Tractor Operators.
Blueprints contain the Publisher, an Advanced Farm function call containing an arbitrary sequence of internal function calls, a set of copy instructions that define how to interpret Operator calldata, expiry parameters and the EIP-712 signature from the Publisher. Any Tractor Operator can execute any Blueprint with any calldata at anytime through the
tractor(...)
function provided that the Blueprint does not revert.Junctions are contracts that are contain basic operations as external functions that are used by Tractor orders. Junctions allow Farmers to define Blueprints that will fail under a predefined set of conditions, such as balance limits, price thresholds, etc.
Examples
Specification
Blueprints
Blueprints are off-chain data structures that are EIP-712 signed to verify Publisher intent. Each Blueprint contains an arbitrary sequence of internal and external function calls wrapped into an AdvancedFarm call and to be executed through the TractorFacet. Any properly signed Blueprint can be executed through Tractor given that:
startTime < block.timestamp < endTime
;blueprintNonce[nonce] < maxNonce
; andadvancedFarm
function call does not revert (Publishers can encode logic checks that revert under arbitrary conditions).Blueprints are defined by the following struct:
Blueprints are wrapped in a Requisition, which contains the Blueprint hash and the Publisher's signature of the hash.
Where:
publisher
is the account that published the Blueprint;data
is bytes that decode into(AdvancedFarmCall[])
;operatorPasteInstrs
are a set of instructions that define how operator-defiend data is injected into the AdvancedFarmCalls of thedata
;maxNonce
is the maximum # of times a Blueprint can be executed;startTime
is the timestamp at which the Blueprint can start to be executed;endTime
is the timestamp at which the Blueprint can no longer be executed;blueprintHash
is the keccak256 hash of the populated Blueprint struct; andsignature
is the Publisher's EIP-712 signature of the Blueprint Hash.Blueprint Hash
Blueprint Hashes are unique identifiers for Blueprints. Blueprint Hashes are used to track the nonce of a Blueprint and used in the signing process. A Blueprint Hash must be hashed following the EIP-712 standard. Beanstalk provides a public helper function
getBlueprintHash(Blueprint blueprint)
.Publish Blueprint
Requisitions do not need to be written on-chain. They can be provided to operators off-chain and verified via the signature. However, Tractor offers a system to publicly publish any Requisition via the
PublishRequisition
function, which emits an event containing the Requisition.Cancel Blueprint
Blueprints can be canceled at anytime by the Blueprint Publisher by calling
cancelBlueprint
. This sets the nonce touint256.max
, rendering the Blueprint unusable.Tractor
Tractor executes a Blueprint. Executing a Blueprint:
startTime < block.timestamp < endTime
;blueprintNonce[blueprintHash] < maxNonce
;blueprintNonce[blueprintHash]
;blueprint.data
using theoperatorPasteInstrs
andoperatorData
;advancedFarm
usingdata
; andTractor
event.Tractor Storage
Instead of adding new state variables to
AppStorage
, aTractorStorage
library is created whereTractorStorage
is loaded at slotkeccak256("diamond.storage.tractor")
(stored as a constant).Tractor Counters
Blueprints can utilize arbitrary counters to track and limit use. These are stored in TractorStorage and writes are restricted based on the Publisher's address. Blueprints using counters are expected to generate sufficiently random counter IDs to avoid collisions with a Publisher's other counters.
Active Publisher
Tractor performs actions on behalf of the Publisher of a Blueprint that that is executed by Tractor. Rather than using
msg.sender
to determine the account to act on, the active Publisher address is used.QoL Improvements
Solidity Version v0.8.20
We propose to upgrade each contract and facet in Beanstalk from v0.7.6 to v0.8.20.
Whitelist Upgrades
We propose to upgrade the whitelisting system such that various Implementations can be set and changed for each Well. Implementations can be used to the set a Well's:
In order for a whitelisted Well to be included in the Minting Whitelist, the Gauge System and Converts, the non-Bean token in the Well must have an Oracle Implementation. Whitelisted Wells without a Gauge Point or Liquidity Weight Implementation use the default Gauge Point and Liquidity Weight Implementation defined in GaugePointFacet and LiquidityWeightFacet, respectively.
An Implementation is defined in App Storage as:
Where:
target
is the the address in whichselector
is called at;selector
is the function selector Beanstalk is calling ataddress
;encodeType
determines the function signature Beanstalk should call at theaddress
; anddata
is arbitrary data that can be added to a function call.For a given Gauge Point Implementation, the function should match the following signature:
For a given Liquidity Weight Implementation, the function should match the following signature:
For a given Oracle Implementation, the function should match the following signature:
Gauge Point and Liquidity Weight Implementations are set per whitelisted Well. Oracle Implementations are set on a token basis.
Beanstalk has 2 default Oracle Implementations, which are used when the whitelisted Well is whitelisted with an oracle encodeType of
0x01
and0x02
:0x01
→ Chainlink Implementation; and0x02
→ Uniswap and Chainlink Implementation.To use the
0x01
default Implementation, the Oracle Implementation address for the non-Bean token in the Well should be set to the Chainlink aggregator that the price should be fetched from. The Oracle Implementation should return the USD price of the non-Bean token.To use the
0x02
default Implementation:For example, for a BEAN:WBTC Well, the
0x02
default Oracle Implementation could be used by combining the WBTC:USDC Uniswap V3 pool with the USDC:USD Chainlink aggregator.Additional support for different function signatures can be accomplished by implementing new code for a given encode type.
Morning Auction Adjustment
We propose to change the control variable in the Morning Auction from 2 to 0.1.
More specifically, change the calculation for the Temperature during blocks 1 to 25 ($x$ ) of each Season from (the blue line):
To the following (the red line):
See Desmos link.
Due to the L2 Migration, in practice the Temperature only updates
L1_BLOCK_TIME / L2_BLOCK_TIME = 12/0.25 = 48
times. The duration of the Morning is still 5 minutes. Thus, on Arbitrum, the Temperature during the first 1200 blocks of each Season is calculated as:New Default Gauge Point Function
We propose to update the default Gauge Point function to change the Gauge Points for the whitelisted LP token by ±5/3/1 based on the following thresholds:
For example, if BEANETH's optimal % is 16%, the thresholds are:
Minimum Bean to Max LP Ratio Upon Oversaturation
We propose to change
beanToMaxLpGpPerBdvRatio
to the minimum value upon Rain (i.e., atstartRain
).Technical Improvements
View Functions
Beanstalk now stores the list of Deposit IDs and Plot indexes on each account, as well as a mapping from Deposit ID to its associated index to support a O(1) read cost.
The list of Deposit IDs are stored on a per token basis.
Deposit data can be fetched using the following functions:
getDepositsForAccount
;getTokenDepositsForAccount
;getTokenDepositIdsForAccount
; andgetIndexForDepositId
.Plot data can be fetched using the following functions:
getPlotIndexesFromAccount
;getPlotsFromAccount
; andbalanceOfPods
.Constants to State
We propose to migrate various parameters that were previously set to constants to be read from contract state. This is stored in the system storage as
EvalutationParameters
like so:App Storage Redesign
App Storage has been redesigned such that two structs are implemented:
Account
contains state stored on an account level; andSystem
contains state stored on a protocol level.Various deprecated state variables are removed between the two structs and state is reordered to improve organization and developer experience. Buffers are placed throughout the state to allow for future upgradability without the need to append new state at the end of the
AppStorage
struct.Reentrancy Design
The current reentrancy system does not support
farm
andfarm
-like functions (such asadvancedFarm
andtractor
), as thefarm
function is used within Beanstalk to call multiple functions in one transaction. This allows Farm calls to be called within other Farm calls, which may introduce additional security risks.We propose a reentrancy redesign that now supports
farm
andfarm
-like calls. A new modifiernonReentrantFarm
is added that allows for the function to call any other function, other than other functions that have thenonReentrantFarm
modifier.Micro Stalk Bug
We propose to increase the precision of Stalk by 1e6 (for a total of 16 decimals) and update various functions that calculate Stalk to account for the new precision.
Farm Balance Transfer Event
We propose a new event that is emitted when
transferToken
is called that explicitly includes the sender and recipient addresses:L2 Migration to Arbitrum
We propose to migrate Beanstalk and its state from Ethereum L1 to Arbitrum.
See the Effective section for full process. Note that BEAN:3CRV liquidity is proposed to be migrated to a BEAN:USDC Well on Arbitrum.
As part of the migration process:
Circulating Beans at the time of the Reseed need to be manually migrated by calling
migrateL2Beans
on L1, which burns the Beans on L1 and issues them on the L2.Beanstalk assets (Deposits, Plots, Beanstalk-related Farm balances, and Fertilizer) belonging to smart contract accounts cannot be automatically migrated, given that Beanstalk cannot assume an owner of a smart contract is able to gain ownership of the same address on L2. Smart contract owners will need to perform a 2 step migration process in order to claim their assets:
approveL2Receiver
; andissueDeposits
,issuePlots
,issueInternalBalances
, andissueFertilizer
with the list of assets and a merkle proof verifying the validity of the list.Smart contract owners can migrate their Beanstalk assets to an EOA prior to the deployment of this BIP if they'd like they assets to be automatically migrated.
The following code is updated to support L2 deployments:
The
gm
incentive is generalized to support L2 deployments by changing the incentive to be based on the time elapsed from the start of the hour. The incentive starts at 1 Bean and compounds 1.0201% every additional 2 seconds that elapse past the first timestamp in whichgm
could have been called, for 300 seconds.New Whitelist
We propose to whitelist the following Wells with Upgradable Well Implementations (owned by Beanstalk) on Arbitrum:
Process Updates
We propose to setup Hypernative on Arbitrum with the same configuration proposed in BIP-46.
We propose to update the Immunefi Bug Bounty Program to reflect the changes proposed in this BIP, notably adding the Stable 2 Well Function and Tractor Junctions as in scope and adding following Impacts as in scope (the updated program can be read here):
We propose to update the Beanstalk DAO Disclosures to include risks associated with Hypernative, Arbitrum and the new set of whitelisted assets. The updated Beanstalk DAO Disclosures can be read here.
Technical Rationale
Secure Beanstalk
Calling
farm
within otherfarm
-like functions (includingadvancedFarm
andtractor
) is disabled in the interest of security with minimal to no loss in composability.Given that packing is no longer necessary for saving gas due to the L2 migration, many variables in the Beanstalk contracts are casted up to
int256
oruint256
to prevent unnecessary overflows.Removing dead code reduces the surface area of potential vulnerabilities in Beanstalk.
Generalized Convert
Unripe Converts cannot be supported by
pipelineConvert
because the underlying tokens are not liquid. For this reason, the existingconvert
function that supports Unripe Converts is left in the ConvertFacet.Pipeline Converts are limited to usage of Pipeline (i.e.
pipeCalls
) rather thanfarm
calls for security reasons (with regard to reentrancy attacks).Generalized Flood
In
LibWhitelist
, Wells are flagged as Floodable (isSoppable
) based on whether or not Beanstalk should sell Beans in the Well during Flood conditions. This functionality is added in the event that future whitelisted Wells should not be Flooded in.Shipments
Within a given Season, if a Shipment gets paid off, the remaining Bean mints are allocated equally to all remaining Shipments until the following Season. In this way, there are not circular dependencies for each Plan to know about other Plans. Doing so with enough Shipments would eventually exceed the gas limit.
Externalizing the Shipment functionality allows the Bean mint distribution to be changed without a diamond cut.
Tractor
All write functions functions in Beanstalk use
LibTractor.getUser
to get eithermsg.sender
or the Publisher of the executing Blueprint. From a developer experience perspective, this is preferable to having a Tractor-specific version of every write function.QoL Improvements
Solidity Version v0.8.20
Most DeFi protocols use Solidity v0.8.0 or higher. Upgrading Solidity versions allows the Beanstalk development community to take advantage of tooling that is developed with v0.8.0^ in mind. For example, using Foundry with v0.7.6 requires a number of workarounds in order to properly use it. While there are more recent versions of Solidity, Beanstalk should strike a balance between using a battle tested compiler and the latest version. For reference, Basin is developed in v0.8.20.
Whitelist Upgrades
Removing friction associated with whitelisting new assets and modifying existing whitelisted assets allows the DAO to upgrade the whitelist more quickly and with fewer security risks.
Morning Auction Adjustment
Using an if-else ladder in
LibDibbler
to approximate the Temperature during the Morning is necessary due to the infeasibility of calculating logarithms on-chain.The if-else ladder is limited to updating the Temperature every 12 seconds due to the contract size limit on Ethereum. For this reason, the Temperature updates every 48 blocks on Arbitrum during the Morning Auction.
View Functions
Getting user balances requires either (1) thousands of calls to RPC providers each time the Beanstalk UI loads (which often gets rate limited), or (2) reliance on infrastructure like the subgraphs. The migration to a L2 makes it possible to update the storage architecture to support getter functions for user balances.
App Storage Redesign
The difficulty of organizing storage data in Ethereum Diamonds can lead to security risks. From a development perspective, the L2 Migration is a great opportunity to address this issue.
Constants to State
Changing facets comes with additional security risks and migrating constants to state eliminates these risks. The migration to a L2 makes this migration more feasible.
L2 Migration to Arbitrum
Removing the SiloFacet and waiting for all Deposits to Germinate (assuming there are Germinating Deposits at the time of BIP passage) before executing the migration simplifies the migration of Deposits.
Given that Beanstalk does not have control of Beans outside of the Beanstalk contract, Circulating Beans at the time of the Reseed need to be manually migrated from L1 to L2.
Beanstalk assets in smart contract accounts cannot be automatically migrated given that Beanstalk cannot assume an owner of a smart contract is able to gain ownership of the same address on L2.
The diamond cut initialization scripts that migrate Beanstalk state are generalized to be executed across multiple transactions given that migration process will exceed the gas limit.
The remaining facets on L1 allow the continued support of Farm Balances on L1 Beanstalk. The L1TokenFacet must be updated to disallow transferring Beanstalk-related assets (which are migrated to L2) out of L1 Beanstalk.
New Whitelist
Deploying the Wells with an Upgradable Well Implementation (owned by Beanstalk) allows the BCM to fix bugs in the corresponding Wells without requiring a Silo migration from the vulnerable Well to a new one.
Economic Rationale
Secure Beanstalk
Ensuring that certain invariants are not violated as a result of transaction execution substantially increases the security of Beanstalk and has the potential to save the DAO a significant number of Beans from being spent on bug reports.
Generalized Convert
Supporting LP → LP Converts significantly increases the efficacy of the Seed Gauge System with respect to achieving the optimal distribution of Bean liquidity.
Using the capped reserves in Multi Flow to measure Convert capacity allows Beanstalk to use the least stale data possible while preserving manipulation resistance.
Updating the existing
convert
function is necessary to penalize Farmers for Converting in a direction that causes the cumulative deltaB to move away from peg.Generalized Flood
Generalizing Flood the occur in multiple Wells at once is an essential peg maintenance tool for Beanstalk.
Capping the number of Pods that become Harvestable upon Flood to 0.1% of the Bean supply is a useful security measure given that it does not seem necessary to make all Pods Harvestable.
Tractor
Decreasing friction for Farmers to automate the execution of their transactions improves the efficiency of Beanstalk.
QoL Improvements
Whitelist Upgrades
Generalizing the whitelisting process substantially reduces the amount of code needed to be written to whitelist new assets, change oracles, change Gauge Point functions, etc.
Morning Auction Adjustment
Decreasing the rate at which the Temperature increases during the Morning Auction should decrease the number of Pods issued by Beanstalk during times of high demand for Soil.
New Default Gauge Point Function
A Gauge Point function that factors in the distance between the current LP BDV distribution and the optimal may be more effective at issuing the proper amount of Grown Stalk to LP Depositors.
Minimum Bean to Max LP Ratio Upon Rain
Changing the Bean to Max LP Ratio to its minimum value before a Flood reflects that Beanstalk would prefer that Farmers first Convert down to add liquidity first before it mints and sells Beans directly on the market.
L2 Migration to Arbitrum
Arbitrum is the largest Ethereum L2 by market cap and TVL. Migrating to a L2 substantially decreases the costs of interacting with Beanstalk.
BEAN:3CRV is migrated to BEAN:USDC given that there is no 3CRV on Arbitrum.
New Whitelist
A wider variety of options for Bean liquidity providers to receive Stalk and Seed rewards increases utility for Silo Depositors.
Whitelisting BEAN:USDC and BEAN:USDT gives Depositors the opportunity to earn Stalk and Seeds while being exposed to less volatile assets. The relatively low optimal LP BDV distribution of 12% for both BEAN:USDC and BEAN:USDT reflects the centralization risks of the two stablecoins. Using the Stable 2 Well Function in these Wells allows for better execution prices for traders around peg.
Setting the initial Gauge Points to 0 (the minimum value) for BEANwstETH and 1000 (the maximum value) for all other whitelisted assets reflects that nearly all Bean liquidity is already in the BEANwstETH Well due to the Unripe liquidity. Given this, Beanstalk should immediately start incentivizing holding the other whitelisted LP tokens.
Whitelisting BEAN:WBTC gives Depositors the opportunity to earn Stalk and Seeds while holding BTC exposure. The relatively low optimal LP BDV distribution of 20% reflects the centralization risks of WBTC.
weETH has the largest TVL of any liquid staking derivative on Arbitrum. Basin does not have a Well Implementation that tracks rebasing tokens—thus, Basin (and thus, Beanstalk) must use weETH (i.e., the wrapped, non-rebasing version of eETH).
Contract Changes
L1 Initialization Contract
The
init
function on the ReseedL2Migration contract is called:0xE35c0397dBB43EB7E2cb28a182d857a3A42eFaDB
L1 Beanstalk
All remaining facets and functions on L1 Beanstalk can be found in the Appendix section.
L2 Beanstalk
The following facets are removed from Beanstalk (i.e., not added to L2 Beanstalk):
FundraiserFacet
LegacyClaimWithdrawalFacet
CurveFacet
MigrationFacet
All facets and functions added to L2 Beanstalk can be found in the Appendix section.
Beans Minted
During the L2 migration, Beans are minted on Arbitrum corresponding to the amount in L1 Beanstalk (i.e., Beans underlying Bean Deposits, Beans underlying Deposited LP tokens, Ripe Beans, Farm Balances and Beans in Pod Orders).
After the conclusion of the L2 migration, anytime a Farmer migrates L1 Circulating Beans, L2 Beans will be minted. Similarly, any time a smart contract account owner on L1 migrates their assets, L2 Beans may be minted depending on which assets are migrated.
Audit
The commit hash of this BIP is faa0ec60a455b0afdd20ad86f28f41cbc52c2e2d.
An audit competition of this upgrade was held via Codehawks using commit hash 4e0ad0b964f74a1b4880114f4dd5b339bc69cd3e. The final report can be read here.
Audit remediations were committed and documented in PRs #970, #1046, #1047, #1054, #1056 and #1076. All changes were reviewed by 2 top Codehawks auditors.
The Upgradable Well Implementation and Stable 2 Well Function were audited by Code4rena—final report here. The final report for the fix review is here.
Post Audit Changelog
Beanstalk
1e6
inLibGauge.issueGrownStalkPerBdv
;LibPipelineConvert
for Wells that do not have any reserves;LibEvaluate.calcLpToSupplyRatio
that skips the evaluation of liquidity when the reserves are 0;ReseedGlobal
to emit theShipmentRouteSet
event; anLibWell.calculateTokenBeanPriceFromReserves
to fail gracefully.Basin
All of the following are implemented in PR #146:
MultiFlowPump
to fail gracefully whencalcRate
fails;IMultiFlowWellFunction
to implementratioPrecision(uint256 j, bytes data)
, which returns the precision thatMultiFlowPump
should use when calculating the capped reserves;MultiFlowPump
to useratioPrecision
when calculatingratios[j]
incalcReservesAtRatioSwap
;ConstantProduct2
,ConstantProduct
, andStable2
to implementratioPrecision
; andIWellFunction
to implementversion
, allowing users to verify Well Functions.Effective
After either:
The L1 BCM will:
ReseedL2Migration
initialization contract, which:DiamondCutFacet
,DiamondLoupeFacet
,OwnershipFacet
andPauseFacet
; andL1TokenFacet
andL2MigrationFacet
;In addition, a deployer will:
After which the L2 BCM will:
Appendix
L1 Beanstalk
The following facets show all functions remaining on L1 Beanstalk:
L1 DiamondCutFacet
Remaining
DiamondCutFacet
address:0xDFeFF7592915bea8D040499E961E332BD453C249
diamondCut
0x1f931c1c
L1 DiamondLoupeFacet
Remaining
DiamondLoupeFacet
address:0xB51D5C699B749E0382e257244610039dDB272Da0
facetAddress
0xcdffacc6
facetAddresses
0x52ef6b2c
facetFunctionSelectors
0xadfca15e
facets
0x7a0ed627
supportsInterface
0x01ffc9a7
L1 OwnershipFacet
Remaining
OwnershipFacet
address:0x5D45283Ff53aabDb93693095039b489Af8b18Cf7
claimOwnership
0x4e71e0c8
owner
0x8da5cb5b
ownerCandidate
0x5f504a82
transferOwnership
0xf2fde38b
L1 PauseFacet
Remaining
PauseFacet
address:0xeab4398f62194948cB25F45fEE4C46Fae2e91229
pause
0x8456cb59
unpause
0x3f4ba83a
L1 L1TokenFacet
Added
L1TokenFacet
address:0x8F66044a9C95FaE9d38B8Bc30665eE04A2456501
approveToken
0xda3e3397
decreaseTokenAllowance
0x0bc33ce4
getAllBalance
0xfdb28811
getAllBalances
0xb6fc38f9
getBalance
0xd4fac45d
getBalances
0x6a385ae9
getExternalBalance
0x4667fa3d
getExternalBalances
0xc3714723
getInternalBalance
0x8a65d2e0
getInternalBalances
0xa98edb17
increaseTokenAllowance
0xb39062e6
onERC1155BatchReceived
0xbc197c81
onERC1155Received
0xf23a6e61
permitToken
0x7c516e94
tokenAllowance
0x8e8758d8
tokenPermitDomainSeparator
0x1f351f6a
tokenPermitNonces
0x4edcab2d
transferInternalTokenFrom
0xd3f4ec6f
transferToken
0x6204aa43
unwrapEth
0xbd32fac3
wrapEth
0x1c059365
L1 L2MigrationFacet
Added
L2MigrationFacet
address:0xb7EA01231e518cd22E118165b290f5CC3263F5bB
migrateL2Beans
0xfe5b810f
approveL2Receiver
0xcb3fcc04
L2 Beanstalk
The following facets show all functions added to L2 Beanstalk:
0xD1A0060ba708BC4BCD3DA6C37EFa8deDF015FB70
Notes:
L2 DiamondCutFacet
Added
DiamondCutFacet
address:0x7B08f0efC94626D373c99fd39353217a371F90c0
diamondCut
0x1f931c1c
L2 DiamondLoupeFacet
Added
DiamondLoupeFacet
address:0x82aF8BC912284F916dBe7208074F3B16ea27BB40
facetAddress
0xcdffacc6
facetAddresses
0x52ef6b2c
facetFunctionSelectors
0xadfca15e
facets
0x7a0ed627
supportsInterface
0x01ffc9a7
L2 OwnershipFacet
Added
OwnershipFacet
address:0x2cb2D140c42b79F602535e2447E7Afa980034464
claimOwnership
0x4e71e0c8
owner
0x8da5cb5b
ownerCandidate
0x5f504a82
transferOwnership
0xf2fde38b
L2 WhitelistFacet
Added
WhitelistFacet
address:0x7f855852a7191635c845c4183a6335ecb0B7aFAb
whitelistTokenWithEncodeType
N/A
whitelistTokenWithExternalImplementation
N/A
getGaugePointImplementationForToken
0x738cb80b
getLiquidityWeightImplementationForToken
0x8104d586
getOracleImplementationForToken
0x56b7b49c
updateGaugePointImplementationForToken
0x4fb907a0
updateLiquidityWeightImplementationForToken
0x88db1a6f
updateOracleImplementationForToken
0x874b87b9
updateSeedGaugeSettings
0xa160f06a
dewhitelistToken
0x86b40a1b
getSiloTokens
0xe9522c08
getWhitelistStatus
0xd9ba32fc
getWhitelistStatuses
0x170cf084
getWhitelistedLpTokens
0x9d1d2877
getWhitelistedTokens
0xe26f7900
getWhitelistedWellLpTokens
0x76a7bc84
updateGaugeForToken
0x19b8f518
updateStalkPerBdvPerSeasonForToken
0xf18d9ed0
whitelistToken
0x4bfd2d75
L2 UnripeFacet
Added
UnripeFacet
address:0x87F1FB2CF1CDC19103739F7cdb0068b203184354
pick
N/A
picked
N/A
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
getRecapitalized
0xe68a543a
getTotalUnderlying
0xadef4533
getUnderlying
0x9f06b3fa
getUnderlyingPerUnripeToken
0xb8a04d1b
getUnderlyingToken
0x691bcc88
isUnripe
0xfc6a19df
switchUnderlyingToken
0xa33fa99f
L2 MetadataFacet
Added
MetadataFacet
address:0x5794fDb0cfE2AbFCB3D22103F5d8c6B4C2cCD1d9
imageURI
0xc20b8071
name
0x06fdde03
symbol
0x95d89b41
uri
0x0e89341c
L2 SeasonFacet
Added
SeasonFacet
address:0x40c8688969c91290311314fbB2f10156b43Fbe4B
getShipmentRoutes
0xfd497a68
setShipmentRoutes
0xf1e2dfb0
gm
0x64ee4b80
seasonTime
0xca7b7d7b
sunrise
0xfc06d2a6
L2 SeasonGettersFacet
Added
SeasonGettersFacet
address:0xfe15fe467d06Ce19d20709eAE9E24B3bD8309132
getBeanEthGaugePointsPerBdv
N/A
getSopWell
N/A
cumulativeCurrentDeltaB
0x89a218d2
getAbsBeanToMaxLpRatioChangeFromCaseId
0xe53b479e
getAbsTemperatureChangeFromCaseId
0x3cee5dea
getCaseData
0x8097f0ca
getCases
0x065cb594
getChangeFromCaseId
0x43e0156a
getDeltaPodDemandLowerBound
0x57801d87
getDeltaPodDemandUpperBound
0x70fd1b06
getEvaluationParameters
0xda61af62
getExcessivePriceThreshold
0x44fb7cc3
getLpToSupplyRatioUpperBound
0x1eedbfbb
getLpToSupplyRatioOptimal
0x1f48a553
getLpToSupplyRatioLowerBound
0x11a8d895
getMaxBeanMaxLpGpPerBdvRatio
0xab843b34
getMinBeanMaxLpGpPerBdvRatio
0xb3c39ce5
getPodRateLowerBound
0xfd6d1483
getPodRateOptimal
0xdd9330d2
getPodRateUpperBound
0x08fa96d3
getRelBeanToMaxLpRatioChangeFromCaseId
0x35870a7a
getRelTemperatureChangeFromCaseId
0x4d65f762
getSeasonStruct
0x738ad142
getSeasonTimestamp
0xf07f0760
getTargetSeasonsToCatchUp
0xcb677411
getWellsByDeltaB
0xbf170533
poolCurrentDeltaB
0x8223eac8
abovePeg
0x2a27c499
getLargestLiqWell
0xd1943f7f
getTotalUsdLiquidity
0xbbf459a7
getTotalWeightedUsdLiquidity
0xf788b47c
getTwaLiquidityForWell
0xa13a3742
getWeightedTwaLiquidityForWell
0x93c9e531
paused
0x5c975abb
plentyPerRoot
0x3fccd20c
poolDeltaB
0x471bcdbe
rain
0x43def26e
season
0xc50b0fb0
sunriseBlock
0x3b2ecb70
time
0x16ada547
totalDeltaB
0x06c499d8
weather
0x686b6159
wellOracleSnapshot
0x597490c0
L2 GaugeGettersFacet
Added
GaugeGettersFacet
address:0x2e804f24134baCF12036757D1dcdcCbBBb3e2f31
getLargestGpPerBDV
0x6bbf3305
calcGaugePointsWithParams
0x7046c9a6
getAverageGrownStalkPerBdv
0x7ba6cbf8
getAverageGrownStalkPerBdvPerSeason
0xeb0e1215
getBeanGaugePointsPerBdv
0x69aa7e02
getBeanToMaxLpGpPerBdvRatio
0xcc88d4f9
getBeanToMaxLpGpPerBdvRatioScaled
0x673c75f0
getDeltaPodDemand
0x64b3496b
getGaugePoints
0x93523425
getGaugePointsPerBdvForToken
0x64887852
getGaugePointsPerBdvForWell
0xb2b0556d
getGaugePointsWithParams
0x141933bf
getGrownStalkIssuedPerGp
0xf98da2de
getGrownStalkIssuedPerSeason
0x383f170f
getLiquidityToSupplyRatio
0xcb2d0a3c
getPodRate
0x11242145
getSeedGauge
0x6af8e5a4
getTotalBdv
0x50539159
L2 PauseFacet
Added
PauseFacet
address:0x926CFCe66aa8A0CC29470dA28095D88CF24ABE16
pause
0x8456cb59
unpause
0x3f4ba83a
L2 MarketplaceFacet
Added
MarketplaceFacet
address:0xcA03AbaBA37566d89B707878495D9EB8Ea48C3c5
cancelPodOrderV2
N/A
createPodListingV2
N/A
createPodOrderV2
N/A
fillPodListingV2
N/A
fillPodOrderV2
N/A
getAmountBeansToFillOrderV2
N/A
getAmountPodsFromFillListingV2
N/A
podListing
N/A
podOrder
N/A
podOrderById
N/A
podOrderV2
N/A
getOrderId
0x631076dd
getPodListing
0x98c02432
getPodOrder
0x674a3e67
transferPlots
0x31ed3796
allowancePods
0xb151226a
approvePods
0x0711f012
cancelPodListing
0x8d398973
cancelPodOrder
0x9ed2801b
createPodListing
0x65865af6
createPodOrder
0x37b4d2ec
fillPodListing
0xf7f228a2
fillPodOrder
0xed8c792f
transferPlot
0xceb39673
L2 FieldFacet
Added
FieldFacet
address:0xa9085918d5632EA12BA91709F819B800fa8B3726
yield
N/A
activeField
0xd1eba544
addField
0xb94e871c
balanceOfPods
0x9a337c1d
fieldCount
0xbb485bbd
getPlotIndexesFromAccount
0x253fcfb5
getPlotsFromAccount
0x91b24284
isHarvesting
0x4bea67c4
setActiveField
0x057c571b
totalHarvestableForActiveField
0x237dbac5
harvest
0xe9bbb033
harvestableIndex
0xb511654d
maxTemperature
0x7907091f
plot
0x9ee7ea12
podIndex
0xccda40b9
remainingPods
0x56ba3e24
sow
0x32ab68ce
sowWithMin
0x553030d0
temperature
0xadccea12
totalHarvestable
0x2e76f597
totalHarvested
0x352525a6
totalPods
0xf1e0a211
totalSoil
0x3285008a
totalUnharvestable
0xf29ffe94
L2 FertilizerFacet
Added
FertilizerFacet
address:0x7B2BDA06CE2cD8287e169b241d68d1Bb6568e342
leftoverBeans
0x8bb3aba8
rinsableSprouts
0x5d7db3b6
rinsedSprouts
0x7562d880
_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
getTotalRecapDollarsNeeded
0x12cb5eab
isFertilizing
0x6ae1c014
mintFertilizer
0x363591d0
payFertilizer
0xd47aee59
remainingRecapitalization
0x4a16607c
totalFertilizedBeans
0x4f9a9678
totalFertilizerBeans
0xf9c4ebde
totalUnfertilizedBeans
0xa3ef48c9
L2 FarmFacet
Added
FarmFacet
address:0x24103B8141F97D9D8794fE2EE0eD96F577EeC05F
advancedFarm
0x36bfafbd
farm
0x300dd6cf
L2 SiloFacet
Added
SiloFacet
address:0x5678345D444918a38ad9dC7CA1b0C208E1927094
deposit
0xf19ed6be
safeBatchTransferFrom
0x2eb2c2d6
safeTransferFrom
0xf242432a
transferDeposit
0x081d77ba
transferDeposits
0xc56411f6
withdrawDeposit
0xe348f82b
withdrawDeposits
0x27e047f1
L2 SiloGettersFacet
Added
SiloGettersFacet
address:0xb4F9d59f787642F64c73346A747Bf1984A52D4Ea
getLegacySeedsPerToken
N/A
migrationNeeded
N/A
seasonToStem
N/A
balanceOfGrownStalkMultiple
0xcb65f1b1
balanceOfPlantableSeeds
0x80c9084b
bdvs
0xd31e4d66
calculateStemForTokenFromGrownStalk
0x0b6413b0
getAddressAndStem
0x805a343f
getBeanIndex
0xb592d450
getBeanstalkTokens
0x3c22a23c
getDepositsForAccount
(notoken
parameter)0x823ccbe9
getDepositsForAccount
(acceptstokens[]
)0xe73c165b
getIndexForDepositId
0x55d0807e
getMowStatus
(acceptstokens[]
)0x047c92cf
getNonBeanTokenAndIndexFromWell
0xf6225118
getStemTips
0x9cf67d70
getTokenDepositIdsForAccount
0x54369b5b
getTokenDepositsForAccount
0xe49b77f5
getTotalSiloDeposited
0xb13d3024
getTotalSiloDepositedBdv
0xbd637860
stalkEarnedPerSeason
0xedd2d167
balanceOf
0x00fdd58e
balanceOfBatch
0x4e1273f4
balanceOfDepositedBDV
0xbc8514cf
balanceOfEarnedBeans
0x3e465a2e
balanceOfEarnedStalk
0x341b94d5
balanceOfFinishedGerminatingStalkAndRoots
0xc063989e
balanceOfGerminatingStalk
0x838082b5
balanceOfGrownStalk
0x8915ba24
balanceOfPlenty
0xb02e7162
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
getMowStatus
(acceptstoken
)0xdc25a650
getOddGerminating
0x85167e51
getTotalDeposited
0x0c9c31bd
getTotalDepositedBDV
0x9d6a924e
getTotalGerminatingAmount
0xb45ef2eb
getTotalGerminatingBdv
0x9dcf67f0
getTotalGerminatingStalk
0x7d4a51cb
getYoungAndMatureGerminatingTotalStalk
0x5a8e63e3
grownStalkForDeposit
0x3a1b0606
lastSeasonOfPlenty
0xbe6547d2
lastUpdate
0xcb03fb1e
stemStartSeason
0xbc771977
stemTipForToken
0xabed2d41
tokenSettings
0xe923e8d4
totalEarnedBeans
0xfd9de166
totalRainRoots
0xaea72f96
totalRoots
0x46544166
totalStalk
0x7b52fadf
L2 EnrootFacet
Added
EnrootFacet
address:0x3AF703FACA14A0201E5aa98D91cA1Dbb10a8f110
balanceOfRevitalizedStalk
0xe43b44ee
enrootDeposit
0x0b58f073
enrootDeposits
0x88fcd169
L2 TokenFacet
Added
TokenFacet
address:0xf8B5Fa117f492608b8f16AAE84C69175ead6A38d
approveToken
0xda3e3397
decreaseTokenAllowance
0x0bc33ce4
getAllBalance
0xfdb28811
getAllBalances
0xb6fc38f9
getBalance
0xd4fac45d
getBalances
0x6a385ae9
getExternalBalance
0x4667fa3d
getExternalBalances
0xc3714723
getInternalBalance
0x8a65d2e0
getInternalBalances
0xa98edb17
increaseTokenAllowance
0xb39062e6
onERC1155BatchReceived
0xbc197c81
onERC1155Received
0xf23a6e61
permitToken
0x7c516e94
tokenAllowance
0x8e8758d8
tokenPermitDomainSeparator
0x1f351f6a
tokenPermitNonces
0x4edcab2d
transferInternalTokenFrom
0xd3f4ec6f
transferToken
0x6204aa43
unwrapEth
0xbd32fac3
wrapEth
0x1c059365
L2 DepotFacet
Added
DepotFacet
address:0x107F33211935bb72B721675c7e95a2d4cC0c96cc
advancedPipe
0xb452c7ae
etherPipe
0x6e47d07b
multiPipe
0xcabec62b
pipe
0x08e1a0ab
readPipe
0xdd756c4f
L2 TokenSupportFacet
Added
TokenSupportFacet
address:0x17AC9d59f4637a16F47C8a77A1c4EE7c7a159A95
batchTransferERC1155
0xa9412a59
permitERC20
0xb442b398
permitERC721
0x4935ed43
transferERC1155
0x0a7e880c
transferERC721
0x1aca6376
L2 ConvertFacet
Added
ConvertFacet
address:0x242A339C73d3b373a91C157865B36a1480ec3b09
convert
0xb362a6e8
L2 ConvertGettersFacet
Added
ConvertGettersFacet
address:0x999A04B54a386b1C68A9Be926AF0200F2C49A47A
calculateDeltaBFromReserves
0xd052f0d5
calculateStalkPenalty
0xb325d2ef
cappedReservesDeltaB
0x6842f2b3
getOverallConvertCapacity
0xf66d5589
getWellConvertCapacity
0xb905065b
overallCappedDeltaB
0x3e8b56f1
overallCurrentDeltaB
0xb267ea07
scaledDeltaB
0x24568abf
getAmountOut
0x4aa06652
getMaxAmountIn
0x24dd285c
L2 ApprovalFacet
Added
ApprovalFacet
address:0x5579358403eD126dB6ed6A213B5129696161Bad6
approveDeposit
0x1302afc2
decreaseDepositAllowance
0xd9ee1269
depositAllowance
0x2a6a8ef5
depositPermitDomainSeparator
0x8966e0ff
depositPermitNonces
0x843bc425
increaseDepositAllowance
0x5793e485
isApprovedForAll
0xe985e9c5
permitDeposit
0x120b5702
permitDeposits
0xd5770dc7
setApprovalForAll
0xa22cb465
L2 BDVFacet
Added
BDVFacet
address:0x4da6AAed2a2C3605f7c098037014003697Cb0426
curveToBDV
N/A
beanToBDV
0x5a049a47
unripeBeanToBDV
0xc8cda2a0
unripeLPToBDV
0xb0c22bb1
wellBdv
0xc84c7727
L2 GaugePointFacet
Added
GaugePointFacet
address:0xbcF3bA03bf792F9f8B5dbd460eAa446529020778
getExtremelyFarAbove
0xafa1704e
getExtremelyFarBelow
0xc26072fe
getRelativelyFarAbove
0x3ad6d656
getRelativelyFarBelow
0x925150c9
defaultGaugePointFunction
0xe4b8d822
L2 LiquidityWeightFacet
Added
LiquidityWeightFacet
address:0x19AC2dc9A0BFda04Dde8EA7437945872DB95B13E
noWeight
0x225f8659
maxWeight
0x2c5fa218
L2 TractorFacet
Added
TractorFacet
address:0xcb84F1a368f303798DB6d9cE7B4084Aaf316479b
cancelBlueprint
0x563957a8
getBlueprintHash
0x5723cc60
getBlueprintNonce
0x5ebc32e6
getCounter
0x5993514b
getPublisherCounter
0x91a45154
getTractorVersion
0x454972dd
publishRequisition
0xcc8a429d
tractor
0xfe414fc8
updatePublisherCounter
0xdf8d26bb
updateTractorVersion
0x04cb49dc
L2 L1ReceiverFacet
Added
L1ReceiverFacet
address:0x8F2bB164dF87183af23E72d49572052e27651A57
approveReceiver
0x72138e1a
getDepositMerkleRoot
0x922c0257
getFertilizerMerkleRoot
0x2c2eeb72
getInternalBalanceMerkleRoot
0x6f5a42e7
getPlotMerkleRoot
0xc4b35a45
getReceiver
0x73139315
issueDeposits
0x6e80f305
issueFertilizer
0xe080f84d
issueInternalBalances
0xaf0dc18a
issuePlots
0xba2332df
receiveL1Beans
0x057835e7
verifyDepositMerkleProof
0xce2dec6c
verifyFertilizerMerkleProof
0xbd1f26a6
verifyInternalBalanceMerkleProof
0xe1d8a20f
verifyPlotMerkleProof
0x00892531
L2 PipelineConvertFacet
Added
PipelineConvertFacet
address:0x6B1B5E5cef71f0cC65d32B67D8794F58faD491a3
pipelineConvert
0xbb25c1c2
L2 ClaimFacet
Added
ClaimFacet
address:0x76eF6b03775A4cDE7666C96f3Ca21feb736afeBC
claimAllPlenty
0xfa2e2617
claimPlenty
0x0d509999
mow
0x150d5173
mowMultiple
0x7d44f5bb
plant
0x779b3c5c
L2 OracleFacet
Added
OracleFacet
address:0x48Fa359664820A12ad6Ae8769ccB4365053da580
getMillionUsdPrice
0xd48274a0
getRatiosAndBeanIndex
0x052c3990
getTokenUsdPrice
0x00593bcf
getTokenUsdPriceFromExternal
0x054ce3bd
getTokenUsdTwap
0xc4c5140f
getUsdTokenPrice
0x8b7750c2
getUsdTokenPriceFromExternal
0x399ff0b5
getUsdTokenTwap
0xdd455fbf
Event Changes from L1 to L2
UpdatedSeedGaugeSettings
SeedsBalanceChanged
RemoveWithdrawal
RemoveWithdrawals
UpdateGaugeSettings
FarmerGerminatingStalkBalanceChanged
UpdatedOptimalPercentDepositedBdvForToken
UpdatedOracleImplementationForToken
UpdatedGaugePointImplementationForToken
UpdatedLiquidityWeightImplementationForToken
WhitelistToken
InternalBalanceChanged
user
parameter toaccount
FieldAdded
ActiveFieldSet
Sow
fieldId
parameterHarvest
fieldId
parameterTemperatureChange
fieldId
parameterPodListingCreated
fieldId
and changed other parameter namesPodListingFilled
fieldId
and changed other parameter namesPodListingCancelled
fieldId
and changed other parameter namesPodOrderCreated
fieldId
and changed other parameter namesPodOrderFilled
fieldId
and changed other parameter namesPodOrderCancelled
fieldId
and changed other parameter namesPlotTransfer
fieldId
parameterPodApproval
fieldId
parameterPublishRequisition
CancelBlueprint
Tractor
ShipmentRoutesSet
UpdatedEvaluationParameters
Receipt
Shipped
Receipt
Reward
SeasonOfPlenty
SeasonOfPlentyWell
SeasonOfPlentyField
MigratedAccountStatus
MigratedPlot
InternalBalanceMigrated
MigratedPodListing
MigratedPodOrder
AddMigratedDeposit
FertilizerMigrated