PI-1: Convert Newly Earned Pinto and Misc. Bug Fixes

Executed on November 27, 2024 at 05:52 UTC.

Summary

  1. Germination of Earned Pinto: Eliminate the Germination Period for Earned Pinto, enabling Pinto → LP Converts immediately after a Farmer Plants their Earned Pinto.
  1. Re-germination of Converted Deposits: Eliminate a bug where Converts can erroneously cause a Deposit to Germinate again.
  1. Minimum Crop Ratio During Rain: Add a distinct Minimum Crop Ratio while the system is Raining.
  1. Initial Soil Supply: Add initialSoil to expose the remaining Soil supply before Morning Auction scaling.
  1. Event and Rain Data Fixes: Correct the number of Pinto emitted by the Sow event and startRain’s emitted Crop Ratio change.
  1. Plenty Claim Return Values: Return the number of tokens claimed as Plenty from claimPlenty and the token addresses and numbers of tokens claimed from claimAllPlenty.

Links

Problems

1. Germination of Earned Pinto

Earned Pinto Deposits should be able to be used in a Pinto → LP Convert immediately upon distribution (i.e., they should not Germinate). However, when a Farmer Planted their Earned Pinto, they were not able to Convert their new Pinto Deposit to an LP token Deposit until 2 Seasons elapsed. This inability to Convert immediately after Planting was a significant inefficiency with respect to peg maintenance because users that just Planted their Earned Pinto needed to wait until the Germination Period ended and then return to the Farm to Convert their Pinto for peg maintenance.

2. Re-germination of Converted Deposits

When a Farmer Converted a Pinto Deposit that had recently finished Germinating to an LP token Deposit (or vice versa), the output Deposit became Germinating again. In this case the then Germinating Deposit lost its Stalk, and instead was issued Germinating Stalk (i.e., a claim on Stalk after the Germination Period ends). Germinating Stalk is ineligible for mints or Flood rewards. Thus, a user was disincentivized to Convert during times of large mints and Floods because they would lose 2 Seasons of mints and eliminate their share of subsequent Flood distributions during the current Rain associated with the Converted Deposits.

3. Minimum Crop Ratio During Rain

When the system is Raining, the minimum Crop Ratio should be lowered to increase the incentive to Convert from Deposited Pinto to the Deposited LP token with the most Seeds.

4. Initial Soil Supply

There was no on-chain function that returned the remaining Soil supply before Morning Auction scaling, so the UI had to make excessive RPC calls to reconstruct it.

5. Event and Rain Data Fixes

The Sow event emitted an incorrect number of Pinto, and startRain did not correctly emit the change in BeanToMaxLpGpPerBdvRatio, resulting in incorrect data in the subgraph.

6. Plenty Claim Return Values

The claimPlenty and claimAllPlenty functions did not return sufficient data to easily compose transactions together in the UI.

Solutions

1. Germination of Earned Pinto

Update the plant function to issue a non-Germinating Pinto Deposit crediting it with the Grown Stalk it would have earned at the previous Season's Seeds per PDV for Pinto, plus an additional 1 micro Seed.

2. Re-germination of Converted Deposits

Update the convert function to issue a non-Germinating token Deposit for Pinto ↔ LP Converts if the value being Converted was not Germinating. If the resulting Deposit would otherwise have a Germinating Stem, top up Grown Stalk to the non-Germinating minimum based on the previous Season's Seeds per PDV of the output token, plus an additional 1 micro Seed.

3. Minimum Crop Ratio During Rain

Add rainingMinBeanMaxLpGpPerBdvRatio to the EvaluationParameters struct in storage and initialize the value to 33333333333333333333 (approximately 33.33%), and update getBeanToMaxLpGpPerBdvRatioScaled to use rainingMinBeanMaxLpGpPerBdvRatio instead of minBeanMaxLpGpPerBdvRatio when the system is Raining.

4. Initial Soil Supply

Add the initialSoil function, which returns s.sys.soil.

5. Event and Rain Data Fixes

Update the Sow event to properly emit the number of Pinto that were used to Sow, rather than the number of Soil deducted from s.sys.soil.

Update the startRain function in LibFlood.sol to properly emit the change in BeanToMaxLpGpPerBdvRatio.

6. Plenty Claim Return Values

Update the claimPlenty function to return the number of tokens claimed. Update claimAllPlenty to return the token addresses and numbers of tokens claimed.

Rationale

1. Germination of Earned Pinto

There is no reason to enforce a Germination Period for newly Planted Earned Pinto Deposits. The Germination Period prevents a specific manipulation. Without it, a user could Deposit value in the Silo to receive Stalk, call the gm (which triggers the Sunrise), and then immediately withdraw the Deposit plus the yield from that Sunrise, all without holding exposure to the price of Pinto. Earned Pinto already accrued from a Deposit that completed Germination, so exempting it does not enable the manipulation described above.

The inability to Convert newly Planted Pinto to Deposited LP tokens is a significant inefficiency with respect to peg maintenance because it creates a lag between when Farmers Plant their Pinto and when they can Convert them. This lag may delay the effect of mint distributions on peg maintenance with respect to the value that stays in the protocol (i.e., wasn’t sold) by at least one Season, because delayed Converts can delay the peg recovery and lead to more Pinto being minted.

2. Re-germination of Converted Deposits

Once value that was Deposited in the Silo has completed its Germination Period, there is no reason to make it Germinate again upon a Convert because the value will have already been in the Silo for a sufficient period of time, ensuring that it is not taking advantage of a Pinto mint without holding exposure to the Pinto price.

The ability to Convert a non-Germinating Pinto Deposit into a Germinating LP token Deposit creates a disincentive to Convert, which can lead to excess mints because holders that would otherwise have Converted do not.

3. Minimum Crop Ratio During Rain

When it's Raining, Pinto should be very aggressive in incentivizing Converts from Pinto Deposits to LP token Deposits. During a Flood, the protocol should be minimizing how much it mints because when the Flood ends it will almost certainly experience heavy outflows. Accordingly, lowering the Crop Ratio to an exceptionally low value – below the Minimum Crop Ratio – will create a stronger incentive for Depositors to Convert their Deposited Pinto to LP token Deposits and minimize excessive minting.

4. Initial Soil Supply

Exposing the remaining unscaled Soil directly lets the UI read the protocol’s current value without reconstructing it through multiple RPC calls.

5. Event and Rain Data Fixes

Emitting the Pinto actually Sown and emitting the Crop Ratio change allows the subgraph and UI to process the protocol’s state changes accurately.

6. Plenty Claim Return Values

Returning the claimed token addresses and numbers of tokens lets the UI use claim results when composing subsequent actions in the same transaction.

Contract Changes

Initialization

InitPI1.init() was called at 0x4cbD1A8ff8E3dcE759dC9049417DeeBC3Ac24ddA to initialize rainingMinBeanMaxLpGpPerBdvRatio to 33333333333333333333 (approximately 33.33%).

Facet Changes

FacetActionPrevious ImplementationNew Implementation
ClaimFacetReplace0x85495A065bEc462d76Fbfa1E344C06f64308Af910xEa0Aad388e2dF06F90A218cA2eDa199294fBAaDB
ApprovalFacetReplace0x77e228C03277e38FcfF8FC21106afDc22389e85c0x540e776e8F0eaC5dFA82110b827CB6ceA6705669
ConvertFacetReplace0x0FAf9BBDDD27647bA9972672aee4E638B364E2490x379D2d7FF9907F127f1226a9024BCF0789619734
ConvertGettersFacetReplace0xF0f2e61939DE4daf29d894B466b51798C5c54A1d0xfE55E1e7f3FdAef6b1E6E3d6D53f84a374151817
SiloFacetReplace0x8A42a986DDB3612437f8445bB199FDb14714fa420x3235540bb01Ef11e4208a9B99c2F2Dd9860E721a
SiloGettersFacetReplace + Add selectors0x12b94E41697AC173d619CecCcAAd1C2C21A2a66C0x039Ec53Bb37F8fe240798E3591d9439C68e72B7b
PipelineConvertFacetReplace0x032CAe4820C7379B1419Af64a3e2a4Ce4861Ab0a0x9d108e7f673C773Ac196bDE4bEBC6758088D2e59
SeasonFacetReplace0x03fbe88B58FceA841A749FF2e93E4e56D2f42C060x269C8386bE50C176f03355c7C7925356fdEF9F84
GaugeGettersFacetReplace0xABcBa236f57a807084F7884B3eEdD25C077595Ba0xD26a44C9F7C58864c2ea938BE9E2f0Ae25954bc2
FieldFacetReplace + Add selector0x34d5239E92720773C2E7a5A93Db8587a3af6Bb040x6430F859a3b8825D25382Ebc7941fCD719635797

Other Contract / Parameter Changes

Introduced a separate minimum Crop Ratio during Rain of approximately 33.33%, using rainingMinBeanMaxLpGpPerBdvRatio. Outside Rain, getBeanToMaxLpGpPerBdvRatioScaled continues to use minBeanMaxLpGpPerBdvRatio. Previously, the 50% minimum also applied during Rain. The minimum remains 50% outside Rain. Ratios use 18 decimal places per percentage point (100e18 = 100%).

Externally linked library deployments changed as follows (previous → new). These address changes do not by themselves imply changes to each library’s behavior.

LibraryPrevious ImplementationNew ImplementationUsed By
LibSilo0x6a634f53d185298ad84a51e2c6fac8b5256d01650x351ca256f86c10b01f2640f22ca379cf1e74d8e2ClaimFacet, ConvertFacet, SiloFacet, PipelineConvertFacet
LibTokenSilo0xa565840bc1a3d3b24fb36c02472aa495259477b60xbbe1d3e7bb0b50d1999f631674efd5446881612aClaimFacet, ConvertFacet, SiloFacet, PipelineConvertFacet
LibConvert0xad4a3b66c5e672acc952d9f4b728b4c845f8cb7a0x3dedd64cfbf6db642cf6a22ce747fdfb9f17b570ConvertFacet
LibPipelineConvert0x9b0943584aa2bd99cefd82004dfe859d369e43260x4917dcbafc47b57b9ec004424a44ccdc5834d054ConvertFacet, PipelineConvertFacet
LibEvaluate0x34ebbb2b16cf20964b6819cef921dd10599f117c0x7f1770fa1b43abdbe8095295ecae37c00d4ba7f8SeasonFacet
LibGauge0xc3ccf1a9cff074fd572c9ab7d55486ef003fd4270xcd376159cfa7ff6c60a3b6d55e2ce75cec515669SeasonFacet
LibIncentive0x7b160137d1298e3b71285ea6a260cb2248176d820x86da3aba20454a441eceae9d5b960564abd0cba1SeasonFacet
LibShipping0x1fa93c17cfe8a33d9a195e904031e262325915710x2b6a87195446b28c404cd5d78351998a1e8b31f9SeasonFacet
LibWellMinting0x4910f9a342c79ea50a4395477cfdb11f36a010ad0x78e2a41721b97f33e13a383d15726b1ac96c2a19SeasonFacet
LibFlood0x2174762d93abebd7c4317104c26b6961d6cb3f100xd668ecc7df030202ee50f9c465db7f7da7581a48SeasonFacet
LibGerminate0x74f409bf422e33bc34d909a1233516307adb6daa0x06cc9fb93b3cefa5dc6bb5f418c7358cd3ea0a85SeasonFacet

ApprovalFacet, ConvertGettersFacet, SiloGettersFacet, GaugeGettersFacet, and FieldFacet have no externally linked libraries.

Function Changes

Event Changes