PI-3: Bug Fixes and Parameter Changes
Executed on December 5, 2024 at 02:52 UTC.
Summary
- Rain Stalk Preservation: Update the Silo such that Deposits do not lose Rain Stalk upon transfer or Convert into non-Germinating Deposits.
- AL2L Converts: Re-add Anti Lambda to Lambda (AL2L) Converts.
gmReward: Update thegmreward to properly issue Pinto when thegmfunction is called 239 to 240 seconds late.
- Flood Pods: Update Soil issuance above peg to properly account for Pods that became Harvestable due to a Flood.
- 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.
- Morning Auction Duration: Extend the duration of the Morning from 5 to 10 minutes.
- Minimum Temperature: Change the minimum Temperature at the beginning of the Morning from a fixed 1% to 1% of the Maximum Temperature.
- Maximum Temperature Increases: Reduce the Maximum Temperature increase from 3 percentage points to 2 percentage points wherever it currently increases by 3 percentage points.
- Excessively Low Pod Rate Threshold: Lower the Excessively Low Pod Rate threshold from 5% to 3%.
Links
- Implementation Commit: 6f65b5ecbe83fe07cf48982963e0203379cfaf0e
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
- Update
LibSilo.transferStalksuch thatrainRootsare transferred rather than burned upon a Deposit transfer.
- Update
LibSilo.burnActiveStalkto returndeltaRainRoots, which corresponds to the number of Rain Stalk removed when burning active Stalk.
- Add a new
LibSilo.mintRainRootsfunction that restores Rain Stalk to the user that performs the Convert.
- Update
LibConvert._withdrawTokensto return the Rain Stalk removed from the user.
- Update
LibConvert._depositTokensForConvertto take indeltaRainRoots, and to callLibSilo.mintRainRoots, ifdeltaRainRoots > 0and the output is non-Germinating.
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
- Add a new storage variable in the
Rainstruct,floodHarvestablePods.
- Update
LibFlood.handleRainto resetfloodHarvestablePodsto 0 each Season, andLibFlood.floodPodlineto store the actual Pods made Harvestable by the Flood.
- Update
Sun.stepSunto always usefloodHarvestablePodswhen calculating the newly Harvestable Pods when issuing Soil above peg.
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
- Update
LibDibbler._scaleTemperaturesuch that there is no longer a Temperature floor (previously set to 1%).
- Update
LibDibbler.morningTemperaturesuch that whendelta == 0, the function returns 1% of the Maximum Temperature.
8. Maximum Temperature Increases
- Replace
T_PLUS_3_L_MINUS_FIFTY,T_PLUS_3_L_PLUS_ONEandT_PLUS_3_L_PLUS_TWOinLibCaseswithT_PLUS_2_L_MINUS_FIFTY,T_PLUS_2_L_PLUS_ONEandT_PLUS_2_L_PLUS_TWO, respectively, which decreases the absolute Maximum Temperature increases from +3 percentage points to +2 percentage points.
- Update
s.sys.casesV2with the new case values.
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.
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.
- Doubled each Morning interval from 6 to 12 Base blocks (12 to 24 seconds), extending the auction from 5 to 10 minutes.
- Changed the initial Morning Temperature from a fixed 1% to 1% of the Maximum Temperature.
- Reduced selected Maximum Temperature increases from +3 to +2 percentage points. Initialization applied the 1.5x-to-1.2x low-Pod-Rate Soil coefficient and 5%-to-3% lower Pod Rate threshold described above.
Function Changes
- Updated
LibSilo.transferStalkto transfer Rain Roots exceeding the sender’s remaining Roots to the recipient instead of burning them from the system.
- Updated
LibSilo.burnActiveStalkto returndeltaRainRootsin addition toroots. UpdatedLibConvert._withdrawTokensto returndeltaRainRootsin addition to grown Stalk and PDV. UpdatedConvertFacetandPipelineConvertFacetto pass this value through to_depositTokensForConvert, which calls the new internalLibSilo.mintRainRootshelper to restore burned Rain Roots for non-Germinating output.
- Restored
ANTI_LAMBDA_LAMBDAdispatch inLibConvert.converttoLibLambdaConvert.antiConvert.
- Corrected the
LibIncentive.fracExpbranch cutoff from 240 to 238 seconds so thegmreward calculation covers 239–240 seconds.
- Updated
LibFlood.handleRainto resetfloodHarvestablePodsto 0 each Season andLibFlood.floodPodlineto store the actual number of Pods made Harvestable after the cap. UpdatedSun.stepSunto include that count in above-peg Soil issuance.
- Added
FieldFacet.floodHarvestablePods(), which returns the stored count.
- Updated
Sun.setSoilAbovePegto apply the 0.5x high-Pod-Rate coefficient whencaseId.mod(36) >= 27instead of>= 24. This excludes cases 24–26 within each 36-case group, where the Pod Rate is Reasonably High and Pinto’s price is above the excessive-price threshold. Those cases now use the unadjusted Soil quantity instead of half that quantity.
- Updated
LibDibbler.morningTemperatureto use 12 Base blocks per interval instead of 6. Removed the fixed 1% floor inLibDibbler._scaleTemperature. Atdelta == 0,morningTemperaturereturns 1% of the Maximum Temperature.
- Updated
LibCases.setCasesV2to use +2-percentage-point adjustments in the cases that previously used +3-percentage-point adjustments.
Event Changes
Existing event signatures were unchanged. The revised calculations changed the following emitted values.
Incentivizationnow reports the correctedgmreward inbeansfor calls 239–240 seconds late.
Soilreports soil issuance that includes Pods made Harvestable by Floods and applies the revised low- and high-Pod-Rate multiplier rules.
Sowreportspodscalculated using the revised Morning Temperature schedule and minimum.
TemperatureChangereports +2 instead of +3 inabsChangefor the revised cases.
TemperatureChangeandBeanToMaxLpGpPerBdvRatioChangereportcaseIdusing the 3% lower Pod Rate threshold instead of 5%. The ratio-change event remains conditional on no oracle failure.