From 1ecb60a1e2aee572950a158d192d30136ecfad3e Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:02:45 -0600 Subject: [PATCH 01/25] 1 --- protocol/contracts/beanstalk/silo/BDVFacet.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/protocol/contracts/beanstalk/silo/BDVFacet.sol b/protocol/contracts/beanstalk/silo/BDVFacet.sol index 76848f2162..a00eb153e7 100644 --- a/protocol/contracts/beanstalk/silo/BDVFacet.sol +++ b/protocol/contracts/beanstalk/silo/BDVFacet.sol @@ -18,6 +18,9 @@ import "contracts/libraries/Well/LibWellBdv.sol"; contract BDVFacet { using SafeMath for uint256; + /** + * @dev Returns the BDV of a given `amount` of Bean:3Crv LP tokens. + */ function curveToBDV(uint256 amount) public view returns (uint256) { return LibBeanMetaCurve.bdv(amount); } From fee9ee8d15059d50ba8e82cbd199cba765c792c1 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:03:24 -0600 Subject: [PATCH 02/25] 2 --- protocol/contracts/beanstalk/AppStorage.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/contracts/beanstalk/AppStorage.sol b/protocol/contracts/beanstalk/AppStorage.sol index e7c22c787b..2109b1e444 100644 --- a/protocol/contracts/beanstalk/AppStorage.sol +++ b/protocol/contracts/beanstalk/AppStorage.sol @@ -424,7 +424,7 @@ contract Storage { * uint256 percentOfDepositedBdv * ) external view returns (uint256); * ``` - * @param gpSelector The encoded liquidityWeight function selector for the token that pertains to + * @param lwSelector The encoded liquidityWeight function selector for the token that pertains to * an external view Beanstalk function with the following signature `function liquidityWeight()` * @param optimalPercentDepositedBdv The target percentage of the total LP deposited BDV for this token. 6 decimal precision. * @param gaugePoints the amount of Gauge points this LP token has in the LP Gauge. Only used for LP whitelisted assets. From 12144b72363e3be00669f2e19b443099a4bf7c21 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:04:56 -0600 Subject: [PATCH 03/25] 3 --- protocol/contracts/libraries/Silo/LibGerminate.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index e28700d132..8d5b798703 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -76,6 +76,9 @@ library LibGerminate { function endTotalGermination(uint32 season, address[] memory tokens) internal { AppStorage storage s = LibAppStorage.diamondStorage(); + // germination can only occur after season 3. + if(season < 2) return; + // base roots are used if there are no roots in the silo. // root calculation is skipped if no deposits have been made // in the season. From 9b0f1d2afcbce0a7eca1c3cc2757b2bda78e4c8c Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:06:09 -0600 Subject: [PATCH 04/25] 4 --- .../beanstalk/silo/SiloFacet/SiloGettersFacet.sol | 2 +- protocol/contracts/libraries/Silo/LibGerminate.sol | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index 1b27aee289..bba848ef05 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -233,7 +233,7 @@ contract SiloGettersFacet is ReentrancyGuard { /** * @notice Returns the total germinating roots for a season. */ - function getGerminatingRootsForSeason(uint32 season) external view returns (uint256) { + function claimGerminatingRootsForSeason(uint32 season) external view returns (uint256) { return s.unclaimedGerminating[season].roots; } diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index 8d5b798703..3f9de74cfb 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -158,14 +158,14 @@ library LibGerminate { // if last mowed season is not equal to current season - 1, if (firstStalk > 0 && lastMowedSeason != currentSeason.sub(1)) { germinatingStalk = firstStalk; - roots = getGerminatingRoots(account, lastMowedSeason, firstStalk, lastUpdateOdd); + roots = claimGerminatingRoots(account, lastMowedSeason, firstStalk, lastUpdateOdd); } // check to end germination for second stalk. if (secondStalk > 0) { germinatingStalk = germinatingStalk.add(secondStalk); roots = roots.add( - getGerminatingRoots(account, lastMowedSeason.sub(1), secondStalk, !lastUpdateOdd) + claimGerminatingRoots(account, lastMowedSeason.sub(1), secondStalk, !lastUpdateOdd) ); } @@ -179,7 +179,7 @@ library LibGerminate { } /** - * @notice returns the germinating roots of an account, + * @notice Claims the germinating roots of an account, * as well as clears the germinating stalk and roots. * * @param account address of the account to end germination for. @@ -187,7 +187,7 @@ library LibGerminate { * @param stalk the stalk to calculate the germinating roots for. * @param clearOdd whether to clear the odd or even germinating stalk. */ - function getGerminatingRoots( + function claimGerminatingRoots( address account, uint32 season, uint128 stalk, From a8eff77ab97f0d7445536d2bc18b262598bd1757 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:19:28 -0600 Subject: [PATCH 05/25] 5 --- protocol/contracts/libraries/Silo/LibGerminate.sol | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index 3f9de74cfb..41c96dfde1 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -170,12 +170,14 @@ library LibGerminate { } // increment users stalk and roots. - s.a[account].s.stalk = s.a[account].s.stalk.add(germinatingStalk); - s.a[account].roots = s.a[account].roots.add(roots); + if (germinatingStalk > 0) { + s.a[account].s.stalk = s.a[account].s.stalk.add(germinatingStalk); + s.a[account].roots = s.a[account].roots.add(roots); - // emit events. Active stalk is incremented, germinating stalk is decremented. - emit LibSilo.StalkBalanceChanged(account, int256(germinatingStalk), int256(roots)); - emit FarmerGerminatingStalkBalanceChanged(account, -int256(germinatingStalk)); + // emit events. Active stalk is incremented, germinating stalk is decremented. + emit LibSilo.StalkBalanceChanged(account, int256(germinatingStalk), int256(roots)); + emit FarmerGerminatingStalkBalanceChanged(account, -int256(germinatingStalk)); + } } /** From 011a3386ba9e3b905fd388ebcea83b96d5c65fd7 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:20:10 -0600 Subject: [PATCH 06/25] 6 --- .../silo/SiloFacet/SiloGettersFacet.sol | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index bba848ef05..4dc0c65e3c 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -176,6 +176,13 @@ contract SiloGettersFacet is ReentrancyGuard { return s.unclaimedGerminating[season].stalk; } + /** + * @notice Returns the total germinating roots for a season. + */ + function getGerminatingRootsForSeason(uint32 season) external view returns (uint256) { + return s.unclaimedGerminating[season].roots; + } + /** * @notice returns the stalk that is currently in the germination process. */ @@ -213,6 +220,19 @@ contract SiloGettersFacet is ReentrancyGuard { ); } + /** + * @notice returns the amount of stalk that will finish germinating upon a silo interaction. + */ + function balanceOfFinishedGerminatingStalkAndRoots( + address account + ) external view returns (uint256 gStalk, uint256 gRoots) { + (gStalk, gRoots) = LibGerminate.getFinishedGerminatingStalkAndRoots( + account, + s.a[account].lastUpdate, + s.season.current + ); + } + /** * @notice gets the even germinating amount and bdv for a given `token`. */ @@ -230,13 +250,6 @@ contract SiloGettersFacet is ReentrancyGuard { return s.s.roots; } - /** - * @notice Returns the total germinating roots for a season. - */ - function claimGerminatingRootsForSeason(uint32 season) external view returns (uint256) { - return s.unclaimedGerminating[season].roots; - } - /** * @notice Returns the total supply of Earned Beans. * @dev Beanstalk's "supply" of Earned Beans is a subset of the total Bean @@ -353,7 +366,6 @@ contract SiloGettersFacet is ReentrancyGuard { view returns (uint256 beans) { - (uint256 germinatingStalk, uint256 germinatingRoots) = LibGerminate.getFinishedGerminatingStalkAndRoots( account, s.a[account].lastUpdate, From 75ddb8a55d942dd2f5c0f47b8c559a501e9deeca Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:21:28 -0600 Subject: [PATCH 07/25] 7 --- .../beanstalk/silo/SiloFacet/SiloGettersFacet.sol | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index 4dc0c65e3c..81d6795d2f 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -170,17 +170,10 @@ contract SiloGettersFacet is ReentrancyGuard { } /** - * @notice Returns the unclaimed germinating stalk for a season. + * @notice Returns the unclaimed germinating stalk and roots for a season. */ - function getGerminatingStalkForSeason(uint32 season) external view returns (uint256) { - return s.unclaimedGerminating[season].stalk; - } - - /** - * @notice Returns the total germinating roots for a season. - */ - function getGerminatingRootsForSeason(uint32 season) external view returns (uint256) { - return s.unclaimedGerminating[season].roots; + function getGerminatingStalkAndRootsForSeason(uint32 season) external view returns (uint256, uint256) { + return (s.unclaimedGerminating[season].stalk, s.unclaimedGerminating[season].roots); } /** From a901a5fd32bc140c1bcf37142beb83a142f7a738 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:22:23 -0600 Subject: [PATCH 08/25] 8 --- .../contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol | 6 +++--- protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol | 6 +++--- protocol/contracts/mocks/mockFacets/MockSiloFacet.sol | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index 81d6795d2f..690a419d1e 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -496,7 +496,7 @@ contract SiloGettersFacet is ReentrancyGuard { view returns (int96 stem) { - uint256 seedsPerBdv = getSeedsPerToken(token).mul(1e6); + uint256 seedsPerBdv = getLegacySeedsPerToken(token).mul(1e6); stem = LibLegacyTokenSilo.seasonToStem(seedsPerBdv, season); } @@ -506,8 +506,8 @@ contract SiloGettersFacet is ReentrancyGuard { * even after the token is whitelisted. * kept for legacy reasons. */ - function getSeedsPerToken(address token) public view virtual returns (uint256) { - return LibLegacyTokenSilo.getSeedsPerToken(token); + function getLegacySeedsPerToken(address token) public view virtual returns (uint256) { + return LibLegacyTokenSilo.getLegacySeedsPerToken(token); } /** diff --git a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol index e94097e027..7cee80c503 100644 --- a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol @@ -298,7 +298,7 @@ library LibLegacyTokenSilo { // calculate how much stalk has grown for this deposit perDepositData.grownStalk = _calcGrownStalkForDeposit( - crateBDV.mul(getSeedsPerToken(address(perTokenData.token))), + crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))), perDepositData.season ); @@ -329,7 +329,7 @@ library LibLegacyTokenSilo { // add to running total of seeds migrateData.totalSeeds = migrateData.totalSeeds.add( - crateBDV.mul(getSeedsPerToken(address(perTokenData.token))).toUint128() + crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))).toUint128() ); // emit legacy RemoveDeposit event @@ -462,7 +462,7 @@ library LibLegacyTokenSilo { * * constants are used in favor of reading from storage for gas savings. */ - function getSeedsPerToken(address token) internal pure returns (uint256) { + function getLegacySeedsPerToken(address token) internal pure returns (uint256) { if (token == C.BEAN) { return 2; } else if (token == C.UNRIPE_BEAN) { diff --git a/protocol/contracts/mocks/mockFacets/MockSiloFacet.sol b/protocol/contracts/mocks/mockFacets/MockSiloFacet.sol index cf86ff1385..a4f3021448 100644 --- a/protocol/contracts/mocks/mockFacets/MockSiloFacet.sol +++ b/protocol/contracts/mocks/mockFacets/MockSiloFacet.sol @@ -71,7 +71,7 @@ contract MockSiloFacet is SiloFacet { // bdv increment of all unripe assets. Thus, we increment total deposited here for testing purposes. incrementTotalDepositedBDV(C.UNRIPE_LP, bdv); - uint256 seeds = bdv.mul(LibLegacyTokenSilo.getSeedsPerToken(C.UNRIPE_LP)); + uint256 seeds = bdv.mul(LibLegacyTokenSilo.getLegacySeedsPerToken(C.UNRIPE_LP)); uint256 stalk = bdv.mul(s.ss[C.UNRIPE_LP].stalkIssuedPerBdv).add(stalkRewardLegacy(seeds, s.season.current - _s)); // not germinating because this is a old deposit. LibSilo.mintActiveStalk(msg.sender, stalk); @@ -89,7 +89,7 @@ contract MockSiloFacet is SiloFacet { // bdv increment of all unripe assets. Thus, we increment total deposited here for testing purposes. incrementTotalDepositedBDV(C.UNRIPE_BEAN, partialAmount); - uint256 seeds = partialAmount.mul(LibLegacyTokenSilo.getSeedsPerToken(C.UNRIPE_BEAN)); + uint256 seeds = partialAmount.mul(LibLegacyTokenSilo.getLegacySeedsPerToken(C.UNRIPE_BEAN)); uint256 stalk = partialAmount.mul(s.ss[C.UNRIPE_BEAN].stalkIssuedPerBdv).add(stalkRewardLegacy(seeds, s.season.current - _s)); LibSilo.mintActiveStalk(msg.sender, stalk); From b79419b905d3c27f91ee630e25692529c7a569ca Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:37:27 -0600 Subject: [PATCH 09/25] 9 --- .../silo/SiloFacet/SiloGettersFacet.sol | 64 ++++++++++++++----- .../contracts/libraries/Silo/LibGerminate.sol | 2 +- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index 690a419d1e..f50292af17 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -186,12 +186,17 @@ contract SiloGettersFacet is ReentrancyGuard { } /** - * @notice gets the total amount of bdv germinating for a given `token`. + * @notice returns the newly and partially germinating stalk. + * partially germinated stalk will finish germinating after 1 `sunrise` call. + * newly germinated stalk will finish germinating after 2 `sunrise` calls. */ - function getTotalGerminatingBdv(address token) external view returns (uint256) { - return s.oddGerminating.deposited[token].bdv.add( - s.evenGerminating.deposited[token].bdv - ); + function getNewAndPartiallyGerminatedTotalStalk() external view returns ( + uint256 partiallyGerminatedStalk, uint256 newlyGerminatedStalk + ) { + return ( + s.unclaimedGerminating[s.season.current - 1].stalk, + s.unclaimedGerminating[s.season.current].stalk + ) ; } /** @@ -202,6 +207,15 @@ contract SiloGettersFacet is ReentrancyGuard { s.evenGerminating.deposited[token].amount ); } + + /** + * @notice gets the total amount of bdv germinating for a given `token`. + */ + function getTotalGerminatingBdv(address token) external view returns (uint256) { + return s.oddGerminating.deposited[token].bdv.add( + s.evenGerminating.deposited[token].bdv + ); + } /** * @notice gets the odd germinating amount and bdv for a given `token`. @@ -213,6 +227,16 @@ contract SiloGettersFacet is ReentrancyGuard { ); } + /** + * @notice gets the even germinating amount and bdv for a given `token`. + */ + function getEvenGerminating(address token) external view returns (uint256, uint256) { + return( + s.evenGerminating.deposited[token].amount, + s.evenGerminating.deposited[token].bdv + ); + } + /** * @notice returns the amount of stalk that will finish germinating upon a silo interaction. */ @@ -226,16 +250,6 @@ contract SiloGettersFacet is ReentrancyGuard { ); } - /** - * @notice gets the even germinating amount and bdv for a given `token`. - */ - function getEvenGerminating(address token) external view returns (uint256, uint256) { - return( - s.evenGerminating.deposited[token].amount, - s.evenGerminating.deposited[token].bdv - ); - } - /** * @notice Returns the total supply of Roots. */ @@ -288,6 +302,26 @@ contract SiloGettersFacet is ReentrancyGuard { return germinatingStalk; } + /** + * @notice returns the amount of newly and partially germinated stalk that an account has. + * @dev stalk here may have already finished the germination process but needs a silo + * interaction to update. + */ + function balanceOfNewAndPartiallyGerminatedStalk( + address account + ) external view returns (uint256 paritallyGerminatedStalk, uint256 newlyGerminatedStalk) { + // if the last mowed season is less than the current season - 1, + // then there are no germinating stalk and roots (as all germinating assets have finished). + if (s.a[account].lastUpdate < s.season.current - 1) { + return (0, 0); + } else { + (newlyGerminatedStalk, paritallyGerminatedStalk) = LibGerminate.getGerminatingStalk( + account, + LibGerminate.isSeasonOdd(s.a[account].lastUpdate) + ); + } + } + /** * @notice Returns the balance of Roots for `account`. * @dev Roots within Beanstalk are entirely separate from the diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index 41c96dfde1..b1c495fdaa 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -241,7 +241,7 @@ library LibGerminate { function getGerminatingStalk( address account, bool lastUpdateOdd - ) private view returns (uint128 firstStalk, uint128 secondStalk) { + ) internal view returns (uint128 firstStalk, uint128 secondStalk) { AppStorage storage s = LibAppStorage.diamondStorage(); if (lastUpdateOdd) { firstStalk = s.a[account].farmerGerminating.odd; From 90a7308e30a05179e94c5eff21c471cf4e12ef45 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:38:51 -0600 Subject: [PATCH 10/25] 10 --- .../beanstalk/silo/SiloFacet/SiloGettersFacet.sol | 3 +-- protocol/contracts/libraries/Silo/LibGerminate.sol | 14 +++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index f50292af17..47da5946b9 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -295,11 +295,10 @@ contract SiloGettersFacet is ReentrancyGuard { * is not included. */ function balanceOfGerminatingStalk(address account) external view returns (uint256) { - (uint256 germinatingStalk, ) = LibGerminate.getCurrentGerminatingStalkAndRoots( + return LibGerminate.getCurrentGerminatingStalk( account, s.a[account].lastUpdate ); - return germinatingStalk; } /** diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index b1c495fdaa..e2320625ff 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -290,30 +290,26 @@ library LibGerminate { } /** - * @notice returns the stalk and roots currently germinating. - * Does not include germinating stalk and roots that will finish germinating + * @notice returns the stalk currently germinating for an account. + * Does not include germinating stalk that will finish germinating * upon an interaction with the silo. */ - function getCurrentGerminatingStalkAndRoots( + function getCurrentGerminatingStalk( address account, uint32 lastMowedSeason - ) internal view returns (uint256 germinatingStalk, uint256 germinatingRoots) { + ) internal view returns (uint256 germinatingStalk) { AppStorage storage s = LibAppStorage.diamondStorage(); // if the last mowed season is less than the current season - 1, // then there are no germinating stalk and roots (as all germinating assets have finished). if (lastMowedSeason < s.season.current.sub(1)) { - return (0, 0); + return 0; } else { (uint128 firstStalk, uint128 secondStalk) = getGerminatingStalk( account, isSeasonOdd(lastMowedSeason) ); - germinatingRoots = calculateGerminatingRoots(lastMowedSeason, firstStalk); germinatingStalk = firstStalk.add(secondStalk); - germinatingRoots = germinatingRoots.add( - calculateGerminatingRoots(lastMowedSeason.sub(1), secondStalk) - ); } } From ea16972b0edc97e5ee2f6e31e157dee2c263bf5d Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:39:20 -0600 Subject: [PATCH 11/25] 11 --- protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol b/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol index 819423fd37..8d1fa13c0f 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol @@ -450,7 +450,7 @@ contract TokenSilo is Silo { token, stems, amounts, - ar.active.tokens.add(ar.odd.tokens).add(ar.even.tokens), + ar.active.tokens, bdvs ); From 87d51ed8e2c887166feba3e10570e596a6acd934 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:45:03 -0600 Subject: [PATCH 12/25] 12 --- protocol/contracts/libraries/Silo/LibSilo.sol | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 33bd719392..9d99382f24 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -376,12 +376,15 @@ library LibSilo { ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); uint256 stalkPerBDV = s.ss[token].stalkIssuedPerBdv; + + // a germinating deposit may have active grown stalk, + // but no active stalk from bdv. if (ar.active.stalk > 0) { ar.active.stalk = ar.active.stalk.add(ar.active.bdv.mul(stalkPerBDV)); transferStalk(sender, recipient, ar.active.stalk); } - if (ar.odd.stalk > 0) { + if (ar.odd.bdv > 0) { ar.odd.stalk = ar.odd.stalk.add(ar.odd.bdv.mul(stalkPerBDV)); transferGerminatingStalk( sender, @@ -391,7 +394,7 @@ library LibSilo { ); } - if (ar.even.stalk > 0) { + if (ar.even.bdv > 0) { ar.even.stalk = ar.even.stalk.add(ar.even.bdv.mul(stalkPerBDV)); transferGerminatingStalk( sender, From 1218fe7ef22649fc4b0773308c9ae1287c13dd7b Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:45:45 -0600 Subject: [PATCH 13/25] 13 --- protocol/contracts/beanstalk/silo/SiloFacet/Silo.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/Silo.sol b/protocol/contracts/beanstalk/silo/SiloFacet/Silo.sol index ff778749e3..e092c08211 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/Silo.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/Silo.sol @@ -152,7 +152,7 @@ contract Silo is ReentrancyGuard { * with an amount of 0. */ function _claimPlenty(address account) internal { - // Plenty is earned in the form of weth. + // Plenty is earned in the form of the sop token. uint256 plenty = s.a[account].sop.plenty; IWell well = IWell(s.sopWell); IERC20[] memory tokens = well.tokens(); From 5f4f3b497aa8985a9bec0f2756a4e3ec31b4fdc9 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:46:23 -0600 Subject: [PATCH 14/25] 14 --- protocol/contracts/beanstalk/silo/ConvertFacet.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/ConvertFacet.sol b/protocol/contracts/beanstalk/silo/ConvertFacet.sol index f4768da7ac..8af7523a67 100644 --- a/protocol/contracts/beanstalk/silo/ConvertFacet.sol +++ b/protocol/contracts/beanstalk/silo/ConvertFacet.sol @@ -132,9 +132,7 @@ contract ConvertFacet is ReentrancyGuard { while ((i < stems.length) && (a.active.tokens < maxTokens)) { // skip any stems that are germinating, due to the ability to // circumvent the germination process. - // subtract amount from maxTokens. if (germStem.germinatingStem <= stems[i]) { - maxTokens = maxTokens <= amounts[i] ? 0 : maxTokens.sub(amounts[i]); i++; continue; } From b0aa9c4f54b3153d117b0eeb6ad6e96cd3539fef Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:46:46 -0600 Subject: [PATCH 15/25] 15 --- protocol/contracts/beanstalk/silo/ConvertFacet.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/contracts/beanstalk/silo/ConvertFacet.sol b/protocol/contracts/beanstalk/silo/ConvertFacet.sol index 8af7523a67..09cc5f38e9 100644 --- a/protocol/contracts/beanstalk/silo/ConvertFacet.sol +++ b/protocol/contracts/beanstalk/silo/ConvertFacet.sol @@ -245,4 +245,4 @@ contract ConvertFacet is ReentrancyGuard { LibTokenSilo.Transfer.emitTransferSingle ); } -} +} \ No newline at end of file From 1281a4d14799ae559d5c3eadfca283d284e04913 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:48:13 -0600 Subject: [PATCH 16/25] 16 --- .../beanstalk/sun/GaugePointFacet.sol | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/protocol/contracts/beanstalk/sun/GaugePointFacet.sol b/protocol/contracts/beanstalk/sun/GaugePointFacet.sol index 42e0289d4c..1d10a156c0 100644 --- a/protocol/contracts/beanstalk/sun/GaugePointFacet.sol +++ b/protocol/contracts/beanstalk/sun/GaugePointFacet.sol @@ -19,14 +19,18 @@ contract GaugePointFacet { uint256 private constant ONE_POINT = 1e18; uint256 private constant MAX_GAUGE_POINTS = 1000e18; + uint256 private constant UPPER_THRESHOLD = 10001; + uint256 private constant LOWER_THRESHOLD = 9999; + uint256 private constant THRESHOLD_PRECISION = 10000; + /** * @notice DefaultGaugePointFunction * is the default function to calculate the gauge points * of an LP asset. - * + * * @dev If % of deposited BDV is .01% within range of optimal, * keep gauge points the same. - * + * * Cap gaugePoints to MAX_GAUGE_POINTS to avoid runaway gaugePoints. */ function defaultGaugePointFunction( @@ -34,11 +38,17 @@ contract GaugePointFacet { uint256 optimalPercentDepositedBdv, uint256 percentOfDepositedBdv ) external pure returns (uint256 newGaugePoints) { - if (percentOfDepositedBdv > optimalPercentDepositedBdv.mul(10001).div(10000)) { + if ( + percentOfDepositedBdv > + optimalPercentDepositedBdv.mul(UPPER_THRESHOLD).div(THRESHOLD_PRECISION) + ) { // gauge points cannot go below 0. if (currentGaugePoints <= ONE_POINT) return 0; newGaugePoints = currentGaugePoints.sub(ONE_POINT); - } else if (percentOfDepositedBdv < optimalPercentDepositedBdv.mul(9999).div(10000)) { + } else if ( + percentOfDepositedBdv < + optimalPercentDepositedBdv.mul(LOWER_THRESHOLD).div(THRESHOLD_PRECISION) + ) { newGaugePoints = currentGaugePoints.add(ONE_POINT); // Cap gaugePoints to MAX_GAUGE_POINTS if it exceeds. From 0df04a2e672f8549fe6e62118c414d7708d2a661 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:48:30 -0600 Subject: [PATCH 17/25] 17 --- protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol index 0ba98fb451..87ba3e95ea 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol @@ -52,7 +52,6 @@ contract SeasonFacet is Weather { LibGerminate.endTotalGermination(season, LibWhitelistedTokens.getWhitelistedTokens()); LibGauge.stepGauge(); stepSun(deltaB, caseId); - // germination should end after beans are issued. return incentivize(account, initialGasLeft, mode); } From f4a724f96f0f75bd724f0b67ba8bc4f9c89529c8 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:57:54 -0600 Subject: [PATCH 18/25] 18 --- protocol/abi/Beanstalk.json | 6 +-- .../sun/SeasonFacet/SeasonGettersFacet.sol | 47 ++++++++++++------- protocol/test/Gauge.test.js | 6 +-- protocol/test/SeedGaugeMainnet.test.js | 2 +- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/protocol/abi/Beanstalk.json b/protocol/abi/Beanstalk.json index 1cfc79d661..17e3e14498 100644 --- a/protocol/abi/Beanstalk.json +++ b/protocol/abi/Beanstalk.json @@ -7027,7 +7027,7 @@ }, { "inputs": [], - "name": "getBeanEthTwaUsdLiquidity", + "name": "getTwaLiquidityForWell", "outputs": [ { "internalType": "uint256", @@ -7239,7 +7239,7 @@ }, { "inputs": [], - "name": "getStalkPerGp", + "name": "", "outputs": [ { "internalType": "uint256", @@ -7278,7 +7278,7 @@ }, { "inputs": [], - "name": "getWeightedBeanEthTwaUsdLiquidity", + "name": "getWeightedTwaLiquidityForWell", "outputs": [ { "internalType": "uint256", diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol index e6b4b104d8..be386c11f4 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol @@ -221,7 +221,7 @@ contract SeasonGettersFacet { /** * @notice Gets the stalk per Gauge Point. Used In gauge system. */ - function getStalkPerGp() external view returns (uint256) { + function getGrownStalkIssuedPerGp() external view returns (uint256) { address[] memory lpGaugeTokens = LibWhitelistedTokens.getWhitelistedLpTokens(); uint256 totalGaugePoints; for(uint i; i < lpGaugeTokens.length; i++) { @@ -264,36 +264,47 @@ contract SeasonGettersFacet { } /** - * @notice returns the twa beanEth liquidity, using the values stored in beanstalk. + * @notice returns the twa liquidity for a well, using the values stored in beanstalk. */ - function getBeanEthTwaUsdLiquidity() public view returns (uint256) { + function getTwaLiquidityForWell(address well) public view returns (uint256) { + (address token, ) = LibWell.getNonBeanTokenAndIndexFromWell(well); return LibWell.getTwaLiquidityFromBeanstalkPump( - C.BEAN_ETH_WELL, - LibUsdOracle.getTokenPrice(C.WETH) + well, + LibUsdOracle.getTokenPrice(token) ); } - + /** - * @notice returns the non-bean usd total liquidity of bean. + * @notice returns the twa liquidity for a well, using the values stored in beanstalk. + * @dev This is the liquidity used in the gauge system. */ - function getTotalUsdLiquidity() external view returns (uint256) { - return getBeanEthTwaUsdLiquidity(); + function getWeightedTwaLiquidityForWell(address well) public view returns (uint256) { + return LibEvaluate.getLiquidityWeight(s.ss[well].lwSelector) + .mul(getTwaLiquidityForWell(well)) + .div(1e18); } /** - * @notice returns the weighted beanEth liquidity used in Gauge calculations. + * @notice Returns the total twa liquidity of beanstalk. */ - function getWeightedBeanEthTwaUsdLiquidity() public view returns (uint256) { - return LibEvaluate.getLiquidityWeight(s.ss[C.BEAN_ETH_WELL].lwSelector) - .mul(getBeanEthTwaUsdLiquidity()) - .div(1e18); + function getTotalLiquidity() external view returns (uint256 totalLiquidity) { + address[] memory wells = LibWhitelistedTokens.getWhitelistedWellLpTokens(); + for (uint i; i < wells.length; i++) { + totalLiquidity = totalLiquidity.add(getTwaLiquidityForWell(wells[i])); + } } - /** - * @notice returns the total weighted liquidity used in Gauge calculations. + /** + * @notice returns the total weighted liquidity of beanstalk. + * @dev this is the liquidity */ - function getWeightedTotalLiquidity() external view returns (uint256) { - return getWeightedBeanEthTwaUsdLiquidity(); + function getTotalWeightedLiquidity() external view returns (uint256 totalWeightedLiquidity) { + address[] memory wells = LibWhitelistedTokens.getWhitelistedWellLpTokens(); + for (uint i; i < wells.length; i++) { + totalWeightedLiquidity = totalWeightedLiquidity.add( + getWeightedTwaLiquidityForWell(wells[i]) + ); + } } /** diff --git a/protocol/test/Gauge.test.js b/protocol/test/Gauge.test.js index 37c49e6145..2cb1596bfe 100644 --- a/protocol/test/Gauge.test.js +++ b/protocol/test/Gauge.test.js @@ -220,9 +220,9 @@ describe('Gauge', function () { describe("getter", function () { it('outputs correct liquidity values:', async function (){ - expect(await this.seasonGetters.getBeanEthTwaUsdLiquidity()).to.be.equal(to18('1000000')) + expect(await this.seasonGetters.getTwaLiquidityForWell(BEAN_ETH_WELL)).to.be.equal(to18('1000000')) expect(await this.seasonGetters.getTotalUsdLiquidity()).to.be.equal(to18('1000000')) - expect(await this.seasonGetters.getWeightedBeanEthTwaUsdLiquidity()).to.be.equal(to18('1000000')) + expect(await this.seasonGetters.getWeightedTwaLiquidityForWell(BEAN_ETH_WELL)).to.be.equal(to18('1000000')) expect(await this.seasonGetters.getWeightedTotalLiquidity()).to.be.equal(to18('1000000')) }) @@ -375,7 +375,7 @@ describe('Gauge', function () { expect(await this.seasonGetters.getBeanEthGaugePointsPerBdv()).to.be.eq(to18('15.811392351684831136')) expect(await this.seasonGetters.getBeanGaugePointsPerBdv()).to.be.eq(to18('11.858544263763623352')) expect(await this.seasonGetters.getGrownStalkIssuedPerSeason()).to.be.eq(to6('489.736611')) - expect(await this.seasonGetters.getStalkPerGp()).to.be.eq(('224048')) + expect(await this.seasonGetters.()).to.be.eq(('224048')) expect((await this.siloGetters.tokenSettings(BEAN))[1]).to.be.eq(2656883) // 2.65 seeds per BDV expect((await this.siloGetters.tokenSettings(BEAN_ETH_WELL))[1]).to.be.eq(3542510) // 3.54 seeds per BDV expect((await this.siloGetters.tokenSettings(BEAN_3_CURVE))[1]).to.be.eq(1) // 1 seeds diff --git a/protocol/test/SeedGaugeMainnet.test.js b/protocol/test/SeedGaugeMainnet.test.js index fa72ba6436..e044442bca 100644 --- a/protocol/test/SeedGaugeMainnet.test.js +++ b/protocol/test/SeedGaugeMainnet.test.js @@ -112,7 +112,7 @@ describe('SeedGauge Init Test', function () { it('usd Liquidity', async function () { // ~13.2m usd liquidity in Bean:Eth - expect(await this.beanstalk.getBeanEthTwaUsdLiquidity()).to.be.within(to18('13100000'), to18('13300000')); + expect(await this.beanstalk.getTwaLiquidityForWell()).to.be.within(to18('13100000'), to18('13300000')); // ~13.2m usd liquidity in Bean:Eth expect(await this.beanstalk.getTotalUsdLiquidity()).to.be.within(to18('13100000'), to18('13300000')); }) From 424cf5804d99d5ac95161db5d9737892d0853f73 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:58:14 -0600 Subject: [PATCH 19/25] 19 --- protocol/contracts/beanstalk/silo/EnrootFacet.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/contracts/beanstalk/silo/EnrootFacet.sol b/protocol/contracts/beanstalk/silo/EnrootFacet.sol index 9b573b5b0f..ef6fefe41e 100644 --- a/protocol/contracts/beanstalk/silo/EnrootFacet.sol +++ b/protocol/contracts/beanstalk/silo/EnrootFacet.sol @@ -187,7 +187,7 @@ contract EnrootFacet is ReentrancyGuard { ) ); LibSilo.mintActiveStalk( - msg.sender, + msg.sender, enrootData.stalkAdded.sub( ar.active.stalk .add(ar.even.stalk) From 9cb2f5ca5e3facbf41b298114341e4167706c36b Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:58:51 -0600 Subject: [PATCH 20/25] 20 --- protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol index 28bb8fba61..84d8df5699 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol @@ -171,7 +171,7 @@ contract Weather is Sun { * @dev Flood was previously called a "Season of Plenty" (SOP for short). * When Beanstalk has been Oversaturated for a Season, Beanstalk returns the * Bean price to its peg by minting additional Beans and selling them directly - * on the BEANETH well. Proceeds from the sale in the form of WETH are distributed to + * on the sop well. Proceeds from the sale in the form of WETH are distributed to * Stalkholders at the beginning of a Season in proportion to their Stalk * ownership when the Farm became Oversaturated. Also, at the beginning of the * Flood, all Pods that were minted before the Farm became Oversaturated Ripen @@ -180,7 +180,7 @@ contract Weather is Sun { */ function sop() private { // calculate the beans from a sop. - // sop beans uses the instantaneous reserves of the beaneth well, + // sop beans uses the min of the current and instantaneous reserves of the sop well, // rather than the twaReserves in order to get bean back to peg. address sopWell = s.sopWell; (uint256 newBeans, IERC20 sopToken) = calculateSop(sopWell); From 034d46c853ad314149e2c6087931ea2d80fb77c7 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 19:59:14 -0600 Subject: [PATCH 21/25] 21 --- protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol index 84d8df5699..090546c075 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol @@ -213,7 +213,7 @@ contract Weather is Sun { } /** - * @dev Allocate WETH during a Season of Plenty. + * @dev Allocate `sop token` during a Season of Plenty. */ function rewardSop(uint256 amount) private { s.sops[s.season.rainStart] = s.sops[s.season.lastSop].add( From 6e61fe0df575ef7582807173595b7d5949be321d Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 22:42:57 -0600 Subject: [PATCH 22/25] fix tests --- protocol/abi/Beanstalk.json | 226 +++++++++++++++--- .../sun/SeasonFacet/SeasonGettersFacet.sol | 4 +- protocol/test/Gauge.test.js | 4 +- protocol/test/SeedGaugeMainnet.test.js | 2 +- protocol/test/SiloToken.test.js | 8 +- protocol/test/WellConvert.test.js | 11 +- 6 files changed, 216 insertions(+), 39 deletions(-) diff --git a/protocol/abi/Beanstalk.json b/protocol/abi/Beanstalk.json index 17e3e14498..9913f64e7f 100644 --- a/protocol/abi/Beanstalk.json +++ b/protocol/abi/Beanstalk.json @@ -5416,6 +5416,30 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfFinishedGerminatingStalkAndRoots", + "outputs": [ + { + "internalType": "uint256", + "name": "gStalk", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "gRoots", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -5459,6 +5483,30 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfNewAndPartiallyGerminatedStalk", + "outputs": [ + { + "internalType": "uint256", + "name": "paritallyGerminatedStalk", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newlyGerminatedStalk", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -5666,13 +5714,18 @@ { "inputs": [ { - "internalType": "uint32", - "name": "season", - "type": "uint32" + "internalType": "address", + "name": "token", + "type": "address" } ], - "name": "getGerminatingRootsForSeason", + "name": "getEvenGerminating", "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, { "internalType": "uint256", "name": "", @@ -5690,8 +5743,13 @@ "type": "uint32" } ], - "name": "getGerminatingStalkForSeason", + "name": "getGerminatingStalkAndRootsForSeason", "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, { "internalType": "uint256", "name": "", @@ -5763,6 +5821,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getLegacySeedsPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -5799,6 +5876,24 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getNewAndPartiallyGerminatedTotalStalk", + "outputs": [ + { + "internalType": "uint256", + "name": "partiallyGerminatedStalk", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newlyGerminatedStalk", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -5807,8 +5902,13 @@ "type": "address" } ], - "name": "getSeedsPerToken", + "name": "getOddGerminating", "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, { "internalType": "uint256", "name": "", @@ -5856,6 +5956,44 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTotalGerminatingAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTotalGerminatingBdv", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getTotalGerminatingStalk", @@ -6166,6 +6304,12 @@ "name": "account", "type": "address" }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, { "indexed": false, "internalType": "uint256", @@ -7025,19 +7169,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "getTwaLiquidityForWell", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "getBeanGaugePointsPerBdv", @@ -7147,6 +7278,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getGrownStalkIssuedPerGp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getGrownStalkIssuedPerSeason", @@ -7239,11 +7383,11 @@ }, { "inputs": [], - "name": "", + "name": "getTotalBdv", "outputs": [ { "internalType": "uint256", - "name": "", + "name": "totalBdv", "type": "uint256" } ], @@ -7252,11 +7396,11 @@ }, { "inputs": [], - "name": "getTotalBdv", + "name": "getTotalUsdLiquidity", "outputs": [ { "internalType": "uint256", - "name": "totalBdv", + "name": "totalLiquidity", "type": "uint256" } ], @@ -7265,11 +7409,11 @@ }, { "inputs": [], - "name": "getTotalUsdLiquidity", + "name": "getTotalWeightedUsdLiquidity", "outputs": [ { "internalType": "uint256", - "name": "", + "name": "totalWeightedLiquidity", "type": "uint256" } ], @@ -7277,8 +7421,14 @@ "type": "function" }, { - "inputs": [], - "name": "getWeightedTwaLiquidityForWell", + "inputs": [ + { + "internalType": "address", + "name": "well", + "type": "address" + } + ], + "name": "getTwaLiquidityForWell", "outputs": [ { "internalType": "uint256", @@ -7290,8 +7440,14 @@ "type": "function" }, { - "inputs": [], - "name": "getWeightedTotalLiquidity", + "inputs": [ + { + "internalType": "address", + "name": "well", + "type": "address" + } + ], + "name": "getWeightedTwaLiquidityForWell", "outputs": [ { "internalType": "uint256", @@ -7631,6 +7787,18 @@ "name": "season", "type": "uint256" }, + { + "indexed": false, + "internalType": "address", + "name": "well", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, { "indexed": false, "internalType": "uint256", diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol index be386c11f4..33f3b39fa4 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol @@ -287,7 +287,7 @@ contract SeasonGettersFacet { /** * @notice Returns the total twa liquidity of beanstalk. */ - function getTotalLiquidity() external view returns (uint256 totalLiquidity) { + function getTotalUsdLiquidity() external view returns (uint256 totalLiquidity) { address[] memory wells = LibWhitelistedTokens.getWhitelistedWellLpTokens(); for (uint i; i < wells.length; i++) { totalLiquidity = totalLiquidity.add(getTwaLiquidityForWell(wells[i])); @@ -298,7 +298,7 @@ contract SeasonGettersFacet { * @notice returns the total weighted liquidity of beanstalk. * @dev this is the liquidity */ - function getTotalWeightedLiquidity() external view returns (uint256 totalWeightedLiquidity) { + function getTotalWeightedUsdLiquidity() external view returns (uint256 totalWeightedLiquidity) { address[] memory wells = LibWhitelistedTokens.getWhitelistedWellLpTokens(); for (uint i; i < wells.length; i++) { totalWeightedLiquidity = totalWeightedLiquidity.add( diff --git a/protocol/test/Gauge.test.js b/protocol/test/Gauge.test.js index 2cb1596bfe..8b4e2bfdab 100644 --- a/protocol/test/Gauge.test.js +++ b/protocol/test/Gauge.test.js @@ -223,7 +223,7 @@ describe('Gauge', function () { expect(await this.seasonGetters.getTwaLiquidityForWell(BEAN_ETH_WELL)).to.be.equal(to18('1000000')) expect(await this.seasonGetters.getTotalUsdLiquidity()).to.be.equal(to18('1000000')) expect(await this.seasonGetters.getWeightedTwaLiquidityForWell(BEAN_ETH_WELL)).to.be.equal(to18('1000000')) - expect(await this.seasonGetters.getWeightedTotalLiquidity()).to.be.equal(to18('1000000')) + expect(await this.seasonGetters.getTotalWeightedUsdLiquidity()).to.be.equal(to18('1000000')) }) it('inital state', async function () { @@ -375,7 +375,7 @@ describe('Gauge', function () { expect(await this.seasonGetters.getBeanEthGaugePointsPerBdv()).to.be.eq(to18('15.811392351684831136')) expect(await this.seasonGetters.getBeanGaugePointsPerBdv()).to.be.eq(to18('11.858544263763623352')) expect(await this.seasonGetters.getGrownStalkIssuedPerSeason()).to.be.eq(to6('489.736611')) - expect(await this.seasonGetters.()).to.be.eq(('224048')) + expect(await this.seasonGetters.getGrownStalkIssuedPerGp()).to.be.eq(('224048')) expect((await this.siloGetters.tokenSettings(BEAN))[1]).to.be.eq(2656883) // 2.65 seeds per BDV expect((await this.siloGetters.tokenSettings(BEAN_ETH_WELL))[1]).to.be.eq(3542510) // 3.54 seeds per BDV expect((await this.siloGetters.tokenSettings(BEAN_3_CURVE))[1]).to.be.eq(1) // 1 seeds diff --git a/protocol/test/SeedGaugeMainnet.test.js b/protocol/test/SeedGaugeMainnet.test.js index e044442bca..8ed4d12cb4 100644 --- a/protocol/test/SeedGaugeMainnet.test.js +++ b/protocol/test/SeedGaugeMainnet.test.js @@ -112,7 +112,7 @@ describe('SeedGauge Init Test', function () { it('usd Liquidity', async function () { // ~13.2m usd liquidity in Bean:Eth - expect(await this.beanstalk.getTwaLiquidityForWell()).to.be.within(to18('13100000'), to18('13300000')); + expect(await this.beanstalk.getTwaLiquidityForWell(BEAN_ETH_WELL)).to.be.within(to18('13100000'), to18('13300000')); // ~13.2m usd liquidity in Bean:Eth expect(await this.beanstalk.getTotalUsdLiquidity()).to.be.within(to18('13100000'), to18('13300000')); }) diff --git a/protocol/test/SiloToken.test.js b/protocol/test/SiloToken.test.js index 9826232616..55700e3c95 100644 --- a/protocol/test/SiloToken.test.js +++ b/protocol/test/SiloToken.test.js @@ -311,7 +311,9 @@ describe("Silo Token", function () { expect(await this.siloGetters.getGerminatingTotalDepositedBdv(this.siloToken.address)).to.eq('500'); // no stalk is active as the deposit is in the germinating period. expect(await this.siloGetters.totalStalk()).to.eq('0'); - expect(await this.siloGetters.getGerminatingStalkForSeason(await this.seasonGetters.season())).to.eq('5000000'); + expect((await this.siloGetters.getGerminatingStalkAndRootsForSeason( + await this.seasonGetters.season() + ))[0]).to.eq('5000000'); }); it('properly updates the user balance', async function () { @@ -360,9 +362,9 @@ describe("Silo Token", function () { expect(await this.siloGetters.getGerminatingTotalDeposited(this.siloToken.address)).to.eq('500'); expect(await this.siloGetters.getGerminatingTotalDepositedBdv(this.siloToken.address)).to.eq('500'); expect(await this.siloGetters.totalStalk()).to.eq('500'); - expect(await this.siloGetters.getGerminatingStalkForSeason( + expect((await this.siloGetters.getGerminatingStalkAndRootsForSeason( toBN(await this.seasonGetters.season()).sub('1') - )).to.eq('5000000'); + ))[0]).to.eq('5000000'); }); it('properly updates the user balance', async function () { // the user should have 500 microStalk, and 5e6 germinating stalk. diff --git a/protocol/test/WellConvert.test.js b/protocol/test/WellConvert.test.js index 5825b3666d..cdb8bfb630 100644 --- a/protocol/test/WellConvert.test.js +++ b/protocol/test/WellConvert.test.js @@ -29,6 +29,7 @@ describe('Well Convert', function () { this.wellToken = await ethers.getContractAt("IERC20", this.well.address) this.convert = await ethers.getContractAt("MockConvertFacet", this.diamond.address) this.bean = await ethers.getContractAt("MockToken", BEAN); + this.season = await ethers.getContractAt('MockSeasonFacet', this.diamond.address) await this.bean.mint(ownerAddress, to18('1000000000')) await this.wellToken.connect(owner).approve(this.beanstalk.address, ethers.constants.MaxUint256) await this.bean.connect(owner).approve(this.beanstalk.address, ethers.constants.MaxUint256) @@ -158,12 +159,15 @@ describe('Well Convert', function () { const convertData = ConvertEncoder.convertBeansToWellLP(to6('100000'), '1338505354221892343955', this.well.address) await this.bean.connect(owner).approve(this.beanstalk.address, to6('100000')) await this.beanstalk.connect(owner).deposit(BEAN, to6('100000'), 0) + // call sunrise twice to finish germination (germinating deposits cannot convert). + await this.season.siloSunrise('0') + await this.season.siloSunrise('0') await this.convert.connect(owner).convert( convertData, ['0'], [to6('100000')] ) - deposit = await this.beanstalk.getDeposit(owner.address, this.well.address, '0') + deposit = await this.beanstalk.getDeposit(owner.address, this.well.address, '4141449') expect(deposit[0]).to.be.equal('1715728752538099023967') }) @@ -252,12 +256,15 @@ describe('Well Convert', function () { it('deposit and convert below max', async function () { const convertData = ConvertEncoder.convertWellLPToBeans(to18('2000'), to6('100000'), this.well.address) await this.beanstalk.connect(owner).deposit(this.well.address, to18('2000'), 0) + // call sunrise twice to finish germination (germinating deposits cannot convert). + await this.season.siloSunrise('0') + await this.season.siloSunrise('0') await this.convert.connect(owner).convert( convertData, ['0'], [to18('2000')] ) - deposit = await this.beanstalk.getDeposit(owner.address, BEAN, '0') + deposit = await this.beanstalk.getDeposit(owner.address, BEAN, '-3588917') expect(deposit[0]).to.be.equal('134564064605') }) From 61ad381b274821844411d5c1ed70f3cc4f6be696 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 22:48:28 -0600 Subject: [PATCH 23/25] style --- protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol | 6 +++--- protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol | 2 +- protocol/contracts/libraries/LibEvaluate.sol | 2 +- protocol/contracts/libraries/LibGauge.sol | 2 +- protocol/contracts/libraries/LibUnripe.sol | 2 +- protocol/contracts/libraries/Silo/LibGerminate.sol | 2 +- protocol/contracts/libraries/Silo/LibSilo.sol | 8 ++++---- protocol/contracts/libraries/Silo/LibTokenSilo.sol | 2 +- protocol/contracts/libraries/Silo/LibWhitelist.sol | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol b/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol index 8d1fa13c0f..cbcb10ef5d 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol @@ -191,7 +191,7 @@ contract TokenSilo is Silo { germinate ); - if(grownStalkRemoved > 0) { + if (grownStalkRemoved > 0) { LibSilo.burnActiveStalk( account, grownStalkRemoved @@ -254,7 +254,7 @@ contract TokenSilo is Silo { ); } - if(ar.grownStalkFromGermDeposits > 0) { + if (ar.grownStalkFromGermDeposits > 0) { LibSilo.burnActiveStalk( account, ar.grownStalkFromGermDeposits @@ -340,7 +340,7 @@ contract TokenSilo is Silo { LibSilo.transferStalk(sender, recipient, initalStalk.add(grownStalk)); } else { LibSilo.transferGerminatingStalk(sender, recipient, initalStalk, germ); - if(grownStalk > 0) { + if (grownStalk > 0) { LibSilo.transferStalk( sender, recipient, diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol index 090546c075..a7d2766c12 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol @@ -233,7 +233,7 @@ contract Weather is Sun { function calculateSop(address well) private view returns (uint256 sopBeans, IERC20 sopToken){ // if the sopWell was not initalized, the should not occur. - if(well == address(0)) return (0, IERC20(0)); + if (well == address(0)) return (0, IERC20(0)); IWell sopWell = IWell(well); IERC20[] memory tokens = sopWell.tokens(); Call[] memory pumps = sopWell.pumps(); diff --git a/protocol/contracts/libraries/LibEvaluate.sol b/protocol/contracts/libraries/LibEvaluate.sol index aef2d49f72..f4c102485d 100644 --- a/protocol/contracts/libraries/LibEvaluate.sol +++ b/protocol/contracts/libraries/LibEvaluate.sol @@ -238,7 +238,7 @@ library LibEvaluate { // `largestLiqWell` is only used to initalize `s.sopWell` upon a sop, // but a hot storage load to skip the block below // is significantly more expensive than performing the logic on every sunrise. - if(wellLiquidity > largestLiq) { + if (wellLiquidity > largestLiq) { largestLiq = wellLiquidity; largestLiqWell = pools[i]; } diff --git a/protocol/contracts/libraries/LibGauge.sol b/protocol/contracts/libraries/LibGauge.sol index e8fa3c1750..24d06752c3 100644 --- a/protocol/contracts/libraries/LibGauge.sol +++ b/protocol/contracts/libraries/LibGauge.sol @@ -240,7 +240,7 @@ library LibGauge { // update the average grown stalk per BDV per Season. // beanstalk must exist for a minimum of the catchup season in order to update the average. - if(s.season.current > TARGET_SEASONS_TO_CATCHUP) { + if (s.season.current > TARGET_SEASONS_TO_CATCHUP) { updateAverageStalkPerBdvPerSeason(); } diff --git a/protocol/contracts/libraries/LibUnripe.sol b/protocol/contracts/libraries/LibUnripe.sol index a2d5b6b4f2..54f0646804 100644 --- a/protocol/contracts/libraries/LibUnripe.sol +++ b/protocol/contracts/libraries/LibUnripe.sol @@ -186,7 +186,7 @@ library LibUnripe { AppStorage storage s = LibAppStorage.diamondStorage(); // if reserves return 0, then skip calculations. - if(reserves[0] == 0) return 0; + if (reserves[0] == 0) return 0; uint256 lockedLpAmount = LibLockedUnderlying.getLockedUnderlying( C.UNRIPE_LP, diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index e2320625ff..8602af5c6b 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -77,7 +77,7 @@ library LibGerminate { AppStorage storage s = LibAppStorage.diamondStorage(); // germination can only occur after season 3. - if(season < 2) return; + if (season < 2) return; // base roots are used if there are no roots in the silo. // root calculation is skipped if no deposits have been made diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 9d99382f24..72ae32f14d 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -426,7 +426,7 @@ library LibSilo { // if the user hasn't updated prior to the seedGauge/siloV3.1 update, // perform a one time `lastStem` scale. - if( + if ( (lastUpdate < s.season.stemScaleSeason && lastUpdate > 0) || (lastUpdate == s.season.stemScaleSeason && checkStemEdgeCase(account)) ) { @@ -796,7 +796,7 @@ library LibSilo { address[] memory siloTokens = LibWhitelistedTokens.getSiloTokens(); for(uint i; i < siloTokens.length; i++) { // scale lastStem by 1e6, if the user has a lastStem. - if(s.a[account].mowStatuses[siloTokens[i]].lastStem > 0) { + if (s.a[account].mowStatuses[siloTokens[i]].lastStem > 0) { s.a[account].mowStatuses[siloTokens[i]].lastStem = s.a[account].mowStatuses[siloTokens[i]].lastStem.mul(int96(PRECISION)); } @@ -817,8 +817,8 @@ library LibSilo { // if the answer is 1e6 or greater, the user has not updated. for(uint i; i < siloTokens.length; i++) { int96 lastStem = s.a[account].mowStatuses[siloTokens[i]].lastStem; - if(lastStem > 0) { - if(LibTokenSilo.stemTipForToken(siloTokens[i]).div(lastStem) >= int96(PRECISION)) { + if (lastStem > 0) { + if (LibTokenSilo.stemTipForToken(siloTokens[i]).div(lastStem) >= int96(PRECISION)) { return true; } } diff --git a/protocol/contracts/libraries/Silo/LibTokenSilo.sol b/protocol/contracts/libraries/Silo/LibTokenSilo.sol index 4324a141ea..01941c9161 100644 --- a/protocol/contracts/libraries/Silo/LibTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibTokenSilo.sol @@ -541,7 +541,7 @@ library LibTokenSilo { // and thus the cast to `uint256` is safe. uint deltaStemTip = uint256(_stemTip.sub(stem)); // no stalk has grown if the stem is equal to the stemTip. - if(deltaStemTip == 0) return 0; + if (deltaStemTip == 0) return 0; (, uint bdv) = getDeposit(account, token, stem); grownStalk = deltaStemTip.mul(bdv).div(PRECISION); diff --git a/protocol/contracts/libraries/Silo/LibWhitelist.sol b/protocol/contracts/libraries/Silo/LibWhitelist.sol index 8af7275d33..899363b875 100644 --- a/protocol/contracts/libraries/Silo/LibWhitelist.sol +++ b/protocol/contracts/libraries/Silo/LibWhitelist.sol @@ -178,7 +178,7 @@ library LibWhitelist { require(s.ss[token].milestoneSeason != 0, "Token not whitelisted"); // beanstalk requires a min. stalkEarnedPerSeason of 1. - if(stalkEarnedPerSeason == 0) stalkEarnedPerSeason = 1; + if (stalkEarnedPerSeason == 0) stalkEarnedPerSeason = 1; // update milestone stem and season. s.ss[token].milestoneStem = LibTokenSilo.stemTipForToken(token); From 3edc346910f9250c23c639a0c6e63ccb3aed2be7 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Tue, 13 Feb 2024 22:57:24 -0600 Subject: [PATCH 24/25] comment --- .../contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol index 33f3b39fa4..ba7965784b 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonGettersFacet.sol @@ -296,7 +296,6 @@ contract SeasonGettersFacet { /** * @notice returns the total weighted liquidity of beanstalk. - * @dev this is the liquidity */ function getTotalWeightedUsdLiquidity() external view returns (uint256 totalWeightedLiquidity) { address[] memory wells = LibWhitelistedTokens.getWhitelistedWellLpTokens(); From f77a9b59c88a8cf92a3a3bd72feafe4fd580d244 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Wed, 14 Feb 2024 00:23:14 -0600 Subject: [PATCH 25/25] young/mature --- protocol/abi/Beanstalk.json | 2 +- .../silo/SiloFacet/SiloGettersFacet.sol | 41 ++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/protocol/abi/Beanstalk.json b/protocol/abi/Beanstalk.json index 9913f64e7f..ccb9739f17 100644 --- a/protocol/abi/Beanstalk.json +++ b/protocol/abi/Beanstalk.json @@ -5878,7 +5878,7 @@ }, { "inputs": [], - "name": "getNewAndPartiallyGerminatedTotalStalk", + "name": "getYoungAndMatureGerminatingTotalStalk", "outputs": [ { "internalType": "uint256", diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index 47da5946b9..b897da2546 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -176,6 +176,20 @@ contract SiloGettersFacet is ReentrancyGuard { return (s.unclaimedGerminating[season].stalk, s.unclaimedGerminating[season].roots); } + /** + * @notice Returns the unclaimed germinating stalk and roots for a season. + */ + function getGerminatingStalkForSeason(uint32 season) external view returns (uint256) { + return (s.unclaimedGerminating[season].stalk); + } + + /** + * @notice Returns the unclaimed germinating stalk and roots for a season. + */ + function getGerminatingRootsForSeason(uint32 season) external view returns (uint256) { + return (s.unclaimedGerminating[season].roots); + } + /** * @notice returns the stalk that is currently in the germination process. */ @@ -186,12 +200,15 @@ contract SiloGettersFacet is ReentrancyGuard { } /** - * @notice returns the newly and partially germinating stalk. - * partially germinated stalk will finish germinating after 1 `sunrise` call. - * newly germinated stalk will finish germinating after 2 `sunrise` calls. + * @notice returns the young and mature germinating stalk. + * `young` germinating stalk are stalk that recently started the germination process. + * (created in the current season) + * `mature` germinating stalk are stalk that are paritially germinated, + * and will finish germinating upon the next sunrise call. + * (created in the previous season) */ - function getNewAndPartiallyGerminatedTotalStalk() external view returns ( - uint256 partiallyGerminatedStalk, uint256 newlyGerminatedStalk + function getYoungAndMatureGerminatingTotalStalk() external view returns ( + uint256 matureGerminatingStalk, uint256 youngGerminatingStalk ) { return ( s.unclaimedGerminating[s.season.current - 1].stalk, @@ -302,19 +319,21 @@ contract SiloGettersFacet is ReentrancyGuard { } /** - * @notice returns the amount of newly and partially germinated stalk that an account has. - * @dev stalk here may have already finished the germination process but needs a silo - * interaction to update. + * @notice returns the amount of young and mature germinating stalk that an account has. + * `young` germinating stalk are the most recent germinating stalk issued to `account`. + * `mature` germinating stalk are germinating stalk that are paritially germinated. + * @dev both `young` and `old stalk here may have already finished the germination process + * but require a silo interaction to update. */ - function balanceOfNewAndPartiallyGerminatedStalk( + function balanceOfYoungAndMatureGerminatingStalk( address account - ) external view returns (uint256 paritallyGerminatedStalk, uint256 newlyGerminatedStalk) { + ) external view returns (uint256 matureGerminatingStalk, uint256 youngGerminatingStalk) { // if the last mowed season is less than the current season - 1, // then there are no germinating stalk and roots (as all germinating assets have finished). if (s.a[account].lastUpdate < s.season.current - 1) { return (0, 0); } else { - (newlyGerminatedStalk, paritallyGerminatedStalk) = LibGerminate.getGerminatingStalk( + (youngGerminatingStalk, matureGerminatingStalk) = LibGerminate.getGerminatingStalk( account, LibGerminate.isSeasonOdd(s.a[account].lastUpdate) );