The previous milestone stem should be scaled for use with the new gauge point system which uses untruncated values moving forward
Within the Beanstalk Silo, the milestone stem for a given token is the cumulative amount of grown stalk per BDV for this token at the last `stalkEarnedPerSeason` update. Previously, the milestone stem was stored in its truncated representation; however, the seed gauge system now stores the value in its untruncated form due to the new granularity of grown stalk and the frequency with which these values are updated.\\nAt the time of upgrade, the previous (truncated) milestone stem for each token should be scaled for use with the gauge point system by multiplying up by a factor of `1e6`. Otherwise, there will be a mismatch in decimals when calculating the stem tip.\\n```\\n_stemTipForToken = s.ss[token].milestoneStem +\\n    int96(s.ss[token].stalkEarnedPerSeason).mul(\\n        int96(s.season.current).sub(int96(s.ss[token].milestoneSeason))\\n    );\\n```\\n
Scale up the existing milestone stem for each token:\\n```\\nfor (uint i = 0; i < siloTokens.length; i// Add the line below\\n// Add the line below\\n) {\\n// Add the line below\\n   s.ss[siloTokens[i]].milestoneStem = int96(s.ss[siloTokens[i]].milestoneStem.mul(1e6));\\n```\\n\\n\\clearpage
The mixing of decimals between the old milestone stem (truncated) and the new milestone stem (untruncated, after the first `gm` call following the BIP-39 upgrade) breaks the existing grown stalk accounting, resulting in a loss of grown stalk for depositors.\\nProof of Concept: The previous implementation returns the cumulative stalk per BDV with 4 decimals:\\n```\\n    function stemTipForToken(address token)\\n        internal\\n        view\\n        returns (int96 _stemTipForToken)\\n    {\\n        AppStorage storage s = LibAppStorage.diamondStorage();\\n\\n        // SafeCast unnecessary because all casted variables are types smaller that int96.\\n        _stemTipForToken = s.ss[token].milestoneStem +\\n        int96(s.ss[token].stalkEarnedPerSeason).mul(\\n            int96(s.season.current).sub(int96(s.ss[token].milestoneSeason))\\n        ).div(1e6); //round here\\n    }\\n```\\n\\nWhich can be mathematically abstracted to: $$StemTip(token) = getMilestonStem(token) + (current \\ season - getMilestonStemSeason(token)) \\times \\frac{stalkEarnedPerSeason(token)}{10^{6}}$$\\nThis division by $10^{6}$ happens because the stem tip previously had just 4 decimals. This division allows backward compatibility by not considering the final 6 decimals. Therefore, the stem tip MUST ALWAYS have 4 decimals.\\nThe milestone stem is now updated in each `gm` call so long as all LP price oracles pass their respective checks. Notably, the milestone stem is now stored with 10 decimals (untruncated), hence why the second term of the abstraction has omited the `10^{6}` division in `LibTokenSilo::stemTipForTokenUntruncated`.\\nHowever, if the existing milestone stem is not escalated by $10^{6}$ then the addition performed during the upgrade and in subsequent `gm` calls makes no sense. This is mandatory to be handled within the upgrade otherwise every part of the protocol which calls `LibTokenSilo.stemTipForToken` will receive an incorrect value, except for BEAN:ETH Well LP (given it was created after the Silo v3 upgrade).\\nSome instances where this function is used include:\\n`EnrootFacet::enrootDeposit`\\n`EnrootFacet::enrootDeposits`\\n`MetaFacet::uri`\\n`ConvertFacet::_withdrawTokens`\\n`LibSilo::__mow`\\n`LibSilo::_removeDepositFromAccount`\\n`LibSilo::_removeDepositsFromAccount`\\n`Silo::_plant`\\n`TokenSilo::_deposit`\\n`TokenSilo::_transferDeposits`\\n`LibLegacyTokenSilo::_mowAndMigrate`\\n`LibTokenSilo::_mowAndMigrate`\\nAs can be observed, critical parts of the protocol are compromised, leading to further cascading issues.
```\\n_stemTipForToken = s.ss[token].milestoneStem +\\n    int96(s.ss[token].stalkEarnedPerSeason).mul(\\n        int96(s.season.current).sub(int96(s.ss[token].milestoneSeason))\\n    );\\n```\\n