Proposed: November 4, 2022
Status: Passed
- Proposer
- Summary
- Links
- Quorum
- Problem
- Proposed Solution
- Technical Rationale
- Economic Rationale
- Contract Changes
- Audit
- Effective
Beanstalk Farms
Proposer Wallet: 0x36998db3f9d958f0ebaef7b0b6bf11f3441b216f
- Implement V2 Pod Orders and Listings such that the Price per Pod is priced as a function of place in the Pod Line (via piecewise cubic polynomials);
- Allow Farmers to delegate use of their Farm balances to other contracts and add EIP-2612 permit support to Farm balances; and
- Add EIP-2612 permit support for Silo Deposits.
Note: BIP-28 was cancelled due to a bug that was reported during the Voting Period. One of the BCM Signers indicated that the transaction should be cancelled by signing a verified message.
A majority of the BCM Signers deemed this bug report valid by submitting and signing an on-chain rejection, rendering BIP-28 cancelled. As such, BIP-28 was removed from Snapshot.
The fix for the reported bug was verified by Halborn and included in the updated audit report.
Quorum is a majority of the Stalk supply voting For, or about 34,070,677 Stalk voting For based on the time of proposal.
The Pod Market currently limits Farmers to creating Pod Orders and Listings with a single Fill price per Pod independent of place in Line.
Because of the ordinal nature of Pods, the price per Pod is partially a function of place in Line. Pod Orders and Listings with a single Fill price fail to maximize overall marketplace liquidity by requiring the placing or updating of multiple orders in order to create a non-flat pricing curve, which is highly expensive for users.
Currently, there is no way for Farmers to delegate use of their Farm balances to other addresses; the only way to transfer Farm balances is by calling transferToken(s)()
through the Farmer's account.
Currently, a separate transaction is required in order for a Farmer to delegate another address to use their Silo Deposits.
We propose the implementation of new V2 Pod Orders and Listings where the Price Per Pod is priced as a piecewise function of Place in Line of up to n
cubic polynomial pieces. A new library, LibPolynomial.sol
, is introduced to evaluate and integrate over piecewise cubic polynomials on-chain in a gas efficient fashion to facilitate dynamic pricing of V2 Pod Orders and Listings.
Implementing dynamically priced Pod Orders and Listings should significantly improve market efficiency by allowing Farmers to place and update prices across the entire Pod Line is a single Order or Listing.
The LibPolynomial.sol
library is introduced, which contains the logical functionality required to store, integrate and evaluate price functions for use within the MarketplaceFacet
.
Price functions as implemented in LibPolynomial.sol
are represented as piecewise cubic polynomials. Each piece can represent any polynomial function of up to degree 3. There is no maximum number of pieces that can be contained within a single piecewise function.
The data required to represent a piecewise cubic polynomial consists of the domain of each piece as well as the coefficient for each polynomial term (up to 4 terms in a cubic). The function domains are represented as an array of uint256
breakpoints in ascending order of domain. Each polynomial's domain is inclusive at the start and exclusive at the end. The final polynomial's domain starts at the final breakpoint and extends until infinity.
The polynomial coefficients are stored in floating point representation and separated into three parts: the significand (numerator), the exponent of base 10 that the significand is shifted by, and the sign of the coefficient, where true is positive. For example, the decimal number 0.1234 could be represented as:
- significand: 1234
- exponent: 4
- sign: true
V2 Orders and Listings use a dynamically sized bytes
array to represent pricing functions in the transaction data allowing its data to be packed tightly without posing any limitation on the number of pieces allowed. All function data is concatenated into a bytes array that is divided up into sections. Data is ordered first by piecewise domain, and second by degree.
The first 32 bytes represent the number of polynomial pieces in the function array, which is then used to determine the length of the following sections of data. If there are n
number of pieces in the function, the next 32n bytes following the length are occupied by the breakpoints. The following 128n bytes are occupied by the function coefficient significands. The following 4n bytes contain the coefficient exponents. And the final 4n bytes contain the coefficient signs.
mapping(bytes32 => uint256) podOrders;
Has been changed to store the amount of Beans to be used by a Pod Order rather than the amount of Pods requested by it. This is because the amount of Pods an Order will Fill is now variable.
We propose adding an approval system to Farm balances, which allows Farmers to delegate their Farm balances to be used by other addresses.
We also propose adding EIP-2612 support for Farm balances, which allows Farmers to delegate use of their Farm balances through permits without the need for a separate transaction.
We propose adding EIP-2612 support for Silo Deposits, which allows Farmers to delegate use of their Silo Deposits through permits without the need for a separate transaction.
Dynamically priced Pod Orders and Pod Listings reduce the user action (and associated gas costs) required to make or update sophisticated pricing curves on the Pod Market to a single transaction.
The ability for Farmers to delegate their Farm balances to another contract allows other protocols to build on top of Beanstalk's Farm balance system. The ability to perform this delegation without a separate transaction reduces the friction of interacting with Beanstalk.
Similarly, the ability for Farmers to delegate their Silo Deposits to another contract without the need for a separate transaction reduces the friction of interacting with Beanstalk.
Implementing dynamically priced Pod Orders and Listings should improve market efficiency and depth.
Improving the composability of and reducing the number of separate transactions required to interact with Beanstalk should improve the utility of Beanstalk and Beans.
The following MarketplaceFacet
(s) are being deprecated:
The following MarketplaceFacet
is being added to Beanstalk:
Function Name | Selector | Action | New Functionality |
---|---|---|---|
cancelPodOrder(...) |
0xdf18a3ee |
Add | ✓ |
cancelPodOrderV2(...) |
0xf22b49ec |
Add | ✓ |
createPodListing(...) |
0x80bd7d33 |
Add | ✓ |
createPodListingV2(...) |
0xa8f135a2 |
Add | ✓ |
createPodOrder(...) |
0x82c65124 |
Add | ✓ |
createPodOrderV2(...) |
0x83601992 |
Add | ✓ |
fillPodListing(...) |
0xeda8156e |
Add | ✓ |
fillPodListingV2(...) |
0xa99d840c |
Add | ✓ |
fillPodOrder(...) |
0x845a022b |
Add | ✓ |
fillPodOrderV2(...) |
0x4214861e |
Add | ✓ |
getAmountBeansToFillOrderV2(...) |
0x7e2a1fd1 |
Add | ✓ |
getAmountPodsFromFillListingV2(...) |
0xc3e14715 |
Add | ✓ |
podOrder(...) |
0x042ff31d |
Add | ✓ |
podOrderV2(...) |
0x045d5763 |
Add | ✓ |
allowancePods(...) |
0x0b385a85 |
Replace | |
approvePods(...) |
0xc5644a60 |
Replace | |
cancelPodListing(...) |
0x3260c49e |
Replace | |
podListing(...) |
0xd6af17ab |
Replace | |
getPodOrderById(...) |
0xb1719e59 |
Replace | |
transferPlot(...) |
0x69d9120d |
Replace | |
cancelPodOrder(...) |
0xeb6fa84f |
Remove | |
createPodListing(...) |
0xed778f8e |
Remove | |
createPodOrder(...) |
0x72db799f |
Remove | |
podOrder(...) |
0x56e70811 |
Remove | |
fillPodOrder(...) |
0x6d679775 |
Remove | |
fillPodListing(...) |
0x1aac9789 |
Remove |
Event Name | Change |
---|---|
PodOrderCreated(...) |
New parameter(s): minFillAmount , pricingFunction , priceType |
PodListingCreated(...) |
New parameter(s): minFillAmount ,pricingFunction , pricingType |
PodListingFilled(...) |
New parameter(s): costInBeans |
PodOrderFilled(...) |
New parameter(s): costInBeans |
The following TokenFacet
is being deprecated:
The following TokenFacet
is being added to Beanstalk:
Function Name | Selector | Action | New Functionality |
---|---|---|---|
approveToken(...) |
0xda3e3397 |
Add | ✓ |
decreaseTokenAllowance(...) |
0x0bc33ce4 |
Add | ✓ |
increaseTokenAllowance(...) |
0xb39062e6 |
Add | ✓ |
permitToken(...) |
0x7c516e94 |
Add | ✓ |
tokenAllowance(...) |
0x8e8758d8 |
Add | ✓ |
tokenPermitDomainSeparator(...) |
0x1f351f6a |
Add | ✓ |
tokenPermitNonces(...) |
0x4edcab2d |
Add | ✓ |
transferTokenFrom(...) |
0x7006e387 |
Add | ✓ |
getAllBalance(...) |
0x0b385a85 |
Replace | |
getAllBalances(...) |
0xb6fc38f9 |
Replace | |
getBalance(...) |
0xd4fac45d |
Replace | |
getBalances(...) |
0x6a385ae9 |
Replace | |
getExternalBalance(...) |
0x4667fa3d |
Replace | |
getExternalBalances(...) |
0xc3714723 |
Replace | |
getInternalBalance(...) |
0x8a65d2e0 |
Replace | |
getInternalBalances(...) |
0xa98edb17 |
Replace | |
transferToken(...) |
0x6204aa43 |
Replace | ✓ |
unwrapEth(...) |
0xbd32fac3 |
Replace | |
wrapEth(...) |
0x1c059365 |
Replace |
Event Name | Change |
---|---|
TokenApproval(...) |
New event |
The following SiloFacet
is being deprecated:
The following SiloFacet
is being added to Beanstalk:
Function Name | Selector | Action | New Functionality |
---|---|---|---|
depositPermitDomainSeparator() |
0x8966e0ff |
Add | ✓ |
depositPermitNonces(...) |
0x843bc425 |
Add | ✓ |
permitDeposit(...) |
0x120b5702 |
Add | ✓ |
permitDeposits(...) |
0xd5770dc7 |
Add | ✓ |
approveDeposit(...) |
0x1302afc2 |
Replace | |
balanceOfEarnedBeans(...) |
0x3e465a2e |
Replace | |
balanceOfEarnedSeeds(...) |
0x602aa123 |
Replace | |
balanceOfEarnedStalk(...) |
0x341b94d5 |
Replace | |
balanceOfGrownStalk(...) |
0x249564aa |
Replace | |
balanceOfPlenty(...) |
0x896651e8 |
Replace | |
balanceOfRainRoots(...) |
0x69fbad94 |
Replace | |
balanceOfRoots(...) |
0xba39dc02 |
Replace | |
balanceOfSeeds(...) |
0x4916bc72 |
Replace | |
balanceOfSop(...) |
0xa7bf680f |
Replace | |
balanceOfStalk(...) |
0x8eeae310 |
Replace | |
claimPlenty() |
0x45947ba9 |
Replace | |
claimWithdrawal(...) |
0x488e94dc |
Replace | |
claimWithdrawals(...) |
0x764a9874 |
Replace | |
decreaseDepositAllowance(...) |
0x82c65124 |
Replace | |
deposit(...) |
0xf19ed6be |
Replace | |
depositAllowance(...) |
0x2a6a8ef5 |
Replace | |
enrootDeposit(...) |
0xd5d2ea8c |
Replace | |
enrootDeposits(...) |
0x83b9e85d |
Replace | |
getDeposit(...) |
0x8a6a7eb4 |
Replace | |
getTotalDeposited(...) |
0x0c9c31bd |
Replace | |
getTotalWithdrawn(...) |
0xb1c7a20f |
Replace | |
getWithdrawal(...) |
0xe23c96a4 |
Replace | |
increaseDepositAllowance(...) |
0x5793e485 |
Replace | |
lastSeasonOfPlenty() |
0xbe6547d2 |
Replace | |
lastUpdate(...) |
0xcb03fb1e |
Replace | |
plant() |
0x779b3c5c |
Replace | |
tokenSettings(...) |
0xe923e8d4 |
Replace | |
totalEarnedBeans(...) |
0xfd9de166 |
Replace | |
totalRoots() |
0x46544166 |
Replace | |
totalSeeds() |
0xd8bd0d9d |
Replace | |
totalStalk() |
0x7b52fadf |
Replace | |
transferDeposit(...) |
0x9e32d261 |
Replace | |
transferDeposits(...) |
0x0d2615b1 |
Replace | |
update(...) |
0x1c1b8772 |
Replace | |
withdrawDeposit(...) |
0x7af9a0ce |
Replace | |
withdrawDeposits(...) |
0xb189d9c8 |
Replace | |
withdrawFreeze(...) |
0x55926690 |
Replace |
The commit hash of this BIP is 0bdd376263b0fe94af84aaf4adb6391b39fa80ab.
Halborn has performed an audit of this commit hash. You can view the Halborn audit report of this commit hash on Arweave here: https://arweave.net/4GwrRBM7K-0SvyryHVH1oQDpkcbwnAm3up45bYf_RYA
Effective immediately upon commit.