BIP-29: Pod Market Price Functions

Proposed: November 4, 2022

Status: Passed

Link: Snapshot


Proposer

Beanstalk Farms

Proposer Wallet: 0x36998db3f9d958f0ebaef7b0b6bf11f3441b216f

Summary

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

Quorum is a majority of the Stalk supply voting For, or about 34,070,677 Stalk voting For based on the time of proposal.

Problem

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.

Proposed Solution

Pod Market Price Functions

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.

Specification

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.

Representation of Piecewise Cubic Polynomials

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.

Floating Point Representation of Polynomial Coefficients

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:

Byte Encoding of Function Data

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.

Storage

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.

Farm Balance Approval System and Permits

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.

Silo Deposit Permits

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.

Technical Rationale

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.

Economic Rationale

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.

Contract Changes

MarketplaceFacet

The following MarketplaceFacet(s) are being deprecated:

The following MarketplaceFacet is being added to Beanstalk:

MarketplaceFacet Function Changes

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

MarketplaceFacet Event Changes

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

TokenFacet

The following TokenFacet is being deprecated:

The following TokenFacet is being added to Beanstalk:

TokenFacet Function Changes

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

TokenFacet Event Changes

Event Name Change
TokenApproval(...) New event

SiloFacet

The following SiloFacet is being deprecated:

The following SiloFacet is being added to Beanstalk:

SiloFacet Function Changes

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

Audit

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

Effective immediately upon commit.