From f8119c783673e3e6efeccda5f91b05b036d754db Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Wed, 1 Nov 2023 16:55:26 -0400 Subject: [PATCH 001/113] ui/sdk: add support for dynamic seeds --- projects/sdk/src/classes/Token/Token.ts | 4 +- projects/sdk/src/lib/BeanstalkSDK.ts | 13 + projects/sdk/src/lib/tokens.ts | 14 +- .../ui/src/components/App/SdkProvider.tsx | 13 +- projects/ui/src/components/Silo/Whitelist.tsx | 5 +- projects/ui/src/constants/tokens.ts | 10 +- projects/ui/src/hooks/sdk/index.ts | 44 +- protocol/abi/Beanstalk.json | 698 ++++++++++++++---- 8 files changed, 617 insertions(+), 184 deletions(-) diff --git a/projects/sdk/src/classes/Token/Token.ts b/projects/sdk/src/classes/Token/Token.ts index a33d1cd990..ee6c6eadce 100644 --- a/projects/sdk/src/classes/Token/Token.ts +++ b/projects/sdk/src/classes/Token/Token.ts @@ -9,7 +9,7 @@ declare module "@beanstalk/sdk-core" { abstract class Token { static _source: string; isUnripe: boolean; - rewards?: { stalk: TokenValue; seeds: TokenValue }; + rewards?: { stalk: TokenValue; seeds: TokenValue | null }; getStalk(bdv?: TokenValue): TokenValue; getSeeds(bdv?: TokenValue): TokenValue; approveBeanstalk(amount: TokenValue | BigNumber): Promise; @@ -34,7 +34,7 @@ CoreToken.prototype.getStalk = function (bdv?: TokenValue): TokenValue { * Get the amount of Seeds rewarded per deposited BDV of this Token. * */ CoreToken.prototype.getSeeds = function (bdv?: TokenValue): TokenValue { - if (!this.rewards?.seeds) return TokenValue.fromHuman(0, SEED_DECIMALS); + if (!this.rewards?.seeds) throw new Error(`Token ${this.symbol} has no seeds defined!`); if (!bdv) return this.rewards.seeds; return this.rewards.seeds.mul(bdv); diff --git a/projects/sdk/src/lib/BeanstalkSDK.ts b/projects/sdk/src/lib/BeanstalkSDK.ts index e320d67e68..8a7f0e08b1 100644 --- a/projects/sdk/src/lib/BeanstalkSDK.ts +++ b/projects/sdk/src/lib/BeanstalkSDK.ts @@ -46,6 +46,7 @@ export class BeanstalkSDK { public providerOrSigner: Signer | Provider; public source: DataSource; public subgraphUrl: string; + public lastRefreshTimestamp: Date; public readonly chainId: ChainId; public readonly addresses: typeof addresses; @@ -99,6 +100,18 @@ export class BeanstalkSDK { this.wells = new WellsSDK(config); } + /** + * Refreshes the SDK's state with updated data from contracts. This should be called immediately after sdk initialization and after every season + */ + async refresh() { + // Reload dynamic stalk per wl token + const whitelist = this.tokens.siloWhitelist; + for await (const token of whitelist) { + const { stalkEarnedPerSeason } = await this.contracts.beanstalk.tokenSettings(token.address); + token.rewards!.seeds = this.tokens.SEEDS.fromBlockchain(stalkEarnedPerSeason); + } + } + debug(...args: any[]) { if (!this.DEBUG) return; console.debug(...args); diff --git a/projects/sdk/src/lib/tokens.ts b/projects/sdk/src/lib/tokens.ts index d9e1a9ae64..48b91de42d 100644 --- a/projects/sdk/src/lib/tokens.ts +++ b/projects/sdk/src/lib/tokens.ts @@ -115,7 +115,7 @@ export class Tokens { ); this.BEAN.rewards = { stalk: this.STALK.amount(1), - seeds: this.SEEDS.amount(3) + seeds: null }; this.BEAN_CRV3_LP = new ERC20Token( @@ -133,7 +133,7 @@ export class Tokens { ); this.BEAN_CRV3_LP.rewards = { stalk: this.STALK.amount(1), - seeds: this.SEEDS.amount(3.25) + seeds: null }; this.BEAN_ETH_WELL_LP = new ERC20Token( @@ -151,7 +151,7 @@ export class Tokens { ); this.BEAN_ETH_WELL_LP.rewards = { stalk: this.STALK.amount(1), - seeds: this.SEEDS.amount(4.5) + seeds: null }; this.UNRIPE_BEAN = new ERC20Token( @@ -167,8 +167,8 @@ export class Tokens { providerOrSigner ); this.UNRIPE_BEAN.rewards = { - stalk: this.STALK.amount(1), - seeds: this.SEEDS.amount(0) + stalk: this.STALK.amount(0), + seeds: null }; this.UNRIPE_BEAN.isUnripe = true; @@ -186,7 +186,7 @@ export class Tokens { ); this.UNRIPE_BEAN_WETH.rewards = { stalk: this.STALK.amount(1), - seeds: this.SEEDS.amount(0) + seeds: null }; this.UNRIPE_BEAN_WETH.isUnripe = true; @@ -334,7 +334,7 @@ export class Tokens { ); this.BEAN_ETH_UNIV2_LP.rewards = { stalk: this.STALK.amount(1), - seeds: this.SEEDS.amount(4) + seeds: null }; this.map.set(addresses.BEAN_ETH_UNIV2_LP.get(chainId), this.BEAN_ETH_UNIV2_LP); diff --git a/projects/ui/src/components/App/SdkProvider.tsx b/projects/ui/src/components/App/SdkProvider.tsx index 366d9f6913..a53082f2f9 100644 --- a/projects/ui/src/components/App/SdkProvider.tsx +++ b/projects/ui/src/components/App/SdkProvider.tsx @@ -30,6 +30,7 @@ import useSetting from '~/hooks/app/useSetting'; import { SUBGRAPH_ENVIRONMENTS } from '~/graph/endpoints'; import { useEthersProvider } from '~/util/wagmi/ethersAdapter'; import { useSigner } from '~/hooks/ledger/useSigner'; +import { useDynamicSeeds } from '~/hooks/sdk'; const IS_DEVELOPMENT_ENV = process.env.NODE_ENV !== 'production'; @@ -94,13 +95,17 @@ export const BeanstalkSDKContext = createContext< >(undefined); function BeanstalkSDKProvider({ children }: { children: React.ReactNode }) { - // use the same instance of the sdk across the app const sdk = useBeanstalkSdkContext(); + const ready = useDynamicSeeds(sdk); return ( - - {children} - + <> + {ready && ( + + {children} + + )} + ); } diff --git a/projects/ui/src/components/Silo/Whitelist.tsx b/projects/ui/src/components/Silo/Whitelist.tsx index e87c3cc0a6..193f2d8c7d 100644 --- a/projects/ui/src/components/Silo/Whitelist.tsx +++ b/projects/ui/src/components/Silo/Whitelist.tsx @@ -266,7 +266,10 @@ const Whitelist: FC<{ - {token.rewards?.seeds} + {Math.round( + (token.rewards?.seeds || 0 + Number.EPSILON) * + 100 + ) / 100} diff --git a/projects/ui/src/constants/tokens.ts b/projects/ui/src/constants/tokens.ts index 6663874d67..971cd0f2b6 100644 --- a/projects/ui/src/constants/tokens.ts +++ b/projects/ui/src/constants/tokens.ts @@ -149,7 +149,7 @@ export const BEAN = { }, { stalk: 1, - seeds: 3, + seeds: 0, } ), }; @@ -242,7 +242,7 @@ export const BEAN_ETH_UNIV2_LP = { }, { stalk: 1, - seeds: 4, + seeds: 0, } ), }; @@ -259,7 +259,7 @@ export const BEAN_LUSD_LP = { }, { stalk: 1, - seeds: 3, + seeds: 0, } ), }; @@ -282,7 +282,7 @@ export const BEAN_CRV3_LP = { }, { stalk: 1, - seeds: 3.25, + seeds: 0, } ), }; @@ -301,7 +301,7 @@ export const BEAN_ETH_WELL_LP = { }, { stalk: 1, - seeds: 4.5, + seeds: 0, } ), }; diff --git a/projects/ui/src/hooks/sdk/index.ts b/projects/ui/src/hooks/sdk/index.ts index 54800f1b00..ccf5966801 100644 --- a/projects/ui/src/hooks/sdk/index.ts +++ b/projects/ui/src/hooks/sdk/index.ts @@ -1,5 +1,5 @@ -import { useContext, useMemo } from 'react'; -import { Token } from '@beanstalk/sdk'; +import { useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import { BeanstalkSDK, Token } from '@beanstalk/sdk'; import { BeanstalkSDKContext } from '~/components/App/SdkProvider'; import { BEAN, @@ -21,8 +21,10 @@ import { BEAN_ETH_UNIV2_LP, RINSABLE_SPROUTS, BEAN_ETH_WELL_LP, + SILO_WHITELIST, } from '~/constants/tokens'; import { Token as TokenOld } from '~/classes'; +import useGetChainToken from '../chain/useGetChainToken'; export default function useSdk() { const sdk = useContext(BeanstalkSDKContext); @@ -61,3 +63,41 @@ export function getNewToOldToken(_token: Token) { } return token as TokenOld; } + +export const useRefreshSeeds = () => { + const getChainToken = useGetChainToken(); + return useCallback( + async (sdk: BeanstalkSDK) => { + await sdk.refresh(); + // Copy the seed values from sdk tokens to ui tokens + + for await (const chainToken of SILO_WHITELIST) { + const token = getChainToken(chainToken); + const seeds = sdk.tokens.findBySymbol(token.symbol)?.rewards?.seeds; + if (!seeds) { + console.log(`SDK token ${token.symbol} did not have any seeds set`); + throw new Error(`No seeds set for ${token.symbol}`); + } + token!.rewards!.seeds = parseFloat(seeds.toHuman()); + } + + console.log('seeds loaded'); + }, + [getChainToken] + ); +}; + +export const useDynamicSeeds = (sdk: BeanstalkSDK) => { + const [ready, setReady] = useState(false); + const refreshSeeds = useRefreshSeeds(); + useEffect(() => { + const load = async () => { + await refreshSeeds(sdk); + setReady(true); + }; + + load(); + }, [refreshSeeds, sdk]); + + return ready; +}; diff --git a/protocol/abi/Beanstalk.json b/protocol/abi/Beanstalk.json index 91ac3ff6e5..e24cd20ae3 100644 --- a/protocol/abi/Beanstalk.json +++ b/protocol/abi/Beanstalk.json @@ -263,13 +263,52 @@ "outputs": [ { "internalType": "uint256", - "name": "underlyingAmount", + "name": "", "type": "uint256" } ], "stateMutability": "payable", "type": "function" }, + { + "inputs": [], + "name": "getLockedBeans", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLockedBeansUnderlyingUnripeBean", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLockedBeansUnderlyingUnripeBeanEth", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -357,7 +396,7 @@ "outputs": [ { "internalType": "uint256", - "name": "penalty", + "name": "percent", "type": "uint256" } ], @@ -400,7 +439,7 @@ "outputs": [ { "internalType": "uint256", - "name": "redeem", + "name": "underlyingAmount", "type": "uint256" } ], @@ -4195,6 +4234,24 @@ "internalType": "uint256", "name": "stalkIssuedPerBdv", "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "gpSelector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" } ], "name": "WhitelistToken", @@ -4213,6 +4270,29 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "gaugePointSelector", + "type": "bytes4" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" + } + ], + "name": "updateGaugeForToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, { "inputs": [ { @@ -4244,14 +4324,29 @@ "type": "bytes4" }, { - "internalType": "uint32", + "internalType": "uint16", "name": "stalkIssuedPerBdv", - "type": "uint32" + "type": "uint16" }, { "internalType": "uint32", "name": "stalkEarnedPerSeason", "type": "uint32" + }, + { + "internalType": "bytes4", + "name": "gaugePointSelector", + "type": "bytes4" + }, + { + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" } ], "name": "whitelistToken", @@ -4285,6 +4380,21 @@ "internalType": "bytes1", "name": "encodeType", "type": "bytes1" + }, + { + "internalType": "bytes4", + "name": "gaugePointSelector", + "type": "bytes4" + }, + { + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" } ], "name": "whitelistTokenWithEncodeType", @@ -6187,6 +6297,21 @@ "internalType": "bytes1", "name": "encodeType", "type": "bytes1" + }, + { + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "internalType": "bytes4", + "name": "gpSelector", + "type": "bytes4" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" } ], "internalType": "struct Storage.SiloSettings", @@ -6465,136 +6590,33 @@ "type": "function" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "beans", - "type": "uint256" - } - ], - "name": "Incentivization", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint32", - "name": "season", - "type": "uint32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "toField", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "toSilo", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "toFertilizer", - "type": "uint256" - } - ], - "name": "Reward", - "type": "event" - }, - { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "uint256", - "name": "season", - "type": "uint256" - }, - { - "indexed": false, "internalType": "uint256", - "name": "amount", + "name": "currentGaugePoints", "type": "uint256" }, { - "indexed": false, "internalType": "uint256", - "name": "toField", + "name": "optimalPercentDepositedBdv", "type": "uint256" - } - ], - "name": "SeasonOfPlenty", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint32", - "name": "season", - "type": "uint32" }, { - "indexed": false, - "internalType": "uint256", - "name": "soil", - "type": "uint256" - } - ], - "name": "Soil", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, "internalType": "uint256", - "name": "season", + "name": "percentOfDepositedBdv", "type": "uint256" } ], - "name": "Sunrise", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "season", - "type": "uint256" - }, + "name": "defaultGaugePointFunction", + "outputs": [ { - "indexed": false, "internalType": "uint256", - "name": "caseId", + "name": "newGaugePoints", "type": "uint256" - }, - { - "indexed": false, - "internalType": "int8", - "name": "change", - "type": "int8" } ], - "name": "WeatherChange", - "type": "event" + "stateMutability": "pure", + "type": "function" }, { "inputs": [], @@ -6645,19 +6667,8 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "enum LibTransfer.To", - "name": "mode", - "type": "uint8" - } - ], - "name": "gm", + "inputs": [], + "name": "getAverageGrownStalkPerBdv", "outputs": [ { "internalType": "uint256", @@ -6665,31 +6676,38 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "paused", + "name": "getAverageGrownStalkPerBdvPerSeason", "outputs": [ { - "internalType": "bool", + "internalType": "uint128", "name": "", - "type": "bool" + "type": "uint128" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "getBean3CRVLiquidity", + "outputs": [ { - "internalType": "uint32", - "name": "season", - "type": "uint32" + "internalType": "uint256", + "name": "usdLiquidity", + "type": "uint256" } ], - "name": "plentyPerRoot", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBeanEthTwaUsdLiquidity", "outputs": [ { "internalType": "uint256", @@ -6701,19 +6719,58 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "getBeanToMaxLpGpPerBdvRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBeanToMaxLpGpPerBdvRatioScaled", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDeltaPodDemand", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", - "name": "pool", + "name": "token", "type": "address" } ], - "name": "poolDeltaB", + "name": "getGaugePoints", "outputs": [ { - "internalType": "int256", + "internalType": "uint256", "name": "", - "type": "int256" + "type": "uint256" } ], "stateMutability": "view", @@ -6721,27 +6778,66 @@ }, { "inputs": [], - "name": "rain", + "name": "getLiquidityToSupplyRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNewAverageGrownStalkPerBdvPerSeason", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPodRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSeedGauge", "outputs": [ { "components": [ { - "internalType": "uint256", - "name": "deprecated", - "type": "uint256" + "internalType": "uint128", + "name": "averageGrownStalkPerBdvPerSeason", + "type": "uint128" }, { - "internalType": "uint256", - "name": "pods", - "type": "uint256" + "internalType": "uint128", + "name": "beanToMaxLpGpPerBdvRatio", + "type": "uint128" }, { - "internalType": "uint256", - "name": "roots", - "type": "uint256" + "internalType": "uint32", + "name": "lastSeedGaugeUpdate", + "type": "uint32" } ], - "internalType": "struct Storage.Rain", + "internalType": "struct Storage.SeedGauge", "name": "", "type": "tuple" } @@ -6751,12 +6847,12 @@ }, { "inputs": [], - "name": "season", + "name": "getTotalBdv", "outputs": [ { - "internalType": "uint32", - "name": "", - "type": "uint32" + "internalType": "uint256", + "name": "totalBdv", + "type": "uint256" } ], "stateMutability": "view", @@ -6764,12 +6860,12 @@ }, { "inputs": [], - "name": "seasonTime", + "name": "getTotalUsdLiquidity", "outputs": [ { - "internalType": "uint32", + "internalType": "uint256", "name": "", - "type": "uint32" + "type": "uint256" } ], "stateMutability": "view", @@ -6777,7 +6873,26 @@ }, { "inputs": [], - "name": "sunrise", + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_season", + "type": "uint32" + } + ], + "name": "plentyPerRoot", "outputs": [ { "internalType": "uint256", @@ -6785,7 +6900,69 @@ "type": "uint256" } ], - "stateMutability": "payable", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "poolDeltaB", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rain", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "deprecated", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pods", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "roots", + "type": "uint256" + } + ], + "internalType": "struct Storage.Rain", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "season", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", "type": "function" }, { @@ -6952,5 +7129,200 @@ ], "stateMutability": "view", "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "caseId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int80", + "name": "absChange", + "type": "int80" + } + ], + "name": "BeanToMaxLpGpPerBdvRatioChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "season", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toField", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toSilo", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toFertilizer", + "type": "uint256" + } + ], + "name": "Reward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toField", + "type": "uint256" + } + ], + "name": "SeasonOfPlenty", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "season", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "soil", + "type": "uint256" + } + ], + "name": "Soil", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + } + ], + "name": "Sunrise", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "caseId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int8", + "name": "absChange", + "type": "int8" + } + ], + "name": "TemperatureChange", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "gm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "seasonTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sunrise", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "updateStalkPerBdvPerSeason", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] From 2b11a27c74f744f6e5208c2744d2f6098a153061 Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Mon, 6 Nov 2023 09:45:42 -0500 Subject: [PATCH 002/113] sdk: add sunrise and updateStalkPerBdvPerSeason calls --- projects/sdk/src/lib/sun.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/projects/sdk/src/lib/sun.ts b/projects/sdk/src/lib/sun.ts index 22304560d5..99b3b5d5ee 100644 --- a/projects/sdk/src/lib/sun.ts +++ b/projects/sdk/src/lib/sun.ts @@ -1,3 +1,4 @@ +import { ContractTransaction } from "ethers"; import { BeanstalkSDK } from "./BeanstalkSDK"; export class Sun { @@ -11,5 +12,11 @@ export class Sun { return Sun.sdk.contracts.beanstalk.season(); } - // ... other sun related things + async sunrise(): Promise { + return Sun.sdk.contracts.beanstalk.sunrise(); + } + + async updateStalkPerBdvPerSeason(): Promise { + return Sun.sdk.contracts.beanstalk.updateStalkPerBdvPerSeason(); + } } From f149ade589f53070eb21ab3f6d04f90dc06eebe6 Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Mon, 6 Nov 2023 09:45:55 -0500 Subject: [PATCH 003/113] ui: reload seeds after each season --- projects/ui/src/state/beanstalk/sun/updater.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/projects/ui/src/state/beanstalk/sun/updater.ts b/projects/ui/src/state/beanstalk/sun/updater.ts index bd4e406346..7bc54688cb 100644 --- a/projects/ui/src/state/beanstalk/sun/updater.ts +++ b/projects/ui/src/state/beanstalk/sun/updater.ts @@ -17,6 +17,7 @@ import { updateSeasonResult, updateSeasonTime, } from './actions'; +import useSdk, { useRefreshSeeds } from '~/hooks/sdk'; export const useSun = () => { const dispatch = useDispatch(); @@ -78,6 +79,7 @@ export const useSun = () => { const SunUpdater = () => { const [fetch, clear] = useSun(); + const sdk = useSdk(); const dispatch = useDispatch(); const season = useSeason(); const next = useSelector( @@ -87,6 +89,8 @@ const SunUpdater = () => { (state) => state._beanstalk.sun.sunrise.awaiting ); + const refreshSeeds = useRefreshSeeds(); + useEffect(() => { if (awaiting === false) { /// Setup timer. Count down from now until the start @@ -115,11 +119,12 @@ const SunUpdater = () => { toast.success( `The Sun has risen. It is now Season ${newSeason.current.toString()}.` ); + await refreshSeeds(sdk); } })(); }, 3000); return () => clearInterval(i); - }, [dispatch, awaiting, season, next, fetch]); + }, [dispatch, awaiting, season, next, fetch, refreshSeeds, sdk]); // Fetch when chain changes useEffect(() => { From 29e1f9b6b32dd63541ba06ca11684bc200595fd0 Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Mon, 6 Nov 2023 15:55:43 -0500 Subject: [PATCH 004/113] ui: updateStalk update stalk button --- .../src/components/Nav/Buttons/SunButton.tsx | 10 +- .../src/components/Sun/UpdateStalkButton.tsx | 166 ++++++++++++++++++ protocol/abi/Beanstalk.json | 30 +++- 3 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 projects/ui/src/components/Sun/UpdateStalkButton.tsx diff --git a/projects/ui/src/components/Nav/Buttons/SunButton.tsx b/projects/ui/src/components/Nav/Buttons/SunButton.tsx index e64aae4f8d..10e0e04db9 100644 --- a/projects/ui/src/components/Nav/Buttons/SunButton.tsx +++ b/projects/ui/src/components/Nav/Buttons/SunButton.tsx @@ -23,6 +23,7 @@ import FolderMenu from '../FolderMenu'; import SeasonCard from '../../Sun/SeasonCard'; import usePeg from '~/hooks/beanstalk/usePeg'; import { FC } from '~/types'; +import UpdateStalkButton from '~/components/Sun/UpdateStalkButton'; const castField = (data: SunButtonQuery['fields'][number]) => ({ season: new BigNumber(data.season), @@ -87,7 +88,11 @@ const PriceButton: FC = ({ ...props }) => { const isLoading = season.eq(NEW_BN); const startIcon = isTiny ? undefined : ( = ({ ...props }) => { })} - + + diff --git a/projects/ui/src/components/Sun/UpdateStalkButton.tsx b/projects/ui/src/components/Sun/UpdateStalkButton.tsx new file mode 100644 index 0000000000..5da53be598 --- /dev/null +++ b/projects/ui/src/components/Sun/UpdateStalkButton.tsx @@ -0,0 +1,166 @@ +import React, { useCallback, useEffect, useMemo } from 'react'; +import { useSelector } from 'react-redux'; +import { Form, Formik, FormikProps } from 'formik'; +import { LoadingButton } from '@mui/lab'; +import { Dialog, Divider, Stack, Typography } from '@mui/material'; +import { DateTime } from 'luxon'; +import { useSigner } from '~/hooks/ledger/useSigner'; +import useToggle from '~/hooks/display/useToggle'; +import { useBeanstalkContract } from '~/hooks/ledger/useContract'; +import TransactionToast from '~/components/Common/TxnToast'; +import { + StyledDialogContent, + StyledDialogTitle, +} from '~/components/Common/Dialog'; +import { BeanstalkPalette } from '~/components/App/muiTheme'; +import Row from '~/components/Common/Row'; + +import { FC } from '~/types'; +import { AppState } from '~/state'; + +const UpdateStalkButton: FC<{}> = () => { + /// Ledger + const { data: signer } = useSigner(); + const beanstalk = useBeanstalkContract(signer); + const d = new Date(); + d.setDate(d.getDate() - 7); + + /// State + const [open, show, hide] = useToggle(); + const { current } = useSelector< + AppState, + AppState['_beanstalk']['sun']['season'] + >((state) => state._beanstalk.sun.season); + const [nextUpdate, setNextUpdate] = React.useState( + current.toNumber() + 7 * 24 + ); + + useEffect(() => { + const run = async () => { + const next = await beanstalk.getNextStalkGrowthRateUpdate(); + setNextUpdate(next.toNumber()); + }; + + run(); + }, [beanstalk]); + + /// Handlers + const onSubmit = useCallback(() => { + const txToast = new TransactionToast({ + loading: 'Updating Stalk Inflation Rate...', + success: 'Successfully updated!', + }); + beanstalk + .updateAverageStalkPerBdvPerSeason() + .then((txn) => { + txToast.confirming(txn); + return txn.wait(); + }) + .then((receipt) => { + txToast.success(receipt); + // formActions.resetForm(); + }) + .catch((err) => { + console.error(txToast.error(err.error || err)); + }); + }, [beanstalk]); + + const getDiff = useMemo(() => { + const end = DateTime.now().plus({ hours: nextUpdate - current.toNumber() }); + + return end.toRelative(); + }, [current, nextUpdate]); + + return ( + <> + + {(formikProps: FormikProps<{}>) => { + const disabled = formikProps.isSubmitting; + return ( +
+ + + Update Stalk Inflation Rate + + + + + + + + Beanstalk automatically calls this once a week on + sunrise. Next update will take place{' '} + + {getDiff} (Season {nextUpdate.toString()}) + + . If you want to call it manually, you can do so at + any time. + + + + + Please see the Docs for more information on what + this does. + + + + + + + + Update Stalk Per BDV Per Season + + + + + + Update Stalk Inflation Rate + +
+ ); + }} +
+ + ); +}; + +export default UpdateStalkButton; diff --git a/protocol/abi/Beanstalk.json b/protocol/abi/Beanstalk.json index e24cd20ae3..43b9ef994e 100644 --- a/protocol/abi/Beanstalk.json +++ b/protocol/abi/Beanstalk.json @@ -6776,6 +6776,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getLastStalkGrowthRateUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getLiquidityToSupplyRatio", @@ -6802,6 +6815,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getNextStalkGrowthRateUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getPodRate", @@ -6833,7 +6859,7 @@ }, { "internalType": "uint32", - "name": "lastSeedGaugeUpdate", + "name": "lastStalkGrowthUpdate", "type": "uint32" } ], @@ -7320,7 +7346,7 @@ }, { "inputs": [], - "name": "updateStalkPerBdvPerSeason", + "name": "updateAverageStalkPerBdvPerSeason", "outputs": [], "stateMutability": "nonpayable", "type": "function" From 1ff473162163a1aba45b4e5939edd2cf25b0e3bc Mon Sep 17 00:00:00 2001 From: Cujowolf Date: Tue, 7 Nov 2023 15:57:50 -0600 Subject: [PATCH 005/113] Initial BIP39 event schema and handlers --- .../subgraph-beanstalk/src/GaugeHandler.ts | 101 + projects/subgraph-beanstalk/subgraph.yaml | 34 + .../abis/Beanstalk/Beanstalk-BIP39.json | 7417 +++++++++++++++++ 3 files changed, 7552 insertions(+) create mode 100644 projects/subgraph-beanstalk/src/GaugeHandler.ts create mode 100644 projects/subgraph-core/abis/Beanstalk/Beanstalk-BIP39.json diff --git a/projects/subgraph-beanstalk/src/GaugeHandler.ts b/projects/subgraph-beanstalk/src/GaugeHandler.ts new file mode 100644 index 0000000000..edd81e33f8 --- /dev/null +++ b/projects/subgraph-beanstalk/src/GaugeHandler.ts @@ -0,0 +1,101 @@ +import { BigDecimal } from "@graphprotocol/graph-ts"; +import { BEANSTALK, BEANSTALK_PRICE } from "../../subgraph-core/utils/Constants"; +import { ONE_BD, ZERO_BD, toDecimal } from "../../subgraph-core/utils/Decimals"; +import { + BeanToMaxLpGpPerBdvRatioChange, + GaugePointChange, + TemperatureChange, + UpdateAverageStalkPerBdvPerSeason, + UpdateGaugeSettings, + UpdatedStalkPerBdvPerSeason, + WhitelistToken +} from "../generated/BIP39-SeedGauge/Beanstalk"; +import { BeanstalkPrice } from "../generated/BIP39-SeedGauge/BeanstalkPrice"; +import { loadField, loadFieldDaily, loadFieldHourly } from "./utils/Field"; +import { loadSeason } from "./utils/Season"; +import { loadWhitelistTokenSetting } from "./utils/SiloAsset"; +import { loadSilo } from "./utils/Silo"; + +export function handleTemperatureChange(event: TemperatureChange): void { + let field = loadField(event.address); + let fieldHourly = loadFieldHourly(event.address, event.params.season.toI32(), event.block.timestamp); + let fieldDaily = loadFieldDaily(event.address, event.block.timestamp); + + field.temperature += event.params.absChange; + fieldHourly.temperature += event.params.absChange; + fieldDaily.temperature += event.params.absChange; + + // Real Rate of Return + + let season = loadSeason(event.address, event.params.season); + + let currentPrice = ZERO_BD; + if (season.price != ZERO_BD) { + currentPrice = season.price; + } else { + // Attempt to pull from Beanstalk Price contract first + let beanstalkPrice = BeanstalkPrice.bind(BEANSTALK_PRICE); + let beanstalkQuery = beanstalkPrice.try_price(); + if (!beanstalkQuery.reverted) { + currentPrice = toDecimal(beanstalkQuery.value.price); + } + } + + field.realRateOfReturn = ONE_BD.plus(BigDecimal.fromString((field.temperature / 100).toString())).div(currentPrice); + fieldHourly.realRateOfReturn = field.realRateOfReturn; + fieldHourly.realRateOfReturn = field.realRateOfReturn; + + field.save(); + fieldHourly.save(); + fieldDaily.save(); +} +export function handleBeanToMaxLpGpPerBdvRatioChange(event: BeanToMaxLpGpPerBdvRatioChange): void { + let silo = loadSilo(BEANSTALK); + + silo.beanToMaxLpGpPerBdvRatio = silo.beanToMaxLpGpPerBdvRatio.plus(event.params.absChange); + silo.save(); +} + +export function handleGaugePointChange(event: GaugePointChange): void { + let siloSettings = loadWhitelistTokenSetting(event.params.token); + siloSettings.gaugePoints = event.params.gaugePoints; + siloSettings.updatedAt = event.block.timestamp; + siloSettings.save(); +} + +export function handleUpdateGaugeSettings(event: UpdateGaugeSettings): void { + let siloSettings = loadWhitelistTokenSetting(event.params.token); + siloSettings.selector = event.params.selector; + siloSettings.optimalPercentDepositedBdv = event.params.optimalPercentDepositedBdv; + siloSettings.updatedAt = event.block.timestamp; + siloSettings.save(); +} + +export function handleUpdateAverageStalkPerBdvPerSeason(event: UpdateAverageStalkPerBdvPerSeason): void { + let silo = loadSilo(BEANSTALK); + + silo.grownStalkPerBdvPerSeason = event.params.newStalkPerBdvPerSeason; + silo.save(); +} + +export function handleUpdateStalkPerBdvPerSeason(event: UpdatedStalkPerBdvPerSeason): void { + let siloSettings = loadWhitelistTokenSetting(event.params.token); + + siloSettings.milestoneSeason = event.params.season.toI32(); + siloSettings.stalkEarnedPerSeason; + siloSettings.updatedAt = event.block.timestamp; + siloSettings.save(); +} + +export function handleWhitelistToken_BIP39(event: WhitelistToken): void { + let siloSettings = loadWhitelistTokenSetting(event.params.token); + + siloSettings.selector = event.params.selector; + siloSettings.stalkEarnedPerSeason = event.params.stalkEarnedPerSeason; + siloSettings.stalkIssuedPerBdv = event.params.stalkIssuedPerBdv; + siloSettings.gaugePoints = event.params.gaugePoints; + siloSettings.gpSelector = event.params.gpSelector; + siloSettings.optimalPercentDepositedBdv = event.params.optimalPercentDepositedBdv; + siloSettings.updatedAt = event.block.timestamp; + siloSettings.save(); +} diff --git a/projects/subgraph-beanstalk/subgraph.yaml b/projects/subgraph-beanstalk/subgraph.yaml index 7ff7009c8c..256858634a 100644 --- a/projects/subgraph-beanstalk/subgraph.yaml +++ b/projects/subgraph-beanstalk/subgraph.yaml @@ -734,3 +734,37 @@ dataSources: - event: PodOrderFilled(indexed address,indexed address,bytes32,uint256,uint256,uint256,uint256) handler: handlePodOrderFilled_v2 file: ./src/MarketplaceHandler.ts + - kind: ethereum/contract + name: BIP39-SeedGauge + network: mainnet + source: + address: "0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5" + abi: Beanstalk + startBlock: 18522900 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - SeedGauge + abis: + - name: Beanstalk + file: ../subgraph-core/abis/Beanstalk/Beanstalk-BIP39.json + - name: BeanstalkPrice + file: ../subgraph-core/abis/BeanstalkPrice.json + eventHandlers: + - event: BeanToMaxLpGpPerBdvRatioChange(indexed uint256,uint256,int80) + handler: handleBeanToMaxLpGpPerBdvRatioChange + - event: GaugePointChange(indexed uint256,indexed address,uint256) + handler: handleGaugePointChange + - event: TemperatureChange(indexed uint256,uint256,int8) + handler: handleTemperatureChange + - event: UpdateGaugeSettings(indexed address,bytes4,uint96) + handler: handleUpdateGaugeSettings + - event: UpdateAverageStalkPerBdvPerSeason(uint256) + handler: handleUpdateAverageStalkPerBdvPerSeason + - event: UpdatedStalkPerBdvPerSeason(indexed address,uint32,uint32) + handler: handleUpdateStalkPerBdvPerSeason + - event: WhitelistToken(indexed address,bytes4,uint32,uint256,bytes4,uint128,uint96) + handler: handleWhitelistToken_BIP39 + file: ./src/GaugeHandler.ts diff --git a/projects/subgraph-core/abis/Beanstalk/Beanstalk-BIP39.json b/projects/subgraph-core/abis/Beanstalk/Beanstalk-BIP39.json new file mode 100644 index 0000000000..45a94708ff --- /dev/null +++ b/projects/subgraph-core/abis/Beanstalk/Beanstalk-BIP39.json @@ -0,0 +1,7417 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + } + ], + "name": "AddUnripeToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "underlying", + "type": "int256" + } + ], + "name": "ChangeUnderlying", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "underlying", + "type": "uint256" + } + ], + "name": "Chop", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Pick", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "underlyingToken", + "type": "address" + } + ], + "name": "SwitchUnderlyingToken", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "name": "_getPenalizedUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "redeem", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "addMigratedUnderlying", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "root", + "type": "bytes32" + } + ], + "name": "addUnripeToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfPenalizedUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "underlying", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "underlying", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "chop", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getLockedBeans", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLockedBeansUnderlyingUnripeBean", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLockedBeansUnderlyingUnripeBeanEth", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "getPenalizedUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "redeem", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + } + ], + "name": "getPenalty", + "outputs": [ + { + "internalType": "uint256", + "name": "penalty", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + } + ], + "name": "getPercentPenalty", + "outputs": [ + { + "internalType": "uint256", + "name": "penalty", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + } + ], + "name": "getRecapFundedPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "percent", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRecapPaidPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "percent", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + } + ], + "name": "getTotalUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "underlying", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "getUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "underlyingAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + } + ], + "name": "getUnderlyingPerUnripeToken", + "outputs": [ + { + "internalType": "uint256", + "name": "underlyingPerToken", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + } + ], + "name": "getUnderlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + } + ], + "name": "isUnripe", + "outputs": [ + { + "internalType": "bool", + "name": "unripe", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "pick", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "picked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "unripeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "newUnderlyingToken", + "type": "address" + } + ], + "name": "switchUnderlyingToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint128", + "name": "id", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "bpf", + "type": "uint128" + } + ], + "name": "SetFertilizer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatchFertilizer", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "lastBpf", + "type": "uint128" + } + ], + "internalType": "struct IFertilizer.Balance[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfFertilized", + "outputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOfFertilizer", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "lastBpf", + "type": "uint128" + } + ], + "internalType": "struct IFertilizer.Balance", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfUnfertilized", + "outputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "beansPerFertilizer", + "outputs": [ + { + "internalType": "uint128", + "name": "bpf", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "claimFertilized", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getActiveFertilizer", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCurrentHumidity", + "outputs": [ + { + "internalType": "uint128", + "name": "humidity", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getEndBpf", + "outputs": [ + { + "internalType": "uint128", + "name": "endBpf", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "id", + "type": "uint128" + } + ], + "name": "getFertilizer", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFertilizers", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "endBpf", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "internalType": "struct FertilizerFacet.Supply[]", + "name": "fertilizers", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFirst", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_s", + "type": "uint128" + } + ], + "name": "getHumidity", + "outputs": [ + { + "internalType": "uint128", + "name": "humidity", + "type": "uint128" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getLast", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wethAmountIn", + "type": "uint256" + } + ], + "name": "getMintFertilizerOut", + "outputs": [ + { + "internalType": "uint256", + "name": "fertilizerAmountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "id", + "type": "uint128" + } + ], + "name": "getNext", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isFertilizing", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wethAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFertilizerOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minLPTokensOut", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "mintFertilizer", + "outputs": [ + { + "internalType": "uint256", + "name": "fertilizerAmountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "payFertilizer", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "remainingRecapitalization", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalFertilizedBeans", + "outputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalFertilizerBeans", + "outputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnfertilizedBeans", + "outputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "Pause", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timePassed", + "type": "uint256" + } + ], + "name": "Unpause", + "type": "event" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "claimOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "owner_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ownerCandidate", + "outputs": [ + { + "internalType": "address", + "name": "ownerCandidate_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "internalType": "address", + "name": "facetAddress_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "facetAddresses_", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "facetFunctionSelectors_", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondLoupe.Facet[]", + "name": "facets_", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "_init", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_calldata", + "type": "bytes" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC1155", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "batchTransferERC1155", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Permit", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permitERC20", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC4494", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "sig", + "type": "bytes" + } + ], + "name": "permitERC721", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC1155", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferERC1155", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC721", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "transferERC721", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "delta", + "type": "int256" + } + ], + "name": "InternalBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenApproval", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approveToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseTokenAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getAllBalance", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "internalBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "externalBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBalance", + "type": "uint256" + } + ], + "internalType": "struct TokenFacet.Balance", + "name": "b", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getAllBalances", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "internalBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "externalBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBalance", + "type": "uint256" + } + ], + "internalType": "struct TokenFacet.Balance[]", + "name": "balances", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getBalances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getExternalBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getExternalBalances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getInternalBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "getInternalBalances", + "outputs": [ + { + "internalType": "uint256[]", + "name": "balances", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseTokenAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155BatchReceived", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permitToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "tokenAllowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tokenPermitDomainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "tokenPermitNonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "transferInternalTokenFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "transferToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "unwrapEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "wrapEth", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "clipboard", + "type": "bytes" + } + ], + "internalType": "struct AdvancedFarmCall[]", + "name": "data", + "type": "tuple[]" + } + ], + "name": "advancedFarm", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "farm", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "clipboard", + "type": "bytes" + } + ], + "internalType": "struct AdvancedPipeCall[]", + "name": "pipes", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "advancedPipe", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct PipeCall", + "name": "p", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "etherPipe", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct PipeCall[]", + "name": "pipes", + "type": "tuple[]" + } + ], + "name": "multiPipe", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct PipeCall", + "name": "p", + "type": "tuple" + } + ], + "name": "pipe", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct PipeCall", + "name": "p", + "type": "tuple" + } + ], + "name": "readPipe", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "registry", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "minAmountOut", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "addLiquidity", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minAmountOut", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "exchange", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minAmountOut", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "exchangeUnderlying", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "registry", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "minAmountsOut", + "type": "uint256[]" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "removeLiquidity", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "registry", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "amountsOut", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "maxAmountIn", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "removeLiquidityImbalance", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minAmountOut", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "fromMode", + "type": "uint8" + }, + { + "internalType": "enum LibTransfer.To", + "name": "toMode", + "type": "uint8" + } + ], + "name": "removeLiquidityOneToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "id", + "type": "uint32" + } + ], + "name": "CompleteFundraiser", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "id", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "address", + "name": "payee", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "CreateFundraiser", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint32", + "name": "id", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundFundraiser", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payee", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "createFundraiser", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "id", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "fund", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "id", + "type": "uint32" + } + ], + "name": "fundingToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "id", + "type": "uint32" + } + ], + "name": "fundraiser", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "payee", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "total", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + } + ], + "internalType": "struct Storage.Fundraiser", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "numberOfFundraisers", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "id", + "type": "uint32" + } + ], + "name": "remainingFunding", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "id", + "type": "uint32" + } + ], + "name": "totalFunding", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "plots", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "PodListingCancelled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "beans", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pods", + "type": "uint256" + } + ], + "name": "Sow", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "plots", + "type": "uint256[]" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "harvest", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "harvestableIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxTemperature", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "plot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "podIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "remainingPods", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minTemperature", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "sow", + "outputs": [ + { + "internalType": "uint256", + "name": "pods", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minTemperature", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minSoil", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "sowWithMin", + "outputs": [ + { + "internalType": "uint256", + "name": "pods", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "temperature", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalHarvestable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalHarvested", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalPods", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSoil", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnharvestable", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "yield", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pods", + "type": "uint256" + } + ], + "name": "PlotTransfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pods", + "type": "uint256" + } + ], + "name": "PodApproval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxHarvestableIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "enum LibPolynomial.PriceType", + "name": "pricingType", + "type": "uint8" + } + ], + "name": "PodListingCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "costInBeans", + "type": "uint256" + } + ], + "name": "PodListingFilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "PodOrderCancelled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "enum LibPolynomial.PriceType", + "name": "priceType", + "type": "uint8" + } + ], + "name": "PodOrderCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "costInBeans", + "type": "uint256" + } + ], + "name": "PodOrderFilled", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowancePods", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approvePods", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "cancelPodListing", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "cancelPodOrder", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "cancelPodOrderV2", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxHarvestableIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "createPodListing", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxHarvestableIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "createPodListingV2", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "beanAmount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "createPodOrder", + "outputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "beanAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "createPodOrderV2", + "outputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxHarvestableIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "internalType": "struct Listing.PodListing", + "name": "l", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "beanAmount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "fillPodListing", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxHarvestableIndex", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "internalType": "struct Listing.PodListing", + "name": "l", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "beanAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "fillPodListingV2", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + } + ], + "internalType": "struct Order.PodOrder", + "name": "o", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "fillPodOrder", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + } + ], + "internalType": "struct Order.PodOrder", + "name": "o", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "fillPodOrderV2", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "placeInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountPodsFromOrder", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + } + ], + "name": "getAmountBeansToFillOrderV2", + "outputs": [ + { + "internalType": "uint256", + "name": "beanAmount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "placeInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "podListingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fillBeanAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + } + ], + "name": "getAmountPodsFromFillListingV2", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "podListing", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint24", + "name": "pricePerPod", + "type": "uint24" + }, + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + } + ], + "name": "podOrder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "podOrderById", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxPlaceInLine", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFillAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "pricingFunction", + "type": "bytes" + } + ], + "name": "podOrderV2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "name": "transferPlot", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "DewhitelistToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "stalkEarnedPerSeason", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "season", + "type": "uint32" + } + ], + "name": "UpdatedStalkPerBdvPerSeason", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "stalkEarnedPerSeason", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stalkIssuedPerBdv", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "gpSelector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" + } + ], + "name": "WhitelistToken", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "dewhitelistToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "gaugePointSelector", + "type": "bytes4" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" + } + ], + "name": "updateGaugeForToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "stalkEarnedPerSeason", + "type": "uint32" + } + ], + "name": "updateStalkPerBdvPerSeasonForToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "internalType": "uint16", + "name": "stalkIssuedPerBdv", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "stalkEarnedPerSeason", + "type": "uint32" + }, + { + "internalType": "bytes4", + "name": "gaugePointSelector", + "type": "bytes4" + }, + { + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" + } + ], + "name": "whitelistToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "internalType": "uint32", + "name": "stalkIssuedPerBdv", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "stalkEarnedPerSeason", + "type": "uint32" + }, + { + "internalType": "bytes1", + "name": "encodeType", + "type": "bytes1" + }, + { + "internalType": "bytes4", + "name": "gaugePointSelector", + "type": "bytes4" + }, + { + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" + } + ], + "name": "whitelistTokenWithEncodeType", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfGrownStalkUpToStemsDeployment", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfLegacySeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "season", + "type": "uint32" + } + ], + "name": "getDepositLegacy", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint32[][]", + "name": "seasons", + "type": "uint32[][]" + }, + { + "internalType": "uint256[][]", + "name": "amounts", + "type": "uint256[][]" + }, + { + "internalType": "uint256", + "name": "stalkDiff", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "seedsDiff", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "proof", + "type": "bytes32[]" + } + ], + "name": "mowAndMigrate", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "mowAndMigrateNoDeposits", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "totalMigratedBdv", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int96", + "name": "stem", + "type": "int96" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bdv", + "type": "uint256" + } + ], + "name": "RemoveDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int96[]", + "name": "stems", + "type": "int96[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "bdvs", + "type": "uint256[]" + } + ], + "name": "RemoveDeposits", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "enrootDeposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96[]", + "name": "stems", + "type": "int96[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "enrootDeposits", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "getAmountOut", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + } + ], + "name": "getMaxAmountIn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fromToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "toToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + } + ], + "name": "Convert", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "convertData", + "type": "bytes" + }, + { + "internalType": "int96[]", + "name": "stems", + "type": "int96[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "convert", + "outputs": [ + { + "internalType": "int96", + "name": "toStem", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "fromAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "toAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "fromBdv", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "toBdv", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "beanToBDV", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "curveToBDV", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unripeBeanToBDV", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unripeLPToBDV", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "wellBdv", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositApproval", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approveDeposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseDepositAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "depositAllowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "depositPermitDomainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "depositPermitNonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseDepositAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permitDeposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permitDeposits", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "int96", + "name": "stem", + "type": "int96" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bdv", + "type": "uint256" + } + ], + "name": "AddDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "plenty", + "type": "uint256" + } + ], + "name": "ClaimPlenty", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "name": "Plant", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "season", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RemoveWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32[]", + "name": "seasons", + "type": "uint32[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RemoveWithdrawals", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "delta", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "deltaRoots", + "type": "int256" + } + ], + "name": "StalkBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "depositId", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "depositIds", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "balanceOfDepositedBdv", + "outputs": [ + { + "internalType": "uint256", + "name": "depositedBdv", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfEarnedBeans", + "outputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfEarnedStalk", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "balanceOfGrownStalk", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfPlenty", + "outputs": [ + { + "internalType": "uint256", + "name": "plenty", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfRainRoots", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfRoots", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfSop", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "lastRain", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastSop", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "roots", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "plentyPerRoot", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "plenty", + "type": "uint256" + } + ], + "internalType": "struct SiloExit.AccountSeasonOfPlenty", + "name": "sop", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOfStalk", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "bdv", + "outputs": [ + { + "internalType": "uint256", + "name": "_bdv", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimPlenty", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.From", + "name": "mode", + "type": "uint8" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_bdv", + "type": "uint256" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + } + ], + "name": "getDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + } + ], + "name": "getDepositId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getLastMowedStem", + "outputs": [ + { + "internalType": "int96", + "name": "lastStem", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getMowStatus", + "outputs": [ + { + "components": [ + { + "internalType": "int96", + "name": "lastStem", + "type": "int96" + }, + { + "internalType": "uint128", + "name": "bdv", + "type": "uint128" + } + ], + "internalType": "struct Account.MowStatus", + "name": "mowStatus", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getSeedsPerToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTotalDeposited", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTotalDepositedBdv", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + } + ], + "name": "grownStalkForDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "grownStalk", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "inVestingPeriod", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastSeasonOfPlenty", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "lastUpdate", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "migrationNeeded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "mow", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "mowMultiple", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "plant", + "outputs": [ + { + "internalType": "uint256", + "name": "beans", + "type": "uint256" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "depositIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "depositId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "season", + "type": "uint32" + } + ], + "name": "seasonToStem", + "outputs": [ + { + "internalType": "int96", + "name": "stem", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "stemStartSeason", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "stemTipForToken", + "outputs": [ + { + "internalType": "int96", + "name": "_stemTip", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "tokenSettings", + "outputs": [ + { + "components": [ + { + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "internalType": "uint32", + "name": "stalkEarnedPerSeason", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "stalkIssuedPerBdv", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "milestoneSeason", + "type": "uint32" + }, + { + "internalType": "int96", + "name": "milestoneStem", + "type": "int96" + }, + { + "internalType": "bytes1", + "name": "encodeType", + "type": "bytes1" + }, + { + "internalType": "uint128", + "name": "gaugePoints", + "type": "uint128" + }, + { + "internalType": "bytes4", + "name": "gpSelector", + "type": "bytes4" + }, + { + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" + } + ], + "internalType": "struct Storage.SiloSettings", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalEarnedBeans", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalRoots", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalStalk", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "_bdv", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96[]", + "name": "stem", + "type": "int96[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "transferDeposits", + "outputs": [ + { + "internalType": "uint256[]", + "name": "bdvs", + "type": "uint256[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "stem", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "withdrawDeposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "int96[]", + "name": "stems", + "type": "int96[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "withdrawDeposits", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "season", + "type": "uint32" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "claimWithdrawal", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32[]", + "name": "seasons", + "type": "uint32[]" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "claimWithdrawals", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getTotalWithdrawn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint32", + "name": "season", + "type": "uint32" + } + ], + "name": "getWithdrawal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "optimalPercentDepositedBdv", + "type": "uint96" + } + ], + "name": "UpdateGaugeSettings", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "gaugePoints", + "type": "uint256" + } + ], + "name": "GaugePointChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newStalkPerBdvPerSeason", + "type": "uint256" + } + ], + "name": "UpdateAverageStalkPerBdvPerSeason", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentGaugePoints", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "optimalPercentDepositedBdv", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "percentOfDepositedBdv", + "type": "uint256" + } + ], + "name": "defaultGaugePointFunction", + "outputs": [ + { + "internalType": "uint256", + "name": "newGaugePoints", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "abovePeg", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "curveOracle", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + }, + { + "internalType": "uint32", + "name": "startSeason", + "type": "uint32" + }, + { + "internalType": "uint256[2]", + "name": "balances", + "type": "uint256[2]" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "internalType": "struct Storage.CurveMetapoolOracle", + "name": "co", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAverageGrownStalkPerBdv", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAverageGrownStalkPerBdvPerSeason", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBean3CRVLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "usdLiquidity", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBeanEthTwaUsdLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBeanToMaxLpGpPerBdvRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBeanToMaxLpGpPerBdvRatioScaled", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getDeltaPodDemand", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getGaugePoints", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLastStalkGrowthRateUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLiquidityToSupplyRatio", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNewAverageGrownStalkPerBdvPerSeason", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextStalkGrowthRateUpdate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPodRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSeedGauge", + "outputs": [ + { + "components": [ + { + "internalType": "uint128", + "name": "averageGrownStalkPerBdvPerSeason", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "beanToMaxLpGpPerBdvRatio", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "lastStalkGrowthUpdate", + "type": "uint32" + } + ], + "internalType": "struct Storage.SeedGauge", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalBdv", + "outputs": [ + { + "internalType": "uint256", + "name": "totalBdv", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalUsdLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_season", + "type": "uint32" + } + ], + "name": "plentyPerRoot", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "poolDeltaB", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rain", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "deprecated", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "pods", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "roots", + "type": "uint256" + } + ], + "internalType": "struct Storage.Rain", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "season", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sunriseBlock", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "time", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "current", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastSop", + "type": "uint32" + }, + { + "internalType": "uint8", + "name": "withdrawSeasons", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "lastSopSeason", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "rainStart", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "raining", + "type": "bool" + }, + { + "internalType": "bool", + "name": "fertilizing", + "type": "bool" + }, + { + "internalType": "uint32", + "name": "sunriseBlock", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "abovePeg", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "stemStartSeason", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "period", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "internalType": "struct Storage.Season", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDeltaB", + "outputs": [ + { + "internalType": "int256", + "name": "deltaB", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weather", + "outputs": [ + { + "components": [ + { + "internalType": "uint256[2]", + "name": "deprecated", + "type": "uint256[2]" + }, + { + "internalType": "uint128", + "name": "lastDSoil", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "lastSowTime", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "thisSowTime", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "t", + "type": "uint32" + } + ], + "internalType": "struct Storage.Weather", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "well", + "type": "address" + } + ], + "name": "wellOracleSnapshot", + "outputs": [ + { + "internalType": "bytes", + "name": "snapshot", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "caseId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int80", + "name": "absChange", + "type": "int80" + } + ], + "name": "BeanToMaxLpGpPerBdvRatioChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "season", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toField", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toSilo", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toFertilizer", + "type": "uint256" + } + ], + "name": "Reward", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toField", + "type": "uint256" + } + ], + "name": "SeasonOfPlenty", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "season", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "soil", + "type": "uint256" + } + ], + "name": "Soil", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + } + ], + "name": "Sunrise", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "season", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "caseId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int8", + "name": "absChange", + "type": "int8" + } + ], + "name": "TemperatureChange", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "enum LibTransfer.To", + "name": "mode", + "type": "uint8" + } + ], + "name": "gm", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "seasonTime", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "sunrise", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "updateAverageStalkPerBdvPerSeason", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] From bcde8cc435b8536238fc88db61f17481ab7ebf66 Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Mon, 6 Nov 2023 15:55:43 -0500 Subject: [PATCH 006/113] ui: updateStalk update stalk button --- projects/sdk/src/lib/sun.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/sdk/src/lib/sun.ts b/projects/sdk/src/lib/sun.ts index 99b3b5d5ee..799dc086a1 100644 --- a/projects/sdk/src/lib/sun.ts +++ b/projects/sdk/src/lib/sun.ts @@ -16,7 +16,7 @@ export class Sun { return Sun.sdk.contracts.beanstalk.sunrise(); } - async updateStalkPerBdvPerSeason(): Promise { - return Sun.sdk.contracts.beanstalk.updateStalkPerBdvPerSeason(); + async updateAverageStalkPerBdvPerSeason(): Promise { + return Sun.sdk.contracts.beanstalk.updateAverageStalkPerBdvPerSeason(); } } From 9ca0d6db22ec3aac5e4847460a0f5a44de80acab Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Tue, 14 Nov 2023 14:20:49 -0500 Subject: [PATCH 007/113] ui: support unripe to ripe convert --- projects/cli/src/commands/setbalance.ts | 2 +- projects/examples/src/silo/convert.ts | 20 ++-- projects/sdk/src/lib/silo/Convert.ts | 26 ++--- projects/sdk/src/lib/silo/ConvertEncoder.ts | 50 ++++------ .../src/components/Silo/Actions/Convert.tsx | 95 +++++++++++++++---- .../ui/src/components/Silo/Actions/index.tsx | 45 ++++++++- .../lib/Txn/FarmSteps/silo/ConvertFarmStep.ts | 13 ++- .../ui/src/lib/Txn/FormTxn/FormTxnBundler.ts | 22 +++-- 8 files changed, 185 insertions(+), 88 deletions(-) diff --git a/projects/cli/src/commands/setbalance.ts b/projects/cli/src/commands/setbalance.ts index aa60c95bca..40fcc83206 100644 --- a/projects/cli/src/commands/setbalance.ts +++ b/projects/cli/src/commands/setbalance.ts @@ -11,7 +11,7 @@ export const setbalance = async (sdk, chain, { account, symbol, amount }) => { if (!symbol) { await chain.setAllBalances(account, amount); } else { - const symbols = ["ETH", "WETH", "BEAN", "USDT", "USDC", "DAI", "3CRV", "BEAN3CRV", "BEANWETH", "urBEAN", "urBEANWETH", "ROOT"]; + const symbols = ["ETH", "WETH", "BEAN", "USDT", "USDC", "DAI", "CRV3", "BEAN3CRV", "BEANWETH", "urBEAN", "urBEANWETH", "ROOT"]; if (!symbols.includes(symbol)) { console.log(`${chalk.bold.red("Error")} - ${chalk.bold.white(symbol)} is not a valid token. Valid options are: `); console.log(symbols.map((s) => chalk.green(s)).join(", ")); diff --git a/projects/examples/src/silo/convert.ts b/projects/examples/src/silo/convert.ts index bf4c510163..02e5371e8f 100644 --- a/projects/examples/src/silo/convert.ts +++ b/projects/examples/src/silo/convert.ts @@ -8,7 +8,7 @@ main().catch((e) => { console.log(e); }); -let sdk:BeanstalkSDK; +let sdk: BeanstalkSDK; async function main() { const account = process.argv[3] || _account; @@ -16,14 +16,20 @@ async function main() { let { sdk: _sdk, stop } = await impersonate(account); sdk = _sdk; sdk.DEBUG = false; + await sdk.refresh(); + // const fromToken = sdk.tokens.UNRIPE_BEAN_WETH; + // const toToken = sdk.tokens.BEAN_ETH_WELL_LP; + const fromToken = sdk.tokens.UNRIPE_BEAN; + const toToken = sdk.tokens.BEAN; - - const fromToken = sdk.tokens.BEAN - const toToken = sdk.tokens.UNRIPE_BEAN - const amount = fromToken.amount(2500) + const maxConvert = await sdk.contracts.beanstalk.getMaxAmountIn(fromToken.address, toToken.address); - let tx = await sdk.silo.convert(fromToken, toToken, amount) + const amount = fromToken.amount(1000); + const quote = await sdk.contracts.beanstalk.getAmountOut(fromToken.address, toToken.address, amount.toBlockchain()); + console.log(quote.toString()); + + let tx = await sdk.silo.convert(fromToken, toToken, amount); await tx.wait(); - + await stop(); } diff --git a/projects/sdk/src/lib/silo/Convert.ts b/projects/sdk/src/lib/silo/Convert.ts index 1f3b38a8c8..3f81bbb6a8 100644 --- a/projects/sdk/src/lib/silo/Convert.ts +++ b/projects/sdk/src/lib/silo/Convert.ts @@ -157,6 +157,16 @@ export class Convert { minAmountOut.toBlockchain(), // minBeans fromToken.address // output token address = pool address ); + } else if (fromToken.address === this.urBean.address && toToken.address === this.Bean.address) { + encoding = ConvertEncoder.unripeToRipe( + amountIn.toBlockchain(), // unRipe Amount + fromToken.address // unRipe Token + ); + } else if (fromToken.address === this.urBeanWeth.address && toToken.address === this.BeanEth.address) { + encoding = ConvertEncoder.unripeToRipe( + amountIn.toBlockchain(), // unRipe Amount + fromToken.address // unRipe Token + ); } else { throw new Error("SDK: Unknown conversion pathway"); } @@ -176,21 +186,5 @@ export class Convert { if (fromToken.equals(toToken)) { throw new Error("Cannot convert between the same token"); } - - if (!this.paths.get(fromToken)?.equals(toToken)) { - throw new Error("Cannot convert between these tokens"); - } - - const deltaB = await Convert.sdk.bean.getDeltaB(); - - if (deltaB.gte(TokenValue.ZERO)) { - if (fromToken.equals(this.BeanCrv3) || fromToken.equals(this.urBeanWeth) || fromToken.equals(this.BeanEth)) { - throw new Error("Cannot convert this token when deltaB is >= 0"); - } - } else if (deltaB.lt(TokenValue.ZERO)) { - if (fromToken.equals(this.Bean) || fromToken.equals(this.urBean)) { - throw new Error("Cannot convert this token when deltaB is < 0"); - } - } } } diff --git a/projects/sdk/src/lib/silo/ConvertEncoder.ts b/projects/sdk/src/lib/silo/ConvertEncoder.ts index 632727449d..d2bde6db66 100644 --- a/projects/sdk/src/lib/silo/ConvertEncoder.ts +++ b/projects/sdk/src/lib/silo/ConvertEncoder.ts @@ -1,48 +1,34 @@ -import { defaultAbiCoder } from 'ethers/lib/utils'; +import { defaultAbiCoder } from "ethers/lib/utils"; export enum ConvertKind { - BEANS_TO_CURVE_LP = 0, - CURVE_LP_TO_BEANS = 1, - UNRIPE_BEANS_TO_LP = 2, - UNRIPE_LP_TO_BEANS = 3, - BEANS_TO_WELL_LP = 5, - WELL_LP_TO_BEANS = 6, + BEANS_TO_CURVE_LP = 0, + CURVE_LP_TO_BEANS = 1, + UNRIPE_BEANS_TO_LP = 2, + UNRIPE_LP_TO_BEANS = 3, + BEANS_TO_WELL_LP = 5, + WELL_LP_TO_BEANS = 6, + UNRIPE_TO_RIPE = 7 } export class ConvertEncoder { static curveLPToBeans = (amountLP: string, minBeans: string, pool: string) => - defaultAbiCoder.encode( - ['uint256', 'uint256', 'uint256', 'address'], - [ConvertKind.CURVE_LP_TO_BEANS, amountLP, minBeans, pool] - ); + defaultAbiCoder.encode(["uint256", "uint256", "uint256", "address"], [ConvertKind.CURVE_LP_TO_BEANS, amountLP, minBeans, pool]); static beansToCurveLP = (amountBeans: string, minLP: string, pool: string) => - defaultAbiCoder.encode( - ['uint256', 'uint256', 'uint256', 'address'], - [ConvertKind.BEANS_TO_CURVE_LP, amountBeans, minLP, pool] - ); + defaultAbiCoder.encode(["uint256", "uint256", "uint256", "address"], [ConvertKind.BEANS_TO_CURVE_LP, amountBeans, minLP, pool]); static unripeLPToBeans = (amountLP: string, minBeans: string) => - defaultAbiCoder.encode( - ['uint256', 'uint256', 'uint256'], - [ConvertKind.UNRIPE_LP_TO_BEANS, amountLP, minBeans] - ); + defaultAbiCoder.encode(["uint256", "uint256", "uint256"], [ConvertKind.UNRIPE_LP_TO_BEANS, amountLP, minBeans]); static unripeBeansToLP = (amountBeans: string, minLP: string) => - defaultAbiCoder.encode( - ['uint256', 'uint256', 'uint256'], - [ConvertKind.UNRIPE_BEANS_TO_LP, amountBeans, minLP] - ); - + defaultAbiCoder.encode(["uint256", "uint256", "uint256"], [ConvertKind.UNRIPE_BEANS_TO_LP, amountBeans, minLP]); + static beansToWellLP = (amountBeans: string, minLP: string, pool: string) => - defaultAbiCoder.encode( - ['uint256', 'uint256', 'uint256', 'address'], - [ConvertKind.BEANS_TO_WELL_LP, amountBeans, minLP, pool] - ); + defaultAbiCoder.encode(["uint256", "uint256", "uint256", "address"], [ConvertKind.BEANS_TO_WELL_LP, amountBeans, minLP, pool]); static wellLPToBeans = (amountLP: string, minBeans: string, pool: string) => - defaultAbiCoder.encode( - ['uint256', 'uint256', 'uint256', 'address'], - [ConvertKind.WELL_LP_TO_BEANS, amountLP, minBeans, pool] - ); + defaultAbiCoder.encode(["uint256", "uint256", "uint256", "address"], [ConvertKind.WELL_LP_TO_BEANS, amountLP, minBeans, pool]); + + static unripeToRipe = (unripeAmount: string, unripeToken: string) => + defaultAbiCoder.encode(["uint256", "uint256", "uint256"], [ConvertKind.UNRIPE_TO_RIPE, unripeAmount, unripeToken]); } diff --git a/projects/ui/src/components/Silo/Actions/Convert.tsx b/projects/ui/src/components/Silo/Actions/Convert.tsx index 3788369c58..2fca6281bc 100644 --- a/projects/ui/src/components/Silo/Actions/Convert.tsx +++ b/projects/ui/src/components/Silo/Actions/Convert.tsx @@ -1,5 +1,12 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { Box, Stack, Typography, Tooltip } from '@mui/material'; +import React, { + Dispatch, + SetStateAction, + useCallback, + useEffect, + useMemo, + useState, +} from 'react'; +import { Box, Stack, Typography, Tooltip, TextField } from '@mui/material'; import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; import { Form, Formik, FormikHelpers, FormikProps } from 'formik'; import BigNumber from 'bignumber.js'; @@ -72,14 +79,6 @@ type ConvertQuoteHandlerParams = { // ----------------------------------------------------------------------- -const INIT_CONVERSION = { - amount: ZERO_BN, - bdv: ZERO_BN, - stalk: ZERO_BN, - seeds: ZERO_BN, - actions: [], -}; - const ConvertForm: FC< FormikProps & { /** List of tokens that can be converted to. */ @@ -92,6 +91,7 @@ const ConvertForm: FC< sdk: BeanstalkSDK; conversion: ConvertDetails; plantAndDoX: ReturnType; + setChopping: Dispatch>; } > = ({ tokenList, @@ -105,10 +105,14 @@ const ConvertForm: FC< isSubmitting, setFieldValue, conversion, + setChopping, }) => { /// Local state const [isTokenSelectVisible, showTokenSelect, hideTokenSelect] = useToggle(); const getBDV = useBDV(); + const [isChopping, setIsChopping] = useState(false); + const [confirmText, setConfirmText] = useState(''); + const [choppingConfirmed, setChoppingConfirmed] = useState(false); const plantCrate = plantAndDoX?.crate?.bn; @@ -165,7 +169,7 @@ const ConvertForm: FC< } else if (!canConvert) { // buttonContent = 'Pathway unavailable'; } else { - buttonContent = 'Convert'; + buttonContent = isChopping ? 'Chop and Convert' : 'Convert'; if ( tokenOut && (amountOut?.gt(0) || isUsingPlanted) && @@ -191,6 +195,14 @@ const ConvertForm: FC< } } + useEffect(() => { + if (confirmText.toUpperCase() === 'THIS WILL CHOP') { + setChoppingConfirmed(true); + } else { + setChoppingConfirmed(false); + } + }, [confirmText, setChoppingConfirmed]); + function getBDVTooltip(instantBDV: BigNumber, depositBDV: BigNumber) { return ( @@ -218,11 +230,16 @@ const ConvertForm: FC< if (tokenOut !== _tokenOut) { setFieldValue('tokenOut', _tokenOut); setFieldValue('maxAmountIn', null); + setConfirmText(''); } }, [setFieldValue, tokenOut] ); + useEffect(() => { + setConfirmText(''); + }, [amountIn]); + /// When `tokenIn` or `tokenOut` changes, refresh the /// max amount that the user can input of `tokenIn`. /// FIXME: flash when clicking convert tab @@ -239,9 +256,19 @@ const ConvertForm: FC< const _maxAmountInStr = tokenIn.amount(_maxAmountIn.toString()); console.debug('[Convert][maxAmountIn]: ', _maxAmountInStr); + + // Figure out if we're chopping + const chopping = + (tokenIn.address === sdk.tokens.UNRIPE_BEAN.address && + tokenOut?.address === sdk.tokens.BEAN.address) || + (tokenIn.address === sdk.tokens.UNRIPE_BEAN_WETH.address && + tokenOut?.address === sdk.tokens.BEAN_ETH_WELL_LP.address); + + setChopping(chopping); + setIsChopping(chopping); } })(); - }, [sdk, setFieldValue, tokenIn, tokenOut]); + }, [sdk, setChopping, setFieldValue, tokenIn, tokenOut]); const quoteHandlerParams = useMemo( () => ({ @@ -448,10 +475,42 @@ const ConvertForm: FC< ) : null} + {isReady && isChopping && ( + + + This conversion will effectively perform a CHOP opperation. Please + confirm you understand this by typing{' '} + "THIS WILL CHOP"below. + + setConfirmText(e.target.value)} + sx={{ + background: '#f5d1d1', + borderRadius: '10px', + border: '1px solid red', + input: { color: '#880202', textTransform: 'uppercase' }, + }} + /> + + )} + {/* Submit */} = ({ fromToken }) => { + setChopping: Dispatch>; +}> = ({ fromToken, setChopping }) => { const sdk = useSdk(); /// Token List @@ -612,11 +672,6 @@ const ConvertPropProvider: FC<{ const isPlanting = plantAndDoX && values.farmActions.primary?.includes(FormTxn.PLANT); - const lpConversion = - tokenOut.equals(sdk.tokens.BEAN_ETH_WELL_LP) || - tokenIn.address.toLowerCase() === - sdk.tokens.BEAN_ETH_WELL_LP.address.toLowerCase(); - const convertTxn = new ConvertFarmStep( sdk, tokenIn, @@ -704,6 +759,7 @@ const ConvertPropProvider: FC<{ /> >; }> = (props) => ( diff --git a/projects/ui/src/components/Silo/Actions/index.tsx b/projects/ui/src/components/Silo/Actions/index.tsx index bd8cdbded3..e8f979b935 100644 --- a/projects/ui/src/components/Silo/Actions/index.tsx +++ b/projects/ui/src/components/Silo/Actions/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Alert, Box, Button, Tab } from '@mui/material'; import { ERC20Token } from '@beanstalk/sdk'; import { Link } from 'react-router-dom'; @@ -47,6 +47,15 @@ const SiloActions: FC<{ const [tab, handleChange] = useTabs(SLUGS, 'action'); const migrationNeeded = useMigrationNeeded(); const account = useAccount(); + const [isChopping, setIsChopping] = useState(false); + + const tabChange = ( + event: React.SyntheticEvent, + newIndex: number + ) => { + setIsChopping(false); + handleChange(event, newIndex); + }; const token = useMemo(() => { const match = sdk.tokens.findBySymbol(props.token.symbol) as ERC20Token; @@ -85,9 +94,20 @@ const SiloActions: FC<{ ? withdrawalItems.length > 0 : false; + console.log('Choppingss: ', isChopping); return ( <> - + {migrationNeeded ? ( ) : null} - + {isChopping ? ( + } + > + This will perform a CHOP operation!! + + ) : null} + {/* */} + @@ -121,7 +156,9 @@ const SiloActions: FC<{ {tab === 0 && } - {tab === 1 && } + {tab === 1 && ( + + )} {tab === 2 && } {tab === 3 && } {tab === 4 && hasClaimableBeans && withdrawalItems && ( diff --git a/projects/ui/src/lib/Txn/FarmSteps/silo/ConvertFarmStep.ts b/projects/ui/src/lib/Txn/FarmSteps/silo/ConvertFarmStep.ts index 15c6a24c9c..73ac64b3d6 100644 --- a/projects/ui/src/lib/Txn/FarmSteps/silo/ConvertFarmStep.ts +++ b/projects/ui/src/lib/Txn/FarmSteps/silo/ConvertFarmStep.ts @@ -146,6 +146,7 @@ export class ConvertFarmStep extends FarmStep { [siloConvert.Bean, siloConvert.BeanEth], [siloConvert.Bean, siloConvert.BeanEth, siloConvert.BeanCrv3], [siloConvert.urBean, siloConvert.urBeanWeth], + [siloConvert.urBean, siloConvert.Bean], ]; /// b/c siloConvert uses it's own token instances @@ -153,7 +154,12 @@ export class ConvertFarmStep extends FarmStep { [sdk.tokens.BEAN, sdk.tokens.BEAN_CRV3_LP], [sdk.tokens.BEAN, sdk.tokens.BEAN_ETH_WELL_LP], [sdk.tokens.BEAN, sdk.tokens.BEAN_ETH_WELL_LP, sdk.tokens.BEAN_CRV3_LP], - [sdk.tokens.UNRIPE_BEAN, sdk.tokens.UNRIPE_BEAN_WETH], + [sdk.tokens.UNRIPE_BEAN, sdk.tokens.UNRIPE_BEAN_WETH, sdk.tokens.BEAN], + [ + sdk.tokens.UNRIPE_BEAN_WETH, + sdk.tokens.UNRIPE_BEAN, + sdk.tokens.BEAN_ETH_WELL_LP, + ], ]; const index = @@ -163,9 +169,10 @@ export class ConvertFarmStep extends FarmStep { ? 1 : tokenIn === sdk.tokens.BEAN ? 2 - : 3; + : tokenIn === sdk.tokens.UNRIPE_BEAN + ? 3 + : 4; const path = pathMatrix[index]; - const tokenInIndex = path.findIndex((t) => t.equals(tokenIn)); const tokenOutIndex = Number(Boolean(!tokenInIndex)); diff --git a/projects/ui/src/lib/Txn/FormTxn/FormTxnBundler.ts b/projects/ui/src/lib/Txn/FormTxn/FormTxnBundler.ts index 383329f873..8110607356 100644 --- a/projects/ui/src/lib/Txn/FormTxn/FormTxnBundler.ts +++ b/projects/ui/src/lib/Txn/FormTxn/FormTxnBundler.ts @@ -1,4 +1,5 @@ import { BeanstalkSDK, TokenValue } from '@beanstalk/sdk'; +import { BigNumber } from 'ethers'; import { ClaimFarmStep, EnrootFarmStep, @@ -14,7 +15,6 @@ import { FormTxnMap, } from '~/lib/Txn/FormTxn/types'; import { FormTxnBundlerPresets as presets } from '~/lib/Txn/FormTxn/presets'; -import { BigNumber } from 'ethers'; import { Token } from '@beanstalk/sdk-core'; type FormTxnFarmStep = @@ -210,16 +210,26 @@ export class FormTxnBundler { const estimate = await farm.estimate(amountIn); console.debug('[FormTxnBundler][bundle]: estimate = ', estimate.toString()); - let gasEstimate: BigNumber - let adjustedGas: string + let gasEstimate: BigNumber; + let adjustedGas: string; if (gasMultiplier) { gasEstimate = await farm.estimateGas(amountIn, { slippage }); - adjustedGas = Math.round(gasEstimate.toNumber() * gasMultiplier).toString(); - console.debug('[FormTxnBundler][bundle]: estimateGas = ', gasEstimate.toString()); + adjustedGas = Math.round( + gasEstimate.toNumber() * gasMultiplier + ).toString(); + console.debug( + '[FormTxnBundler][bundle]: estimateGas = ', + gasEstimate.toString() + ); console.debug('[FormTxnBundler][bundle]: adjustedGas = ', adjustedGas); } - const execute = () => farm.execute(amountIn, { slippage }, gasMultiplier ? { gasLimit: adjustedGas } : undefined); + const execute = () => + farm.execute( + amountIn, + { slippage }, + gasMultiplier ? { gasLimit: adjustedGas } : undefined + ); return { estimate, From e8da405f1d5eba94f071f5f1942f0b06a31f0a6b Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Tue, 14 Nov 2023 14:31:35 -0500 Subject: [PATCH 008/113] ui: cleanup --- projects/ui/src/components/App/SdkProvider.tsx | 2 +- projects/ui/src/components/Silo/Actions/index.tsx | 1 - projects/ui/src/hooks/sdk/index.ts | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/projects/ui/src/components/App/SdkProvider.tsx b/projects/ui/src/components/App/SdkProvider.tsx index a53082f2f9..53aaa1cb0e 100644 --- a/projects/ui/src/components/App/SdkProvider.tsx +++ b/projects/ui/src/components/App/SdkProvider.tsx @@ -45,7 +45,7 @@ const useBeanstalkSdkContext = () => { SUBGRAPH_ENVIRONMENTS?.[subgraphEnv]?.subgraphs?.beanstalk; const sdk = useMemo(() => { - console.info(`Instantiating BeanstalkSDK`, { + console.debug(`Instantiating BeanstalkSDK`, { provider, signer, datasource, diff --git a/projects/ui/src/components/Silo/Actions/index.tsx b/projects/ui/src/components/Silo/Actions/index.tsx index e8f979b935..68fd1659f1 100644 --- a/projects/ui/src/components/Silo/Actions/index.tsx +++ b/projects/ui/src/components/Silo/Actions/index.tsx @@ -94,7 +94,6 @@ const SiloActions: FC<{ ? withdrawalItems.length > 0 : false; - console.log('Choppingss: ', isChopping); return ( <> { } token!.rewards!.seeds = parseFloat(seeds.toHuman()); } - - console.log('seeds loaded'); }, [getChainToken] ); From 28b0d5abb3ab1fe05dbb61642eef86f7cd386b29 Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Tue, 12 Dec 2023 21:13:04 -0500 Subject: [PATCH 009/113] ui: update convert warning for unripe assets --- projects/sdk/src/classes/Token/Token.ts | 4 +- projects/sdk/src/lib/BeanstalkSDK.ts | 4 +- projects/sdk/src/lib/tokens.ts | 4 +- .../ui/src/components/Common/EmbeddedCard.tsx | 10 +- .../components/Common/Form/SettingSwitch.tsx | 7 +- .../components/Common/Form/TokenOutput.tsx | 9 +- .../src/components/Silo/Actions/Convert.tsx | 98 ++++++++++++++----- .../ui/src/components/Silo/Actions/index.tsx | 44 +-------- .../ui/src/hooks/farmer/useRevitalized.ts | 1 - 9 files changed, 107 insertions(+), 74 deletions(-) diff --git a/projects/sdk/src/classes/Token/Token.ts b/projects/sdk/src/classes/Token/Token.ts index ee6c6eadce..ebba0e4dc5 100644 --- a/projects/sdk/src/classes/Token/Token.ts +++ b/projects/sdk/src/classes/Token/Token.ts @@ -34,7 +34,9 @@ CoreToken.prototype.getStalk = function (bdv?: TokenValue): TokenValue { * Get the amount of Seeds rewarded per deposited BDV of this Token. * */ CoreToken.prototype.getSeeds = function (bdv?: TokenValue): TokenValue { - if (!this.rewards?.seeds) throw new Error(`Token ${this.symbol} has no seeds defined!`); + if (this.rewards?.seeds === undefined || this.rewards.seeds === null) { + throw new Error(`Token ${this.symbol} has no seeds defined!`); + } if (!bdv) return this.rewards.seeds; return this.rewards.seeds.mul(bdv); diff --git a/projects/sdk/src/lib/BeanstalkSDK.ts b/projects/sdk/src/lib/BeanstalkSDK.ts index 8a7f0e08b1..ccab9c1074 100644 --- a/projects/sdk/src/lib/BeanstalkSDK.ts +++ b/projects/sdk/src/lib/BeanstalkSDK.ts @@ -46,7 +46,7 @@ export class BeanstalkSDK { public providerOrSigner: Signer | Provider; public source: DataSource; public subgraphUrl: string; - public lastRefreshTimestamp: Date; + public lastRefreshTimestamp: number; public readonly chainId: ChainId; public readonly addresses: typeof addresses; @@ -110,6 +110,7 @@ export class BeanstalkSDK { const { stalkEarnedPerSeason } = await this.contracts.beanstalk.tokenSettings(token.address); token.rewards!.seeds = this.tokens.SEEDS.fromBlockchain(stalkEarnedPerSeason); } + this.lastRefreshTimestamp = Date.now(); } debug(...args: any[]) { @@ -180,6 +181,7 @@ export class BeanstalkSDK { toJSON() { return { chainId: this.chainId, + lastRefreshTimestamp: this.lastRefreshTimestamp, provider: { url: this.provider?.connection?.url, network: this.provider?._network diff --git a/projects/sdk/src/lib/tokens.ts b/projects/sdk/src/lib/tokens.ts index 48b91de42d..c2a03b01d4 100644 --- a/projects/sdk/src/lib/tokens.ts +++ b/projects/sdk/src/lib/tokens.ts @@ -168,7 +168,7 @@ export class Tokens { ); this.UNRIPE_BEAN.rewards = { stalk: this.STALK.amount(0), - seeds: null + seeds: TokenValue.ZERO }; this.UNRIPE_BEAN.isUnripe = true; @@ -186,7 +186,7 @@ export class Tokens { ); this.UNRIPE_BEAN_WETH.rewards = { stalk: this.STALK.amount(1), - seeds: null + seeds: TokenValue.ZERO }; this.UNRIPE_BEAN_WETH.isUnripe = true; diff --git a/projects/ui/src/components/Common/EmbeddedCard.tsx b/projects/ui/src/components/Common/EmbeddedCard.tsx index f1ac4e5994..4ca3debee5 100644 --- a/projects/ui/src/components/Common/EmbeddedCard.tsx +++ b/projects/ui/src/components/Common/EmbeddedCard.tsx @@ -4,14 +4,20 @@ import { Card, CardProps } from '@mui/material'; import { FC } from '~/types'; import { BeanstalkPalette } from '../App/muiTheme'; -const EmbeddedCard: FC = ({ children, ...cardProps }) => ( +const EmbeddedCard: FC = ({ + children, + danger, + ...cardProps +}) => ( {children} diff --git a/projects/ui/src/components/Common/Form/SettingSwitch.tsx b/projects/ui/src/components/Common/Form/SettingSwitch.tsx index b8fb0d3987..3ca6d3d70a 100644 --- a/projects/ui/src/components/Common/Form/SettingSwitch.tsx +++ b/projects/ui/src/components/Common/Form/SettingSwitch.tsx @@ -10,14 +10,17 @@ const SettingSwitch: FC<{ name: string; label: string; }> = ({ name, label }) => ( - + {(fieldProps: FieldProps) => ( - {label} + {label} { + fieldProps.form.setFieldValue(name, checked); + }} /> diff --git a/projects/ui/src/components/Common/Form/TokenOutput.tsx b/projects/ui/src/components/Common/Form/TokenOutput.tsx index 234431a7e5..6cb021525f 100644 --- a/projects/ui/src/components/Common/Form/TokenOutput.tsx +++ b/projects/ui/src/components/Common/Form/TokenOutput.tsx @@ -24,9 +24,14 @@ type SizeProps = { type Props = { children: React.ReactNode; + danger: boolean; } & SizeProps; -export default function TokenOutput({ children, size = 'medium' }: Props) { +export default function TokenOutput({ + children, + size = 'medium', + danger, +}: Props) { const isMedium = size === 'medium'; const px = isMedium ? 2 : 1; @@ -34,7 +39,7 @@ export default function TokenOutput({ children, size = 'medium' }: Props) { const gap = isMedium ? 1 : 0.5; return ( - + {children} diff --git a/projects/ui/src/components/Silo/Actions/Convert.tsx b/projects/ui/src/components/Silo/Actions/Convert.tsx index 2fca6281bc..6d1763c1e6 100644 --- a/projects/ui/src/components/Silo/Actions/Convert.tsx +++ b/projects/ui/src/components/Silo/Actions/Convert.tsx @@ -1,11 +1,4 @@ -import React, { - Dispatch, - SetStateAction, - useCallback, - useEffect, - useMemo, - useState, -} from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Box, Stack, Typography, Tooltip, TextField } from '@mui/material'; import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; import { Form, Formik, FormikHelpers, FormikProps } from 'formik'; @@ -19,10 +12,12 @@ import { TokenValue, ConvertDetails, } from '@beanstalk/sdk'; +import { useSelector } from 'react-redux'; import { FormStateNew, FormTxnsFormState, SettingInput, + SettingSwitch, SmartSubmitButton, TxnSettings, } from '~/components/Common/Form'; @@ -30,7 +25,7 @@ import TxnPreview from '~/components/Common/Form/TxnPreview'; import TxnSeparator from '~/components/Common/Form/TxnSeparator'; import PillRow from '~/components/Common/Form/PillRow'; import { TokenSelectMode } from '~/components/Common/Form/TokenSelectDialog'; -import { displayFullBN, MaxBN, MinBN } from '~/util/Tokens'; +import { displayBN, displayFullBN, MaxBN, MinBN } from '~/util/Tokens'; import { ZERO_BN } from '~/constants'; import useToggle from '~/hooks/display/useToggle'; import { tokenValueToBN, bnToTokenValue, transform } from '~/util'; @@ -61,12 +56,15 @@ import useFormTxnContext from '~/hooks/sdk/useFormTxnContext'; import { FormTxn, ConvertFarmStep } from '~/lib/Txn'; import usePlantAndDoX from '~/hooks/farmer/form-txn/usePlantAndDoX'; import StatHorizontal from '~/components/Common/StatHorizontal'; +import { BeanstalkPalette, FontSize } from '~/components/App/muiTheme'; +import { AppState } from '~/state'; // ----------------------------------------------------------------------- type ConvertFormValues = FormStateNew & { settings: { slippage: number; + allowUnripeConvert: boolean; }; maxAmountIn: BigNumber | undefined; tokenOut: Token | undefined; @@ -79,6 +77,15 @@ type ConvertQuoteHandlerParams = { // ----------------------------------------------------------------------- +const filterTokenList = ( + fromToken: Token, + allowUnripeConvert: boolean, + list: Token[] +): Token[] => { + if (allowUnripeConvert || !fromToken.isUnripe) return list; + return list.filter((token) => token.isUnripe); +}; + const ConvertForm: FC< FormikProps & { /** List of tokens that can be converted to. */ @@ -91,13 +98,11 @@ const ConvertForm: FC< sdk: BeanstalkSDK; conversion: ConvertDetails; plantAndDoX: ReturnType; - setChopping: Dispatch>; } > = ({ - tokenList, + tokenList: tokenListFull, siloBalances, handleQuote, - currentSeason, plantAndDoX, sdk, // Formik @@ -105,7 +110,6 @@ const ConvertForm: FC< isSubmitting, setFieldValue, conversion, - setChopping, }) => { /// Local state const [isTokenSelectVisible, showTokenSelect, hideTokenSelect] = useToggle(); @@ -113,6 +117,26 @@ const ConvertForm: FC< const [isChopping, setIsChopping] = useState(false); const [confirmText, setConfirmText] = useState(''); const [choppingConfirmed, setChoppingConfirmed] = useState(false); + const unripeTokens = useSelector( + (_state) => _state._bean.unripe + ); + const [tokenList, setTokenList] = useState( + filterTokenList( + values.tokens[0].token, + values.settings.allowUnripeConvert, + tokenListFull + ) + ); + + useEffect(() => { + setTokenList( + filterTokenList( + values.tokens[0].token, + values.settings.allowUnripeConvert, + tokenListFull + ) + ); + }, [tokenListFull, values.settings.allowUnripeConvert, values.tokens]); const plantCrate = plantAndDoX?.crate?.bn; @@ -196,7 +220,7 @@ const ConvertForm: FC< } useEffect(() => { - if (confirmText.toUpperCase() === 'THIS WILL CHOP') { + if (confirmText.toUpperCase() === 'CHOP MY ASSETS') { setChoppingConfirmed(true); } else { setChoppingConfirmed(false); @@ -264,11 +288,10 @@ const ConvertForm: FC< (tokenIn.address === sdk.tokens.UNRIPE_BEAN_WETH.address && tokenOut?.address === sdk.tokens.BEAN_ETH_WELL_LP.address); - setChopping(chopping); setIsChopping(chopping); } })(); - }, [sdk, setChopping, setFieldValue, tokenIn, tokenOut]); + }, [sdk, setFieldValue, tokenIn, tokenOut]); const quoteHandlerParams = useMemo( () => ({ @@ -302,6 +325,8 @@ const ConvertForm: FC< return message; }; + const chopPercent = unripeTokens[tokenIn?.address || 0]?.chopPenalty || 0; + return (
- + + + You will forfeit {displayBN(chopPercent)}% your claim to future + Ripe assets through this transaction + +
This conversion will effectively perform a CHOP opperation. Please confirm you understand this by typing{' '} - "THIS WILL CHOP"below. + "CHOP MY ASSETS"below. >; -}> = ({ fromToken, setChopping }) => { +}> = ({ fromToken }) => { const sdk = useSdk(); /// Token List @@ -580,6 +625,7 @@ const ConvertPropProvider: FC<{ // Settings settings: { slippage: 0.05, + allowUnripeConvert: false, }, // Token Inputs tokens: [ @@ -757,9 +803,16 @@ const ConvertPropProvider: FC<{ label="Slippage Tolerance" endAdornment="%" /> + + {/* Only show the switch if we are on an an unripe silo's page */} + {fromToken.isUnripe && ( + + )} >; }> = (props) => ( diff --git a/projects/ui/src/components/Silo/Actions/index.tsx b/projects/ui/src/components/Silo/Actions/index.tsx index 68fd1659f1..bd8cdbded3 100644 --- a/projects/ui/src/components/Silo/Actions/index.tsx +++ b/projects/ui/src/components/Silo/Actions/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; import { Alert, Box, Button, Tab } from '@mui/material'; import { ERC20Token } from '@beanstalk/sdk'; import { Link } from 'react-router-dom'; @@ -47,15 +47,6 @@ const SiloActions: FC<{ const [tab, handleChange] = useTabs(SLUGS, 'action'); const migrationNeeded = useMigrationNeeded(); const account = useAccount(); - const [isChopping, setIsChopping] = useState(false); - - const tabChange = ( - event: React.SyntheticEvent, - newIndex: number - ) => { - setIsChopping(false); - handleChange(event, newIndex); - }; const token = useMemo(() => { const match = sdk.tokens.findBySymbol(props.token.symbol) as ERC20Token; @@ -96,17 +87,7 @@ const SiloActions: FC<{ return ( <> - + {migrationNeeded ? ( ) : null} - {isChopping ? ( - } - > - This will perform a CHOP operation!! - - ) : null} - {/* */} - + @@ -155,9 +121,7 @@ const SiloActions: FC<{ {tab === 0 && } - {tab === 1 && ( - - )} + {tab === 1 && } {tab === 2 && } {tab === 3 && } {tab === 4 && hasClaimableBeans && withdrawalItems && ( diff --git a/projects/ui/src/hooks/farmer/useRevitalized.ts b/projects/ui/src/hooks/farmer/useRevitalized.ts index 8b61fe1af4..05bf0dbb39 100644 --- a/projects/ui/src/hooks/farmer/useRevitalized.ts +++ b/projects/ui/src/hooks/farmer/useRevitalized.ts @@ -48,7 +48,6 @@ export default function useRevitalized() { (state) => state._beanstalk.silo ); const sdk = useSdk(); - return useMemo(() => { let revitalizedBDV = ZERO_BN; let revitalizedStalk = ZERO_BN; From 4ea7bd78957647ec27e624946e51da9df802d371 Mon Sep 17 00:00:00 2001 From: alecks <0xalecks@gmail.com> Date: Wed, 7 Feb 2024 19:57:20 -0500 Subject: [PATCH 010/113] ui: bean:3crv dewhitelist --- .../components/Nav/Buttons/PriceButton.tsx | 321 ++++++++++++++++-- .../ui/src/components/Silo/Actions/index.tsx | 8 +- projects/ui/src/components/Silo/Whitelist.tsx | 213 +++++++----- projects/ui/src/constants/pools.ts | 7 + projects/ui/src/constants/tokens.ts | 8 +- projects/ui/src/hooks/beanstalk/usePools.ts | 6 +- .../ui/src/hooks/beanstalk/useWhitelist.ts | 13 +- projects/ui/src/pages/silo/index.tsx | 2 +- projects/ui/src/pages/silo/token.tsx | 24 +- 9 files changed, 470 insertions(+), 132 deletions(-) diff --git a/projects/ui/src/components/Nav/Buttons/PriceButton.tsx b/projects/ui/src/components/Nav/Buttons/PriceButton.tsx index a6ff74a208..08d0cceea2 100644 --- a/projects/ui/src/components/Nav/Buttons/PriceButton.tsx +++ b/projects/ui/src/components/Nav/Buttons/PriceButton.tsx @@ -1,8 +1,20 @@ -import React, { useMemo } from 'react'; -import { ButtonProps, Stack, Typography, useMediaQuery, Box } from '@mui/material'; +import React, { useMemo, useState } from 'react'; +import { + ButtonProps, + Stack, + Typography, + useMediaQuery, + Box, + Link, + Switch, + Chip, + Avatar, +} from '@mui/material'; import throttle from 'lodash/throttle'; import { useTheme } from '@mui/material/styles'; +import { Close } from '@mui/icons-material'; import { useSelector } from 'react-redux'; +import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward'; import usePools from '~/hooks/beanstalk/usePools'; import PoolCard from '~/components/Silo/PoolCard'; import BeanProgressIcon from '~/components/Common/BeanProgressIcon'; @@ -13,6 +25,7 @@ import { BASIN_WELL_LINK, CURVE_LINK, NEW_BN, ZERO_BN } from '~/constants'; import { useFetchPools } from '~/state/bean/pools/updater'; import { AppState } from '~/state'; import FolderMenu from '../FolderMenu'; +import ethereumLogo from '~/img/tokens/eth-logo-circled.svg'; // ------------------------------------------------------------ @@ -20,13 +33,28 @@ import { FC } from '~/types'; import useDataFeedTokenPrices from '~/hooks/beanstalk/useDataFeedTokenPrices'; const PriceButton: FC = ({ ...props }) => { - // Data - const pools = usePools(); + const [showDeprecated, setShowDeprecated] = useState(false); + + const pools = usePools(showDeprecated); + const [showTWA, setShowTWA] = useState(false); + const [showPrices, setShowPrices] = useState(false); const season = useSeason(); const beanPrice = usePrice(); const beanPools = useSelector( (state) => state._bean.pools ); + + const toggleDisplayedPools = (e: React.MouseEvent) => { + e.stopPropagation(); + e.nativeEvent.stopImmediatePropagation(); + setShowDeprecated(!showDeprecated); + }; + + const toggleTWA = (v: React.ChangeEvent) => + setShowTWA(v.target.checked); + + const togglePrices = () => setShowPrices(!showPrices); + const beanTokenData = useSelector( (state) => state._bean.token ); @@ -36,7 +64,7 @@ const PriceButton: FC = ({ ...props }) => { () => throttle(_refetchPools, 10_000), [_refetchPools] ); // max refetch = 10s - + // Theme const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('lg')); @@ -48,43 +76,262 @@ const PriceButton: FC = ({ ...props }) => { ); - const combinedDeltaB = Object.values(beanPools).reduce((accumulator, pool) => pool.deltaB.plus(accumulator), ZERO_BN); - - const poolsContent = - <> - {Object.values(pools).map((pool, index) => ( - ({ ...value, address })) + .filter((item) => Object.keys(pools).includes(item.address)) + .reduce((accumulator, pool) => pool.deltaB.plus(accumulator), ZERO_BN); + + const poolsContent = ( + <> + - ))} -
- - -
Cumulative Instantaneous deltaB:
-
{combinedDeltaB.gte(0) && '+'}{displayBN(combinedDeltaB, true)}
+ > +
+ } + onClick={togglePrices} + label={ + + {showTWA ? ( + <> ${tokenPrices['ETH-TWA']?.toFixed(2) || 0} + ) : ( + <> ${tokenPrices.eth?.toFixed(2) || 0} + )} + + + + } + /> +
+
+ + {showTWA ? ( + <> + Total TWA deltaB:{' '} + + {beanTokenData.deltaB.gte(0) && '+'} + {displayBN(beanTokenData.deltaB, true)} + + + ) : ( + <> + Total deltaB:{' '} + + {combinedDeltaB.gte(0) && '+'} + {displayBN(combinedDeltaB, true)} + + + )} + + } + /> +
+
+ {Object.values(pools).map((pool, index) => ( + + ))} +
+ + + + Show deltaB as time-weighted average + + + + + {showTWA ? ( + <> + {' '} + View the average deltaB of Bean over the last hour, the shortage + or excess of Beans in a liquidity pool Beans trade in. +
+
+ Beanstalk uses the time-weighted average deltaB to determine how + many Beans to mint per season. + + ) : ( + <> + {' '} + View the time-weighted average shortage or excess of Beans in + each pool over the last hour, i.e., the TWA deltaB. + + )} +
+ + {/* Leaving here for reference + + +
Cumulative Instantaneous deltaB:
+
+ {combinedDeltaB.gte(0) && '+'} + {displayBN(combinedDeltaB, true)} +
+
+ +
Cumulative Time-Weighted deltaB:
+
+ {beanTokenData.deltaB.gte(0) && '+'} + {displayBN(beanTokenData.deltaB, true)} +
+
+ +
Instantaneous ETH Price:
+
${tokenPrices.eth?.toFixed(2) || 0}
+
+ +
Time-Weighted ETH Price:
+
${tokenPrices['ETH-TWA']?.toFixed(2) || 0}
+
*/}
- -
Cumulative Time-Weighted deltaB:
-
{beanTokenData.deltaB.gte(0) && '+'}{displayBN(beanTokenData.deltaB, true)}
+ + + {showDeprecated + ? 'Show only whitelisted' + : 'Show all pools (inc non-whitelisted)'} + - -
Instantaneous ETH Price:
-
${tokenPrices.eth?.toFixed(2) || 0}
+
+ + ); + + const priceContent = ( + + + + Prices of Non-Bean assets + + + + + {/* ETH Price */} + + + {' '} + ETH Price - -
Time-Weighted ETH Price:
-
${tokenPrices["ETH-TWA"]?.toFixed(2) || 0}
+
${tokenPrices.eth?.toFixed(2) || 0}
+
+ + {/* TWA ETH Price */} + + + {' '} + TWA ETH Price +
${tokenPrices['ETH-TWA']?.toFixed(2) || 0}
-
- + + + + TWA Prices represent the prices of these non-Bean assets over the last + hour according to Beanstalk + + +
+ ); return ( = ({ ...props }) => { } popoverContent={ - {poolsContent} + {showPrices ? priceContent : poolsContent} } hotkey="opt+1, alt+1" diff --git a/projects/ui/src/components/Silo/Actions/index.tsx b/projects/ui/src/components/Silo/Actions/index.tsx index bd8cdbded3..ea72c5f887 100644 --- a/projects/ui/src/components/Silo/Actions/index.tsx +++ b/projects/ui/src/components/Silo/Actions/index.tsx @@ -25,6 +25,7 @@ import LegacyClaim, { LegacyWithdrawalSubgraph, } from '~/components/Silo/Actions/LegacyClaim'; import { transform } from '~/util'; +import { useIsTokenDeprecated } from '~/hooks/beanstalk/useWhitelist'; /** * Show the three primary Silo actions: Deposit, Withdraw, Claim. @@ -44,6 +45,7 @@ const SiloActions: FC<{ siloBalance: FarmerSiloTokenBalance; }> = (props) => { const sdk = useSdk(); + const checkIfDeprecated = useIsTokenDeprecated(); const [tab, handleChange] = useTabs(SLUGS, 'action'); const migrationNeeded = useMigrationNeeded(); const account = useAccount(); @@ -85,6 +87,8 @@ const SiloActions: FC<{ ? withdrawalItems.length > 0 : false; + const isDeprecated = checkIfDeprecated(token); + return ( <> @@ -107,7 +111,9 @@ const SiloActions: FC<{ ) : null} - + {!isDeprecated && ( + + )} diff --git a/projects/ui/src/components/Silo/Whitelist.tsx b/projects/ui/src/components/Silo/Whitelist.tsx index 193f2d8c7d..2eb81df86f 100644 --- a/projects/ui/src/components/Silo/Whitelist.tsx +++ b/projects/ui/src/components/Silo/Whitelist.tsx @@ -12,6 +12,7 @@ import { Typography, } from '@mui/material'; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; +import { ReportGmailerrorred } from '@mui/icons-material'; import { Link as RouterLink } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { useAccount } from 'wagmi'; @@ -50,6 +51,9 @@ import BeanProgressIcon from '../Common/BeanProgressIcon'; * Display a pseudo-table of Whitelisted Silo Tokens. * This table is the entry point to deposit Beans, LP, etc. */ +import { FC } from '~/types'; +import StatHorizontal from '../Common/StatHorizontal'; +import { useIsTokenDeprecated } from '~/hooks/beanstalk/useWhitelist'; const ARROW_CONTAINER_WIDTH = 20; const TOOLTIP_COMPONENT_PROPS = { @@ -71,6 +75,7 @@ const Whitelist: FC<{ /// Settings const [denomination] = useSetting('denomination'); const account = useAccount(); + const checkIfDeprecated = useIsTokenDeprecated(); /// Chain const getChainToken = useGetChainToken(); @@ -91,6 +96,7 @@ const Whitelist: FC<{ return ( + {/* Header */} + {/* Rows */} {config.whitelist.map((token) => { const deposited = farmerSilo.balances[token.address]?.deposited; const isUnripe = token === urBean || token === urBeanWeth; + const isDeprecated = checkIfDeprecated(token.address); + // Unripe data const underlyingToken = isUnripe ? unripeUnderlyingTokens[token.address] @@ -197,6 +206,33 @@ const Whitelist: FC<{ ).div(unripeTokens[token.address]?.supply || ONE_BN) : ONE_BN; + const wlSx = { + textAlign: 'left', + px: 2, + py: 1.5, + borderColor: 'divider', + borderWidth: '0.5px', + background: BeanstalkPalette.white, + '&:hover': { + borderColor: 'primary.main', + backgroundColor: 'primary.light', + }, + }; + + const depSx = { + textAlign: 'left', + px: 2, + py: 1.5, + height: '90px', + borderColor: '#d2ebfd', + borderWidth: '0.5px', + background: BeanstalkPalette.white, + '&:hover': { + borderColor: '#dae8f2', + backgroundColor: 'primary.light', + }, + }; + return (