PI-3: Bug Fixes and Parameter Changes

Executed on December 5, 2024 at 02:52 UTC.

Summary

  1. Rain Stalk Preservation: Update the Silo such that Deposits do not lose Rain Stalk upon transfer or Convert into non-Germinating Deposits.
  1. AL2L Converts: Re-add Anti Lambda to Lambda (AL2L) Converts.
  1. gm Reward: Update the gm reward to properly issue Pinto when the gm function is called 239 to 240 seconds late.
  1. Flood Pods: Update Soil issuance above peg to properly account for Pods that became Harvestable due to a Flood.
  1. Soil Issuance Above Peg: Change the Soil issuance above peg multiplier on Pods that became Harvestable from 1.5x to 1.2x when the Pod Rate is Excessively Low. Stop halving above-peg Soil issuance when the Pod Rate is Reasonably High and Pinto’s price is above the excessive-price threshold. Retain the 0.5x multiplier for Excessively High Pod Rates.
  1. Morning Auction Duration: Extend the duration of the Morning from 5 to 10 minutes.
  1. Minimum Temperature: Change the minimum Temperature at the beginning of the Morning from a fixed 1% to 1% of the Maximum Temperature.
  1. Maximum Temperature Increases: Reduce the Maximum Temperature increase from 3 percentage points to 2 percentage points wherever it currently increases by 3 percentage points.
  1. Excessively Low Pod Rate Threshold: Lower the Excessively Low Pod Rate threshold from 5% to 3%.

Links

Problems

1. Rain Stalk Preservation

Rain Stalk is the snapshot of Stalk holdings taken each time it begins to Rain, which determines pro rata ownership of the proceeds from the Flood sale. Rain Stalk was erroneously burned upon the transfer or Convert of a Deposit.

2. AL2L Converts

AL2L Converts were disabled in PI-2 due to a bug where all Rain Stalk was erroneously removed as a result of an AL2L Convert while it was Raining.

3. gm Reward

The gm reward was 0 Pinto when the gm function was called 239 to 240 seconds after it could have been called.

4. Flood Pods

Soil issuance above peg is intended to be a function of the number of Pods that became Harvestable at the beginning of the Season. Pods that became Harvestable due to a Flood were erroneously omitted from this calculation.

5. Soil Issuance Above Peg

Soil issuance above peg was too aggressive when the Pod Rate was Excessively Low. The 0.5x multiplier intended for Excessively High Pod Rates also applied when the Pod Rate was Reasonably High and Pinto’s price was above the excessive-price threshold. This incorrectly halved Soil issuance in those cases.

6. Morning Auction Duration

The previous 5 minute duration of the Morning did not give sufficient time to participants in the Morning Auction who are submitting transactions manually to participate.

7. Minimum Temperature

The minimum Temperature of 1% at the beginning of the Morning resulted in paying more interest than necessary at lower Maximum Temperatures.

8. Maximum Temperature Increases

The Maximum Temperature increased too quickly below peg, which disincentivized lending to the protocol in an efficient fashion and resulted in the protocol overpaying for loans.

9. Excessively Low Pod Rate Threshold

The Excessively Low Pod Rate threshold was too high.

Solutions

1. Rain Stalk Preservation

2. AL2L Converts

Re-add ANTI_LAMBDA_LAMBDA as a valid Convert type with a fix to the bug that removed all of the Rain Stalk during an AL2L Convert instead of reducing it by the appropriate number.

3. gm Reward

Update LibIncentive.fracExp to properly return the scaled reward when the gm function is 239 to 240 seconds late.

4. Flood Pods

5. Soil Issuance Above Peg

Update soilCoefficientLow in the evaluationParameters struct from 1.5e18 to 1.2e18 (i.e., 1.5x -> 1.2x). Update Sun.setSoilAbovePeg to apply the 0.5x Soil multiplier only when the Pod Rate is Excessively High. When the Pod Rate is Reasonably High and Pinto’s price is above the excessive-price threshold, issue the unadjusted Soil quantity instead of halving it.

6. Morning Auction Duration

Update delta in LibDibbler.morningTemperature such that each interval during the Morning lasts 24 seconds (12 blocks) instead of 12 seconds (6 blocks), extending the length of the Morning from 5 minutes to 10 minutes.

7. Minimum Temperature

8. Maximum Temperature Increases

9. Excessively Low Pod Rate Threshold

Update podRateLowerBound in the evaluationParameters struct from 0.05e18 (5%) to 0.03e18 (3%).

Rationale

1. Rain Stalk Preservation

Preserving Rain Roots through Deposit transfers and Converts into non-Germinating Deposits preserves ownership of Flood proceeds while allowing those operations.

2. AL2L Converts

Restoring AL2L Converts with the Rain Stalk fix restores their functionality without removing all of a user’s Rain Stalk.

3. gm Reward

Correcting the reward calculation preserves the intended incentive to call gm throughout the 239-to-240-second interval.

4. Flood Pods

Including Pods made Harvestable by a Flood keeps above-peg Soil issuance consistent with the total number of Pods made Harvestable.

5. Soil Issuance Above Peg

There is no need for the protocol to so aggressively try to increase the Pod Rate when the protocol has an excessively low Pod Rate. Removing the unintended 0.5x multiplier approximately doubles Soil issuance in the affected Reasonably High Pod Rate cases, restoring the quantity calculated from newly Harvestable Pods and the Maximum Temperature. The 0.5x reduction remains in place when the Pod Rate is Excessively High, when the protocol more strongly limits new debt.

6. Morning Auction Duration

By doubling the duration of the Morning Auction – and each interval of the auction – farmers will have more opportunity to participate manually, which should generally result in the protocol having to pay lower interest rates. A longer Morning Auction has minimal downside because the protocol will still offer Soil at the Maximum Temperature for 50 minutes during each Season, which leaves ample time for farmers to participate once the Morning Auction ends.

7. Minimum Temperature

The hard set minimum of 1% Temperature during the Morning Auction reduced the effectiveness of the auction during periods where the Maximum Temperature was very low. In instances where the protocol has little to no outstanding debt, it is highly plausible that some farmers would be willing to lend to the protocol at less than 1%. This minimum made it such that even if farmers were willing to do so, they would be unable to, resulting in the protocol potentially overpaying to issue debt.

8. Maximum Temperature Increases

The protocol raised the Maximum Temperature too quickly. By changing the Maximum Temperature increases from 3 percentage points to 2 percentage points it should decrease the rate the protocol needs to pay to attract creditors without decreasing its ability to do so.

The protocol was experiencing a nearly constantly increasing Maximum Temperature, which poses a short term threat to the protocol because it creates an incentive for potential creditors to wait for a higher interest rate, and a long term threat because if the Maximum Temperature increases in perpetuity, the protocol may eventually collapse under the weight of excessive outstanding debt.

By lowering the rate at which the Maximum Temperature increases, it should create a more efficient market for Soil in the short term and give contributors more time to design a better mechanism to prevent runaway Maximum Temperature in the long run.

9. Excessively Low Pod Rate Threshold

The Excessively Low Pod Rate threshold indicates the rate below which the protocol strongly prefers to take on more debt. It is likely safer for the protocol to be slightly more conservative and set this threshold to be 3% instead of 5%.

Contract Changes

Initialization

Executed InitPI3.init() at 0xa35c864c9154ef9fccdc037c489ee8bc30631477. It updated podRateLowerBound from 0.05e18 (5%) to 0.03e18 (3%), soilCoefficientLow from 1.5e18 (1.5x) to 1.2e18 (1.2x), and s.sys.casesV2 with the revised Temperature adjustments. If lastSopSeason equaled the current Season, it added totalSupply / 1000 to Soil.

Facet Changes

ApprovalFacet, ConvertGettersFacet, ClaimFacet, SiloFacet, SiloGettersFacet and SeasonGettersFacet were replaced without changes to their facet source files. Shared-library changes are described below.

FacetActionPrevious ImplementationNew Implementation
ConvertFacetReplace0xf07c34e81d56ff02c01869bf1f833c07bb52bf2b0x7bab1d09727be8f0427c6dd1d503b3d4ba697d93
PipelineConvertFacetReplace0x9d108e7f673c773ac196bde4bebc6758088d2e590x508320dcc2b4e9f79555bcae1478e6ce736b22ab
FieldFacetAddN/A0x0ab2b647fdfaa3abffca2a10fe78eb0ded438faf
FieldFacetReplace0x6430f859a3b8825d25382ebc7941fcd7196357970x0ab2b647fdfaa3abffca2a10fe78eb0ded438faf
SeasonFacetReplace0x269c8386be50c176f03355c7c7925356fdef9f840x6ea855d9473168f4540d4818976ea814ecbf3456
ApprovalFacetReplace0x540e776e8f0eac5dfa82110b827cb6cea67056690xa7df4372b0404cd468703451950e2af8615996b2
ConvertGettersFacetReplace0x518f109e57c872f8acec3b3e9a6ce5f5e8e800970xb70708268fff1b6038def6f7d29a3bee037e901c
ClaimFacetReplace0xea0aad388e2df06f90a218ca2eda199294fbaadb0x28bcfb5ad84dd460f2fd080dfd706105b8fc21c6
SiloFacetReplace0x3235540bb01ef11e4208a9b99c2f2dd9860e721a0xd2d3d44edbbc66ef90b29627dfd0a06d3ca0cad4
SiloGettersFacetReplace0x039ec53bb37f8fe240798e3591d9439c68e72b7b0x6abfe707418d80a6e06b77853ed6c098b8af6711
SeasonGettersFacetReplace0x8b1ba2ea90916eca3d5b0ba428a8c5909768492a0xd0813e2378a73b7cb49bd4ff6a4bf67edcea1264

Other Contract / Parameter Changes

Externally Linked Libraries

The table lists the external library deployments linked by the replaced facets. Where previous deployments differed by facet, the previous address is labeled with its consuming facets.

FieldFacet, ApprovalFacet, ConvertGettersFacet and SiloGettersFacet had no externally linked libraries in either implementation.

LibPipelineConvert, LibTokenSilo, LibEvaluate, LibGauge, LibShipping, LibWellMinting and LibGerminate were redeployed with unchanged library source files. Their new addresses do not indicate additional source changes beyond those described below.

LibraryPrevious ImplementationNew ImplementationUsed By
LibConvert0x67e19ab71b645b8b42062b2a5c8e49ef900fee9e0xcce6631b13ee44ad9d8146241b20f10c1a803aa2ConvertFacet
LibPipelineConvert0x2fc411d1ed590416ec2bc398f624bf462b60ff49 (ConvertFacet); 0x4917dcbafc47b57b9ec004424a44ccdc5834d054 (PipelineConvertFacet)0xb387ad744cc1a80ab629eea5ca15459076719a7aConvertFacet, PipelineConvertFacet
LibSilo0x453c79a1c29d81b67b3be4e2b8810674f63606d8 (ConvertFacet); 0x351ca256f86c10b01f2640f22ca379cf1e74d8e2 (PipelineConvertFacet, ClaimFacet, SiloFacet)0x5a686e6024d1d40994ae99979ceb63bf67724b04ConvertFacet, PipelineConvertFacet, ClaimFacet, SiloFacet
LibTokenSilo0x1915dcd16475dd25e2f5588888421cf80fc8d116 (ConvertFacet); 0xbbe1d3e7bb0b50d1999f631674efd5446881612a (PipelineConvertFacet, ClaimFacet, SiloFacet)0x0da233676f46427c31928f5f85678d6737f4ec7eConvertFacet, PipelineConvertFacet, ClaimFacet, SiloFacet
LibEvaluate0x7f1770fa1b43abdbe8095295ecae37c00d4ba7f80x7a7d5a8899f9d68530ef3c551b9cb5610bc9bd02SeasonFacet
LibGauge0xcd376159cfa7ff6c60a3b6d55e2ce75cec5156690x6c2736cfc57c1328b7d3db611812297c9754e230SeasonFacet
LibIncentive0x86da3aba20454a441eceae9d5b960564abd0cba10xeb9bd84e354e68142e8e996823887edb4dfcf433SeasonFacet
LibShipping0x2b6a87195446b28c404cd5d78351998a1e8b31f90x64d40771f9f6490afe20c135dc07ea48b8addc78SeasonFacet
LibWellMinting0x78e2a41721b97f33e13a383d15726b1ac96c2a19 (SeasonFacet); 0x4910f9a342c79ea50a4395477cfdb11f36a010ad (SeasonGettersFacet)0x7124f182847880f4961de89068b249c3299304afSeasonFacet, SeasonGettersFacet
LibFlood0xd668ecc7df030202ee50f9c465db7f7da7581a480xed513e167369af0119090d67b8910c02b2b468f6SeasonFacet
LibGerminate0x06cc9fb93b3cefa5dc6bb5f418c7358cd3ea0a850x384374407a64aa24d3335ff12c870debaa04c3e5SeasonFacet

Function Changes

Event Changes

Existing event signatures were unchanged. The revised calculations changed the following emitted values.