From c0bbdc042ac1d52f6d15b9cb0dd72d8190338cf9 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Fri, 7 Jun 2024 12:22:14 -0600 Subject: [PATCH 01/43] Update migrate all test to fork from recent block --- protocol/test/StemMigrateAll.test.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/protocol/test/StemMigrateAll.test.js b/protocol/test/StemMigrateAll.test.js index b71327d0eb..20bbf805e1 100644 --- a/protocol/test/StemMigrateAll.test.js +++ b/protocol/test/StemMigrateAll.test.js @@ -10,7 +10,7 @@ const { BigNumber } = require('ethers'); const { EXTERNAL, INTERNAL, INTERNAL_EXTERNAL, INTERNAL_TOLERANT } = require('./utils/balances.js') const { expect } = require('chai'); -const BLOCK_NUMBER = 17301500; //a recent block number. Using this so that the currentStalkDiff in _mowAndMigrateMerkleCheck is exercised +const BLOCK_NUMBER = 20000000; //a recent block number. Using this so that the currentStalkDiff in _mowAndMigrateMerkleCheck is exercised //17251905 is the block the enroot fix was deployed @@ -49,7 +49,7 @@ const eventsAbi = [ } ]; -describe.skip('Silo V3: Stem deployment migrate everyone', function () { +describe.only('Silo V3: Stem deployment migrate everyone', function () { before(async function () { try { @@ -76,7 +76,22 @@ describe.skip('Silo V3: Stem deployment migrate everyone', function () { await upgradeWithNewFacets({ diamondAddress: BEANSTALK, facetNames: ['ConvertFacet', 'WhitelistFacet', 'MockSiloFacet', 'MockSeasonFacet', 'MigrationFacet'], - // libraryNames: ['LibLegacyTokenSilo'], + libraryNames: ['LibConvert', 'LibSilo', 'LibGauge', 'LibIncentive', 'LibLockedUnderlying', 'LibCurveMinting', 'LibGerminate'], + facetLibraries: { + 'ConvertFacet': [ + 'LibConvert' + ], + 'MockSiloFacet': [ + 'LibSilo' + ], + 'MockSeasonFacet': [ + 'LibGauge', + 'LibIncentive', + 'LibLockedUnderlying', + 'LibCurveMinting', + 'LibGerminate' + ], + }, initFacetName: 'InitBipNewSilo', bip: false, object: false, From f0a9ec66a204c844b4bb3138ae35f1d0ae3f4162 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Fri, 7 Jun 2024 14:24:42 -0600 Subject: [PATCH 02/43] Log accounts that aren't able to migrate --- protocol/contracts/libraries/Silo/LibSilo.sol | 7 ++++ .../contracts/libraries/Silo/LibTokenSilo.sol | 3 ++ protocol/test/StemMigrateAll.test.js | 40 ++++++++++++++++--- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 3e51c25897..ea7890dbea 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -16,6 +16,7 @@ import {LibSafeMath32} from "../LibSafeMath32.sol"; import {LibSafeMathSigned96} from "../LibSafeMathSigned96.sol"; import {LibGerminate} from "./LibGerminate.sol"; import {LibWhitelistedTokens} from "./LibWhitelistedTokens.sol"; +import {console} from "hardhat/console.sol"; /** * @title LibSilo @@ -250,6 +251,12 @@ library LibSilo { // Decrease supply of Stalk; Remove Stalk from the balance of `account` s.s.stalk = s.s.stalk.sub(stalk); + if (stalk > s.a[account].s.stalk) { + console.log("burning too much"); + console.log("account: ", account); + console.log("stalk: ", stalk); + console.log("s.a[account].s.stalk: ", s.a[account].s.stalk); + } s.a[account].s.stalk = s.a[account].s.stalk.sub(stalk); // Decrease supply of Roots; Remove Roots from the balance of `account` diff --git a/protocol/contracts/libraries/Silo/LibTokenSilo.sol b/protocol/contracts/libraries/Silo/LibTokenSilo.sol index b03a0c6967..a79372df1f 100644 --- a/protocol/contracts/libraries/Silo/LibTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibTokenSilo.sol @@ -16,6 +16,7 @@ import {LibSafeMathSigned96} from "contracts/libraries/LibSafeMathSigned96.sol"; import {LibBytes} from "contracts/libraries/LibBytes.sol"; import {LibGerminate} from "contracts/libraries/Silo/LibGerminate.sol"; import {LibWhitelistedTokens} from "contracts/libraries/Silo/LibWhitelistedTokens.sol"; +import {console} from "hardhat/console.sol"; /** * @title LibTokenSilo @@ -152,6 +153,8 @@ library LibTokenSilo { } // decrement germinating amount and bdv. + console.log("germinate.deposited[token].amount: ", germinate.deposited[token].amount); + console.log("amount: ", amount); germinate.deposited[token].amount = germinate.deposited[token].amount.sub( amount.toUint128() ); diff --git a/protocol/test/StemMigrateAll.test.js b/protocol/test/StemMigrateAll.test.js index 20bbf805e1..e96c9d061e 100644 --- a/protocol/test/StemMigrateAll.test.js +++ b/protocol/test/StemMigrateAll.test.js @@ -10,6 +10,7 @@ const { BigNumber } = require('ethers'); const { EXTERNAL, INTERNAL, INTERNAL_EXTERNAL, INTERNAL_TOLERANT } = require('./utils/balances.js') const { expect } = require('chai'); +// 17301500 20000000 const BLOCK_NUMBER = 20000000; //a recent block number. Using this so that the currentStalkDiff in _mowAndMigrateMerkleCheck is exercised //17251905 is the block the enroot fix was deployed @@ -73,6 +74,7 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { const signer = await impersonateBeanstalkOwner(); // const signer = await impersonateSigner(BCM); await mintEth(signer.address); + await upgradeWithNewFacets({ diamondAddress: BEANSTALK, facetNames: ['ConvertFacet', 'WhitelistFacet', 'MockSiloFacet', 'MockSeasonFacet', 'MigrationFacet'], @@ -483,7 +485,7 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { //load stalk balance changed from disk let stalkChanges = JSON.parse(await fs.readFileSync(__dirname + '/data/stalk_balance_changed.json')); - console.log('stalkChanges: ', stalkChanges); + // console.log('stalkChanges: ', stalkChanges); //load seed balance changed from disk let seedChanges = JSON.parse(await fs.readFileSync(__dirname + '/data/seed_balance_changed.json')); @@ -496,9 +498,11 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { const eventsInterface = new ethers.utils.Interface(eventsAbi); + var failed = 0; + var failedAccounts = []; + var progress = 0; for (const depositorAddress in deposits) { - console.log('progress:', progress, 'depositorAddress: ', depositorAddress); const tokens = deposits[depositorAddress]['tokenAddresses']; const seasons = deposits[depositorAddress]['seasonsArray']; @@ -517,10 +521,32 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { const depositorSigner = await impersonateSigner(depositorAddress); mintEth(depositorAddress); await this.silo.connect(depositorSigner); - - const migrateResult = await this.migrate.mowAndMigrate(depositorAddress, tokens, seasons, amounts, stalkDiff, seedsDiff, proof); - const receipt = await migrateResult.wait(); + + var migrateResult; + var receipt; + + try { + migrateResult = await this.migrate.mowAndMigrate(depositorAddress, tokens, seasons, amounts, stalkDiff, seedsDiff, proof); + receipt = await migrateResult.wait(); + + console.log('migrated, progress:', progress, 'depositorAddress: ', depositorAddress); + } catch (error) { + failed++; + failedAccounts.push(depositorAddress); + console.log('failed: ', depositorAddress); + continue; + } + + // the below commented out code withdraws all deposits to verify that they can be withdrawn, + // but now with germination, we would need to wait a couple seasons before withdrawing + // so just commenting out for now to verify that migration itself works fine + + + await this.season.fastForward(3); + + // advance two seasons + /* const migratedDeposits = []; //stores AddDeposit events emitted by migrate let migrateStalkBalanceChanged = BigNumber.from(0); //stores stalk balance changes from migrate @@ -565,6 +591,7 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { let stalkDeltaSum = ethers.BigNumber.from(0); let seedDeltaSum = ethers.BigNumber.from(0); + for (let k = 0; k < migratedDeposits.length; k++) { const migratedDeposit = migratedDeposits[k]; const withdraw = await this.silo.connect(depositorSigner).withdrawDeposit(migratedDeposit.token, migratedDeposit.stem, migratedDeposit.amount, EXTERNAL); @@ -588,9 +615,12 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { const finalSeedSum = seedDeltaSum.add(seedBalanceChangedSum).add(migrateSeedBalanceChanged); expect(finalSeedSum).to.equal('0'); + */ progress++; } + console.log('failed count: ', failed); + console.log('failed accounts: ', failedAccounts); }); }); }); \ No newline at end of file From f237c2983c6544c1a60aa1d2eea855ce063063d6 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Fri, 7 Jun 2024 15:01:42 -0600 Subject: [PATCH 03/43] Fix for migration --- .../beanstalk/silo/MigrationFacet.sol | 4 +-- .../libraries/Silo/LibLegacyTokenSilo.sol | 30 ++++++++++++------- protocol/test/StemMigrateAll.test.js | 14 ++++----- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/MigrationFacet.sol b/protocol/contracts/beanstalk/silo/MigrationFacet.sol index 21e3beefcb..b5a6411c53 100644 --- a/protocol/contracts/beanstalk/silo/MigrationFacet.sol +++ b/protocol/contracts/beanstalk/silo/MigrationFacet.sol @@ -47,9 +47,9 @@ contract MigrationFacet is ReentrancyGuard { uint256 seedsDiff, bytes32[] calldata proof ) external payable { - uint256 seedsVariance = LibLegacyTokenSilo._mowAndMigrate(account, tokens, seasons, amounts); + (uint256 seedsVariance, uint256 totalBdv) = LibLegacyTokenSilo._mowAndMigrate(account, tokens, seasons, amounts); //had to break up the migration function into two parts to avoid stack too deep errors - LibLegacyTokenSilo._mowAndMigrateMerkleCheck(account, stalkDiff, seedsDiff, proof, seedsVariance); + LibLegacyTokenSilo._mowAndMigrateMerkleCheck(account, stalkDiff, seedsDiff, proof, seedsVariance, totalBdv); } /** diff --git a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol index 7cee80c503..b4b27ab730 100644 --- a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol @@ -71,6 +71,7 @@ library LibLegacyTokenSilo { struct MigrateData { uint128 totalSeeds; uint128 totalGrownStalk; + uint256 totalBdv; } struct PerDepositData { @@ -82,6 +83,7 @@ library LibLegacyTokenSilo { struct PerTokenData { address token; int96 stemTip; + uint256 crateBDV; } //////////////////////// REMOVE DEPOSIT //////////////////////// @@ -251,14 +253,14 @@ library LibLegacyTokenSilo { * Deposits are migrated to the stem storage system on a 1:1 basis. Accounts with * lots of deposits may take a considerable amount of gas to migrate. * - * Returns seeds diff compared to stored amount, for verification in merkle check. + * Returns seeds diff compared to stored amount, for verification in merkle check, and total bdv. */ function _mowAndMigrate( address account, address[] calldata tokens, uint32[][] calldata seasons, uint256[][] calldata amounts - ) internal returns (uint256) { + ) internal returns (uint256, uint256) { // Validates whether a user needs to perform migration. checkForMigration(account); @@ -289,22 +291,25 @@ library LibLegacyTokenSilo { } // withdraw this deposit - uint256 crateBDV = removeDepositFromAccount( + perTokenData.crateBDV = removeDepositFromAccount( account, perTokenData.token, perDepositData.season, perDepositData.amount ); + // add to running total of bdv + migrateData.totalBdv = migrateData.totalBdv.add(perTokenData.crateBDV); + // calculate how much stalk has grown for this deposit perDepositData.grownStalk = _calcGrownStalkForDeposit( - crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))), + perTokenData.crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))), perDepositData.season ); // also need to calculate how much stalk has grown since the migration uint128 stalkGrownSinceStemStartSeason = LibSilo - .stalkReward(0, perTokenData.stemTip, crateBDV.toUint128()) + .stalkReward(0, perTokenData.stemTip, perTokenData.crateBDV.toUint128()) .toUint128(); perDepositData.grownStalk = perDepositData.grownStalk.add( stalkGrownSinceStemStartSeason @@ -320,16 +325,16 @@ library LibLegacyTokenSilo { LibTokenSilo.grownStalkAndBdvToStem( perTokenData.token, perDepositData.grownStalk, - crateBDV + perTokenData.crateBDV ), perDepositData.amount, - crateBDV, + perTokenData.crateBDV, LibTokenSilo.Transfer.emitTransferSingle ); // add to running total of seeds migrateData.totalSeeds = migrateData.totalSeeds.add( - crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))).toUint128() + perTokenData.crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))).toUint128() ); // emit legacy RemoveDeposit event @@ -349,7 +354,7 @@ library LibLegacyTokenSilo { LibSilo.mintActiveStalk(account, migrateData.totalGrownStalk); //return seeds diff for checking in the "part 2" of this function (stack depth kept it from all fitting in one) - return balanceOfSeeds(account).sub(migrateData.totalSeeds); + return (balanceOfSeeds(account).sub(migrateData.totalSeeds), migrateData.totalBdv); } function _mowAndMigrateMerkleCheck( @@ -357,7 +362,8 @@ library LibLegacyTokenSilo { uint256 stalkDiff, uint256 seedsDiff, bytes32[] calldata proof, - uint256 seedsVariance + uint256 seedsVariance, + uint256 totalBdv ) internal { if (seedsDiff > 0) { // verify merkle tree to determine stalk/seeds diff drift from convert issue @@ -382,7 +388,9 @@ library LibLegacyTokenSilo { // stalk diff was calculated based on ENROOT_FIX_SEASON, so we need to calculate // the amount of stalk that has grown since then - if (seedsDiff > 0) { + // if totalBdv is zero, the stalk diff should be zero, so we can skip this step. + if (seedsDiff > 0 && totalBdv > 3) { + console.log("totalBdv: ", totalBdv); uint256 currentStalkDiff = (uint256(s.season.current).sub(ENROOT_FIX_SEASON)) .mul(seedsDiff) .add(stalkDiff); diff --git a/protocol/test/StemMigrateAll.test.js b/protocol/test/StemMigrateAll.test.js index e96c9d061e..b65d46d999 100644 --- a/protocol/test/StemMigrateAll.test.js +++ b/protocol/test/StemMigrateAll.test.js @@ -525,18 +525,18 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { var migrateResult; var receipt; - try { + // try { migrateResult = await this.migrate.mowAndMigrate(depositorAddress, tokens, seasons, amounts, stalkDiff, seedsDiff, proof); receipt = await migrateResult.wait(); console.log('migrated, progress:', progress, 'depositorAddress: ', depositorAddress); - } catch (error) { - failed++; - failedAccounts.push(depositorAddress); - console.log('failed: ', depositorAddress); - continue; - } + // } catch (error) { + // failed++; + // failedAccounts.push(depositorAddress); + // console.log('failed: ', depositorAddress); + // continue; + // } // the below commented out code withdraws all deposits to verify that they can be withdrawn, // but now with germination, we would need to wait a couple seasons before withdrawing From acdeb077ca422358b19ede8d0c5ec1d9a57e230a Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Fri, 7 Jun 2024 21:19:12 -0600 Subject: [PATCH 04/43] Stalk burn fix --- .../libraries/Silo/LibLegacyTokenSilo.sol | 15 ++++++++++++-- protocol/contracts/libraries/Silo/LibSilo.sol | 2 +- protocol/test/StemMigrateAll.test.js | 20 +++++++++++-------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol index b4b27ab730..d6fc16a092 100644 --- a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol @@ -39,6 +39,8 @@ library LibLegacyTokenSilo { bytes32 constant DISCREPANCY_MERKLE_ROOT = 0xa84dc86252c556839dff46b290f0c401088a65584aa38a163b6b3f7dd7a5b0e8; uint32 constant ENROOT_FIX_SEASON = 12793; //season in which enroot ebip-8 fix was deployed + // "silo V3 was deployed on block 17671557. the following sunrise was at block 17671715" + uint32 constant SILOV3_DEPLOYMENT_SEASON = 14210; //season in which silov3 was deployed //this is the legacy seasons-based remove deposits event, emitted on migration event RemoveDeposit( @@ -389,12 +391,21 @@ library LibLegacyTokenSilo { // stalk diff was calculated based on ENROOT_FIX_SEASON, so we need to calculate // the amount of stalk that has grown since then // if totalBdv is zero, the stalk diff should be zero, so we can skip this step. - if (seedsDiff > 0 && totalBdv > 3) { + // && totalBdv > 3 + if (seedsDiff > 0) { console.log("totalBdv: ", totalBdv); - uint256 currentStalkDiff = (uint256(s.season.current).sub(ENROOT_FIX_SEASON)) + uint256 currentStalkDiff = uint256(SILOV3_DEPLOYMENT_SEASON - ENROOT_FIX_SEASON) .mul(seedsDiff) .add(stalkDiff); + console.log("uint256(s.season.current): ", uint256(s.season.current)); + console.log("ENROOT_FIX_SEASON: ", ENROOT_FIX_SEASON); + console.log("seedsDiff: ", seedsDiff); + console.log("stalkDiff: ", stalkDiff); + console.log("seasons diff: ", (uint256(s.season.current).sub(ENROOT_FIX_SEASON))); + + console.log("currentStalkDiff: ", currentStalkDiff); + // emit the stalk variance. // all deposits in siloV2 are not germinating. if (currentStalkDiff > 0) { diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index ea7890dbea..fd22c973e3 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -252,7 +252,7 @@ library LibSilo { // Decrease supply of Stalk; Remove Stalk from the balance of `account` s.s.stalk = s.s.stalk.sub(stalk); if (stalk > s.a[account].s.stalk) { - console.log("burning too much"); + console.log("burning too much, by amount: ", stalk.sub(s.a[account].s.stalk)); console.log("account: ", account); console.log("stalk: ", stalk); console.log("s.a[account].s.stalk: ", s.a[account].s.stalk); diff --git a/protocol/test/StemMigrateAll.test.js b/protocol/test/StemMigrateAll.test.js index b65d46d999..18d725a6c5 100644 --- a/protocol/test/StemMigrateAll.test.js +++ b/protocol/test/StemMigrateAll.test.js @@ -525,18 +525,22 @@ describe.only('Silo V3: Stem deployment migrate everyone', function () { var migrateResult; var receipt; - // try { + if (stalkDiff > 0) { + console.log('passing in stalk diff of ', stalkDiff); + } + + try { + console.log('migrating, progress:', progress, 'depositorAddress: ', depositorAddress); migrateResult = await this.migrate.mowAndMigrate(depositorAddress, tokens, seasons, amounts, stalkDiff, seedsDiff, proof); receipt = await migrateResult.wait(); - console.log('migrated, progress:', progress, 'depositorAddress: ', depositorAddress); - // } catch (error) { - // failed++; - // failedAccounts.push(depositorAddress); - // console.log('failed: ', depositorAddress); - // continue; - // } + } catch (error) { + failed++; + failedAccounts.push(depositorAddress); + console.log('failed: ', depositorAddress); + continue; + } // the below commented out code withdraws all deposits to verify that they can be withdrawn, // but now with germination, we would need to wait a couple seasons before withdrawing From 64304d11385280deeec525c7b112bef9cc58b8e0 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 21:34:06 -0500 Subject: [PATCH 05/43] implement non-zero fill value. --- .../market/MarketplaceFacet/Order.sol | 1 + protocol/test/Marketplace.test.js | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol b/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol index 1dd530e813..00a0ba43cc 100644 --- a/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol +++ b/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol @@ -61,6 +61,7 @@ contract Order is Listing { ) internal returns (bytes32 id) { require(beanAmount > 0, "Marketplace: Order amount must be > 0."); require(pricePerPod > 0, "Marketplace: Pod price must be greater than 0."); + require(minFillAmount > 0, "Marketplace: Minimum fill amount must be greater than 0."); id = createOrderId(msg.sender, pricePerPod, maxPlaceInLine, minFillAmount); diff --git a/protocol/test/Marketplace.test.js b/protocol/test/Marketplace.test.js index e08e06b1ab..ba62842a30 100644 --- a/protocol/test/Marketplace.test.js +++ b/protocol/test/Marketplace.test.js @@ -1286,13 +1286,13 @@ describe('Marketplace', function () { describe("Create", async function () { describe("revert", async function () { it("Reverts if price is 0", async function () { - await expect(this.marketplace.connect(user2).createPodOrder("100", "0", "100000", '0', EXTERNAL)).to.be.revertedWith("Marketplace: Pod price must be greater than 0."); + await expect(this.marketplace.connect(user2).createPodOrder("100", "0", "100000", '1', EXTERNAL)).to.be.revertedWith("Marketplace: Pod price must be greater than 0."); }); it("Reverts if amount is 0", async function () { await expect( this.marketplace .connect(user2) - .createPodOrder("0", "100000", "100000", '0', EXTERNAL) + .createPodOrder("0", "100000", "100000", '1', EXTERNAL) ).to.be.revertedWith("Marketplace: Order amount must be > 0."); }); }); @@ -1305,7 +1305,7 @@ describe('Marketplace', function () { ); this.result = await this.marketplace .connect(user) - .createPodOrder("500", "100000", "1000", '0', EXTERNAL); + .createPodOrder("500", "100000", "1000", '1', EXTERNAL); this.id = await getOrderId(this.result); this.userBeanBalanceAfter = await this.bean.balanceOf(userAddress); this.beanstalkBeanBalanceAfter = await this.bean.balanceOf( @@ -1325,7 +1325,7 @@ describe('Marketplace', function () { it("Creates the order", async function () { expect(await this.marketplace.podOrderById(this.id)).to.equal("500"); expect( - await this.marketplace.podOrder(userAddress, "100000", "1000", '0') + await this.marketplace.podOrder(userAddress, "100000", "1000", '1') ).to.equal("500"); }); @@ -1336,9 +1336,9 @@ describe('Marketplace', function () { }); it("cancels old order, replacing with new order", async function () { - let newOrder = await this.marketplace.connect(user).createPodOrder("100", "100000", "1000", '0', EXTERNAL); + let newOrder = await this.marketplace.connect(user).createPodOrder("100", "100000", "1000", '1', EXTERNAL); expect(newOrder).to.emit(this.marketplace, "PodOrderCancelled").withArgs(userAddress, this.id); - expect(await this.marketplace.podOrder(userAddress, "100000", "1000", "0")).to.equal("100"); + expect(await this.marketplace.podOrder(userAddress, "100000", "1000", "1")).to.equal("100"); }) }); @@ -1630,7 +1630,7 @@ describe('Marketplace', function () { describe("Cancel", async function () { beforeEach(async function () { - this.result = await this.marketplace.connect(user).createPodOrder('500', '100000', '1000', '0', EXTERNAL) + this.result = await this.marketplace.connect(user).createPodOrder('500', '100000', '1000', '1', EXTERNAL) this.id = await getOrderId(this.result) }) @@ -1638,7 +1638,7 @@ describe('Marketplace', function () { beforeEach(async function () { this.userBeanBalance = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalance = await this.bean.balanceOf(this.marketplace.address) - this.result = await this.marketplace.connect(user).cancelPodOrder('100000', '1000', '0', EXTERNAL); + this.result = await this.marketplace.connect(user).cancelPodOrder('100000', '1000', '1', EXTERNAL); this.userBeanBalanceAfter = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalanceAfter = await this.bean.balanceOf(this.marketplace.address) }) @@ -1662,7 +1662,7 @@ describe('Marketplace', function () { beforeEach(async function () { this.userBeanBalance = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalance = await this.bean.balanceOf(this.marketplace.address) - this.result = await this.marketplace.connect(user).cancelPodOrder('100000', '1000', '0', INTERNAL); + this.result = await this.marketplace.connect(user).cancelPodOrder('100000', '1000', '1', INTERNAL); this.userBeanBalanceAfter = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalanceAfter = await this.bean.balanceOf(this.marketplace.address) }) From c2a6b9507bd2d706e8d03ce1cc97a60fabb64a9a Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 21:42:48 -0500 Subject: [PATCH 06/43] add scripts. --- protocol/hardhat.config.js | 6 +++++- protocol/scripts/ebips.js | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/protocol/hardhat.config.js b/protocol/hardhat.config.js index ef7f61558b..99b5ae321e 100644 --- a/protocol/hardhat.config.js +++ b/protocol/hardhat.config.js @@ -29,7 +29,7 @@ const { BEANSTALK, PUBLIUS, BEAN_3_CURVE, PRICE } = require("./test/utils/consta const { task } = require("hardhat/config"); const { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } = require("hardhat/builtin-tasks/task-names"); const { bipNewSilo, bipMorningAuction, bipSeedGauge } = require("./scripts/bips.js"); -const { ebip9, ebip10, ebip11, ebip13, ebip14, ebip15, ebip16 } = require("./scripts/ebips.js"); +const { ebip9, ebip10, ebip11, ebip13, ebip14, ebip15, ebip16, ebip17 } = require("./scripts/ebips.js"); //////////////////////// UTILITIES //////////////////////// @@ -220,6 +220,10 @@ task("deploySeedGauge", async function () { /// EBIPS /// +task("ebip17", async function () { + await ebip17(); +}) + task("ebip16", async function () { await ebip16(); }) diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index 298354aa9d..4c3ac8b2f1 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -188,6 +188,22 @@ async function ebip16(mock = true, account = undefined) { }); } +async function ebip17(mock = true, account = undefined) { + if (account == undefined) { + account = await impersonateBeanstalkOwner(); + await mintEth(account.address); + } + + await upgradeWithNewFacets({ + diamondAddress: BEANSTALK, + facetNames: ["MarketplaceFacet"], + bip: false, + object: !mock, + verbose: true, + account: account + }); +} + async function bipDiamondCut(name, dc, account, mock = true) { beanstalk = await getBeanstalk(); @@ -215,4 +231,5 @@ exports.ebip11 = ebip11; exports.ebip13 = ebip13; exports.ebip14 = ebip14; exports.ebip15 = ebip15; -exports.ebip16 = ebip16; \ No newline at end of file +exports.ebip16 = ebip16; +exports.ebip17 = ebip17; \ No newline at end of file From 2aceae9f55cae2d36ddb28dfacc7912ba8e28158 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 21:50:05 -0500 Subject: [PATCH 07/43] add additional min fill test. --- protocol/test/Marketplace.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/protocol/test/Marketplace.test.js b/protocol/test/Marketplace.test.js index ba62842a30..18acfadf95 100644 --- a/protocol/test/Marketplace.test.js +++ b/protocol/test/Marketplace.test.js @@ -1295,6 +1295,13 @@ describe('Marketplace', function () { .createPodOrder("0", "100000", "100000", '1', EXTERNAL) ).to.be.revertedWith("Marketplace: Order amount must be > 0."); }); + it("Reverts if minFill is 0", async function () { + await expect( + this.marketplace + .connect(user2) + .createPodOrder("100", "100000", "100000", '0', EXTERNAL) + ).to.be.revertedWith("Marketplace: Minimum fill amount must be greater than 0."); + }); }); describe("create order", async function () { From eb24bc9d7951162ade84f1b09733edaeaf7b247a Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 22:05:36 -0500 Subject: [PATCH 08/43] Update _createPodOrderV2 and tests. --- .../market/MarketplaceFacet/Order.sol | 1 + protocol/test/Marketplace.test.js | 24 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol b/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol index 00a0ba43cc..0645195244 100644 --- a/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol +++ b/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol @@ -79,6 +79,7 @@ contract Order is Listing { bytes calldata pricingFunction ) internal returns (bytes32 id) { require(beanAmount > 0, "Marketplace: Order amount must be > 0."); + require(minFillAmount > 0, "Marketplace: Pod price must be greater than 0."); id = createOrderIdV2(msg.sender, 0, maxPlaceInLine, minFillAmount, pricingFunction); if (s.podOrders[id] > 0) _cancelPodOrderV2(maxPlaceInLine, minFillAmount, pricingFunction, LibTransfer.To.INTERNAL); s.podOrders[id] = beanAmount; diff --git a/protocol/test/Marketplace.test.js b/protocol/test/Marketplace.test.js index 18acfadf95..b21e2d8e51 100644 --- a/protocol/test/Marketplace.test.js +++ b/protocol/test/Marketplace.test.js @@ -1698,12 +1698,16 @@ describe('Marketplace', function () { describe("Create", async function () { describe("revert", async function () { it("Reverts if amount is 0", async function () { - await expect(this.marketplace.connect(user2).createPodOrderV2("0","1000",'0',this.f.packedFunction,EXTERNAL)).to.be.revertedWith("Marketplace: Order amount must be > 0."); + await expect(this.marketplace.connect(user2).createPodOrderV2("0","1000",'1',this.f.packedFunction,EXTERNAL)).to.be.revertedWith("Marketplace: Order amount must be > 0."); + }); + + it("Reverts if minFill is 0", async function () { + await expect(this.marketplace.connect(user2).createPodOrderV2("500","1000",'0',this.f.packedFunction,EXTERNAL)).to.be.revertedWith("Marketplace: Order amount must be > 0."); }); it("Reverts with invalid function", async function () { let brokenFunction = this.f.packedFunction.slice(0,-2); - await expect(this.marketplace.connect(user2).createPodOrderV2("500","1000",'0',brokenFunction,EXTERNAL)).to.be.revertedWith("Marketplace: Invalid pricing function."); + await expect(this.marketplace.connect(user2).createPodOrderV2("500","1000",'1',brokenFunction,EXTERNAL)).to.be.revertedWith("Marketplace: Invalid pricing function."); }); }); @@ -1714,7 +1718,7 @@ describe('Marketplace', function () { this.beanstalkBeanBalance = await this.bean.balanceOf( this.marketplace.address ); - this.result = await this.marketplace.connect(user).createPodOrderV2("500","1000",'0',this.f.packedFunction,EXTERNAL); + this.result = await this.marketplace.connect(user).createPodOrderV2("500","1000",'1',this.f.packedFunction,EXTERNAL); this.id = await getOrderId(this.result); this.userBeanBalanceAfter = await this.bean.balanceOf(userAddress); this.beanstalkBeanBalanceAfter = await this.bean.balanceOf( @@ -1737,7 +1741,7 @@ describe('Marketplace', function () { await this.marketplace.podOrderV2( userAddress, "1000", - '0', + '1', this.f.packedFunction ) ).to.equal("500"); @@ -1759,16 +1763,16 @@ describe('Marketplace', function () { }); it("cancels old order, replacing with new order", async function () { - let newOrder = await this.marketplace.connect(user).createPodOrderV2("100", "1000", '0', this.f.packedFunction, EXTERNAL); + let newOrder = await this.marketplace.connect(user).createPodOrderV2("100", "1000", '1', this.f.packedFunction, EXTERNAL); expect(newOrder).to.emit(this.marketplace, "PodOrderCancelled").withArgs(userAddress, this.id); - expect(await this.marketplace.podOrderV2(userAddress, "1000", "0", this.f.packedFunction)).to.equal("100"); + expect(await this.marketplace.podOrderV2(userAddress, "1000", "1", this.f.packedFunction)).to.equal("100"); }) }); }); describe("Fill", async function () { beforeEach(async function () { - this.result = await this.marketplace.connect(user).createPodOrderV2("50", "2500", '0', this.f.packedFunction, EXTERNAL); + this.result = await this.marketplace.connect(user).createPodOrderV2("50", "2500", '1', this.f.packedFunction, EXTERNAL); this.id = await getOrderId(this.result); this.order = [userAddress, "0", "2500", '0']; }); @@ -1973,7 +1977,7 @@ describe('Marketplace', function () { describe("Cancel", async function () { beforeEach(async function () { - this.result = await this.marketplace.connect(user).createPodOrderV2('500','1000','0', this.f.packedFunction, EXTERNAL) + this.result = await this.marketplace.connect(user).createPodOrderV2('500','1000','1', this.f.packedFunction, EXTERNAL) this.id = await getOrderId(this.result) }) @@ -1981,7 +1985,7 @@ describe('Marketplace', function () { beforeEach(async function () { this.userBeanBalance = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalance = await this.bean.balanceOf(this.marketplace.address) - this.result = await this.marketplace.connect(user).cancelPodOrderV2('1000', '0', this.f.packedFunction, EXTERNAL); + this.result = await this.marketplace.connect(user).cancelPodOrderV2('1000', '1', this.f.packedFunction, EXTERNAL); this.userBeanBalanceAfter = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalanceAfter = await this.bean.balanceOf(this.marketplace.address) }) @@ -2005,7 +2009,7 @@ describe('Marketplace', function () { beforeEach(async function () { this.userBeanBalance = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalance = await this.bean.balanceOf(this.marketplace.address) - this.result = await this.marketplace.connect(user).cancelPodOrderV2('1000', '0', this.f.packedFunction, INTERNAL); + this.result = await this.marketplace.connect(user).cancelPodOrderV2('1000', '1', this.f.packedFunction, INTERNAL); this.userBeanBalanceAfter = await this.bean.balanceOf(userAddress) this.beanstalkBeanBalanceAfter = await this.bean.balanceOf(this.marketplace.address) }) From b3734d7bdcbb916b6fbe675cacfcccd6f37e0645 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 22:12:35 -0500 Subject: [PATCH 09/43] update tests. --- protocol/test/Marketplace.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol/test/Marketplace.test.js b/protocol/test/Marketplace.test.js index b21e2d8e51..444793b350 100644 --- a/protocol/test/Marketplace.test.js +++ b/protocol/test/Marketplace.test.js @@ -1702,7 +1702,7 @@ describe('Marketplace', function () { }); it("Reverts if minFill is 0", async function () { - await expect(this.marketplace.connect(user2).createPodOrderV2("500","1000",'0',this.f.packedFunction,EXTERNAL)).to.be.revertedWith("Marketplace: Order amount must be > 0."); + await expect(this.marketplace.connect(user2).createPodOrderV2("500","1000",'0',this.f.packedFunction,EXTERNAL)).to.be.revertedWith("Marketplace: Pod price must be greater than 0."); }); it("Reverts with invalid function", async function () { @@ -1756,7 +1756,7 @@ describe('Marketplace', function () { "500", 0, "1000", - '0', + '1', this.f.packedFunction, Dynamic ); @@ -1774,7 +1774,7 @@ describe('Marketplace', function () { beforeEach(async function () { this.result = await this.marketplace.connect(user).createPodOrderV2("50", "2500", '1', this.f.packedFunction, EXTERNAL); this.id = await getOrderId(this.result); - this.order = [userAddress, "0", "2500", '0']; + this.order = [userAddress, "0", "2500", '1']; }); describe("revert", async function () { From 0990b40b5b40e6a15992bfe63e1abad8cf13f19f Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 22:56:03 -0500 Subject: [PATCH 10/43] add init script. --- .../contracts/beanstalk/init/InitEbip17.sol | 46 +++++++++++++++++++ protocol/scripts/ebips.js | 1 + 2 files changed, 47 insertions(+) create mode 100644 protocol/contracts/beanstalk/init/InitEbip17.sol diff --git a/protocol/contracts/beanstalk/init/InitEbip17.sol b/protocol/contracts/beanstalk/init/InitEbip17.sol new file mode 100644 index 0000000000..fddd1e61c8 --- /dev/null +++ b/protocol/contracts/beanstalk/init/InitEbip17.sol @@ -0,0 +1,46 @@ +/* + SPDX-License-Identifier: MIT +*/ + +pragma solidity =0.7.6; +pragma experimental ABIEncoderV2; + +import {AppStorage} from "../AppStorage.sol"; + +/** + * @author Brean + * @title InitEBip17 cancels the invalid pod orders, and recreates the pod orders with the correct values. + **/ +contract InitEbip17 { + AppStorage internal s; + + // there are 4 existing pod orders, 2 of which have a min fill amount of 0. + // 0x0503e8467eb328bcb9b1f2656db905311d47cb14ea1955b8a0c8441d8943ca33, + // 0xf47df2678d29e9d57c5e9ed5f8c990e71910918154a2ed6d5235718035d7d8b0. + // these orders are invalid, as they have a min fill amount of 0, and will need to be re-created. + function init() external { + // get bean order values. + uint256 beanAmount0 = s.podOrders[0x0503e8467eb328bcb9b1f2656db905311d47cb14ea1955b8a0c8441d8943ca33]; + uint256 beanAmount1 = s.podOrders[0xf47df2678d29e9d57c5e9ed5f8c990e71910918154a2ed6d5235718035d7d8b0]; + + // cancel orders. + delete s.podOrders[0x0503e8467eb328bcb9b1f2656db905311d47cb14ea1955b8a0c8441d8943ca33]; + delete s.podOrders[0xf47df2678d29e9d57c5e9ed5f8c990e71910918154a2ed6d5235718035d7d8b0]; + + // reinitalize orders, with a min fill amount of 1. + s.podOrders[createOrderId(address(0x8a9C930896e453cA3D87f1918996423A589Dd529), 1000, 109233726000000, 1)] = beanAmount0; + s.podOrders[createOrderId(address(0x8a9C930896e453cA3D87f1918996423A589Dd529), 1000, 109233726000000, 1)] = beanAmount1; + } + + // see: {Order.createOrderId} + function createOrderId( + address account, + uint24 pricePerPod, + uint256 maxPlaceInLine, + uint256 minFillAmount + ) internal pure returns (bytes32 id) { + if(minFillAmount > 0) id = keccak256(abi.encodePacked(account, pricePerPod, maxPlaceInLine, minFillAmount)); + else id = keccak256(abi.encodePacked(account, pricePerPod, maxPlaceInLine)); + } + +} diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index 4c3ac8b2f1..819ddae372 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -197,6 +197,7 @@ async function ebip17(mock = true, account = undefined) { await upgradeWithNewFacets({ diamondAddress: BEANSTALK, facetNames: ["MarketplaceFacet"], + initFacetName: "InitBipSeedGauge", bip: false, object: !mock, verbose: true, From c9f93d0b926035cb5295564a9cb1c1a0f77c2ebb Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 23:25:45 -0500 Subject: [PATCH 11/43] add fill validation, remove init scripts. --- .../contracts/beanstalk/init/InitEbip17.sol | 46 ------------------- .../market/MarketplaceFacet/Order.sol | 2 + protocol/scripts/ebips.js | 1 - 3 files changed, 2 insertions(+), 47 deletions(-) delete mode 100644 protocol/contracts/beanstalk/init/InitEbip17.sol diff --git a/protocol/contracts/beanstalk/init/InitEbip17.sol b/protocol/contracts/beanstalk/init/InitEbip17.sol deleted file mode 100644 index fddd1e61c8..0000000000 --- a/protocol/contracts/beanstalk/init/InitEbip17.sol +++ /dev/null @@ -1,46 +0,0 @@ -/* - SPDX-License-Identifier: MIT -*/ - -pragma solidity =0.7.6; -pragma experimental ABIEncoderV2; - -import {AppStorage} from "../AppStorage.sol"; - -/** - * @author Brean - * @title InitEBip17 cancels the invalid pod orders, and recreates the pod orders with the correct values. - **/ -contract InitEbip17 { - AppStorage internal s; - - // there are 4 existing pod orders, 2 of which have a min fill amount of 0. - // 0x0503e8467eb328bcb9b1f2656db905311d47cb14ea1955b8a0c8441d8943ca33, - // 0xf47df2678d29e9d57c5e9ed5f8c990e71910918154a2ed6d5235718035d7d8b0. - // these orders are invalid, as they have a min fill amount of 0, and will need to be re-created. - function init() external { - // get bean order values. - uint256 beanAmount0 = s.podOrders[0x0503e8467eb328bcb9b1f2656db905311d47cb14ea1955b8a0c8441d8943ca33]; - uint256 beanAmount1 = s.podOrders[0xf47df2678d29e9d57c5e9ed5f8c990e71910918154a2ed6d5235718035d7d8b0]; - - // cancel orders. - delete s.podOrders[0x0503e8467eb328bcb9b1f2656db905311d47cb14ea1955b8a0c8441d8943ca33]; - delete s.podOrders[0xf47df2678d29e9d57c5e9ed5f8c990e71910918154a2ed6d5235718035d7d8b0]; - - // reinitalize orders, with a min fill amount of 1. - s.podOrders[createOrderId(address(0x8a9C930896e453cA3D87f1918996423A589Dd529), 1000, 109233726000000, 1)] = beanAmount0; - s.podOrders[createOrderId(address(0x8a9C930896e453cA3D87f1918996423A589Dd529), 1000, 109233726000000, 1)] = beanAmount1; - } - - // see: {Order.createOrderId} - function createOrderId( - address account, - uint24 pricePerPod, - uint256 maxPlaceInLine, - uint256 minFillAmount - ) internal pure returns (bytes32 id) { - if(minFillAmount > 0) id = keccak256(abi.encodePacked(account, pricePerPod, maxPlaceInLine, minFillAmount)); - else id = keccak256(abi.encodePacked(account, pricePerPod, maxPlaceInLine)); - } - -} diff --git a/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol b/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol index 0645195244..b3074ebff0 100644 --- a/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol +++ b/protocol/contracts/beanstalk/market/MarketplaceFacet/Order.sol @@ -100,6 +100,7 @@ contract Order is Listing { ) internal { require(amount >= o.minFillAmount, "Marketplace: Fill must be >= minimum amount."); + require(amount > 0, "Marketplace: amount must be > 0."); require(s.a[msg.sender].field.plots[index] >= (start.add(amount)), "Marketplace: Invalid Plot."); require(index.add(start).add(amount).sub(s.f.harvestable) <= o.maxPlaceInLine, "Marketplace: Plot too far in line."); @@ -128,6 +129,7 @@ contract Order is Listing { ) internal { require(amount >= o.minFillAmount, "Marketplace: Fill must be >= minimum amount."); + require(amount > 0, "Marketplace: amount must be > 0."); require(s.a[msg.sender].field.plots[index] >= (start.add(amount)), "Marketplace: Invalid Plot."); require(index.add(start).add(amount).sub(s.f.harvestable) <= o.maxPlaceInLine, "Marketplace: Plot too far in line."); diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index 819ddae372..4c3ac8b2f1 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -197,7 +197,6 @@ async function ebip17(mock = true, account = undefined) { await upgradeWithNewFacets({ diamondAddress: BEANSTALK, facetNames: ["MarketplaceFacet"], - initFacetName: "InitBipSeedGauge", bip: false, object: !mock, verbose: true, From 9fa1a0b163a6324223c91b3b96475cfececdd475 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sat, 8 Jun 2024 23:30:22 -0500 Subject: [PATCH 12/43] add amount == 0 test. --- protocol/test/Marketplace.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/protocol/test/Marketplace.test.js b/protocol/test/Marketplace.test.js index 444793b350..0bbf5f29c8 100644 --- a/protocol/test/Marketplace.test.js +++ b/protocol/test/Marketplace.test.js @@ -1395,6 +1395,7 @@ describe('Marketplace', function () { this.result = await this.marketplace.connect(user).createPodOrder("50", "100000", "2500", '10', EXTERNAL); this.id = await getOrderId(this.result); this.order = [userAddress, "100000", "2500", '10']; + this.invalidOrder = [userAddress, "100000", "2500", '0']; }); describe("revert", async function () { @@ -1436,6 +1437,14 @@ describe('Marketplace', function () { .fillPodOrder(this.order, 1000, 0, 1, INTERNAL) ).to.revertedWith("Marketplace: Fill must be >= minimum amount."); }); + + it("zero amount", async function () { + await expect( + this.marketplace + .connect(user2) + .fillPodOrder(this.invalidOrder, 1000, 0, 0, INTERNAL) + ).to.revertedWith("Marketplace: amount must be > 0."); + }); }); describe("Full order", async function () { @@ -1775,6 +1784,7 @@ describe('Marketplace', function () { this.result = await this.marketplace.connect(user).createPodOrderV2("50", "2500", '1', this.f.packedFunction, EXTERNAL); this.id = await getOrderId(this.result); this.order = [userAddress, "0", "2500", '1']; + this.invalidOrder = [userAddress, "0", "2500", '0']; }); describe("revert", async function () { @@ -1802,6 +1812,12 @@ describe('Marketplace', function () { this.marketplace.connect(user2).fillPodOrderV2(this.order,1000, 0, 1000, this.f.packedFunction, INTERNAL) ).to.revertedWith("Marketplace: Not enough beans in order."); }); + + it("invalid amount", async function () { + await expect( + this.marketplace.connect(user2).fillPodOrderV2(this.invalidOrder,1000, 0, 0, this.f.packedFunction, INTERNAL) + ).to.revertedWith("Marketplace: amount must be > 0."); + }); }); describe("Full order", async function () { From 933a74b7c86b35770008057a3db9214a9f780843 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Wed, 3 Jul 2024 13:28:50 +0200 Subject: [PATCH 13/43] Germination order fix --- protocol/contracts/libraries/Silo/LibSilo.sol | 12 ++-- protocol/test/Sop.test.js | 55 +++++++++++++++++-- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 3d837ef758..e74f14fea7 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -456,9 +456,15 @@ library LibSilo { migrateStems(account); } + uint32 currentSeason = s.season.current; + + // End account germination. + if (lastUpdate < currentSeason) { + LibGerminate.endAccountGermination(account, lastUpdate, currentSeason); + } + // sop data only needs to be updated once per season, // if it started raining and it's still raining, or there was a sop - uint32 currentSeason = s.season.current; if (s.season.rainStart > s.season.stemStartSeason) { if (lastUpdate <= s.season.rainStart && lastUpdate <= currentSeason) { // Increments `plenty` for `account` if a Flood has occured. @@ -467,10 +473,6 @@ library LibSilo { } } - // End account germination. - if (lastUpdate < currentSeason) { - LibGerminate.endAccountGermination(account, lastUpdate, currentSeason); - } // Calculate the amount of Grown Stalk claimable by `account`. // Increase the account's balance of Stalk and Roots. __mow(account, token); diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 8d98b068f9..e78f973269 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -7,14 +7,15 @@ const { deployMockWell, whitelistWell, deployMockWellWithMockPump } = require('. const { setEthUsdPrice, setEthUsdcPrice, setEthUsdtPrice } = require('../scripts/usdOracle.js'); const { takeSnapshot, revertToSnapshot } = require("./utils/snapshot") -let user,user2,owner; -let userAddress, ownerAddress, user2Address; +let user,user2,user3,owner; +let userAddress, ownerAddress, user2Address, user3Address; describe('Sop', function () { before(async function () { - [owner,user,user2] = await ethers.getSigners() + [owner,user,user2,user3] = await ethers.getSigners() userAddress = user.address; user2Address = user2.address; + user3Address = user3.address; const contracts = await deploy("Test", false, true) ownerAddress = contracts.account; this.diamond = contracts.beanstalkDiamond @@ -64,7 +65,6 @@ describe('Sop', function () { // they have updated their deposit at least once after silo sunrise) await this.silo.mow(userAddress, this.bean.address); await this.silo.mow(user2Address, this.bean.address); - }) beforeEach(async function () { @@ -325,4 +325,51 @@ describe('Sop', function () { expect(await this.seasonGetters.getSopWell()).to.be.equal(this.well.address) }) }) + + describe.only('Germination and Plenty', function () { + it('not germinated', async function () { + + await this.bean.mint(user3Address, to6('10000')); + await this.bean.connect(user3).approve(this.silo.address, MAX_UINT256); + await this.silo.connect(user3).deposit(this.bean.address, to6('1000'), EXTERNAL); + + await this.season.siloSunrise(0); + await this.season.siloSunrise(0); + await this.season.siloSunrise(0); // should be germinated by now, not mown though + + await this.well.setReserves([to6('1000000'), to18('1100')]) + await this.pump.setInstantaneousReserves([to6('1000000'), to18('1100')]) + + + await this.season.rainSunrise(); + await this.season.rainSunrise(); + + await this.silo.mow(user3Address, this.bean.address); + + const balanceOfPlenty = await this.siloGetters.balanceOfPlenty(user3Address); + expect(balanceOfPlenty).to.equal('17059168165054954010'); + }); + + it('germinated', async function () { + await this.bean.mint(user3Address, to6('10000')); + await this.bean.connect(user3).approve(this.silo.address, MAX_UINT256); + await this.silo.connect(user3).deposit(this.bean.address, to6('1000'), EXTERNAL); + + await this.season.siloSunrise(0); + await this.season.siloSunrise(0); + await this.season.siloSunrise(0); // should be germinated by now, not mown though + + await this.well.setReserves([to6('1000000'), to18('1100')]); + await this.pump.setInstantaneousReserves([to6('1000000'), to18('1100')]) + + await this.silo.mow(user3Address, this.bean.address); + await this.season.rainSunrise(); + await this.season.rainSunrise(); + await this.silo.mow(user3Address, this.bean.address); + + const balanceOfPlenty = await this.siloGetters.balanceOfPlenty(user3Address); + // Note user has more plenty here than previous test because of the earlier mow, giving them more stalk + expect(balanceOfPlenty).to.equal('17065991377622017778'); + }); + }); }) \ No newline at end of file From 213ac9b4e4c7dba03eff851aba51490dc26c7962 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Wed, 3 Jul 2024 13:34:26 +0200 Subject: [PATCH 14/43] Cleanup --- protocol/contracts/libraries/Silo/LibSilo.sol | 7 ------- protocol/contracts/libraries/Silo/LibTokenSilo.sol | 3 --- protocol/test/StemMigrateAll.test.js | 2 +- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index fd22c973e3..3e51c25897 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -16,7 +16,6 @@ import {LibSafeMath32} from "../LibSafeMath32.sol"; import {LibSafeMathSigned96} from "../LibSafeMathSigned96.sol"; import {LibGerminate} from "./LibGerminate.sol"; import {LibWhitelistedTokens} from "./LibWhitelistedTokens.sol"; -import {console} from "hardhat/console.sol"; /** * @title LibSilo @@ -251,12 +250,6 @@ library LibSilo { // Decrease supply of Stalk; Remove Stalk from the balance of `account` s.s.stalk = s.s.stalk.sub(stalk); - if (stalk > s.a[account].s.stalk) { - console.log("burning too much, by amount: ", stalk.sub(s.a[account].s.stalk)); - console.log("account: ", account); - console.log("stalk: ", stalk); - console.log("s.a[account].s.stalk: ", s.a[account].s.stalk); - } s.a[account].s.stalk = s.a[account].s.stalk.sub(stalk); // Decrease supply of Roots; Remove Roots from the balance of `account` diff --git a/protocol/contracts/libraries/Silo/LibTokenSilo.sol b/protocol/contracts/libraries/Silo/LibTokenSilo.sol index a79372df1f..b03a0c6967 100644 --- a/protocol/contracts/libraries/Silo/LibTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibTokenSilo.sol @@ -16,7 +16,6 @@ import {LibSafeMathSigned96} from "contracts/libraries/LibSafeMathSigned96.sol"; import {LibBytes} from "contracts/libraries/LibBytes.sol"; import {LibGerminate} from "contracts/libraries/Silo/LibGerminate.sol"; import {LibWhitelistedTokens} from "contracts/libraries/Silo/LibWhitelistedTokens.sol"; -import {console} from "hardhat/console.sol"; /** * @title LibTokenSilo @@ -153,8 +152,6 @@ library LibTokenSilo { } // decrement germinating amount and bdv. - console.log("germinate.deposited[token].amount: ", germinate.deposited[token].amount); - console.log("amount: ", amount); germinate.deposited[token].amount = germinate.deposited[token].amount.sub( amount.toUint128() ); diff --git a/protocol/test/StemMigrateAll.test.js b/protocol/test/StemMigrateAll.test.js index 18d725a6c5..11bcb95ada 100644 --- a/protocol/test/StemMigrateAll.test.js +++ b/protocol/test/StemMigrateAll.test.js @@ -50,7 +50,7 @@ const eventsAbi = [ } ]; -describe.only('Silo V3: Stem deployment migrate everyone', function () { +describe('Silo V3: Stem deployment migrate everyone', function () { before(async function () { try { From ebc8f1d7d49cf12195efe1dd888269eec1c801f0 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Wed, 3 Jul 2024 15:37:18 +0200 Subject: [PATCH 15/43] Remove total bdv counter --- .../beanstalk/silo/MigrationFacet.sol | 4 +- .../libraries/Silo/LibLegacyTokenSilo.sol | 37 +++++-------------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/protocol/contracts/beanstalk/silo/MigrationFacet.sol b/protocol/contracts/beanstalk/silo/MigrationFacet.sol index b5a6411c53..21e3beefcb 100644 --- a/protocol/contracts/beanstalk/silo/MigrationFacet.sol +++ b/protocol/contracts/beanstalk/silo/MigrationFacet.sol @@ -47,9 +47,9 @@ contract MigrationFacet is ReentrancyGuard { uint256 seedsDiff, bytes32[] calldata proof ) external payable { - (uint256 seedsVariance, uint256 totalBdv) = LibLegacyTokenSilo._mowAndMigrate(account, tokens, seasons, amounts); + uint256 seedsVariance = LibLegacyTokenSilo._mowAndMigrate(account, tokens, seasons, amounts); //had to break up the migration function into two parts to avoid stack too deep errors - LibLegacyTokenSilo._mowAndMigrateMerkleCheck(account, stalkDiff, seedsDiff, proof, seedsVariance, totalBdv); + LibLegacyTokenSilo._mowAndMigrateMerkleCheck(account, stalkDiff, seedsDiff, proof, seedsVariance); } /** diff --git a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol index d6fc16a092..1ac8029ef3 100644 --- a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol @@ -73,7 +73,6 @@ library LibLegacyTokenSilo { struct MigrateData { uint128 totalSeeds; uint128 totalGrownStalk; - uint256 totalBdv; } struct PerDepositData { @@ -85,7 +84,6 @@ library LibLegacyTokenSilo { struct PerTokenData { address token; int96 stemTip; - uint256 crateBDV; } //////////////////////// REMOVE DEPOSIT //////////////////////// @@ -262,7 +260,7 @@ library LibLegacyTokenSilo { address[] calldata tokens, uint32[][] calldata seasons, uint256[][] calldata amounts - ) internal returns (uint256, uint256) { + ) internal returns (uint256) { // Validates whether a user needs to perform migration. checkForMigration(account); @@ -293,25 +291,22 @@ library LibLegacyTokenSilo { } // withdraw this deposit - perTokenData.crateBDV = removeDepositFromAccount( + uint256 crateBDV = removeDepositFromAccount( account, perTokenData.token, perDepositData.season, perDepositData.amount ); - // add to running total of bdv - migrateData.totalBdv = migrateData.totalBdv.add(perTokenData.crateBDV); - // calculate how much stalk has grown for this deposit perDepositData.grownStalk = _calcGrownStalkForDeposit( - perTokenData.crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))), + crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))), perDepositData.season ); // also need to calculate how much stalk has grown since the migration uint128 stalkGrownSinceStemStartSeason = LibSilo - .stalkReward(0, perTokenData.stemTip, perTokenData.crateBDV.toUint128()) + .stalkReward(0, perTokenData.stemTip, crateBDV.toUint128()) .toUint128(); perDepositData.grownStalk = perDepositData.grownStalk.add( stalkGrownSinceStemStartSeason @@ -327,16 +322,16 @@ library LibLegacyTokenSilo { LibTokenSilo.grownStalkAndBdvToStem( perTokenData.token, perDepositData.grownStalk, - perTokenData.crateBDV + crateBDV ), perDepositData.amount, - perTokenData.crateBDV, + crateBDV, LibTokenSilo.Transfer.emitTransferSingle ); // add to running total of seeds migrateData.totalSeeds = migrateData.totalSeeds.add( - perTokenData.crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))).toUint128() + crateBDV.mul(getLegacySeedsPerToken(address(perTokenData.token))).toUint128() ); // emit legacy RemoveDeposit event @@ -356,7 +351,7 @@ library LibLegacyTokenSilo { LibSilo.mintActiveStalk(account, migrateData.totalGrownStalk); //return seeds diff for checking in the "part 2" of this function (stack depth kept it from all fitting in one) - return (balanceOfSeeds(account).sub(migrateData.totalSeeds), migrateData.totalBdv); + return balanceOfSeeds(account).sub(migrateData.totalSeeds); } function _mowAndMigrateMerkleCheck( @@ -364,8 +359,7 @@ library LibLegacyTokenSilo { uint256 stalkDiff, uint256 seedsDiff, bytes32[] calldata proof, - uint256 seedsVariance, - uint256 totalBdv + uint256 seedsVariance ) internal { if (seedsDiff > 0) { // verify merkle tree to determine stalk/seeds diff drift from convert issue @@ -389,23 +383,12 @@ library LibLegacyTokenSilo { setBalanceOfSeeds(account, 0); // stalk diff was calculated based on ENROOT_FIX_SEASON, so we need to calculate - // the amount of stalk that has grown since then - // if totalBdv is zero, the stalk diff should be zero, so we can skip this step. - // && totalBdv > 3 + // the amount of stalk that has grown between the silo v3 deployment season and the enroot fix season if (seedsDiff > 0) { - console.log("totalBdv: ", totalBdv); uint256 currentStalkDiff = uint256(SILOV3_DEPLOYMENT_SEASON - ENROOT_FIX_SEASON) .mul(seedsDiff) .add(stalkDiff); - console.log("uint256(s.season.current): ", uint256(s.season.current)); - console.log("ENROOT_FIX_SEASON: ", ENROOT_FIX_SEASON); - console.log("seedsDiff: ", seedsDiff); - console.log("stalkDiff: ", stalkDiff); - console.log("seasons diff: ", (uint256(s.season.current).sub(ENROOT_FIX_SEASON))); - - console.log("currentStalkDiff: ", currentStalkDiff); - // emit the stalk variance. // all deposits in siloV2 are not germinating. if (currentStalkDiff > 0) { From d8ecc3f5294ec6ef0bf2bce4858fd680f69e65e4 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Thu, 4 Jul 2024 11:31:37 +0200 Subject: [PATCH 16/43] Update comment --- protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol index 1ac8029ef3..71c79c9806 100644 --- a/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol +++ b/protocol/contracts/libraries/Silo/LibLegacyTokenSilo.sol @@ -253,7 +253,7 @@ library LibLegacyTokenSilo { * Deposits are migrated to the stem storage system on a 1:1 basis. Accounts with * lots of deposits may take a considerable amount of gas to migrate. * - * Returns seeds diff compared to stored amount, for verification in merkle check, and total bdv. + * Returns seeds diff compared to stored amount, for verification in merkle check */ function _mowAndMigrate( address account, From 88dc535ce4d4cb0b97bf8fc79b891a32c246e6c3 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 15:40:27 +0200 Subject: [PATCH 17/43] Initial setup of init hot fix 6 script --- .../contracts/beanstalk/init/InitHotFix6.sol | 63 ++ .../beanstalk/init/InitHotFix6Data.json | 597 ++++++++++++++++++ .../beanstalk/init/InitHotFix6_generate.js | 25 + 3 files changed, 685 insertions(+) create mode 100644 protocol/contracts/beanstalk/init/InitHotFix6.sol create mode 100644 protocol/contracts/beanstalk/init/InitHotFix6Data.json create mode 100644 protocol/contracts/beanstalk/init/InitHotFix6_generate.js diff --git a/protocol/contracts/beanstalk/init/InitHotFix6.sol b/protocol/contracts/beanstalk/init/InitHotFix6.sol new file mode 100644 index 0000000000..237c0dc961 --- /dev/null +++ b/protocol/contracts/beanstalk/init/InitHotFix6.sol @@ -0,0 +1,63 @@ +/* + SPDX-License-Identifier: MIT +*/ + +pragma solidity =0.7.6; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import {AppStorage} from "../AppStorage.sol"; +import {C} from "../../C.sol"; + +contract InitHotFix6 { + AppStorage internal s; + using SafeMath for uint256; + + function init() external { + // generated using the script at InitHotFix6_generate.js + adjustAccount(address(0xa7e3fed558e81dab40cd87f334d68b0bf0ab3fd6), 1339045260000, 0x108288355466404f3e7a6); + adjustAccount(address(0xe203096d7583e30888902b2608652c720d6c38da), 895630340000, 0xb0af280a27dd55e15186); + adjustAccount(address(0xe5d36124de24481dac81cc06b2cd0bbe81701d14), 2719827460000, 0x2188cd396d713453f2385); + adjustAccount(address(0xdff24806405f62637e0b44cc2903f1dfc7c111cd), 4465241140000, 0x370dfc5bf2d37e323068e); + adjustAccount(address(0xcde68f6a7078f47ee664ccbc594c9026a8a72d25), 87310400000, 0x11395a60856002fd2bb2); + adjustAccount(address(0x6343b307c288432bb9ad9003b4230b08b56b3b82), 1587607930000, 0x139316f233f39b2d7fc7a); + adjustAccount(address(0xfe7a7f227967104299e2ed9c47ca28eadc3a7c5f), 800384040000, 0x9de506359f0bad67dd9b); + adjustAccount(address(0xf6f6d531ed0f7fa18cae2c73b21aa853c765c4d8), 20368615360000, 0xfb2309014e60e822b7351); + adjustAccount(address(0xcba1a275e2d858ecffaf7a87f606f74b719a8a93), 2488521800000, 0x1eaeb6b687d242423820f); + adjustAccount(address(0xcfd9c9ac52b4b6fe30537803caeb327dadd411bb), 2265290610000, 0x1bee1ca2f7c590350cd56); + adjustAccount(address(0x91953b70d0861309f7d3a429a1cf82c8353132be), 4742314480000, 0x3a7888a5bfb29eb0da262); + adjustAccount(address(0x19831b174e9deabf9e4b355aadfd157f09e2af1f), 10904953700000, 0x867425f8ce119587b9de6); + adjustAccount(address(0xe249d1be97f4a716cde0d7c5b6b682f491621c41), 2813491850000, 0x22b0711a97fac34a4ff80); + adjustAccount(address(0x19c5bad4354e9a78a1ca0235af29b9eacf54ff2b), 815845330000, 0xa0f1d9d41775c1be9a18); + adjustAccount(address(0x6cd83315e4c4bfdf95d4a8442927c018f328c9fe), 1737884960000, 0x156d6baf092d9ce69e24e); + adjustAccount(address(0xf05b641229bb2aa63b205ad8b423a390f7ef05a7), 1636015800000, 0x142be2152769fa6a1e6a6); + adjustAccount(address(0x7d50bfead43d4fdd47a8a61f32305b2de21068bd), 3004066550000, 0x2509d6ed94de16f5eac68); + adjustAccount(address(0xd3e0ef0ebb7bc536405918d4d8dbdf981185d435), 50000000000000, 0x26878bc7521efacb1e9a15); + adjustAccount(address(0xe146313a9d6d6ccdd733cc15af3cf11d47e96f25), 229584270000, 0x2d4a511d471dc4e8b28e); + adjustAccount(address(0x4ca3e5bdf3823febbe18f9664cded14b7243971c), 421932770000, 0x533c2d45ba7bc6e67620); + adjustAccount(address(0xf62405e188bb9629ed623d60b7c70dcc4e2abd81), 2113424040000, 0x1a0eac76731c01011962e); + adjustAccount(address(0x52eaa3345a9b68d3b5d52da2fd47ebfc5ed11d4e), 1176225810000, 0xe808ff73ff408717ef32); + adjustAccount(address(0xd441c97ef1458d847271f91714799007081494ef), 24242385640000, 0x12ae51564d62b1f98c00d5); + adjustAccount(address(0xeaa4f3773f57af1d4c7130e07cde48050245511b), 43414340140000, 0x2174630740c9787fc077a2); + adjustAccount(address(0x2bf046a052942b53ca6746de4d3295d8f10d4562), 2580594620000, 0x1fd1386c8296b8f435874); + adjustAccount(address(0x7de837caff6a19898e507f644939939cb9341209), 6846927200000, 0x546b31ae800ccacbe5126); + adjustAccount(address(0xc56725de9274e17847db0e45c1da36e46a7e197f), 4881455690000, 0x3c2f8212788e5a5158657); + adjustAccount(address(0x0be9a9100a95075270e47de519d53c5fc8f7c936), 4913752530000, 0x3c95729e8e9795a27c2da); + adjustAccount(address(0xc7c1b169a8d3c5f2d6b25642c4d10da94ffcd3c9), 3599776050000, 0x2c62191fde7981d7d1bef); + adjustAccount(address(0xf840aa35b73ee0bbf488d81d684706729aba0a15), 142499790000, 0x1c1c6ebc7efe0c2b0949); + adjustAccount(address(0x11b197e2c61c2959ae84bc7f9db8e3fefe511043), 7875550010000, 0x6119df38da1aef59eccdc); + adjustAccount(address(0xda8c9d1b00d12ddf67f2aa6af582fd6a38209b39), 3764622150000, 0x2e6a685941d5cbb0d48ce); + adjustAccount(address(0x53bd04892c7147e1126bc7ba68f2fb6bf5a43910), 41586641380000, 0x200bd5c36c99660fed5e56); + adjustAccount(address(0x4bf44e0c856d096b755d54ca1e9cfdc0115ed2e6), 1269973450000, 0xfa876179d7c800e2c28a); + adjustAccount(address(0x2972bf9b54ac5100d747150dfd684899c0abec5e), 35735731380000, 0x1b899ee086192386fc657e); + + // fix system-level deposited bean and bdv + s.siloBalances[C.BEAN].deposited = s.siloBalances[C.BEAN].deposited - 29746746393; + s.siloBalances[C.BEAN].depositedBdv = s.siloBalances[C.BEAN].depositedBdv - 29746746393; + } + + function adjustAccount(address account, uint128 stalk, uint128 roots) internal { + s.a[account].s.stalk = s.a[account].s.stalk - stalk; + s.a[account].roots = s.a[account].roots - roots; + } +} diff --git a/protocol/contracts/beanstalk/init/InitHotFix6Data.json b/protocol/contracts/beanstalk/init/InitHotFix6Data.json new file mode 100644 index 0000000000..a8986cbf79 --- /dev/null +++ b/protocol/contracts/beanstalk/init/InitHotFix6Data.json @@ -0,0 +1,597 @@ +[ + { + "account": "0xa7e3fed558e81dab40cd87f334d68b0bf0ab3fd6", + "accountDiscrepancy": { + "depositedBean": 133904526, + "depositedBdv": 133904526, + "stalk": 1339045260000, + "roots": "0x108288355466404f3e7a6" + }, + "cumulativeDiscrepancy": { + "depositedBean": 133904526, + "depositedBdv": 133904526, + "stalk": 1339045260000, + "roots": "0x108288355466404f3e7a6" + }, + "block": 19941969, + "txHash": "0xc13e96784c0218751ff8f9c0de21b3dbe1879ae3902798fbfaf77017cda3bb48" + }, + { + "account": "0xe203096d7583e30888902b2608652c720d6c38da", + "accountDiscrepancy": { + "depositedBean": 89563034, + "depositedBdv": 89563034, + "stalk": 895630340000, + "roots": "0xb0af280a27dd55e15186" + }, + "cumulativeDiscrepancy": { + "depositedBean": 223467560, + "depositedBdv": 223467560, + "stalk": 2234675600000, + "roots": "0x1b8d7ab5f6e415ad5392c" + }, + "block": 19942000, + "txHash": "0xe3138f983bd7de4baec19e7000abe80a42a8024b7162ea5618bb72459780afb8" + }, + { + "account": "0xe5d36124de24481dac81cc06b2cd0bbe81701d14", + "accountDiscrepancy": { + "depositedBean": 271982746, + "depositedBdv": 271982746, + "stalk": 2719827460000, + "roots": "0x2188cd396d713453f2385" + }, + "cumulativeDiscrepancy": { + "depositedBean": 495450306, + "depositedBdv": 495450306, + "stalk": 4954503060000, + "roots": "0x3d1647ef64554a0145cb1" + }, + "block": 19942640, + "txHash": "0x48f452e6f2e6cd07280a4bab98a470c4a5f1cce0026a7eceb244b786d8abe663" + }, + { + "account": "0xdff24806405f62637e0b44cc2903f1dfc7c111cd", + "accountDiscrepancy": { + "depositedBean": 446524114, + "depositedBdv": 446524114, + "stalk": 4465241140000, + "roots": "0x370dfc5bf2d37e323068e" + }, + "cumulativeDiscrepancy": { + "depositedBean": 941974420, + "depositedBdv": 941974420, + "stalk": 9419744200000, + "roots": "0x7424444b5728c8337633f" + }, + "block": 19943955, + "txHash": "0x0492af41b8aa36bd2bd78eacf9ad576806d8fd66f34f096611aee80814a6181e" + }, + { + "account": "0xcde68f6a7078f47ee664ccbc594c9026a8a72d25", + "accountDiscrepancy": { + "depositedBean": 8731040, + "depositedBdv": 8731040, + "stalk": 87310400000, + "roots": "0x11395a60856002fd2bb2" + }, + "cumulativeDiscrepancy": { + "depositedBean": 950705460, + "depositedBdv": 950705460, + "stalk": 9507054600000, + "roots": "0x7537d9f15f7ec86348ef1" + }, + "block": 19944606, + "txHash": "0xebdb85436aa97e1bd6e9a106ec4bc39f7e595f82e30cd8cfe29fcb3a323dd93a" + }, + { + "account": "0x6343b307c288432bb9ad9003b4230b08b56b3b82", + "accountDiscrepancy": { + "depositedBean": 158760793, + "depositedBdv": 158760793, + "stalk": 1587607930000, + "roots": "0x139316f233f39b2d7fc7a" + }, + "cumulativeDiscrepancy": { + "depositedBean": 1109466253, + "depositedBdv": 1109466253, + "stalk": 11094662530000, + "roots": "0x88caf0e393726390c8b6b" + }, + "block": 19944956, + "txHash": "0x1b6e13bf3c94e5aa2a8445ffad21d6ff77ad49e80aa6d56897295c59366c8243" + }, + { + "account": "0xfe7a7f227967104299e2ed9c47ca28eadc3a7c5f", + "accountDiscrepancy": { + "depositedBean": 80038404, + "depositedBdv": 80038404, + "stalk": 800384040000, + "roots": "0x9de506359f0bad67dd9b" + }, + "cumulativeDiscrepancy": { + "depositedBean": 1189504657, + "depositedBdv": 1189504657, + "stalk": 11895046570000, + "roots": "0x92a94146ed631e6746906" + }, + "block": 19946180, + "txHash": "0x74108cdbe98ece9ebf97a8cb24f17f81582afe352af6f3173abcab3fe36ab8d9" + }, + { + "account": "0xf6f6d531ed0f7fa18cae2c73b21aa853c765c4d8", + "accountDiscrepancy": { + "depositedBean": 2036861536, + "depositedBdv": 2036861536, + "stalk": 20368615360000, + "roots": "0xfb2309014e60e822b7351" + }, + "cumulativeDiscrepancy": { + "depositedBean": 3226366193, + "depositedBdv": 3226366193, + "stalk": 32263661930000, + "roots": "0x18dcc4a483bc40689fdc57" + }, + "block": 19946460, + "txHash": "0xdeb93e488d8c850914dd32a91f1bd32a03e5d3fa9da0e1517a52a00d1ff23a0f" + }, + { + "account": "0xcba1a275e2d858ecffaf7a87f606f74b719a8a93", + "accountDiscrepancy": { + "depositedBean": 248852180, + "depositedBdv": 248852180, + "stalk": 2488521800000, + "roots": "0x1eaeb6b687d242423820f" + }, + "cumulativeDiscrepancy": { + "depositedBean": 3475218373, + "depositedBdv": 3475218373, + "stalk": 34752183730000, + "roots": "0x1ac7b00fec39648cc35e66" + }, + "block": 19946615, + "txHash": "0xc71bef3a0838158da7f2a73f6239dcd963d321c653b733a00e0e398108381e9f" + }, + { + "account": "0xcfd9c9ac52b4b6fe30537803caeb327dadd411bb", + "accountDiscrepancy": { + "depositedBean": 226529061, + "depositedBdv": 226529061, + "stalk": 2265290610000, + "roots": "0x1bee1ca2f7c590350cd56" + }, + "cumulativeDiscrepancy": { + "depositedBean": 3701747434, + "depositedBdv": 3701747434, + "stalk": 37017474340000, + "roots": "0x1c8691da1bb5bd90142bbc" + }, + "block": 19947349, + "txHash": "0xa0e76ca36a82d0eb1d862f125699d173680fb84bc1ab575f40e0794fdb0d432a" + }, + { + "account": "0x91953b70d0861309f7d3a429a1cf82c8353132be", + "accountDiscrepancy": { + "depositedBean": 474231448, + "depositedBdv": 474231448, + "stalk": 4742314480000, + "roots": "0x3a7888a5bfb29eb0da262" + }, + "cumulativeDiscrepancy": { + "depositedBean": 4175978882, + "depositedBdv": 4175978882, + "stalk": 41759788820000, + "roots": "0x202e1a6477b0e77b21ce1e" + }, + "block": 19953632, + "txHash": "0xe598db0643bece20c6ab5db1ebaafcfb873e4b64ce662c9a9bd7b47e62900ce2" + }, + { + "account": "0x19831b174e9deabf9e4b355aadfd157f09e2af1f", + "accountDiscrepancy": { + "depositedBean": 1090495370, + "depositedBdv": 1090495370, + "stalk": 10904953700000, + "roots": "0x867425f8ce119587b9de6" + }, + "cumulativeDiscrepancy": { + "depositedBean": 5266474252, + "depositedBdv": 5266474252, + "stalk": 52664742520000, + "roots": "0x28955cc4049200d39d6c04" + }, + "block": 19956101, + "txHash": "0xf381409f445bcc836f904a36b2ed9b6497a75a509507abd9571c993b231fe99b" + }, + { + "account": "0xe249d1be97f4a716cde0d7c5b6b682f491621c41", + "accountDiscrepancy": { + "depositedBean": 281349185, + "depositedBdv": 281349185, + "stalk": 2813491850000, + "roots": "0x22b0711a97fac34a4ff80" + }, + "cumulativeDiscrepancy": { + "depositedBean": 5547823437, + "depositedBdv": 5547823437, + "stalk": 55478234370000, + "roots": "0x2ac063d5ae11ad08426b84" + }, + "block": 19956694, + "txHash": "0x69a02efde93c9fd3cbae189b8b8abe30877424c12073422805ff8866bc938034" + }, + { + "account": "0x19c5bad4354e9a78a1ca0235af29b9eacf54ff2b", + "accountDiscrepancy": { + "depositedBean": 81584533, + "depositedBdv": 81584533, + "stalk": 815845330000, + "roots": "0xa0f1d9d41775c1be9a18" + }, + "cumulativeDiscrepancy": { + "depositedBean": 5629407970, + "depositedBdv": 5629407970, + "stalk": 56294079700000, + "roots": "0x2b6155af822922ca01059c" + }, + "block": 19957438, + "txHash": "0x22dcf2e91034f85e571184291f74f6481f2c793a4c987c47a7e5fab53631a525" + }, + { + "account": "0x6cd83315e4c4bfdf95d4a8442927c018f328c9fe", + "accountDiscrepancy": { + "depositedBean": 173788496, + "depositedBdv": 173788496, + "stalk": 1737884960000, + "roots": "0x156d6baf092d9ce69e24e" + }, + "cumulativeDiscrepancy": { + "depositedBean": 5803196466, + "depositedBdv": 5803196466, + "stalk": 58031964660000, + "roots": "0x2cb82c6a72bbfc986ae7ea" + }, + "block": 19957455, + "txHash": "0x8b9aa1130b213df31bea992148a2b6e1d80b2ddd31d425f9672917c0e5cf4156" + }, + { + "account": "0xf05b641229bb2aa63b205ad8b423a390f7ef05a7", + "accountDiscrepancy": { + "depositedBean": 163601580, + "depositedBdv": 163601580, + "stalk": 1636015800000, + "roots": "0x142be2152769fa6a1e6a6" + }, + "cumulativeDiscrepancy": { + "depositedBean": 5966798046, + "depositedBdv": 5966798046, + "stalk": 59667980460000, + "roots": "0x2dfaea8bc5329c3f0cce90" + }, + "block": 19957739, + "txHash": "0x6ebdd4084df99c31c089abef15232b3b90e3e29268c8b1781663a38685b5ea69" + }, + { + "account": "0x7d50bfead43d4fdd47a8a61f32305b2de21068bd", + "accountDiscrepancy": { + "depositedBean": 300406655, + "depositedBdv": 300406655, + "stalk": 3004066550000, + "roots": "0x2509d6ed94de16f5eac68" + }, + "cumulativeDiscrepancy": { + "depositedBean": 6267204701, + "depositedBdv": 6267204701, + "stalk": 62672047010000, + "roots": "0x304b87fa9e807dae6b7af8" + }, + "block": 19962793, + "txHash": "0xecddbc54465eb60d8429d739f9a28d0e8133bcebefcb913e05bd7ff8bd8e8533" + }, + { + "account": "0xd3e0ef0ebb7bc536405918d4d8dbdf981185d435", + "accountDiscrepancy": { + "depositedBean": 5000000000, + "depositedBdv": 5000000000, + "stalk": 50000000000000, + "roots": "0x26878bc7521efacb1e9a15" + }, + "cumulativeDiscrepancy": { + "depositedBean": 11267204701, + "depositedBdv": 11267204701, + "stalk": 112672047010000, + "roots": "0x56d313c1f09f78798a150d" + }, + "block": 19962879, + "txHash": "0x563f865c941b942b7219aff8d5548b00870dc4f804a94b1967f729eaa5caf239" + }, + { + "account": "0xe146313a9d6d6ccdd733cc15af3cf11d47e96f25", + "accountDiscrepancy": { + "depositedBean": 22958427, + "depositedBdv": 22958427, + "stalk": 229584270000, + "roots": "0x2d4a511d471dc4e8b28e" + }, + "cumulativeDiscrepancy": { + "depositedBean": 11290163128, + "depositedBdv": 11290163128, + "stalk": 112901631280000, + "roots": "0x57005e130de6963e72c79b" + }, + "block": 19963829, + "txHash": "0x94422f8d4bb906ab687e714a1c9dffbe940300dfd37256e78034c421a85a6a31" + }, + { + "account": "0x4ca3e5bdf3823febbe18f9664cded14b7243971c", + "accountDiscrepancy": { + "depositedBean": 42193277, + "depositedBdv": 42193277, + "stalk": 421932770000, + "roots": "0x533c2d45ba7bc6e67620" + }, + "cumulativeDiscrepancy": { + "depositedBean": 11332356405, + "depositedBdv": 11332356405, + "stalk": 113323564050000, + "roots": "0x57539a4053a11205593dbb" + }, + "block": 19964305, + "txHash": "0x87432bf56b535cd2c8588c71bfc6b35b7dde134cfc4956bed6d5519fded02712" + }, + { + "account": "0xf62405e188bb9629ed623d60b7c70dcc4e2abd81", + "accountDiscrepancy": { + "depositedBean": 211342404, + "depositedBdv": 211342404, + "stalk": 2113424040000, + "roots": "0x1a0eac76731c01011962e" + }, + "cumulativeDiscrepancy": { + "depositedBean": 11543698809, + "depositedBdv": 11543698809, + "stalk": 115436988090000, + "roots": "0x58f48507bad2d2156ad3e9" + }, + "block": 19966550, + "txHash": "0xa1e6aea13a21da1e1e12e6547dfa953fc0da0a49c9e674051a99ef0f39e3e0b8" + }, + { + "account": "0x52eaa3345a9b68d3b5d52da2fd47ebfc5ed11d4e", + "accountDiscrepancy": { + "depositedBean": 117622581, + "depositedBdv": 117622581, + "stalk": 1176225810000, + "roots": "0xe808ff73ff408717ef32" + }, + "cumulativeDiscrepancy": { + "depositedBean": 11661321390, + "depositedBdv": 11661321390, + "stalk": 116613213900000, + "roots": "0x59dc8e072ed2129c82c31b" + }, + "block": 19967148, + "txHash": "0xafecee0d22dd94ae34a79fddbb803f7e747a86fd02a0b1bbb886fe618889a2d7" + }, + { + "account": "0xd441c97ef1458d847271f91714799007081494ef", + "accountDiscrepancy": { + "depositedBean": 2424238564, + "depositedBdv": 2424238564, + "stalk": 24242385640000, + "roots": "0x12ae51564d62b1f98c00d5" + }, + "cumulativeDiscrepancy": { + "depositedBean": 14085559954, + "depositedBdv": 14085559954, + "stalk": 140855599540000, + "roots": "0x6c8adf5d7c34c4960ec3f0" + }, + "block": 19968983, + "txHash": "0xbf5828bf704fd7dc3a5e7228145214cca68dc12ebea4558c837bac56c9c13f92" + }, + { + "account": "0xeaa4f3773f57af1d4c7130e07cde48050245511b", + "accountDiscrepancy": { + "depositedBean": 4341434014, + "depositedBdv": 4341434014, + "stalk": 43414340140000, + "roots": "0x2174630740c9787fc077a2" + }, + "cumulativeDiscrepancy": { + "depositedBean": 18426993968, + "depositedBdv": 18426993968, + "stalk": 184269939680000, + "roots": "0x8dff4264bcfe3d15cf3b92" + }, + "block": 19969909, + "txHash": "0xb86fe4294118f2150887a7c6776c95b01b212cdefed1878368a59280600af829" + }, + { + "account": "0x2bf046a052942b53ca6746de4d3295d8f10d4562", + "accountDiscrepancy": { + "depositedBean": 258059462, + "depositedBdv": 258059462, + "stalk": 2580594620000, + "roots": "0x1fd1386c8296b8f435874" + }, + "cumulativeDiscrepancy": { + "depositedBean": 18685053430, + "depositedBdv": 18685053430, + "stalk": 186850534300000, + "roots": "0x8ffc55eb8527a8a5129406" + }, + "block": 19972427, + "txHash": "0x13cb92c6afa3a1f4670124a3c9b022208948e5ad1302cfd1dfed5d103d6b31d3" + }, + { + "account": "0x7de837caff6a19898e507f644939939cb9341209", + "accountDiscrepancy": { + "depositedBean": 684692720, + "depositedBdv": 684692720, + "stalk": 6846927200000, + "roots": "0x546b31ae800ccacbe5126" + }, + "cumulativeDiscrepancy": { + "depositedBean": 19369746150, + "depositedBdv": 19369746150, + "stalk": 193697461500000, + "roots": "0x954309066d287551d0e52c" + }, + "block": 19974811, + "txHash": "0x2628551e82d89723be8acf6631753b5486e2c707989ff68b9deb22cc2b192577" + }, + { + "account": "0xc56725de9274e17847db0e45c1da36e46a7e197f", + "accountDiscrepancy": { + "depositedBean": 488145569, + "depositedBdv": 488145569, + "stalk": 4881455690000, + "roots": "0x3c2f8212788e5a5158657" + }, + "cumulativeDiscrepancy": { + "depositedBean": 19857891719, + "depositedBdv": 19857891719, + "stalk": 198578917190000, + "roots": "0x9906012794b15af6e66b83" + }, + "block": 19976352, + "txHash": "0xe358468c5bc418ea875b87172624eee8355233e57138f2f9bcb922b5e6835250" + }, + { + "account": "0x0be9a9100a95075270e47de519d53c5fc8f7c936", + "accountDiscrepancy": { + "depositedBean": 491375253, + "depositedBdv": 491375253, + "stalk": 4913752530000, + "roots": "0x3c95729e8e9795a27c2da" + }, + "cumulativeDiscrepancy": { + "depositedBean": 20349266972, + "depositedBdv": 20349266972, + "stalk": 203492669720000, + "roots": "0x9ccf58517d9ad4510e2e5d" + }, + "block": 19980662, + "txHash": "0x6674577fb706fb4a28afb6452600b65797b335fbb604e5dfef4f4bd02af2a869" + }, + { + "account": "0xc7c1b169a8d3c5f2d6b25642c4d10da94ffcd3c9", + "accountDiscrepancy": { + "depositedBean": 359977605, + "depositedBdv": 359977605, + "stalk": 3599776050000, + "roots": "0x2c62191fde7981d7d1bef" + }, + "cumulativeDiscrepancy": { + "depositedBean": 20709244577, + "depositedBdv": 20709244577, + "stalk": 207092445770000, + "roots": "0x9f9579e37b826c6e8b4a4c" + }, + "block": 19983194, + "txHash": "0x9047747fa52a8a417f0745eebb9676077384e105b96c013dce59b9efda092ff7" + }, + { + "account": "0xf840aa35b73ee0bbf488d81d684706729aba0a15", + "accountDiscrepancy": { + "depositedBean": 14249979, + "depositedBdv": 14249979, + "stalk": 142499790000, + "roots": "0x1c1c6ebc7efe0c2b0949" + }, + "cumulativeDiscrepancy": { + "depositedBean": 20723494556, + "depositedBdv": 20723494556, + "stalk": 207234945560000, + "roots": "0x9fb1965238016a7ab65395" + }, + "block": 19983874, + "txHash": "0x5a5b4bc15de098f438208f91c26a4880c8061837e39909f1134544dac461b5db" + }, + { + "account": "0x11b197e2c61c2959ae84bc7f9db8e3fefe511043", + "accountDiscrepancy": { + "depositedBean": 787555001, + "depositedBdv": 787555001, + "stalk": 7875550010000, + "roots": "0x6119df38da1aef59eccdc" + }, + "cumulativeDiscrepancy": { + "depositedBean": 21511049557, + "depositedBdv": 21511049557, + "stalk": 215110495570000, + "roots": "0xa5c33445c5a31970552071" + }, + "block": 19983878, + "txHash": "0x36eca6d017f86cd3bfa9e63ed181732cab2ef1a90bd4a1d429b82aa568ea088f" + }, + { + "account": "0xda8c9d1b00d12ddf67f2aa6af582fd6a38209b39", + "accountDiscrepancy": { + "depositedBean": 376462215, + "depositedBdv": 376462215, + "stalk": 3764622150000, + "roots": "0x2e6a685941d5cbb0d48ce" + }, + "cumulativeDiscrepancy": { + "depositedBean": 21887511772, + "depositedBdv": 21887511772, + "stalk": 218875117720000, + "roots": "0xa8a9dacb59c0762b62693f" + }, + "block": 19985609, + "txHash": "0xb5fab47f76c4cf036456ef64020ae636c437aa04b14bd969540aaf25af634a06" + }, + { + "account": "0x53bd04892c7147e1126bc7ba68f2fb6bf5a43910", + "accountDiscrepancy": { + "depositedBean": 4158664138, + "depositedBdv": 4158664138, + "stalk": 41586641380000, + "roots": "0x200bd5c36c99660fed5e56" + }, + "cumulativeDiscrepancy": { + "depositedBean": 26046175910, + "depositedBdv": 26046175910, + "stalk": 260461759100000, + "roots": "0xc8b5b08ec659dc3b4fc795" + }, + "block": 19993199, + "txHash": "0x6f4577dddf7eb9ded095ef7d4e480c423acb0abd6e1ab530b27669ede4590a9d" + }, + { + "account": "0x4bf44e0c856d096b755d54ca1e9cfdc0115ed2e6", + "accountDiscrepancy": { + "depositedBean": 126997345, + "depositedBdv": 126997345, + "stalk": 1269973450000, + "roots": "0xfa876179d7c800e2c28a" + }, + "cumulativeDiscrepancy": { + "depositedBean": 26173173255, + "depositedBdv": 26173173255, + "stalk": 261731732550000, + "roots": "0xc9b037f04031a43c328a1f" + }, + "block": 19994008, + "txHash": "0x3b3125a10e1a5980f6ab387ae6d74ebcdfe3f4e170bfd4d9d487ae930c516fbe" + }, + { + "account": "0x2972bf9b54ac5100d747150dfd684899c0abec5e", + "accountDiscrepancy": { + "depositedBean": 3573573138, + "depositedBdv": 3573573138, + "stalk": 35735731380000, + "roots": "0x1b899ee086192386fc657e" + }, + "cumulativeDiscrepancy": { + "depositedBean": 29746746393, + "depositedBdv": 29746746393, + "stalk": 297467463930000, + "roots": "0xe539d6d0c64ac7c32eef9d" + }, + "block": 20000251, + "txHash": "0x2c6009f7bca5b19d48d02068d5b4d45dc2759cb7d6a0c3b0f9bdfb5eb7cf3825" + } +] diff --git a/protocol/contracts/beanstalk/init/InitHotFix6_generate.js b/protocol/contracts/beanstalk/init/InitHotFix6_generate.js new file mode 100644 index 0000000000..fd2ea8a591 --- /dev/null +++ b/protocol/contracts/beanstalk/init/InitHotFix6_generate.js @@ -0,0 +1,25 @@ +const fs = require('fs'); + +// Read and parse the JSON file +fs.readFile('InitHotFix6Data.json', 'utf8', (err, data) => { + if (err) { + console.error('Error reading file:', err); + return; + } + + try { + const jsonData = JSON.parse(data); + + // Loop through each object in the array + jsonData.forEach(item => { + const address = item.account; + const stalk = item.accountDiscrepancy.stalk; + const roots = item.accountDiscrepancy.roots; + + // Print the adjustAccount call with filled-in data + console.log(`adjustAccount(address(${address}), ${stalk}, ${roots});`); + }); + } catch (parseError) { + console.error('Error parsing JSON:', parseError); + } +}); \ No newline at end of file From 1c0377680f89af91c13a8c00db6fe0edd30b4093 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 15:44:38 +0200 Subject: [PATCH 18/43] Update to use checksummed addresses as solidity requires --- .../contracts/beanstalk/init/InitHotFix6.sol | 70 +++++++++---------- .../beanstalk/init/InitHotFix6Data.json | 70 +++++++++---------- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/protocol/contracts/beanstalk/init/InitHotFix6.sol b/protocol/contracts/beanstalk/init/InitHotFix6.sol index 237c0dc961..af3056d0f0 100644 --- a/protocol/contracts/beanstalk/init/InitHotFix6.sol +++ b/protocol/contracts/beanstalk/init/InitHotFix6.sol @@ -15,41 +15,41 @@ contract InitHotFix6 { function init() external { // generated using the script at InitHotFix6_generate.js - adjustAccount(address(0xa7e3fed558e81dab40cd87f334d68b0bf0ab3fd6), 1339045260000, 0x108288355466404f3e7a6); - adjustAccount(address(0xe203096d7583e30888902b2608652c720d6c38da), 895630340000, 0xb0af280a27dd55e15186); - adjustAccount(address(0xe5d36124de24481dac81cc06b2cd0bbe81701d14), 2719827460000, 0x2188cd396d713453f2385); - adjustAccount(address(0xdff24806405f62637e0b44cc2903f1dfc7c111cd), 4465241140000, 0x370dfc5bf2d37e323068e); - adjustAccount(address(0xcde68f6a7078f47ee664ccbc594c9026a8a72d25), 87310400000, 0x11395a60856002fd2bb2); - adjustAccount(address(0x6343b307c288432bb9ad9003b4230b08b56b3b82), 1587607930000, 0x139316f233f39b2d7fc7a); - adjustAccount(address(0xfe7a7f227967104299e2ed9c47ca28eadc3a7c5f), 800384040000, 0x9de506359f0bad67dd9b); - adjustAccount(address(0xf6f6d531ed0f7fa18cae2c73b21aa853c765c4d8), 20368615360000, 0xfb2309014e60e822b7351); - adjustAccount(address(0xcba1a275e2d858ecffaf7a87f606f74b719a8a93), 2488521800000, 0x1eaeb6b687d242423820f); - adjustAccount(address(0xcfd9c9ac52b4b6fe30537803caeb327dadd411bb), 2265290610000, 0x1bee1ca2f7c590350cd56); - adjustAccount(address(0x91953b70d0861309f7d3a429a1cf82c8353132be), 4742314480000, 0x3a7888a5bfb29eb0da262); - adjustAccount(address(0x19831b174e9deabf9e4b355aadfd157f09e2af1f), 10904953700000, 0x867425f8ce119587b9de6); - adjustAccount(address(0xe249d1be97f4a716cde0d7c5b6b682f491621c41), 2813491850000, 0x22b0711a97fac34a4ff80); - adjustAccount(address(0x19c5bad4354e9a78a1ca0235af29b9eacf54ff2b), 815845330000, 0xa0f1d9d41775c1be9a18); - adjustAccount(address(0x6cd83315e4c4bfdf95d4a8442927c018f328c9fe), 1737884960000, 0x156d6baf092d9ce69e24e); - adjustAccount(address(0xf05b641229bb2aa63b205ad8b423a390f7ef05a7), 1636015800000, 0x142be2152769fa6a1e6a6); - adjustAccount(address(0x7d50bfead43d4fdd47a8a61f32305b2de21068bd), 3004066550000, 0x2509d6ed94de16f5eac68); - adjustAccount(address(0xd3e0ef0ebb7bc536405918d4d8dbdf981185d435), 50000000000000, 0x26878bc7521efacb1e9a15); - adjustAccount(address(0xe146313a9d6d6ccdd733cc15af3cf11d47e96f25), 229584270000, 0x2d4a511d471dc4e8b28e); - adjustAccount(address(0x4ca3e5bdf3823febbe18f9664cded14b7243971c), 421932770000, 0x533c2d45ba7bc6e67620); - adjustAccount(address(0xf62405e188bb9629ed623d60b7c70dcc4e2abd81), 2113424040000, 0x1a0eac76731c01011962e); - adjustAccount(address(0x52eaa3345a9b68d3b5d52da2fd47ebfc5ed11d4e), 1176225810000, 0xe808ff73ff408717ef32); - adjustAccount(address(0xd441c97ef1458d847271f91714799007081494ef), 24242385640000, 0x12ae51564d62b1f98c00d5); - adjustAccount(address(0xeaa4f3773f57af1d4c7130e07cde48050245511b), 43414340140000, 0x2174630740c9787fc077a2); - adjustAccount(address(0x2bf046a052942b53ca6746de4d3295d8f10d4562), 2580594620000, 0x1fd1386c8296b8f435874); - adjustAccount(address(0x7de837caff6a19898e507f644939939cb9341209), 6846927200000, 0x546b31ae800ccacbe5126); - adjustAccount(address(0xc56725de9274e17847db0e45c1da36e46a7e197f), 4881455690000, 0x3c2f8212788e5a5158657); - adjustAccount(address(0x0be9a9100a95075270e47de519d53c5fc8f7c936), 4913752530000, 0x3c95729e8e9795a27c2da); - adjustAccount(address(0xc7c1b169a8d3c5f2d6b25642c4d10da94ffcd3c9), 3599776050000, 0x2c62191fde7981d7d1bef); - adjustAccount(address(0xf840aa35b73ee0bbf488d81d684706729aba0a15), 142499790000, 0x1c1c6ebc7efe0c2b0949); - adjustAccount(address(0x11b197e2c61c2959ae84bc7f9db8e3fefe511043), 7875550010000, 0x6119df38da1aef59eccdc); - adjustAccount(address(0xda8c9d1b00d12ddf67f2aa6af582fd6a38209b39), 3764622150000, 0x2e6a685941d5cbb0d48ce); - adjustAccount(address(0x53bd04892c7147e1126bc7ba68f2fb6bf5a43910), 41586641380000, 0x200bd5c36c99660fed5e56); - adjustAccount(address(0x4bf44e0c856d096b755d54ca1e9cfdc0115ed2e6), 1269973450000, 0xfa876179d7c800e2c28a); - adjustAccount(address(0x2972bf9b54ac5100d747150dfd684899c0abec5e), 35735731380000, 0x1b899ee086192386fc657e); + adjustAccount(address(0xA7e3feD558E81dAb40Cd87F334D68b0BF0AB3fD6), 1339045260000, 0x108288355466404f3e7a6); + adjustAccount(address(0xE203096D7583E30888902b2608652c720D6C38da), 895630340000, 0xb0af280a27dd55e15186); + adjustAccount(address(0xe5D36124DE24481daC81cc06b2Cd0bbE81701D14), 2719827460000, 0x2188cd396d713453f2385); + adjustAccount(address(0xdff24806405f62637E0b44cc2903F1DfC7c111Cd), 4465241140000, 0x370dfc5bf2d37e323068e); + adjustAccount(address(0xcDe68F6a7078f47Ee664cCBc594c9026a8a72d25), 87310400000, 0x11395a60856002fd2bb2); + adjustAccount(address(0x6343B307C288432BB9AD9003B4230B08B56b3b82), 1587607930000, 0x139316f233f39b2d7fc7a); + adjustAccount(address(0xFE7A7F227967104299E2ED9c47ca28eADc3a7C5f), 800384040000, 0x9de506359f0bad67dd9b); + adjustAccount(address(0xF6f6d531ed0f7fa18cae2C73b21aa853c765c4d8), 20368615360000, 0xfb2309014e60e822b7351); + adjustAccount(address(0xCba1A275e2D858EcffaF7a87F606f74B719a8A93), 2488521800000, 0x1eaeb6b687d242423820f); + adjustAccount(address(0xcfd9c9Ac52b4B6Fe30537803CaEb327daDD411bB), 2265290610000, 0x1bee1ca2f7c590350cd56); + adjustAccount(address(0x91953b70d0861309f7D3A429A1CF82C8353132Be), 4742314480000, 0x3a7888a5bfb29eb0da262); + adjustAccount(address(0x19831b174e9deAbF9E4B355AadFD157F09E2af1F), 10904953700000, 0x867425f8ce119587b9de6); + adjustAccount(address(0xe249d1bE97f4A716CDE0D7C5B6b682F491621C41), 2813491850000, 0x22b0711a97fac34a4ff80); + adjustAccount(address(0x19c5baD4354e9a78A1CA0235Af29b9EAcF54fF2b), 815845330000, 0xa0f1d9d41775c1be9a18); + adjustAccount(address(0x6CD83315e4c4bFdf95D4A8442927C018F328C9fe), 1737884960000, 0x156d6baf092d9ce69e24e); + adjustAccount(address(0xf05b641229bB2aA63b205Ad8B423a390F7Ef05A7), 1636015800000, 0x142be2152769fa6a1e6a6); + adjustAccount(address(0x7d50bfeAD43d4FDD47a8A61f32305b2dE21068Bd), 3004066550000, 0x2509d6ed94de16f5eac68); + adjustAccount(address(0xd3e0Ef0eBB7bC536405918d4D8dBDF981185d435), 50000000000000, 0x26878bc7521efacb1e9a15); + adjustAccount(address(0xE146313a9D6D6cCdd733CC15af3Cf11d47E96F25), 229584270000, 0x2d4a511d471dc4e8b28e); + adjustAccount(address(0x4Ca3E5bDf3823fEBbE18F9664cdEd14b7243971C), 421932770000, 0x533c2d45ba7bc6e67620); + adjustAccount(address(0xF62405e188Bb9629eD623d60B7c70dCc4e2ABd81), 2113424040000, 0x1a0eac76731c01011962e); + adjustAccount(address(0x52EAa3345a9b68d3b5d52DA2fD47EbFc5ed11d4e), 1176225810000, 0xe808ff73ff408717ef32); + adjustAccount(address(0xD441C97eF1458d847271f91714799007081494eF), 24242385640000, 0x12ae51564d62b1f98c00d5); + adjustAccount(address(0xEAa4F3773F57af1D4c7130e07CDE48050245511B), 43414340140000, 0x2174630740c9787fc077a2); + adjustAccount(address(0x2bF046A052942B53Ca6746de4D3295d8f10d4562), 2580594620000, 0x1fd1386c8296b8f435874); + adjustAccount(address(0x7dE837cAff6A19898e507F644939939cB9341209), 6846927200000, 0x546b31ae800ccacbe5126); + adjustAccount(address(0xC56725DE9274E17847db0E45c1DA36E46A7e197F), 4881455690000, 0x3c2f8212788e5a5158657); + adjustAccount(address(0x0be9A9100A95075270e47De519D53c5fc8F7C936), 4913752530000, 0x3c95729e8e9795a27c2da); + adjustAccount(address(0xC7C1b169a8d3c5F2D6b25642c4d10DA94fFCd3c9), 3599776050000, 0x2c62191fde7981d7d1bef); + adjustAccount(address(0xF840AA35b73EE0Bbf488D81d684706729Aba0a15), 142499790000, 0x1c1c6ebc7efe0c2b0949); + adjustAccount(address(0x11b197e2C61c2959Ae84bC7f9db8E3fEFe511043), 7875550010000, 0x6119df38da1aef59eccdc); + adjustAccount(address(0xDa8C9D1B00D12DdF67F2aa6aF582fD6A38209b39), 3764622150000, 0x2e6a685941d5cbb0d48ce); + adjustAccount(address(0x53BD04892c7147E1126bC7bA68f2fB6bF5A43910), 41586641380000, 0x200bd5c36c99660fed5e56); + adjustAccount(address(0x4bf44E0c856d096B755D54CA1e9CFdc0115ED2e6), 1269973450000, 0xfa876179d7c800e2c28a); + adjustAccount(address(0x2972bf9B54aC5100d747150Dfd684899c0aBEc5E), 35735731380000, 0x1b899ee086192386fc657e); // fix system-level deposited bean and bdv s.siloBalances[C.BEAN].deposited = s.siloBalances[C.BEAN].deposited - 29746746393; diff --git a/protocol/contracts/beanstalk/init/InitHotFix6Data.json b/protocol/contracts/beanstalk/init/InitHotFix6Data.json index a8986cbf79..1d8ddb1bd2 100644 --- a/protocol/contracts/beanstalk/init/InitHotFix6Data.json +++ b/protocol/contracts/beanstalk/init/InitHotFix6Data.json @@ -1,6 +1,6 @@ [ { - "account": "0xa7e3fed558e81dab40cd87f334d68b0bf0ab3fd6", + "account": "0xA7e3feD558E81dAb40Cd87F334D68b0BF0AB3fD6", "accountDiscrepancy": { "depositedBean": 133904526, "depositedBdv": 133904526, @@ -17,7 +17,7 @@ "txHash": "0xc13e96784c0218751ff8f9c0de21b3dbe1879ae3902798fbfaf77017cda3bb48" }, { - "account": "0xe203096d7583e30888902b2608652c720d6c38da", + "account": "0xE203096D7583E30888902b2608652c720D6C38da", "accountDiscrepancy": { "depositedBean": 89563034, "depositedBdv": 89563034, @@ -34,7 +34,7 @@ "txHash": "0xe3138f983bd7de4baec19e7000abe80a42a8024b7162ea5618bb72459780afb8" }, { - "account": "0xe5d36124de24481dac81cc06b2cd0bbe81701d14", + "account": "0xe5D36124DE24481daC81cc06b2Cd0bbE81701D14", "accountDiscrepancy": { "depositedBean": 271982746, "depositedBdv": 271982746, @@ -51,7 +51,7 @@ "txHash": "0x48f452e6f2e6cd07280a4bab98a470c4a5f1cce0026a7eceb244b786d8abe663" }, { - "account": "0xdff24806405f62637e0b44cc2903f1dfc7c111cd", + "account": "0xdff24806405f62637E0b44cc2903F1DfC7c111Cd", "accountDiscrepancy": { "depositedBean": 446524114, "depositedBdv": 446524114, @@ -68,7 +68,7 @@ "txHash": "0x0492af41b8aa36bd2bd78eacf9ad576806d8fd66f34f096611aee80814a6181e" }, { - "account": "0xcde68f6a7078f47ee664ccbc594c9026a8a72d25", + "account": "0xcDe68F6a7078f47Ee664cCBc594c9026a8a72d25", "accountDiscrepancy": { "depositedBean": 8731040, "depositedBdv": 8731040, @@ -85,7 +85,7 @@ "txHash": "0xebdb85436aa97e1bd6e9a106ec4bc39f7e595f82e30cd8cfe29fcb3a323dd93a" }, { - "account": "0x6343b307c288432bb9ad9003b4230b08b56b3b82", + "account": "0x6343B307C288432BB9AD9003B4230B08B56b3b82", "accountDiscrepancy": { "depositedBean": 158760793, "depositedBdv": 158760793, @@ -102,7 +102,7 @@ "txHash": "0x1b6e13bf3c94e5aa2a8445ffad21d6ff77ad49e80aa6d56897295c59366c8243" }, { - "account": "0xfe7a7f227967104299e2ed9c47ca28eadc3a7c5f", + "account": "0xFE7A7F227967104299E2ED9c47ca28eADc3a7C5f", "accountDiscrepancy": { "depositedBean": 80038404, "depositedBdv": 80038404, @@ -119,7 +119,7 @@ "txHash": "0x74108cdbe98ece9ebf97a8cb24f17f81582afe352af6f3173abcab3fe36ab8d9" }, { - "account": "0xf6f6d531ed0f7fa18cae2c73b21aa853c765c4d8", + "account": "0xF6f6d531ed0f7fa18cae2C73b21aa853c765c4d8", "accountDiscrepancy": { "depositedBean": 2036861536, "depositedBdv": 2036861536, @@ -136,7 +136,7 @@ "txHash": "0xdeb93e488d8c850914dd32a91f1bd32a03e5d3fa9da0e1517a52a00d1ff23a0f" }, { - "account": "0xcba1a275e2d858ecffaf7a87f606f74b719a8a93", + "account": "0xCba1A275e2D858EcffaF7a87F606f74B719a8A93", "accountDiscrepancy": { "depositedBean": 248852180, "depositedBdv": 248852180, @@ -153,7 +153,7 @@ "txHash": "0xc71bef3a0838158da7f2a73f6239dcd963d321c653b733a00e0e398108381e9f" }, { - "account": "0xcfd9c9ac52b4b6fe30537803caeb327dadd411bb", + "account": "0xcfd9c9Ac52b4B6Fe30537803CaEb327daDD411bB", "accountDiscrepancy": { "depositedBean": 226529061, "depositedBdv": 226529061, @@ -170,7 +170,7 @@ "txHash": "0xa0e76ca36a82d0eb1d862f125699d173680fb84bc1ab575f40e0794fdb0d432a" }, { - "account": "0x91953b70d0861309f7d3a429a1cf82c8353132be", + "account": "0x91953b70d0861309f7D3A429A1CF82C8353132Be", "accountDiscrepancy": { "depositedBean": 474231448, "depositedBdv": 474231448, @@ -187,7 +187,7 @@ "txHash": "0xe598db0643bece20c6ab5db1ebaafcfb873e4b64ce662c9a9bd7b47e62900ce2" }, { - "account": "0x19831b174e9deabf9e4b355aadfd157f09e2af1f", + "account": "0x19831b174e9deAbF9E4B355AadFD157F09E2af1F", "accountDiscrepancy": { "depositedBean": 1090495370, "depositedBdv": 1090495370, @@ -204,7 +204,7 @@ "txHash": "0xf381409f445bcc836f904a36b2ed9b6497a75a509507abd9571c993b231fe99b" }, { - "account": "0xe249d1be97f4a716cde0d7c5b6b682f491621c41", + "account": "0xe249d1bE97f4A716CDE0D7C5B6b682F491621C41", "accountDiscrepancy": { "depositedBean": 281349185, "depositedBdv": 281349185, @@ -221,7 +221,7 @@ "txHash": "0x69a02efde93c9fd3cbae189b8b8abe30877424c12073422805ff8866bc938034" }, { - "account": "0x19c5bad4354e9a78a1ca0235af29b9eacf54ff2b", + "account": "0x19c5baD4354e9a78A1CA0235Af29b9EAcF54fF2b", "accountDiscrepancy": { "depositedBean": 81584533, "depositedBdv": 81584533, @@ -238,7 +238,7 @@ "txHash": "0x22dcf2e91034f85e571184291f74f6481f2c793a4c987c47a7e5fab53631a525" }, { - "account": "0x6cd83315e4c4bfdf95d4a8442927c018f328c9fe", + "account": "0x6CD83315e4c4bFdf95D4A8442927C018F328C9fe", "accountDiscrepancy": { "depositedBean": 173788496, "depositedBdv": 173788496, @@ -255,7 +255,7 @@ "txHash": "0x8b9aa1130b213df31bea992148a2b6e1d80b2ddd31d425f9672917c0e5cf4156" }, { - "account": "0xf05b641229bb2aa63b205ad8b423a390f7ef05a7", + "account": "0xf05b641229bB2aA63b205Ad8B423a390F7Ef05A7", "accountDiscrepancy": { "depositedBean": 163601580, "depositedBdv": 163601580, @@ -272,7 +272,7 @@ "txHash": "0x6ebdd4084df99c31c089abef15232b3b90e3e29268c8b1781663a38685b5ea69" }, { - "account": "0x7d50bfead43d4fdd47a8a61f32305b2de21068bd", + "account": "0x7d50bfeAD43d4FDD47a8A61f32305b2dE21068Bd", "accountDiscrepancy": { "depositedBean": 300406655, "depositedBdv": 300406655, @@ -289,7 +289,7 @@ "txHash": "0xecddbc54465eb60d8429d739f9a28d0e8133bcebefcb913e05bd7ff8bd8e8533" }, { - "account": "0xd3e0ef0ebb7bc536405918d4d8dbdf981185d435", + "account": "0xd3e0Ef0eBB7bC536405918d4D8dBDF981185d435", "accountDiscrepancy": { "depositedBean": 5000000000, "depositedBdv": 5000000000, @@ -306,7 +306,7 @@ "txHash": "0x563f865c941b942b7219aff8d5548b00870dc4f804a94b1967f729eaa5caf239" }, { - "account": "0xe146313a9d6d6ccdd733cc15af3cf11d47e96f25", + "account": "0xE146313a9D6D6cCdd733CC15af3Cf11d47E96F25", "accountDiscrepancy": { "depositedBean": 22958427, "depositedBdv": 22958427, @@ -323,7 +323,7 @@ "txHash": "0x94422f8d4bb906ab687e714a1c9dffbe940300dfd37256e78034c421a85a6a31" }, { - "account": "0x4ca3e5bdf3823febbe18f9664cded14b7243971c", + "account": "0x4Ca3E5bDf3823fEBbE18F9664cdEd14b7243971C", "accountDiscrepancy": { "depositedBean": 42193277, "depositedBdv": 42193277, @@ -340,7 +340,7 @@ "txHash": "0x87432bf56b535cd2c8588c71bfc6b35b7dde134cfc4956bed6d5519fded02712" }, { - "account": "0xf62405e188bb9629ed623d60b7c70dcc4e2abd81", + "account": "0xF62405e188Bb9629eD623d60B7c70dCc4e2ABd81", "accountDiscrepancy": { "depositedBean": 211342404, "depositedBdv": 211342404, @@ -357,7 +357,7 @@ "txHash": "0xa1e6aea13a21da1e1e12e6547dfa953fc0da0a49c9e674051a99ef0f39e3e0b8" }, { - "account": "0x52eaa3345a9b68d3b5d52da2fd47ebfc5ed11d4e", + "account": "0x52EAa3345a9b68d3b5d52DA2fD47EbFc5ed11d4e", "accountDiscrepancy": { "depositedBean": 117622581, "depositedBdv": 117622581, @@ -374,7 +374,7 @@ "txHash": "0xafecee0d22dd94ae34a79fddbb803f7e747a86fd02a0b1bbb886fe618889a2d7" }, { - "account": "0xd441c97ef1458d847271f91714799007081494ef", + "account": "0xD441C97eF1458d847271f91714799007081494eF", "accountDiscrepancy": { "depositedBean": 2424238564, "depositedBdv": 2424238564, @@ -391,7 +391,7 @@ "txHash": "0xbf5828bf704fd7dc3a5e7228145214cca68dc12ebea4558c837bac56c9c13f92" }, { - "account": "0xeaa4f3773f57af1d4c7130e07cde48050245511b", + "account": "0xEAa4F3773F57af1D4c7130e07CDE48050245511B", "accountDiscrepancy": { "depositedBean": 4341434014, "depositedBdv": 4341434014, @@ -408,7 +408,7 @@ "txHash": "0xb86fe4294118f2150887a7c6776c95b01b212cdefed1878368a59280600af829" }, { - "account": "0x2bf046a052942b53ca6746de4d3295d8f10d4562", + "account": "0x2bF046A052942B53Ca6746de4D3295d8f10d4562", "accountDiscrepancy": { "depositedBean": 258059462, "depositedBdv": 258059462, @@ -425,7 +425,7 @@ "txHash": "0x13cb92c6afa3a1f4670124a3c9b022208948e5ad1302cfd1dfed5d103d6b31d3" }, { - "account": "0x7de837caff6a19898e507f644939939cb9341209", + "account": "0x7dE837cAff6A19898e507F644939939cB9341209", "accountDiscrepancy": { "depositedBean": 684692720, "depositedBdv": 684692720, @@ -442,7 +442,7 @@ "txHash": "0x2628551e82d89723be8acf6631753b5486e2c707989ff68b9deb22cc2b192577" }, { - "account": "0xc56725de9274e17847db0e45c1da36e46a7e197f", + "account": "0xC56725DE9274E17847db0E45c1DA36E46A7e197F", "accountDiscrepancy": { "depositedBean": 488145569, "depositedBdv": 488145569, @@ -459,7 +459,7 @@ "txHash": "0xe358468c5bc418ea875b87172624eee8355233e57138f2f9bcb922b5e6835250" }, { - "account": "0x0be9a9100a95075270e47de519d53c5fc8f7c936", + "account": "0x0be9A9100A95075270e47De519D53c5fc8F7C936", "accountDiscrepancy": { "depositedBean": 491375253, "depositedBdv": 491375253, @@ -476,7 +476,7 @@ "txHash": "0x6674577fb706fb4a28afb6452600b65797b335fbb604e5dfef4f4bd02af2a869" }, { - "account": "0xc7c1b169a8d3c5f2d6b25642c4d10da94ffcd3c9", + "account": "0xC7C1b169a8d3c5F2D6b25642c4d10DA94fFCd3c9", "accountDiscrepancy": { "depositedBean": 359977605, "depositedBdv": 359977605, @@ -493,7 +493,7 @@ "txHash": "0x9047747fa52a8a417f0745eebb9676077384e105b96c013dce59b9efda092ff7" }, { - "account": "0xf840aa35b73ee0bbf488d81d684706729aba0a15", + "account": "0xF840AA35b73EE0Bbf488D81d684706729Aba0a15", "accountDiscrepancy": { "depositedBean": 14249979, "depositedBdv": 14249979, @@ -510,7 +510,7 @@ "txHash": "0x5a5b4bc15de098f438208f91c26a4880c8061837e39909f1134544dac461b5db" }, { - "account": "0x11b197e2c61c2959ae84bc7f9db8e3fefe511043", + "account": "0x11b197e2C61c2959Ae84bC7f9db8E3fEFe511043", "accountDiscrepancy": { "depositedBean": 787555001, "depositedBdv": 787555001, @@ -527,7 +527,7 @@ "txHash": "0x36eca6d017f86cd3bfa9e63ed181732cab2ef1a90bd4a1d429b82aa568ea088f" }, { - "account": "0xda8c9d1b00d12ddf67f2aa6af582fd6a38209b39", + "account": "0xDa8C9D1B00D12DdF67F2aa6aF582fD6A38209b39", "accountDiscrepancy": { "depositedBean": 376462215, "depositedBdv": 376462215, @@ -544,7 +544,7 @@ "txHash": "0xb5fab47f76c4cf036456ef64020ae636c437aa04b14bd969540aaf25af634a06" }, { - "account": "0x53bd04892c7147e1126bc7ba68f2fb6bf5a43910", + "account": "0x53BD04892c7147E1126bC7bA68f2fB6bF5A43910", "accountDiscrepancy": { "depositedBean": 4158664138, "depositedBdv": 4158664138, @@ -561,7 +561,7 @@ "txHash": "0x6f4577dddf7eb9ded095ef7d4e480c423acb0abd6e1ab530b27669ede4590a9d" }, { - "account": "0x4bf44e0c856d096b755d54ca1e9cfdc0115ed2e6", + "account": "0x4bf44E0c856d096B755D54CA1e9CFdc0115ED2e6", "accountDiscrepancy": { "depositedBean": 126997345, "depositedBdv": 126997345, @@ -578,7 +578,7 @@ "txHash": "0x3b3125a10e1a5980f6ab387ae6d74ebcdfe3f4e170bfd4d9d487ae930c516fbe" }, { - "account": "0x2972bf9b54ac5100d747150dfd684899c0abec5e", + "account": "0x2972bf9B54aC5100d747150Dfd684899c0aBEc5E", "accountDiscrepancy": { "depositedBean": 3573573138, "depositedBdv": 3573573138, From a64fb74298386e2099326fdf4857171448e8fe61 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 15:45:43 +0200 Subject: [PATCH 19/43] Emit events --- protocol/contracts/beanstalk/init/InitHotFix6.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/protocol/contracts/beanstalk/init/InitHotFix6.sol b/protocol/contracts/beanstalk/init/InitHotFix6.sol index af3056d0f0..36563e25bc 100644 --- a/protocol/contracts/beanstalk/init/InitHotFix6.sol +++ b/protocol/contracts/beanstalk/init/InitHotFix6.sol @@ -13,6 +13,9 @@ contract InitHotFix6 { AppStorage internal s; using SafeMath for uint256; + // copied from LibSilo.sol + event StalkBalanceChanged(address indexed account, int256 delta, int256 deltaRoots); + function init() external { // generated using the script at InitHotFix6_generate.js adjustAccount(address(0xA7e3feD558E81dAb40Cd87F334D68b0BF0AB3fD6), 1339045260000, 0x108288355466404f3e7a6); @@ -59,5 +62,8 @@ contract InitHotFix6 { function adjustAccount(address account, uint128 stalk, uint128 roots) internal { s.a[account].s.stalk = s.a[account].s.stalk - stalk; s.a[account].roots = s.a[account].roots - roots; + + // emit the event + emit StalkBalanceChanged(account, -int256(stalk), -int256(roots)); } } From f3e393c4824fee3bfec2901e308fec4db7ba7bc4 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 15:52:30 +0200 Subject: [PATCH 20/43] Fix system level stalk and roots --- protocol/contracts/beanstalk/init/InitHotFix6.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/protocol/contracts/beanstalk/init/InitHotFix6.sol b/protocol/contracts/beanstalk/init/InitHotFix6.sol index 36563e25bc..896feba51f 100644 --- a/protocol/contracts/beanstalk/init/InitHotFix6.sol +++ b/protocol/contracts/beanstalk/init/InitHotFix6.sol @@ -57,6 +57,9 @@ contract InitHotFix6 { // fix system-level deposited bean and bdv s.siloBalances[C.BEAN].deposited = s.siloBalances[C.BEAN].deposited - 29746746393; s.siloBalances[C.BEAN].depositedBdv = s.siloBalances[C.BEAN].depositedBdv - 29746746393; + + s.s.stalk = s.s.stalk - 297467463930000; + s.s.roots = s.s.roots - 0xe539d6d0c64ac7c32eef9d; } function adjustAccount(address account, uint128 stalk, uint128 roots) internal { From c501218a0be27833fc47c4631dcb4429a6f2b501 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 17:23:42 +0200 Subject: [PATCH 21/43] Script to run ebip --- protocol/hardhat.config.js | 7 ++++++- protocol/scripts/ebips.js | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/protocol/hardhat.config.js b/protocol/hardhat.config.js index ef7f61558b..4033ed9c42 100644 --- a/protocol/hardhat.config.js +++ b/protocol/hardhat.config.js @@ -29,7 +29,7 @@ const { BEANSTALK, PUBLIUS, BEAN_3_CURVE, PRICE } = require("./test/utils/consta const { task } = require("hardhat/config"); const { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } = require("hardhat/builtin-tasks/task-names"); const { bipNewSilo, bipMorningAuction, bipSeedGauge } = require("./scripts/bips.js"); -const { ebip9, ebip10, ebip11, ebip13, ebip14, ebip15, ebip16 } = require("./scripts/ebips.js"); +const { ebip9, ebip10, ebip11, ebip13, ebip14, ebip15, ebip16, ebip17 } = require("./scripts/ebips.js"); //////////////////////// UTILITIES //////////////////////// @@ -220,6 +220,11 @@ task("deploySeedGauge", async function () { /// EBIPS /// + +task("ebip17", async function () { + await ebip17(); +}) + task("ebip16", async function () { await ebip16(); }) diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index 298354aa9d..3551ae8293 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -188,6 +188,25 @@ async function ebip16(mock = true, account = undefined) { }); } +async function ebip17(mock = true, account = undefined) { + if (account == undefined) { + account = await impersonateBeanstalkOwner(); + await mintEth(account.address); + } + + await upgradeWithNewFacets({ + diamondAddress: BEANSTALK, + facetNames: [], + initFacetName: 'InitHotFix6', + initArgs: [], + selectorsToRemove: [''], + bip: false, + object: !mock, + verbose: true, + account: account + }); +} + async function bipDiamondCut(name, dc, account, mock = true) { beanstalk = await getBeanstalk(); @@ -215,4 +234,5 @@ exports.ebip11 = ebip11; exports.ebip13 = ebip13; exports.ebip14 = ebip14; exports.ebip15 = ebip15; -exports.ebip16 = ebip16; \ No newline at end of file +exports.ebip16 = ebip16; +exports.ebip17 = ebip17; \ No newline at end of file From 3fea162dc4ea8092f0cb7d2a58365e226c9591ef Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 22:02:52 +0200 Subject: [PATCH 22/43] Fix deployment --- protocol/scripts/ebips.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index 3551ae8293..ebe3e98622 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -199,7 +199,7 @@ async function ebip17(mock = true, account = undefined) { facetNames: [], initFacetName: 'InitHotFix6', initArgs: [], - selectorsToRemove: [''], + selectorsToRemove: [], bip: false, object: !mock, verbose: true, From ac101811bfb7eaddc9c9b31248febdeff7e9ff1c Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 22:08:29 +0200 Subject: [PATCH 23/43] Fix immunefi report balanceOfPlenty related bug --- protocol/contracts/libraries/Silo/LibSilo.sol | 12 +++--- protocol/test/Sop.test.js | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 3d837ef758..c81d0594eb 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -460,7 +460,7 @@ library LibSilo { // if it started raining and it's still raining, or there was a sop uint32 currentSeason = s.season.current; if (s.season.rainStart > s.season.stemStartSeason) { - if (lastUpdate <= s.season.rainStart && lastUpdate <= currentSeason) { + if ((lastUpdate <= s.season.rainStart || s.a[account].lastRain > 0) && lastUpdate <= currentSeason) { // Increments `plenty` for `account` if a Flood has occured. // Saves Rain Roots for `account` if it is Raining. handleRainAndSops(account, lastUpdate); @@ -525,17 +525,17 @@ library LibSilo { */ function handleRainAndSops(address account, uint32 lastUpdate) private { AppStorage storage s = LibAppStorage.diamondStorage(); + // If a Sop has occured since last update, calculate rewards and set last Sop. + if (s.season.lastSopSeason > lastUpdate) { + s.a[account].sop.plenty = balanceOfPlenty(account); + s.a[account].lastSop = s.season.lastSop; + } // If no roots, reset Sop counters variables if (s.a[account].roots == 0) { s.a[account].lastSop = s.season.rainStart; s.a[account].lastRain = 0; return; } - // If a Sop has occured since last update, calculate rewards and set last Sop. - if (s.season.lastSopSeason > lastUpdate) { - s.a[account].sop.plenty = balanceOfPlenty(account); - s.a[account].lastSop = s.season.lastSop; - } if (s.season.raining) { // If rain started after update, set account variables to track rain. if (s.season.rainStart > lastUpdate) { diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 8d98b068f9..091a12c69c 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -75,6 +75,43 @@ describe('Sop', function () { await revertToSnapshot(snapshotId) }) + + describe("bug report", async function () { + it("lost plenty 2", async function () { + const beanStem = to6("4"); + + //rain sunrise + await this.season.rainSunrise(); // start raining + await this.silo.mow(user.address, BEAN); + + // rain sunrise + await this.season.rainSunrise(); // still raining, no sop + await this.silo.mow(user.address, BEAN); // lastUpdated = rainStart + 1 + + // set reserves so next season plenty is accrued + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // 1st actual sop + + await this.silo.mow(user.address, BEAN); // this will do nothing as lastUpdated > rainStart + + await this.season.rainSunrise(); + await this.season.rainSunrise(); + + await this.season.droughtSunrise(); + await this.season.droughtSunrise(); + + await this.silo.connect(user).withdrawDeposit(BEAN, beanStem, to6("1000"), EXTERNAL); + + await this.season.rainSunrise(); + await this.silo.mow(user.address, BEAN); + + const userPlenty = await this.siloGetters.balanceOfPlenty(user.address); + expect(userPlenty).to.be.equal("25595575914848452999"); + }); + }); + describe("Rain", async function () { it("Not raining", async function () { const season = await this.seasonGetters.time() From ca73468ff974ee58a78d49e30b68a39a7d510604 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 22:54:26 +0200 Subject: [PATCH 24/43] Fix deployment --- protocol/scripts/ebips.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index 4c3ac8b2f1..fc579ed419 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -196,7 +196,12 @@ async function ebip17(mock = true, account = undefined) { await upgradeWithNewFacets({ diamondAddress: BEANSTALK, - facetNames: ["MarketplaceFacet"], + facetNames: ["MigrationFacet", "MarketplaceFacet", "ConvertFacet", "EnrootFacet", "SiloGettersFacet", "SiloFacet"], + libraryNames: ['LibSilo', 'LibConvert'], + facetLibraries: { + 'SiloFacet': ['LibSilo'], + 'ConvertFacet': ['LibConvert'] + }, bip: false, object: !mock, verbose: true, From 2cfdafbcfd153321ad8edabcde6b9ed0e9cb497b Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 7 Jul 2024 23:12:10 +0200 Subject: [PATCH 25/43] Add back burn stalk fix --- projects/sdk/src/lib/silo/Withdraw.test.ts | 2 +- protocol/contracts/libraries/Silo/LibSilo.sol | 10 ++++++++++ protocol/test/Sop.test.js | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/projects/sdk/src/lib/silo/Withdraw.test.ts b/projects/sdk/src/lib/silo/Withdraw.test.ts index d78ccdbd71..f8d174d6da 100644 --- a/projects/sdk/src/lib/silo/Withdraw.test.ts +++ b/projects/sdk/src/lib/silo/Withdraw.test.ts @@ -47,7 +47,7 @@ describe("Silo Withdrawl", function () { expect(t).rejects.toThrow("Insufficient balance"); }); - it.only("Calculates crates correctly", async () => { + it("Calculates crates correctly", async () => { const currentSeason = 10_000; const c1 = utils.mockDepositCrate(token, 900, "200", currentSeason); const c2 = utils.mockDepositCrate(token, 800, "500", currentSeason); diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index b67e37c6e6..6b7bc838be 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -256,6 +256,16 @@ library LibSilo { s.s.roots = s.s.roots.sub(roots); s.a[account].roots = s.a[account].roots.sub(roots); + // If it is Raining and the account now has less roots than the + // account's current rain roots, set the account's rain roots + // to the account's current roots and subtract the difference + // from Beanstalk's total rain roots. + if (s.season.raining && s.a[account].sop.roots > s.a[account].roots) { + uint256 deltaRoots = s.a[account].sop.roots - s.a[account].roots; + s.a[account].sop.roots = s.a[account].roots; + s.r.roots = s.r.roots.sub(deltaRoots); + } + // emit event. emit StalkBalanceChanged(account, -int256(stalk), -int256(roots)); } diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 4b95bc5418..c6da57d09d 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -363,7 +363,7 @@ describe('Sop', function () { }) }) - describe.only('Germination and Plenty', function () { + describe('Germination and Plenty', function () { it('not germinated', async function () { await this.bean.mint(user3Address, to6('10000')); From 2e103bce41534dfa3b0594c0216b9f36a5536d41 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Wed, 10 Jul 2024 15:10:17 +0200 Subject: [PATCH 26/43] Transfer rain roots upon deposit transfer (rain roots transferred first) --- protocol/contracts/libraries/Silo/LibSilo.sol | 13 +++ protocol/test/Sop.test.js | 95 +++++++++++++++++++ protocol/test/StemMigrateAll.test.js | 2 +- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 6b7bc838be..8594d41517 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -319,6 +319,19 @@ library LibSilo { ? s.a[sender].roots : s.s.roots.sub(1).mul(stalk).div(s.s.stalk).add(1); + + // Transfer rain roots + // Sop roots are transferred first, can't transfer more than sender's roots + uint256 sopRootsToTransfer = s.a[sender].sop.roots; + if (sopRootsToTransfer > s.a[sender].roots) { + sopRootsToTransfer = s.a[sender].roots; + } + // subtract rain roots from the sender + s.a[sender].sop.roots = s.a[sender].sop.roots.sub(sopRootsToTransfer); + + // add rain roots to the recipient + s.a[recipient].sop.roots = s.a[recipient].sop.roots.add(sopRootsToTransfer); + // Subtract Stalk and Roots from the 'sender' balance. s.a[sender].s.stalk = s.a[sender].s.stalk.sub(stalk); s.a[sender].roots = s.a[sender].roots.sub(roots); diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index c6da57d09d..a4bb9cda28 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -363,6 +363,101 @@ describe('Sop', function () { }) }) + describe('Rain roots reduced', function () { + it('reduces rain roots upon withdrawal', async function () { + const beanStem = to6("4"); + + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // start raining + await this.season.rainSunrise(); // sop + + await this.silo.mow(user.address, BEAN); + + let rainRoots = await this.siloGetters.balanceOfRainRoots(userAddress); + + expect(rainRoots).to.be.equal('10004000000000000000000000'); + + await this.silo.connect(user).withdrawDeposit(BEAN, beanStem, to6('1000'), EXTERNAL); + + rainRoots = await this.siloGetters.balanceOfRainRoots(userAddress); + + expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('0'); + }); + + it('reduces rain roots upon transfer', async function () { + const beanStem = to6("4"); + + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // start raining + await this.season.rainSunrise(); // sop + + await this.silo.mow(user.address, BEAN); + + let rainRootsBefore = await this.siloGetters.balanceOfRainRoots(userAddress); + + expect(rainRootsBefore).to.be.equal('10004000000000000000000000'); + + await this.silo.connect(user).transferDeposit(userAddress, user3Address, BEAN, beanStem, to6('1000')); + await this.silo.mow(user.address, BEAN); + + let rainRootsAfter = await this.siloGetters.balanceOfRainRoots(userAddress); + console.log("rainRoots after: ", rainRootsAfter.toString()); + + // user should have 0 rain roots + expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('0'); + // user3 should have the rain roots + expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal(rainRootsBefore); + }); + + // same as above test, however another deposit before the transfer + // so that we can verify rain roots are transferred first + it('transfers rain roots first', async function () { + const beanStem = to6("4"); + + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // start raining + await this.season.rainSunrise(); // sop + + await this.silo.mow(user.address, BEAN); + + // deposit + await this.silo.connect(user).deposit(BEAN, to6('1000'), EXTERNAL); + + // pass two seasons + await this.season.siloSunrise(0); + await this.season.siloSunrise(0); + + // mow so we get roots + await this.silo.mow(user.address, BEAN); + + // verify actual roots + let actualRoots = await this.siloGetters.balanceOfRoots(userAddress); + expect(actualRoots).to.be.equal('20016000000000000000000000'); + let rainRootsBefore = await this.siloGetters.balanceOfRainRoots(userAddress); + expect(rainRootsBefore).to.be.equal('10004000000000000000000000'); + + await this.silo.connect(user).transferDeposit(userAddress, user3Address, BEAN, beanStem, to6('1000')); + await this.silo.mow(user.address, BEAN); + + let rainRootsAfter = await this.siloGetters.balanceOfRainRoots(userAddress); + console.log("rainRoots after: ", rainRootsAfter.toString()); + + // user should have 0 rain roots + expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('0'); + // user3 should have the rain roots + expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal(rainRootsBefore); + }); + }) + describe('Germination and Plenty', function () { it('not germinated', async function () { diff --git a/protocol/test/StemMigrateAll.test.js b/protocol/test/StemMigrateAll.test.js index 11bcb95ada..c56dfafa5e 100644 --- a/protocol/test/StemMigrateAll.test.js +++ b/protocol/test/StemMigrateAll.test.js @@ -50,7 +50,7 @@ const eventsAbi = [ } ]; -describe('Silo V3: Stem deployment migrate everyone', function () { +describe.skip('Silo V3: Stem deployment migrate everyone', function () { before(async function () { try { From 92b2fd4c9127a342946ef7a847e99ae04dbdd267 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Wed, 10 Jul 2024 15:23:44 +0200 Subject: [PATCH 27/43] Add amount requirement to _transferPlot --- .../contracts/beanstalk/market/MarketplaceFacet/PodTransfer.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/contracts/beanstalk/market/MarketplaceFacet/PodTransfer.sol b/protocol/contracts/beanstalk/market/MarketplaceFacet/PodTransfer.sol index 99c780b7db..f5dded7f99 100644 --- a/protocol/contracts/beanstalk/market/MarketplaceFacet/PodTransfer.sol +++ b/protocol/contracts/beanstalk/market/MarketplaceFacet/PodTransfer.sol @@ -58,6 +58,7 @@ contract PodTransfer is ReentrancyGuard { uint256 amount ) internal { require(from != to, "Field: Cannot transfer Pods to oneself."); + require(amount > 0, "Marketplace: amount must be > 0."); insertPlot(to, index.add(start), amount); removePlot(from, index, start, amount.add(start)); emit PlotTransfer(from, to, index.add(start), amount); From 29d255e73ba4eb9652c2db1897ad19936a792efe Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Wed, 10 Jul 2024 17:14:36 +0200 Subject: [PATCH 28/43] Burn rain roots upon transfer --- protocol/contracts/libraries/Silo/LibSilo.sol | 17 +++---- protocol/test/Sop.test.js | 51 ++----------------- 2 files changed, 9 insertions(+), 59 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 8594d41517..8d4bf69595 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -261,7 +261,7 @@ library LibSilo { // to the account's current roots and subtract the difference // from Beanstalk's total rain roots. if (s.season.raining && s.a[account].sop.roots > s.a[account].roots) { - uint256 deltaRoots = s.a[account].sop.roots - s.a[account].roots; + uint256 deltaRoots = s.a[account].sop.roots.sub(s.a[account].roots); s.a[account].sop.roots = s.a[account].roots; s.r.roots = s.r.roots.sub(deltaRoots); } @@ -320,17 +320,12 @@ library LibSilo { : s.s.roots.sub(1).mul(stalk).div(s.s.stalk).add(1); - // Transfer rain roots - // Sop roots are transferred first, can't transfer more than sender's roots - uint256 sopRootsToTransfer = s.a[sender].sop.roots; - if (sopRootsToTransfer > s.a[sender].roots) { - sopRootsToTransfer = s.a[sender].roots; + // Rain roots cannot be transferred, burn them + if (s.season.raining) { + uint256 burnRainRoots = roots > s.a[sender].sop.roots ? s.a[sender].sop.roots : roots; + s.a[sender].sop.roots = s.a[sender].sop.roots.sub(burnRainRoots); + s.r.roots = s.r.roots.sub(burnRainRoots); } - // subtract rain roots from the sender - s.a[sender].sop.roots = s.a[sender].sop.roots.sub(sopRootsToTransfer); - - // add rain roots to the recipient - s.a[recipient].sop.roots = s.a[recipient].sop.roots.add(sopRootsToTransfer); // Subtract Stalk and Roots from the 'sender' balance. s.a[sender].s.stalk = s.a[sender].s.stalk.sub(stalk); diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index a4bb9cda28..34391ad7d8 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -387,7 +387,7 @@ describe('Sop', function () { expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('0'); }); - it('reduces rain roots upon transfer', async function () { + it('burns rain roots upon transfer', async function () { const beanStem = to6("4"); // set reserves so we'll sop @@ -406,55 +406,10 @@ describe('Sop', function () { await this.silo.connect(user).transferDeposit(userAddress, user3Address, BEAN, beanStem, to6('1000')); await this.silo.mow(user.address, BEAN); - let rainRootsAfter = await this.siloGetters.balanceOfRainRoots(userAddress); - console.log("rainRoots after: ", rainRootsAfter.toString()); - // user should have 0 rain roots expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('0'); - // user3 should have the rain roots - expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal(rainRootsBefore); - }); - - // same as above test, however another deposit before the transfer - // so that we can verify rain roots are transferred first - it('transfers rain roots first', async function () { - const beanStem = to6("4"); - - // set reserves so we'll sop - await this.well.setReserves([to6("1000000"), to18("1100")]); - await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); - - await this.season.rainSunrise(); // start raining - await this.season.rainSunrise(); // sop - - await this.silo.mow(user.address, BEAN); - - // deposit - await this.silo.connect(user).deposit(BEAN, to6('1000'), EXTERNAL); - - // pass two seasons - await this.season.siloSunrise(0); - await this.season.siloSunrise(0); - - // mow so we get roots - await this.silo.mow(user.address, BEAN); - - // verify actual roots - let actualRoots = await this.siloGetters.balanceOfRoots(userAddress); - expect(actualRoots).to.be.equal('20016000000000000000000000'); - let rainRootsBefore = await this.siloGetters.balanceOfRainRoots(userAddress); - expect(rainRootsBefore).to.be.equal('10004000000000000000000000'); - - await this.silo.connect(user).transferDeposit(userAddress, user3Address, BEAN, beanStem, to6('1000')); - await this.silo.mow(user.address, BEAN); - - let rainRootsAfter = await this.siloGetters.balanceOfRainRoots(userAddress); - console.log("rainRoots after: ", rainRootsAfter.toString()); - - // user should have 0 rain roots - expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('0'); - // user3 should have the rain roots - expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal(rainRootsBefore); + // user3 should have 0 rain roots, none transferred + expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal('0'); }); }) From 47b0a8172ed9e00ba53c3cd8b74ac4c2bbdcb1ad Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Thu, 11 Jul 2024 16:07:11 +0200 Subject: [PATCH 29/43] Add total rain roots getter --- .../contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol index 55ccc7b7cd..1aab895ec7 100644 --- a/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol +++ b/protocol/contracts/beanstalk/silo/SiloFacet/SiloGettersFacet.sol @@ -529,6 +529,10 @@ contract SiloGettersFacet is ReentrancyGuard { sop.plentyPerRoot = s.a[account].sop.plentyPerRoot; } + function totalRainRoots() external view returns (uint256) { + return s.r.roots; + } + //////////////////////// STEM //////////////////////// /** From a1c6b2e63df64d59438b1216b38161b38d9c2aa8 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Thu, 11 Jul 2024 16:09:53 +0200 Subject: [PATCH 30/43] Add total roots manipulation test, fix end germination in mock, change order of germination --- .../beanstalk/sun/SeasonFacet/SeasonFacet.sol | 2 +- .../mocks/mockFacets/MockSeasonFacet.sol | 1 + protocol/test/Sop.test.js | 51 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol index 01a7cdfd9e..7791b7bc44 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/SeasonFacet.sol @@ -48,8 +48,8 @@ contract SeasonFacet is Weather { require(seasonTime() > s.season.current, "Season: Still current Season."); uint32 season = stepSeason(); int256 deltaB = stepOracle(); - uint256 caseId = calcCaseIdandUpdate(deltaB); LibGerminate.endTotalGermination(season, LibWhitelistedTokens.getWhitelistedTokens()); + uint256 caseId = calcCaseIdandUpdate(deltaB); LibGauge.stepGauge(); stepSun(deltaB, caseId); diff --git a/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol b/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol index b407c9c99b..35803ec952 100644 --- a/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol +++ b/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol @@ -93,6 +93,7 @@ contract MockSeasonFacet is SeasonFacet { s.season.sunriseBlock = uint32(block.number); // update last snapshot in beanstalk. stepOracle(); + LibGerminate.endTotalGermination(s.season.current, LibWhitelistedTokens.getWhitelistedTokens()); mockStartSop(); } diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 34391ad7d8..373db502e1 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -411,6 +411,57 @@ describe('Sop', function () { // user3 should have 0 rain roots, none transferred expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal('0'); }); + + it('manipulation test', async function () { + const beanStem = to6("4"); + + // user 3 deposits a bunch of bean + + const depositAmount = to6('50000'); + await this.bean.mint(user3Address, depositAmount); + await this.bean.connect(user3).approve(this.silo.address, MAX_UINT256); + await this.silo.connect(user3).deposit(this.bean.address, depositAmount, EXTERNAL); + + + // call sunrise twice to skip germination. + // await this.season.siloSunrise(0) + // await this.season.siloSunrise(0) + + // await this.silo.mow(user3Address, BEAN); + + + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // start raining + + // log current total rain roots and current total roots + let totalRainRoots = await this.siloGetters.totalRainRoots(); + console.log("totalRainRoots: ", totalRainRoots); + + let totalRoots = await this.siloGetters.totalRoots(); + console.log("totalRoots: ", totalRoots); + + + await this.season.rainSunrise(); // sop + + + await this.silo.mow(user3Address, BEAN); + + let totalRainRoots2 = await this.siloGetters.totalRainRoots(); + console.log("2 totalRainRoots: ", totalRainRoots2); + + let totalRoots2 = await this.siloGetters.totalRoots(); + console.log("2 totalRoots: ", totalRoots2); + + let userRainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); + console.log("userRainRoots: ", userRainRoots); + + // shouldn't be a way for a user to get more rain roots than total rain roots + // couldn't find a way to do lessThan without importing something else that supports BigNumber from chai + expect(userRainRoots.lt(totalRainRoots2)).to.be.true; + }); }) describe('Germination and Plenty', function () { From 4d0b34cd6c3d8fc68cdbdd3bddc71310c5987b65 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Fri, 12 Jul 2024 10:27:12 +0200 Subject: [PATCH 31/43] Germination roots fix --- .../contracts/beanstalk/sun/SeasonFacet/Weather.sol | 10 ++++++++++ protocol/test/Sop.test.js | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol index e81eaa0083..e7d1b9ca81 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol @@ -171,6 +171,16 @@ contract Weather is Sun { s.r.pods = s.f.pods; s.r.roots = s.s.roots; } else { + // Beanstalk wants to distribute plenty to users who have germinating assets + // prior to the start of the sop + // During handleRain, the sop roots are set to the current roots at the time of rain, + // which do not include the germinating roots. + if (s.season.current-1 == s.season.rainStart) { + // increase by germinating roots of previous season + // get 2 season's ago's germinating roots + uint256 germinatingRoots = s.unclaimedGerminating[s.season.current-2].roots; + s.r.roots = s.r.roots.add(germinatingRoots); + } if (s.r.roots > 0) { // initialize sopWell if it is not already set. if (s.sopWell == address(0)) s.sopWell = well; diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 373db502e1..ae85b700c0 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -413,8 +413,6 @@ describe('Sop', function () { }); it('manipulation test', async function () { - const beanStem = to6("4"); - // user 3 deposits a bunch of bean const depositAmount = to6('50000'); @@ -422,14 +420,6 @@ describe('Sop', function () { await this.bean.connect(user3).approve(this.silo.address, MAX_UINT256); await this.silo.connect(user3).deposit(this.bean.address, depositAmount, EXTERNAL); - - // call sunrise twice to skip germination. - // await this.season.siloSunrise(0) - // await this.season.siloSunrise(0) - - // await this.silo.mow(user3Address, BEAN); - - // set reserves so we'll sop await this.well.setReserves([to6("1000000"), to18("1100")]); await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); From a7c25b00875f6726c9cbc1677033193137594b67 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Fri, 12 Jul 2024 10:39:59 +0200 Subject: [PATCH 32/43] Second germination related test --- protocol/test/Sop.test.js | 41 ++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index ae85b700c0..e6a0430c61 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -412,7 +412,7 @@ describe('Sop', function () { expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal('0'); }); - it('manipulation test', async function () { + it('germination rain roots test', async function () { // user 3 deposits a bunch of bean const depositAmount = to6('50000'); @@ -436,15 +436,11 @@ describe('Sop', function () { await this.season.rainSunrise(); // sop - await this.silo.mow(user3Address, BEAN); let totalRainRoots2 = await this.siloGetters.totalRainRoots(); console.log("2 totalRainRoots: ", totalRainRoots2); - let totalRoots2 = await this.siloGetters.totalRoots(); - console.log("2 totalRoots: ", totalRoots2); - let userRainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); console.log("userRainRoots: ", userRainRoots); @@ -452,6 +448,41 @@ describe('Sop', function () { // couldn't find a way to do lessThan without importing something else that supports BigNumber from chai expect(userRainRoots.lt(totalRainRoots2)).to.be.true; }); + + // verifies that total rain roots are not affected by anything deposited after raining starts + it('second germination rain roots test', async function () { + + await this.season.rainSunrise(); // start raining + + let totalRainRootsBefore = await this.siloGetters.totalRainRoots(); + + const depositAmount = to6('50000'); + await this.bean.mint(user3Address, depositAmount); + await this.bean.connect(user3).approve(this.silo.address, MAX_UINT256); + await this.silo.connect(user3).deposit(this.bean.address, depositAmount, EXTERNAL); + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + + await this.season.rainSunrise(); // sop + + await this.silo.mow(user3Address, BEAN); + + let totalRainRootsAfter = await this.siloGetters.totalRainRoots(); + + // rain roots before should equal rain roots after, anything deposited after raining doesn't count + expect(totalRainRootsBefore).to.be.equal(totalRainRootsAfter); + + let userRainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); + + // assert that user rain roots are zero + expect(userRainRoots).to.be.equal('0'); + + // shouldn't be a way for a user to get more rain roots than total rain roots + // couldn't find a way to do lessThan without importing something else that supports BigNumber from chai + expect(userRainRoots.lt(totalRainRootsAfter)).to.be.true; + }); }) describe('Germination and Plenty', function () { From 052f6cf361ad5714ce4ddf32b13fc8949580bbd5 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 14 Jul 2024 14:26:48 +0200 Subject: [PATCH 33/43] Number formatting --- 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 e7d1b9ca81..2c70a8013a 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol @@ -175,10 +175,10 @@ contract Weather is Sun { // prior to the start of the sop // During handleRain, the sop roots are set to the current roots at the time of rain, // which do not include the germinating roots. - if (s.season.current-1 == s.season.rainStart) { + if (s.season.current - 1 == s.season.rainStart) { // increase by germinating roots of previous season // get 2 season's ago's germinating roots - uint256 germinatingRoots = s.unclaimedGerminating[s.season.current-2].roots; + uint256 germinatingRoots = s.unclaimedGerminating[s.season.current - 2].roots; s.r.roots = s.r.roots.add(germinatingRoots); } if (s.r.roots > 0) { From f7ce932c1a3bda8a9e24008e7d79742b0001fd9f Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 14 Jul 2024 15:17:49 +0200 Subject: [PATCH 34/43] Repro rain and withdraw issue --- protocol/test/Sop.test.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index e6a0430c61..313c2f8792 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -387,6 +387,43 @@ describe('Sop', function () { expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('0'); }); + it('stops raining and withdraw test', async function () { + const beanStem = to6("4"); + + const depositAmount = to6('50000'); + await this.bean.mint(user3Address, depositAmount); + await this.bean.connect(user3).approve(this.silo.address, MAX_UINT256); + await this.silo.connect(user3).deposit(BEAN, depositAmount, EXTERNAL); + + // log current bean stemTip + const stemTip = await this.siloGetters.stemTipForToken(BEAN); + console.log("stemTip: ", stemTip); + + // pass germination + await this.season.siloSunrise(0); + await this.season.siloSunrise(0); + + + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // start raining + + await this.silo.mow(user3Address, BEAN); + + let rainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); + expect(rainRoots).to.be.equal('500000000000000000000000000'); + + // stop raining + await this.season.droughtSunrise(); + + // withdraw + await this.silo.connect(user3).withdrawDeposit(BEAN, stemTip, to6('50000'), EXTERNAL); + rainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); + expect(rainRoots).to.be.equal('0'); + }); + it('burns rain roots upon transfer', async function () { const beanStem = to6("4"); From efc28ac896516285214613e547a446239c69e475 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 14 Jul 2024 15:32:18 +0200 Subject: [PATCH 35/43] Test user still has rain roots even through they have no roots --- protocol/test/Sop.test.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 313c2f8792..27e6b9f8f3 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -421,7 +421,19 @@ describe('Sop', function () { // withdraw await this.silo.connect(user3).withdrawDeposit(BEAN, stemTip, to6('50000'), EXTERNAL); rainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); - expect(rainRoots).to.be.equal('0'); + // rain roots still non-zero since they'll be zero'd when it starts raining again + expect(rainRoots).to.be.equal('500000000000000000000000000'); + + // start raining again + await this.season.rainSunrise(); + await this.season.rainSunrise(); + await this.silo.mow(user3Address, BEAN); + rainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); + expect(rainRoots).to.be.equal('500000000000000000000000000'); // actually should be zero here + + // measure user actual roots + const userRoots = await this.siloGetters.balanceOfRoots(user3Address); + expect(userRoots).to.be.equal('0'); }); it('burns rain roots upon transfer', async function () { From c56df9d35d326bfdce55b4ec7aebfea713c5c278 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 14 Jul 2024 15:46:56 +0200 Subject: [PATCH 36/43] Transfer partial stalk burn rain roots test --- protocol/test/Sop.test.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 27e6b9f8f3..551aa0b2ee 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -461,6 +461,29 @@ describe('Sop', function () { expect(await this.siloGetters.balanceOfRainRoots(user3Address)).to.be.equal('0'); }); + it('burns rain half of roots upon half transfer', async function () { + const beanStem = to6("4"); + + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // start raining + await this.season.rainSunrise(); // sop + + await this.silo.mow(user.address, BEAN); + + let rainRootsBefore = await this.siloGetters.balanceOfRainRoots(userAddress); + + expect(rainRootsBefore).to.be.equal('10004000000000000000000000'); + + await this.silo.connect(user).transferDeposit(userAddress, user3Address, BEAN, beanStem, to6('500')); + await this.silo.mow(user.address, BEAN); + + // user should have half rain roots + expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('5000000000000000000000000'); + }); + it('germination rain roots test', async function () { // user 3 deposits a bunch of bean From e2668ea9355873f7859072db4435ff30dd151d6b Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 14 Jul 2024 16:20:37 +0200 Subject: [PATCH 37/43] Transfer stalk adjustment and tests --- protocol/contracts/libraries/Silo/LibSilo.sol | 17 ++++----- protocol/test/Sop.test.js | 38 ++++++++++++++++++- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 8d4bf69595..bb0022e07d 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -260,7 +260,7 @@ library LibSilo { // account's current rain roots, set the account's rain roots // to the account's current roots and subtract the difference // from Beanstalk's total rain roots. - if (s.season.raining && s.a[account].sop.roots > s.a[account].roots) { + if (s.a[account].sop.roots > s.a[account].roots) { uint256 deltaRoots = s.a[account].sop.roots.sub(s.a[account].roots); s.a[account].sop.roots = s.a[account].roots; s.r.roots = s.r.roots.sub(deltaRoots); @@ -319,19 +319,18 @@ library LibSilo { ? s.a[sender].roots : s.s.roots.sub(1).mul(stalk).div(s.s.stalk).add(1); - - // Rain roots cannot be transferred, burn them - if (s.season.raining) { - uint256 burnRainRoots = roots > s.a[sender].sop.roots ? s.a[sender].sop.roots : roots; - s.a[sender].sop.roots = s.a[sender].sop.roots.sub(burnRainRoots); - s.r.roots = s.r.roots.sub(burnRainRoots); - } - // Subtract Stalk and Roots from the 'sender' balance. s.a[sender].s.stalk = s.a[sender].s.stalk.sub(stalk); s.a[sender].roots = s.a[sender].roots.sub(roots); emit StalkBalanceChanged(sender, -int256(stalk), -int256(roots)); + // Rain roots cannot be transferred, burn them + if (s.season.raining && s.a[sender].sop.roots > s.a[sender].roots) { + uint256 deltaRoots = s.a[sender].sop.roots.sub(s.a[sender].roots); + s.a[sender].sop.roots = s.a[sender].roots; + s.r.roots = s.r.roots.sub(deltaRoots); + } + // Add Stalk and Roots to the 'recipient' balance. s.a[recipient].s.stalk = s.a[recipient].s.stalk.add(stalk); s.a[recipient].roots = s.a[recipient].roots.add(roots); diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 551aa0b2ee..70ffb051a7 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -481,7 +481,43 @@ describe('Sop', function () { await this.silo.mow(user.address, BEAN); // user should have half rain roots - expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('5000000000000000000000000'); + expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('5004000000000000000000000'); + }); + + it('does not burn rain roots upon transfer if extra roots available', async function () { + const beanStem = to6("4"); + + // set reserves so we'll sop + await this.well.setReserves([to6("1000000"), to18("1100")]); + await this.pump.setInstantaneousReserves([to6("1000000"), to18("1100")]); + + await this.season.rainSunrise(); // start raining + await this.season.rainSunrise(); // sop + + await this.silo.mow(user.address, BEAN); + + let rainRootsBefore = await this.siloGetters.balanceOfRainRoots(userAddress); + + expect(rainRootsBefore).to.be.equal('10004000000000000000000000'); + + // do another deposit + await this.silo.connect(user).deposit(BEAN, to6('1000'), EXTERNAL); + + // pass germination + await this.season.siloSunrise(0); + await this.season.siloSunrise(0); + + // verify roots went up + expect(await this.siloGetters.balanceOfRoots(userAddress)).to.be.equal('20008000000000000000000000'); + // verify rain roots stayed the same + expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('10004000000000000000000000'); + + // then transfer + await this.silo.connect(user).transferDeposit(userAddress, user3Address, BEAN, beanStem, to6('500')); + await this.silo.mow(user.address, BEAN); + + // user should have full rain roots, since they had non-rain roots that could be removed before + expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('10004000000000000000000000'); }); it('germination rain roots test', async function () { From 61dd27dde6cd2d964c39917f40e45960ca70a815 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Sun, 14 Jul 2024 17:55:57 +0200 Subject: [PATCH 38/43] Fix tests and other changes --- .../contracts/beanstalk/sun/SeasonFacet/Weather.sol | 10 ---------- protocol/contracts/libraries/Silo/LibSilo.sol | 2 +- protocol/test/Sop.test.js | 8 ++++---- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol index 2c70a8013a..e81eaa0083 100644 --- a/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol +++ b/protocol/contracts/beanstalk/sun/SeasonFacet/Weather.sol @@ -171,16 +171,6 @@ contract Weather is Sun { s.r.pods = s.f.pods; s.r.roots = s.s.roots; } else { - // Beanstalk wants to distribute plenty to users who have germinating assets - // prior to the start of the sop - // During handleRain, the sop roots are set to the current roots at the time of rain, - // which do not include the germinating roots. - if (s.season.current - 1 == s.season.rainStart) { - // increase by germinating roots of previous season - // get 2 season's ago's germinating roots - uint256 germinatingRoots = s.unclaimedGerminating[s.season.current - 2].roots; - s.r.roots = s.r.roots.add(germinatingRoots); - } if (s.r.roots > 0) { // initialize sopWell if it is not already set. if (s.sopWell == address(0)) s.sopWell = well; diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index bb0022e07d..994c9a4d9c 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -325,7 +325,7 @@ library LibSilo { emit StalkBalanceChanged(sender, -int256(stalk), -int256(roots)); // Rain roots cannot be transferred, burn them - if (s.season.raining && s.a[sender].sop.roots > s.a[sender].roots) { + if (s.a[sender].sop.roots > s.a[sender].roots) { uint256 deltaRoots = s.a[sender].sop.roots.sub(s.a[sender].roots); s.a[sender].sop.roots = s.a[sender].roots; s.r.roots = s.r.roots.sub(deltaRoots); diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 70ffb051a7..835b7e9d46 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -421,15 +421,15 @@ describe('Sop', function () { // withdraw await this.silo.connect(user3).withdrawDeposit(BEAN, stemTip, to6('50000'), EXTERNAL); rainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); - // rain roots still non-zero since they'll be zero'd when it starts raining again - expect(rainRoots).to.be.equal('500000000000000000000000000'); + // rain roots zero after withdrawing deposit + expect(rainRoots).to.be.equal('0'); // start raining again await this.season.rainSunrise(); await this.season.rainSunrise(); await this.silo.mow(user3Address, BEAN); rainRoots = await this.siloGetters.balanceOfRainRoots(user3Address); - expect(rainRoots).to.be.equal('500000000000000000000000000'); // actually should be zero here + expect(rainRoots).to.be.equal('0'); // measure user actual roots const userRoots = await this.siloGetters.balanceOfRoots(user3Address); @@ -520,7 +520,7 @@ describe('Sop', function () { expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('10004000000000000000000000'); }); - it('germination rain roots test', async function () { + it.only('germination rain roots test', async function () { // user 3 deposits a bunch of bean const depositAmount = to6('50000'); From 7f49d8c1dcbc3547feca16fac471a8fd5a19ac1e Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sun, 14 Jul 2024 18:01:02 +0200 Subject: [PATCH 39/43] update handleRainAndSops to omit roots from deposits 1 season before raining --- .../contracts/libraries/Silo/LibGerminate.sol | 7 ++++++- protocol/contracts/libraries/Silo/LibSilo.sol | 19 ++++++++++++++++--- protocol/test/Sop.test.js | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index b48faf0a1c..50af5428a5 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -165,12 +165,16 @@ library LibGerminate { * the germination process: * - increments the assoicated values (bdv, stalk, roots) * - clears the germination struct for the account. + * + * @return firstGerminatingRoots the roots from the first germinating stalk. + * used in {handleRainAndSops} to properly set the rain roots of a user, + * if the user had deposited in the season prior to a rain. */ function endAccountGermination( address account, uint32 lastMowedSeason, uint32 currentSeason - ) internal { + ) internal returns (uint128 firstGerminatingRoots) { AppStorage storage s = LibAppStorage.diamondStorage(); bool lastUpdateOdd = isSeasonOdd(lastMowedSeason); (uint128 firstStalk, uint128 secondStalk) = getGerminatingStalk(account, lastUpdateOdd); @@ -189,6 +193,7 @@ library LibGerminate { ); germinatingStalk = firstStalk; totalRootsFromGermination = roots; + firstGerminatingRoots = roots; emit FarmerGerminatingStalkBalanceChanged( account, -int256(germinatingStalk), diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 994c9a4d9c..9eddba6280 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -476,8 +476,9 @@ library LibSilo { uint32 currentSeason = s.season.current; // End account germination. + uint128 firstGerminatingRoots; if (lastUpdate < currentSeason) { - LibGerminate.endAccountGermination(account, lastUpdate, currentSeason); + firstGerminatingRoots = LibGerminate.endAccountGermination(account, lastUpdate, currentSeason); } // sop data only needs to be updated once per season, @@ -486,7 +487,7 @@ library LibSilo { if ((lastUpdate <= s.season.rainStart || s.a[account].lastRain > 0) && lastUpdate <= currentSeason) { // Increments `plenty` for `account` if a Flood has occured. // Saves Rain Roots for `account` if it is Raining. - handleRainAndSops(account, lastUpdate); + handleRainAndSops(account, lastUpdate, firstGerminatingRoots); } } @@ -542,7 +543,7 @@ library LibSilo { /** * @dev internal logic to handle when beanstalk is raining. */ - function handleRainAndSops(address account, uint32 lastUpdate) private { + function handleRainAndSops(address account, uint32 lastUpdate, uint128 firstGerminatingRoots) private { AppStorage storage s = LibAppStorage.diamondStorage(); // If a Sop has occured since last update, calculate rewards and set last Sop. if (s.season.lastSopSeason > lastUpdate) { @@ -560,6 +561,18 @@ library LibSilo { if (s.season.rainStart > lastUpdate) { s.a[account].lastRain = s.season.rainStart; s.a[account].sop.roots = s.a[account].roots; + if (s.season.rainStart - 1 == lastUpdate) { + if (firstGerminatingRoots > 0) { + // if the account had just finished germinating roots this season (i.e, + // deposited in the previous season before raining, and mowed during a sop), + // Beanstalk will not allocate plenty to this deposit, and thus the roots + // needs to be deducted from the sop roots. + s.a[account].sop.roots = s.a[account].sop.roots.sub(firstGerminatingRoots); + } + } + + // s.a[account].roots includes newly finished germinating roots from a fresh deposit + // @ season before rainStart } // If there has been a Sop since rain started, // save plentyPerRoot in case another SOP happens during rain. diff --git a/protocol/test/Sop.test.js b/protocol/test/Sop.test.js index 835b7e9d46..533c8eb790 100644 --- a/protocol/test/Sop.test.js +++ b/protocol/test/Sop.test.js @@ -520,7 +520,7 @@ describe('Sop', function () { expect(await this.siloGetters.balanceOfRainRoots(userAddress)).to.be.equal('10004000000000000000000000'); }); - it.only('germination rain roots test', async function () { + it('germination rain roots test', async function () { // user 3 deposits a bunch of bean const depositAmount = to6('50000'); From 53653bfa9dc137634f29885a484ab467913673d8 Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sun, 14 Jul 2024 18:19:54 +0200 Subject: [PATCH 40/43] fix contract size, update ebip --- protocol/contracts/libraries/Silo/LibSilo.sol | 2 +- protocol/scripts/ebips.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/protocol/contracts/libraries/Silo/LibSilo.sol b/protocol/contracts/libraries/Silo/LibSilo.sol index 9eddba6280..a82a5fc253 100644 --- a/protocol/contracts/libraries/Silo/LibSilo.sol +++ b/protocol/contracts/libraries/Silo/LibSilo.sol @@ -707,7 +707,7 @@ library LibSilo { int96[] calldata stems, uint256[] calldata amounts, ERC1155Event emission - ) internal returns (AssetsRemoved memory ar) { + ) external returns (AssetsRemoved memory ar) { AppStorage storage s = LibAppStorage.diamondStorage(); uint256[] memory bdvsRemoved = new uint256[](stems.length); diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index fc579ed419..ea1987d385 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -200,7 +200,8 @@ async function ebip17(mock = true, account = undefined) { libraryNames: ['LibSilo', 'LibConvert'], facetLibraries: { 'SiloFacet': ['LibSilo'], - 'ConvertFacet': ['LibConvert'] + 'ConvertFacet': ['LibConvert'], + 'EnrootFacet': ['LibSilo'] }, bip: false, object: !mock, From f552dd69473ded06cd253f9d466d09b589210e1e Mon Sep 17 00:00:00 2001 From: Brean0 Date: Sun, 14 Jul 2024 18:43:12 +0200 Subject: [PATCH 41/43] fix linked libraries --- protocol/lib/forge-std | 2 +- protocol/scripts/bips.js | 3 +++ protocol/scripts/deploy.js | 3 +++ protocol/test/Stem.test.js | 3 +++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/protocol/lib/forge-std b/protocol/lib/forge-std index bb4ceea94d..07263d193d 160000 --- a/protocol/lib/forge-std +++ b/protocol/lib/forge-std @@ -1 +1 @@ -Subproject commit bb4ceea94d6f10eeb5b41dc2391c6c8bf8e734ef +Subproject commit 07263d193d621c4b2b0ce8b4d54af58f6957d97d diff --git a/protocol/scripts/bips.js b/protocol/scripts/bips.js index de2b21baf2..3e53f1c22a 100644 --- a/protocol/scripts/bips.js +++ b/protocol/scripts/bips.js @@ -270,6 +270,9 @@ async function bipSeedGauge(mock = true, account = undefined, verbose = true) { ], 'SiloFacet': [ 'LibSilo' + ], + 'EnrootFacet': [ + 'LibSilo' ] }, bip: false, diff --git a/protocol/scripts/deploy.js b/protocol/scripts/deploy.js index 94fb2a7300..07892a9de6 100644 --- a/protocol/scripts/deploy.js +++ b/protocol/scripts/deploy.js @@ -145,6 +145,9 @@ async function main(scriptName, verbose = true, mock = false, reset = true) { ], 'SiloFacet': [ 'LibSilo' + ], + 'EnrootFacet': [ + 'LibSilo' ] } diff --git a/protocol/test/Stem.test.js b/protocol/test/Stem.test.js index a39fbb4d0e..7aec3aae6b 100644 --- a/protocol/test/Stem.test.js +++ b/protocol/test/Stem.test.js @@ -65,6 +65,9 @@ describe('Silo V3: Grown Stalk Per Bdv deployment', function () { ], 'MockSiloFacet': [ 'LibSilo' + ], + 'EnrootFacet': [ + 'LibSilo' ] }, bip: false, From 36d115fad15a129f15d3c93255e7cd51dba245a2 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Mon, 15 Jul 2024 14:54:34 +0200 Subject: [PATCH 42/43] End germination in more mock sunrise functions --- protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol b/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol index 35803ec952..9a03f22b4f 100644 --- a/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol +++ b/protocol/contracts/mocks/mockFacets/MockSeasonFacet.sol @@ -102,6 +102,7 @@ contract MockSeasonFacet is SeasonFacet { for (uint256 i; i < amount; ++i) { s.season.current += 1; stepOracle(); + LibGerminate.endTotalGermination(s.season.current, LibWhitelistedTokens.getWhitelistedTokens()); mockStartSop(); } s.season.sunriseBlock = uint32(block.number); @@ -113,6 +114,7 @@ contract MockSeasonFacet is SeasonFacet { s.season.sunriseBlock = uint32(block.number); // update last snapshot in beanstalk. stepOracle(); + LibGerminate.endTotalGermination(s.season.current, LibWhitelistedTokens.getWhitelistedTokens()); handleRain(2, C.BEAN_ETH_WELL); } @@ -122,6 +124,7 @@ contract MockSeasonFacet is SeasonFacet { s.season.sunriseBlock = uint32(block.number); // update last snapshot in beanstalk. stepOracle(); + LibGerminate.endTotalGermination(s.season.current, LibWhitelistedTokens.getWhitelistedTokens()); mockStartSop(); mockStepSilo(amount); } @@ -132,6 +135,7 @@ contract MockSeasonFacet is SeasonFacet { s.season.sunriseBlock = uint32(block.number); // update last snapshot in beanstalk. stepOracle(); + LibGerminate.endTotalGermination(s.season.current, LibWhitelistedTokens.getWhitelistedTokens()); mockStartSop(); mockStepSilo(amount); } From 10e1be94188b9b9343c6115f63d33a2d576261d9 Mon Sep 17 00:00:00 2001 From: pizzaman1337 Date: Mon, 15 Jul 2024 15:57:48 +0200 Subject: [PATCH 43/43] Add init facet contract name --- protocol/scripts/ebips.js | 1 + 1 file changed, 1 insertion(+) diff --git a/protocol/scripts/ebips.js b/protocol/scripts/ebips.js index ea1987d385..4eb40d1e67 100644 --- a/protocol/scripts/ebips.js +++ b/protocol/scripts/ebips.js @@ -197,6 +197,7 @@ async function ebip17(mock = true, account = undefined) { await upgradeWithNewFacets({ diamondAddress: BEANSTALK, facetNames: ["MigrationFacet", "MarketplaceFacet", "ConvertFacet", "EnrootFacet", "SiloGettersFacet", "SiloFacet"], + initFacetName: "InitHotFix6", libraryNames: ['LibSilo', 'LibConvert'], facetLibraries: { 'SiloFacet': ['LibSilo'],