Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reseed revised #1138

Merged
merged 15 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 178 additions & 0 deletions protocol/contracts/beanstalk/init/reseed/L2/ReseedGlobalRevised.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
SPDX-License-Identifier: MIT
*/

pragma solidity ^0.8.20;
pragma experimental ABIEncoderV2;

import "contracts/beanstalk/storage/System.sol";
import {AppStorage} from "contracts/beanstalk/storage/AppStorage.sol";
import {LibTractor} from "contracts/libraries/LibTractor.sol";
import {LibCases} from "contracts/libraries/LibCases.sol";
import {Distribution} from "contracts/beanstalk/sun/SeasonFacet/Distribution.sol";

/**
* @author Brean
* @notice ReseedGlobalRevised sets the global state of Beanstalk.
* @dev Sets only the the internal balances and deposits.
*/
contract ReseedGlobalRevised is Distribution {
/**
* @param system contains the global state of Beanstalk.
* 1) replaces mappings with arrays, so that the state can be re-initialized.
* 2) omits variables that do not need to be set.
* 3) omits Pod Orders and Listings. (Set in ReseedOrders.sol)
*/
struct ReseedSystemData {
SystemInternalBalances sysBalances;
SystemFertilizer sysFert;
SystemSilo sysSilo;
Field f;
Season s;
Weather w;
SeedGauge sg;
Rain r;
EvaluationParameters ep;
ShipmentRoute[] shipmentRoutes;
}

struct SystemInternalBalances {
IERC20[] tokens;
uint256[] internalTokenBalanceTotal;
}
/**
* @notice contains data related to the system's Silo.
*/
struct SystemSilo {
uint256 stalk;
uint256 roots;
uint256 earnedBeans;
uint256 orderLockedBeans;
address[] tokens;
AssetSilo[] balances;
UnripeSettings[] u;
Deposited[] germDepositOdd;
Deposited[] germDepositEven;
uint32[] unclaimedGerminatingSeasons;
GerminatingSilo[] unclaimedGerminating;
}

/**
* @notice contains data related to the system's fertilizer.
* @dev `fertilizerIds` and `fertilizerAmounts` are used to recreate the
* `fertilizer` and `nextFid` mapping.
*/
struct SystemFertilizer {
uint128[] fertilizerIds;
uint256[] fertilizerAmounts;
uint256 activeFertilizer;
uint256 fertilizedIndex;
uint256 unfertilizedIndex;
uint256 fertilizedPaidIndex;
uint128 fertFirst;
uint128 fertLast;
uint128 bpf;
uint256 recapitalized;
uint256 leftoverBeans;
}

/**
* @notice initializes the global state of Beanstalk.
*/
function init(ReseedSystemData calldata system) external {
// s.sys.reentrantStatus = 1;
// s.sys.farmingStatus = 1;
// s.sys.activeField = 0;
// s.sys.fieldCount = 1;

// LibCases.setCasesV2();
setInternalBalanceTotals(system.sysBalances);
// _setShipmentRoutes(system.shipmentRoutes);
setSilo(system.sysSilo);
// setFertilizer(system.sysFert);
// s.sys.fields[0] = system.f;
// s.sys.season = system.s;
// s.sys.weather = system.w;
// s.sys.seedGauge = system.sg;
// s.sys.rain = system.r;
// s.sys.evaluationParameters = system.ep;

// initalize tractor:
// setTractor();
}

function setInternalBalanceTotals(SystemInternalBalances calldata balances) internal {
for (uint i; i < balances.tokens.length; i++) {
s.sys.internalTokenBalanceTotal[balances.tokens[i]] = balances
.internalTokenBalanceTotal[i];
}
}

/**
* @notice sets the Fertilizer data.
*/
function setFertilizer(SystemFertilizer calldata fert) internal {
for (uint256 i; i < fert.fertilizerIds.length; i++) {
s.sys.fert.fertilizer[fert.fertilizerIds[i]] = fert.fertilizerAmounts[i];

if (i != 0) s.sys.fert.nextFid[fert.fertilizerIds[i - 1]] = fert.fertilizerIds[i];
}
s.sys.fert.activeFertilizer = fert.activeFertilizer;
s.sys.fert.fertilizedIndex = fert.fertilizedIndex;
s.sys.fert.unfertilizedIndex = fert.unfertilizedIndex;
s.sys.fert.fertilizedPaidIndex = fert.fertilizedPaidIndex;
s.sys.fert.fertFirst = fert.fertFirst;
s.sys.fert.fertLast = fert.fertLast;
s.sys.fert.bpf = fert.bpf;
s.sys.fert.recapitalized = fert.recapitalized;
s.sys.fert.leftoverBeans = fert.leftoverBeans;
}

/**
* @notice initializes the Global silo settings.
* @dev assumes the first two tokens are unripe tokens.
* Assumes correct index matching.
*/
function setSilo(SystemSilo calldata silo) internal {
s.sys.silo.stalk = silo.stalk;
s.sys.silo.roots = silo.roots;
s.sys.silo.earnedBeans = silo.earnedBeans;
s.sys.orderLockedBeans = silo.orderLockedBeans;

// loop through tokens:
for (uint i; i < silo.tokens.length; i++) {
address token = silo.tokens[i];
if (i < 2) {
s.sys.silo.unripeSettings[token] = silo.u[i];
}
s.sys.silo.balances[token] = silo.balances[i];
}

for (uint i; i < silo.germDepositEven.length; i++) {
s.sys.silo.germinating[GerminationSide.ODD][silo.tokens[i]] = silo.germDepositOdd[i];
s.sys.silo.germinating[GerminationSide.EVEN][silo.tokens[i]] = silo.germDepositEven[i];
}

for (uint i; i < silo.unclaimedGerminatingSeasons.length; i++) {
uint32 season = silo.unclaimedGerminatingSeasons[i];
s.sys.silo.unclaimedGerminating[season] = silo.unclaimedGerminating[i];
}
}

/**
* @notice sets the routes.
* @dev Solidity does not support direct assignment of array structs to Storage.
*/
function _setShipmentRoutes(ShipmentRoute[] calldata routes) internal {
for (uint i; i < routes.length; i++) {
s.sys.shipmentRoutes.push(routes[i]);
}
emit ShipmentRoutesSet(routes);
}

function setTractor() internal {
LibTractor.TractorStorage storage ts = LibTractor._tractorStorage();
ts.activePublisher = payable(address(1));
ts.version = "1.0.0";
}
}
141 changes: 141 additions & 0 deletions protocol/contracts/beanstalk/init/reseed/L2/ReseedSiloRevised.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
SPDX-License-Identifier: MIT
*/

pragma solidity ^0.8.20;
pragma experimental ABIEncoderV2;

import {AppStorage} from "contracts/beanstalk/storage/AppStorage.sol";
import {LibTokenSilo} from "contracts/libraries/Silo/LibTokenSilo.sol";
import {LibBytes} from "contracts/libraries/LibBytes.sol";
import {C} from "contracts/C.sol";

/**
* @author Brean, Deadmanwalking
* @notice ReseedSilo re-initializes the Silo.
* @dev revised such that the deposit Id list is not updated, and the transfer single event is emitted,
* if the current deposit amount is not equal to the current amount.
*/
contract ReseedSiloRevised {
using LibBytes for uint256;

/**
* @notice AccountSiloDeposits is a struct that contains the silo deposit entries
* for a given account.
*/
struct AccountSiloDeposits {
address account;
AccountDepositData[] dd;
}

struct AccountDepositData {
uint256 depositId;
uint128 amount;
uint128 bdv;
}

/**
* @notice AddMigratedDeposit event is emitted when a deposit is added to the silo.
* See {TokenSilo.AddDeposit}
*/
event AddMigratedDeposit(
address indexed account,
address indexed token,
int96 stem,
uint256 amount,
uint256 bdv
);

/**
* @notice TransferSingle event is emitted when a transfer is made. See {IERC1155.TransferSingle}
*/
event TransferSingle(
address indexed operator,
address indexed sender,
address indexed recipient,
uint256 depositId,
uint256 amount
);

AppStorage internal s;

/**
* @notice Initialize the silo with the given deposits.
* @dev performs the following:
* - re-deposits the provided deposits to the silo.
* note: token addresses will differ from L1.
*/
function init(AccountSiloDeposits[] calldata accountDeposits) external {
// initialize deposits.
reseedSiloDeposit(accountDeposits);
}

/**
* @notice reseed the silo deposits.
* @param accountDeposits an array of account deposits to reseed where each account
* can have multiple deposits.
* @dev the account's stalk and mow statuses are handled in a separate contract.
*/
function reseedSiloDeposit(AccountSiloDeposits[] calldata accountDeposits) internal {
// for all accounts
for (uint256 i; i < accountDeposits.length; i++) {
// for all of account's deposits.
for (uint256 j; j < accountDeposits[i].dd.length; j++) {
// get token and stem from depositId.
(address token, int96 stem) = LibBytes.unpackAddressAndStem(
accountDeposits[i].dd[j].depositId
);

// get the current amount stored in the depositId.
uint256 currentAmount = s
.accts[accountDeposits[i].account]
.deposits[accountDeposits[i].dd[j].depositId]
.amount;

// add deposit to account.
s
.accts[accountDeposits[i].account]
.deposits[accountDeposits[i].dd[j].depositId]
.amount = accountDeposits[i].dd[j].amount;
s
.accts[accountDeposits[i].account]
.deposits[accountDeposits[i].dd[j].depositId]
.bdv = accountDeposits[i].dd[j].bdv;

// Stems were not affected due to the invalid data processing, and thus the depositId and depositIdList
// do not need to be updated.

// add deposit to depositIdList.
// s.accts[accountDeposits[i].account].depositIdList[token].depositIds.push(
// accountDeposits[i].dd[j].depositId
// );
// set deposit id to index mapping, after adding deposit to deposit list
// this way the length of the depositIds array is always >0.
// s.accts[accountDeposits[i].account].depositIdList[token].idIndex[
// accountDeposits[i].dd[j].depositId
// ] = s.accts[accountDeposits[i].account].depositIdList[token].depositIds.length - 1;

// emit events. Subgraphs should omit previous `AddMigratedDeposit`
emit AddMigratedDeposit(
accountDeposits[i].account,
token,
stem,
accountDeposits[i].dd[j].amount,
accountDeposits[i].dd[j].bdv
);

// if the current amount is not equal to the amount in the deposit,
// emit a transfer event equal to the difference in order to remain compliant with ERC1155.
if (currentAmount != accountDeposits[i].dd[j].amount) {
emit TransferSingle(
accountDeposits[i].account, // operator
address(0), // from
accountDeposits[i].account, // to
accountDeposits[i].dd[j].depositId, // depositID
accountDeposits[i].dd[j].amount - currentAmount // delta
);
}
}
}
}
}
9 changes: 4 additions & 5 deletions protocol/contracts/beanstalk/migration/L1ReceiverFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ contract L1ReceiverFacet is ReentrancyGuard {

// todo: update with correct merkle roots once once L1 Beanstalk has been paused.
bytes32 internal constant DEPOSIT_MERKLE_ROOT =
0xe8c85107aea17dd6d4330a7a996c8ec23d62aa22f3feb4c97cdd5368e1fa756b;
0xeb066652d7a4697ff79e41b89a3c0687bff9b2eca24abae3ce2227353c0f7fa2;
bytes32 internal constant PLOT_MERKLE_ROOT =
0x8d60edfd9ab5f687b1d92f441b577b43d2ad8cb22e66779e6c37e3dc3b91f3e1;
0x77468b9d2123fccf86470df51a08fe459e39d534d5db5fd389b9094f855c3159;
bytes32 internal constant INTERNAL_BALANCE_MERKLE_ROOT =
0x3b6f4a3ceb1dc34f3a00414b79dcc5c16756093de2e4062e726ec22afd36741c;
0xa3f8aa1737eb885b5bada4bf550a69a775f87bb3d76ded62116753ed88758806;
bytes32 internal constant FERTILIZER_MERKLE_ROOT =
0x6329fea484065f1f62d989fbf443406e3487276c4397ad36e0370f60ffbaa2e5;
0x5819d7a6b10bfd421d78835493ed50442b4d658d0e9022caa4507c9c0ef54a97;
// bytes32 internal constant POD_ORDER_MERKLE_ROOT =
// 0x4a000e44e0820fdb1ef4194538de1404629221d77e7c920fa8c000ce5902d503;

Expand Down Expand Up @@ -443,7 +443,6 @@ contract L1ReceiverFacet is ReentrancyGuard {
bdvs[i],
LibTokenSilo.Transfer.emitTransferSingle
);

// calculate the stalk assoicated with the deposit and increment.
stalk += (bdvs[i] * stalkIssuedPerBdv) + (uint256(uint96(stemTip - stem)) * bdvs[i]);
}
Expand Down
5 changes: 5 additions & 0 deletions protocol/contracts/interfaces/IMockFBeanstalk.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,11 @@ interface IMockFBeanstalk {
address account
) external view returns (TokenDepositId[] memory deposits);

function getDepositsForAccount(
address account,
address[] calldata tokens
) external view returns (TokenDepositId[] memory deposits);

function getEndBpf() external view returns (uint128 endBpf);

function getEvenGerminating(address token) external view returns (uint256, uint256);
Expand Down
9 changes: 8 additions & 1 deletion protocol/hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ const {
BEAN_ETH_WELL,
BCM,
L2_BCM,
L2_BEANSTALK
L2_BEANSTALK,
BEAN
} = require("./test/hardhat/utils/constants.js");
const { to6 } = require("./test/hardhat/utils/helpers.js");
//const { replant } = require("./replant/replant.js")
Expand Down Expand Up @@ -132,6 +133,12 @@ task("getTime", async function () {
console.log("Current time: ", await this.seasonGetter.time());
});

task("tokenSettings", async function () {
beanstalk = await getBeanstalk("0xD1A0060ba708BC4BCD3DA6C37EFa8deDF015FB70");
const tokenSettings = await beanstalk.tokenSettings("0xBEA0005B8599265D41256905A9B3073D397812E4");
console.log(tokenSettings);
});

/*task('replant', async () => {
const account = await impersonateSigner(PUBLIUS)
await replant(account)
Expand Down
Loading
Loading