diff --git a/protocol/contracts/beanstalk/silo/PipelineConvertFacet.sol b/protocol/contracts/beanstalk/silo/PipelineConvertFacet.sol index 1b16bdffe..f8eec46e1 100644 --- a/protocol/contracts/beanstalk/silo/PipelineConvertFacet.sol +++ b/protocol/contracts/beanstalk/silo/PipelineConvertFacet.sol @@ -7,7 +7,6 @@ pragma solidity ^0.8.20; import {C} from "contracts/C.sol"; import {LibTractor} from "contracts/libraries/LibTractor.sol"; import {LibSilo} from "contracts/libraries/Silo/LibSilo.sol"; -import {LibTokenSilo} from "contracts/libraries/Silo/LibTokenSilo.sol"; import {LibRedundantMath32} from "contracts/libraries/LibRedundantMath32.sol"; import {ReentrancyGuard} from "../ReentrancyGuard.sol"; import {LibRedundantMath256} from "contracts/libraries/LibRedundantMath256.sol"; @@ -16,7 +15,6 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {LibConvert} from "contracts/libraries/Convert/LibConvert.sol"; import {AdvancedPipeCall} from "contracts/interfaces/IPipeline.sol"; import {LibWell} from "contracts/libraries/Well/LibWell.sol"; -import {LibConvertData} from "contracts/libraries/Convert/LibConvertData.sol"; import {Invariable} from "contracts/beanstalk/Invariable.sol"; import {LibRedundantMathSigned256} from "contracts/libraries/LibRedundantMathSigned256.sol"; import {LibPipelineConvert} from "contracts/libraries/Convert/LibPipelineConvert.sol"; @@ -31,7 +29,6 @@ import {LibDeltaB} from "contracts/libraries/Oracle/LibDeltaB.sol"; contract PipelineConvertFacet is Invariable, ReentrancyGuard { using LibRedundantMathSigned256 for int256; using SafeCast for uint256; - using LibConvertData for bytes; using LibRedundantMath256 for uint256; using SafeCast for uint256; using LibRedundantMath32 for uint32; diff --git a/protocol/contracts/beanstalk/storage/System.sol b/protocol/contracts/beanstalk/storage/System.sol index 6eff47285..7c448ae61 100644 --- a/protocol/contracts/beanstalk/storage/System.sol +++ b/protocol/contracts/beanstalk/storage/System.sol @@ -316,10 +316,10 @@ struct AssetSettings { int96 milestoneStem; // │ 12 (30) bytes1 encodeType; // │ 1 (31) // one byte is left here. ──┘ 1 (32) - int24 deltaStalkEarnedPerSeason; // ────┐ 3 - uint128 gaugePoints; // │ 16 (19) - uint64 optimalPercentDepositedBdv; // │ 8 (27) - // 5 bytes are left here. ──┘ 5 (32) + int32 deltaStalkEarnedPerSeason; // ────┐ 4 + uint128 gaugePoints; // │ 16 (20) + uint64 optimalPercentDepositedBdv; // │ 8 (28) + // 4 bytes are left here. ──┘ 4 (32) Implementation gaugePointImplementation; Implementation liquidityWeightImplementation; } diff --git a/protocol/contracts/interfaces/IMockFBeanstalk.sol b/protocol/contracts/interfaces/IMockFBeanstalk.sol index add13b11f..347e3221c 100644 --- a/protocol/contracts/interfaces/IMockFBeanstalk.sol +++ b/protocol/contracts/interfaces/IMockFBeanstalk.sol @@ -55,7 +55,7 @@ interface IMockFBeanstalk { uint32 milestoneSeason; int96 milestoneStem; bytes1 encodeType; - int24 deltaStalkEarnedPerSeason; + int32 deltaStalkEarnedPerSeason; uint128 gaugePoints; uint64 optimalPercentDepositedBdv; Implementation gaugePointImplementation; @@ -1692,10 +1692,10 @@ interface IMockFBeanstalk { function pipelineConvert( address inputToken, - int96[] memory stems, - uint256[] memory amounts, + int96[] calldata stems, + uint256[] calldata amounts, address outputToken, - AdvancedFarmCall[] memory advancedFarmCalls + AdvancedPipeCall[] memory advancedPipeCalls ) external payable diff --git a/protocol/contracts/libraries/LibGauge.sol b/protocol/contracts/libraries/LibGauge.sol index 33c8517db..b2ac2c22e 100644 --- a/protocol/contracts/libraries/LibGauge.sol +++ b/protocol/contracts/libraries/LibGauge.sol @@ -28,6 +28,7 @@ library LibGauge { uint256 internal constant BDV_PRECISION = 1e6; uint256 internal constant GP_PRECISION = 1e18; + uint256 internal constant GROWN_STALK_PER_GP_PRECISION = 1e6; // Max and min are the ranges that the beanToMaxLpGpPerBdvRatioScaled can output. // uint256 internal constant MAX_BEAN_MAX_LP_GP_PER_BDV_RATIO = 100e18; //state @@ -288,7 +289,10 @@ library LibGauge { ) internal { LibWhitelist.updateStalkPerBdvPerSeasonForToken( token, - grownStalkPerGp.mul(gpPerBdv).div(GP_PRECISION).toUint32() + grownStalkPerGp + .mul(gpPerBdv) + .div(GP_PRECISION * GROWN_STALK_PER_GP_PRECISION) + .toUint32() ); } diff --git a/protocol/contracts/libraries/Silo/LibGerminate.sol b/protocol/contracts/libraries/Silo/LibGerminate.sol index 7a320f20f..088008dc4 100644 --- a/protocol/contracts/libraries/Silo/LibGerminate.sol +++ b/protocol/contracts/libraries/Silo/LibGerminate.sol @@ -450,6 +450,7 @@ library LibGerminate { * @dev if the milestone season is not the current season, then the stalkEarnedPerSeason * hasn't changed from the previous season. Otherwise, we calculate the prevStalkEarnedPerSeason. */ + function getPrevStalkEarnedPerSeason( address token ) private view returns (uint32 prevStalkEarnedPerSeason) { @@ -458,7 +459,7 @@ library LibGerminate { if (s.sys.silo.assetSettings[token].milestoneSeason < s.sys.season.current) { prevStalkEarnedPerSeason = s.sys.silo.assetSettings[token].stalkEarnedPerSeason; } else { - int24 deltaStalkEarnedPerSeason = s + int32 deltaStalkEarnedPerSeason = s .sys .silo .assetSettings[token] @@ -466,11 +467,11 @@ library LibGerminate { if (deltaStalkEarnedPerSeason >= 0) { prevStalkEarnedPerSeason = s.sys.silo.assetSettings[token].stalkEarnedPerSeason - - uint32(int32(deltaStalkEarnedPerSeason)); + uint32(deltaStalkEarnedPerSeason); } else { prevStalkEarnedPerSeason = s.sys.silo.assetSettings[token].stalkEarnedPerSeason + - uint32(int32(-deltaStalkEarnedPerSeason)); + uint32(-deltaStalkEarnedPerSeason); } } } diff --git a/protocol/contracts/libraries/Silo/LibWhitelist.sol b/protocol/contracts/libraries/Silo/LibWhitelist.sol index 08029f2ff..c77eafdf3 100644 --- a/protocol/contracts/libraries/Silo/LibWhitelist.sol +++ b/protocol/contracts/libraries/Silo/LibWhitelist.sol @@ -203,8 +203,9 @@ library LibWhitelist { s.sys.silo.assetSettings[token].milestoneSeason = s.sys.season.current; // stalkEarnedPerSeason is set to int32 before casting down. - s.sys.silo.assetSettings[token].deltaStalkEarnedPerSeason = (int32(stalkEarnedPerSeason) - - int32(s.sys.silo.assetSettings[token].stalkEarnedPerSeason)).toInt24(); + s.sys.silo.assetSettings[token].deltaStalkEarnedPerSeason = + int32(stalkEarnedPerSeason) - + int32(s.sys.silo.assetSettings[token].stalkEarnedPerSeason); s.sys.silo.assetSettings[token].stalkEarnedPerSeason = stalkEarnedPerSeason; emit UpdatedStalkPerBdvPerSeason(token, stalkEarnedPerSeason, s.sys.season.current); diff --git a/protocol/hardhat.config.js b/protocol/hardhat.config.js index c3d8e0ec0..3400838ea 100644 --- a/protocol/hardhat.config.js +++ b/protocol/hardhat.config.js @@ -11,6 +11,7 @@ require("hardhat-tracer"); require("@openzeppelin/hardhat-upgrades"); require("dotenv").config(); require("@nomiclabs/hardhat-etherscan"); +const { time } = require("@nomicfoundation/hardhat-network-helpers"); const { upgradeWithNewFacets } = require("./scripts/diamond"); const { @@ -92,6 +93,35 @@ task("sunrise2", async function () { await season.sunrise(); }); +task("sunriseArb", async function () { + const lastTimestamp = (await ethers.provider.getBlock("latest")).timestamp; + const hourTimestamp = parseInt(lastTimestamp / 3600 + 1) * 3600; + await network.provider.send("evm_setNextBlockTimestamp", [hourTimestamp]); + + season = await ethers.getContractAt("SeasonFacet", "0xD1A0060ba708BC4BCD3DA6C37EFa8deDF015FB70"); + await season.sunrise(); + + seasonGetters = await ethers.getContractAt( + "SeasonGettersFacet", + "0xD1A0060ba708BC4BCD3DA6C37EFa8deDF015FB70" + ); + const unixTime = await time.latest(); + const currentTime = new Date(unixTime * 1000).toLocaleString(); + + console.log( + "sunrise complete!\ncurrent season:", + await seasonGetters.season(), + "\ncurrent blockchain time:", + unixTime, + "\nhuman readable time:", + currentTime, + "\ncurrent block:", + (await ethers.provider.getBlock("latest")).number, + "\ndeltaB:", + (await seasonGetters.totalDeltaB()).toString() + ); +}); + task("getTime", async function () { beanstalk = await ethers.getContractAt("SeasonFacet", BEANSTALK); console.log("Current time: ", await this.seasonGetter.time()); diff --git a/protocol/reseed/data/r9-whitelist.json b/protocol/reseed/data/r9-whitelist.json index 36c5b4064..b37083825 100644 --- a/protocol/reseed/data/r9-whitelist.json +++ b/protocol/reseed/data/r9-whitelist.json @@ -205,7 +205,7 @@ [ "0xc84c7727", "1", - "10000", + "10000000000", "0x5fbc", "0", "0x01", @@ -245,7 +245,7 @@ [ "0xc84c7727", "1", - "10000", + "10000000000", "0x5fbc", "0", "0x01", @@ -325,7 +325,7 @@ [ "0xc84c7727", "1", - "10000", + "10000000000", "0x5fbc", "0", "0x01", diff --git a/protocol/reseed/reseed10.js b/protocol/reseed/reseed10.js index 70ce2311f..3bb921e97 100644 --- a/protocol/reseed/reseed10.js +++ b/protocol/reseed/reseed10.js @@ -20,6 +20,7 @@ async function reseed10(account, L2Beanstalk, mock, verbose = true) { "OracleFacet", "ConvertFacet", // CONVERT "ConvertGettersFacet", + "PipelineConvertFacet", "MetadataFacet", // METADATA "MarketplaceFacet", // MARKET "FieldFacet", // FIELD @@ -65,12 +66,13 @@ async function reseed10(account, L2Beanstalk, mock, verbose = true) { "LibFlood" ], ConvertFacet: ["LibConvert", "LibPipelineConvert", "LibSilo"], + PipelineConvertFacet: ["LibPipelineConvert", "LibSilo"], UnripeFacet: ["LibLockedUnderlying"], SeasonGettersFacet: ["LibLockedUnderlying", "LibWellMinting"], SiloFacet: ["LibSilo"], EnrootFacet: ["LibSilo"], L1RecieverFacet: ["LibSilo"], - ClaimFacet: ["LibSilo"], + ClaimFacet: ["LibSilo"] }; // upgrade beanstalk with all facets. calls `InitReseed` diff --git a/protocol/reseed/reseedAddLiquidityAndTransfer.js b/protocol/reseed/reseedAddLiquidityAndTransfer.js index 7e68c8397..b8417e1b6 100644 --- a/protocol/reseed/reseedAddLiquidityAndTransfer.js +++ b/protocol/reseed/reseedAddLiquidityAndTransfer.js @@ -36,18 +36,18 @@ async function reseedAddLiquidityAndTransfer(account, L2Beanstalk, mock = true, ); const nonBeanAmounts = [ - to18("100"), // BEAN/WETH - to18("100"), // BEAN/WstETH - to18("1500"), // BEAN/WEEETH - toX("20", 8), // BEAN/WBTC (8 decimals) - to6("1000000"), // BEAN/USDC - to6("1000000") // BEAN/USDT + to18("20"), // BEAN/WETH + to18("2556"), // BEAN/WstETH + to18("16"), // BEAN/WEEETH + toX("8", 8), // BEAN/WBTC (8 decimals) + to6("190000"), // BEAN/USDC + to6("190000") // BEAN/USDT ]; const beanAmounts = [ - to6("1000000"), // BEAN/WETH - to6("1000000"), // BEAN/WstETH - to6("1000000"), // BEAN/WEEETH + to6("108357"), // BEAN/WETH + to6("14642617"), // BEAN/WstETH + to6("100000"), // BEAN/WEEETH to6("1000000"), // BEAN/WBTC to6("1000000"), // BEAN/USDC to6("1000000") // BEAN/USDT diff --git a/protocol/test/foundry/Migration/ReseedState.t.sol b/protocol/test/foundry/Migration/ReseedState.t.sol index c97203f7a..7e8aa237f 100644 --- a/protocol/test/foundry/Migration/ReseedState.t.sol +++ b/protocol/test/foundry/Migration/ReseedState.t.sol @@ -93,6 +93,29 @@ contract ReseedStateTest is TestHelper { // l2Beanstalk.gm(address(this), 1); } + function test_Sunrise() public { + // jump forward one hour in vm + vm.warp(block.timestamp + 3600); + console.log("calling sunrise"); + l2Beanstalk.sunrise(); + } + + function test_pipelineConvert() public { + int96[] memory stems = new int96[](1); + stems[0] = 1; + uint256[] memory amounts = new uint256[](1); + amounts[0] = 1; + // simply verify the function exists + vm.expectRevert("Convert: Input token must be Bean or a well"); + l2Beanstalk.pipelineConvert( + address(0), + stems, + amounts, + address(0), + new IMockFBeanstalk.AdvancedPipeCall[](0) + ); + } + // LibUsdOracle: 0x5003dF9E48dA96e4B4390373c8ae70EbFA5415A7 function test_beanstalkPrice() public { // Get beanstalk price