Skip to content

Commit

Permalink
change libGerminate implmentation
Browse files Browse the repository at this point in the history
- before, we checked if the stem was < or == to the germinating stem. This assumed if the stem was higher, it was the stem tip and thus was starting the germination process.

- if a user converts from a deposit of lower seeds to higher, this would cause them to wait an additional season. By checking if the stem < germinatingStem and stem == stemTip, we reduce the germination period by one season.
  • Loading branch information
Brean0 committed Dec 14, 2023
1 parent 12cad55 commit fc881fe
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 33 deletions.
2 changes: 1 addition & 1 deletion protocol/contracts/beanstalk/silo/EnrootFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ contract EnrootFacet is ReentrancyGuard {
amount,
bdv,
LibTokenSilo.Transfer.noEmitTransferSingle,
LibGerminate._getGerminationState(stem, enrootData.germStem.germinatingStem)
LibGerminate._getGerminationState(stem, enrootData.germStem)
);

return bdv.mul(enrootData.stalkPerBdv).add(
Expand Down
2 changes: 1 addition & 1 deletion protocol/contracts/beanstalk/silo/SiloFacet/TokenSilo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ contract TokenSilo is Silo {
for (uint256 i; i < stems.length; ++i) {
LibGerminate.Germinate germ = LibGerminate._getGerminationState(
stems[i],
germStem.germinatingStem
germStem
);
uint256 crateBdv = LibTokenSilo.removeDepositFromAccount(
sender,
Expand Down
14 changes: 7 additions & 7 deletions protocol/contracts/libraries/Silo/LibGerminate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ library LibGerminate {
function getGerminationState(address token, int96 stem) internal view returns (Germinate, int96) {
// if the stem of the token is the stemTip, then it should be germinating.
GermStem memory germStem = getGerminatingStem(token);
return (_getGerminationState(stem, germStem.germinatingStem), germStem.stemTip);
return (_getGerminationState(stem, germStem), germStem.stemTip);
}

/**
Expand Down Expand Up @@ -230,19 +230,19 @@ library LibGerminate {
*/
function _getGerminationState(
int96 stem,
int96 germinationStem
GermStem memory germData
) internal view returns (Germinate) {

if (stem < germinationStem) {
if (stem < germData.germinatingStem) {
// if the stem of the deposit is lower than the germination stem,
// then the deposit is not germinating.
return Germinate.NOT_GERMINATING;
} else {
// return the gemination state based on whether the stem
// is equal to the germination stem or stemTip.
// if the stem is not equal to the germination stem, then it
// must equal the stemTip here.
if (stem == germinationStem) {
// is equal to the stemTip.
// if the stem is equal to the stem tip, it is in the inital stages of germination.
// if the stem is not equal to the stemTip, its in the germination process.
if (stem == germData.stemTip) {
return isCurrentSeasonOdd() ? Germinate.ODD : Germinate.EVEN;
} else {
return isCurrentSeasonOdd() ? Germinate.EVEN : Germinate.ODD;
Expand Down
38 changes: 15 additions & 23 deletions protocol/contracts/libraries/Silo/LibSilo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ library LibSilo {
s.s.roots = s.s.roots.add(roots);
s.a[account].roots = s.a[account].roots.add(roots);
} else {

Account.FarmerGerminating storage farmerGerm;
Storage.TotalGerminating storage totalGerm;

Expand All @@ -170,14 +169,13 @@ library LibSilo {
farmerGerm = s.a[account].evenGerminating;
totalGerm = s.evenGerminating;
}

farmerGerm.stalk = farmerGerm.stalk.add(stalk.toUint112());
farmerGerm.roots = farmerGerm.roots.add(roots.toUint112());

totalGerm.stalk = totalGerm.stalk.add(stalk.toUint128());
totalGerm.roots = totalGerm.roots.add(roots.toUint128());
}


emit StalkBalanceChanged(account, int256(stalk), int256(roots));
}
Expand Down Expand Up @@ -221,7 +219,7 @@ library LibSilo {
farmerGerm = s.a[account].evenGerminating;
totalGerm = s.evenGerminating;
}

farmerGerm.stalk = farmerGerm.stalk.sub(stalk.toUint112());
farmerGerm.roots = farmerGerm.roots.sub(roots.toUint112());

Expand Down Expand Up @@ -272,9 +270,9 @@ library LibSilo {
* @dev assumes stalk is germinating.
*/
function transferGerminatingStalk(
address sender,
address recipient,
uint256 stalk,
address sender,
address recipient,
uint256 stalk,
LibGerminate.Germinate GermState
) internal {
AppStorage storage s = LibAppStorage.diamondStorage();
Expand Down Expand Up @@ -322,9 +320,7 @@ library LibSilo {
}

if (ar.oddStalkRemoved > 0) {
ar.oddStalkRemoved = ar.oddStalkRemoved.add(
ar.oddBdvRemoved.mul(stalkPerBDV)
);
ar.oddStalkRemoved = ar.oddStalkRemoved.add(ar.oddBdvRemoved.mul(stalkPerBDV));
transferGerminatingStalk(
sender,
recipient,
Expand All @@ -334,9 +330,7 @@ library LibSilo {
}

if (ar.evenStalkRemoved > 0) {
ar.evenStalkRemoved = ar.evenStalkRemoved.add(
ar.evenBdvRemoved.mul(stalkPerBDV)
);
ar.evenStalkRemoved = ar.evenStalkRemoved.add(ar.evenBdvRemoved.mul(stalkPerBDV));
transferGerminatingStalk(
sender,
recipient,
Expand Down Expand Up @@ -408,12 +402,8 @@ library LibSilo {
if (_lastStem == _stemTip) {
return;
}

mintStalk(
account,
_balanceOfGrownStalk(_lastStem, _stemTip, _bdv),
germ
);

mintStalk(account, _balanceOfGrownStalk(_lastStem, _stemTip, _bdv), germ);
}

// If this `account` has no BDV, skip to save gas. Still need to update lastStem
Expand Down Expand Up @@ -583,7 +573,10 @@ library LibSilo {
uint256[] memory removedDepositIDs = new uint256[](stems.length);
LibGerminate.GermStem memory germStem = LibGerminate.getGerminatingStem(token);
for (uint256 i; i < stems.length; ++i) {
LibGerminate.Germinate germState = LibGerminate._getGerminationState(stems[i], germStem.germinatingStem);
LibGerminate.Germinate germState = LibGerminate._getGerminationState(
stems[i],
germStem
);
uint256 crateBdv = LibTokenSilo.removeDepositFromAccount(
account,
token,
Expand All @@ -598,8 +591,8 @@ library LibSilo {
// if the deposit is germinating, decrement germinating values,
// otherwise increment deposited values.
// token is added to `ar.tokensRemoved` regardless of germination state.
if (germState == LibGerminate.Germinate.NOT_GERMINATING) {

if (germState == LibGerminate.Germinate.NOT_GERMINATING) {
ar.bdvRemoved = ar.bdvRemoved.add(crateBdv);
ar.stalkRemoved = ar.stalkRemoved.add(crateStalk);
ar.tokensRemoved = ar.tokensRemoved.add(amounts[i]);
Expand Down Expand Up @@ -632,7 +625,6 @@ library LibSilo {
);
}


// "removing" deposits is equivalent to "burning" a batch of ERC1155 tokens.
emit TransferBatch(msg.sender, account, address(0), removedDepositIDs, amounts);
emit RemoveDeposits(account, token, stems, amounts, ar.tokensRemoved, bdvsRemoved);
Expand Down
2 changes: 1 addition & 1 deletion protocol/contracts/libraries/Silo/LibTokenSilo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ library LibTokenSilo {
LibGerminate.GermStem memory germStem = LibGerminate.getGerminatingStem(token);
stem = germStem.stemTip.sub(toInt96(grownStalk.div(bdv)));
_grownStalk = uint256(germStem.stemTip.sub(stem).mul(toInt96(bdv)));
germ = LibGerminate._getGerminationState(stem, germStem.germinatingStem);
germ = LibGerminate._getGerminationState(stem, germStem);
}

/**
Expand Down

0 comments on commit fc881fe

Please sign in to comment.