From 3b3c051f8a00c5c4f7a51f3983757d12e86d6f34 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Fri, 10 May 2024 18:58:18 -0700 Subject: [PATCH 01/89] add mock events --- .../tests/event-mocking/Marketplace.ts | 113 +++++++++++++++++- 1 file changed, 107 insertions(+), 6 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts index 4c4783db51..d5ce61cde7 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts @@ -16,6 +16,16 @@ import { PodOrderCreated as PodOrderCreated_v2, PodOrderFilled as PodOrderFilled_v2 } from "../../generated/BIP29-PodMarketplace/Beanstalk"; +import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; +import { toStringBaseUnitBN } from "../../../ui/src/util"; + +// Default mock to include beanstalk address +// TODO: update to use the subgraph-core one after merge +const mockBeanstalkEvent = (): ethereum.Event => { + let e = changetype(newMockEvent()); + e.address = BEANSTALK; + return e; +}; /* V1 Marketplace events */ export function createPodListingCreatedEvent( @@ -27,11 +37,10 @@ export function createPodListingCreatedEvent( maxHarvestableIndex: BigInt, toWallet: Boolean ): void {} -export function createPodListingCancelledEvent(account: string, index: BigInt): void {} + export function createPodListingFilledEvent(from: string, to: string, index: BigInt, start: BigInt, amount: BigInt): void {} export function createPodOrderCreatedEvent(account: string, id: Bytes, amount: BigInt, pricePerPod: BigInt, maxPlaceInLine: BigInt): void {} export function createPodOrderFilledEvent(from: string, to: string, id: Bytes, index: BigInt, start: BigInt, amount: BigInt): void {} -export function createPodOrderCancelledEvent(account: string, id: Bytes): void {} /* V1_1 Marketplace events (on replant) */ export function createPodListingCreatedEvent_v1_1( @@ -57,7 +66,7 @@ export function createPodListingCreatedEvent_v2( mode: BigInt, pricingType: BigInt ): PodListingCreated_v2 { - let event = changetype(newMockEvent()); + let event = changetype(mockBeanstalkEvent()); event.parameters = new Array(); let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); @@ -92,7 +101,27 @@ export function createPodListingFilledEvent_v2( start: BigInt, amount: BigInt, costInBeans: BigInt -): void {} +): PodListingFilled_v2 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("from", ethereum.Value.fromAddress(Address.fromString(from))); + let param2 = new ethereum.EventParam("to", ethereum.Value.fromAddress(Address.fromString(to))); + let param3 = new ethereum.EventParam("index", ethereum.Value.fromUnsignedBigInt(index)); + let param4 = new ethereum.EventParam("start", ethereum.Value.fromUnsignedBigInt(start)); + let param5 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param6 = new ethereum.EventParam("costInBeans", ethereum.Value.fromUnsignedBigInt(costInBeans)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + event.parameters.push(param6); + + return event as PodListingFilled_v2; +} + export function createPodOrderCreatedEvent_v2( account: string, id: Bytes, @@ -102,7 +131,31 @@ export function createPodOrderCreatedEvent_v2( minFillAmount: BigInt, pricingFunction: Bytes, pricingType: BigInt -): void {} +): PodOrderCreated_v2 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); + let param2 = new ethereum.EventParam("id", ethereum.Value.fromBytes(id)); + let param3 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param4 = new ethereum.EventParam("pricePerPod", ethereum.Value.fromUnsignedBigInt(pricePerPod)); + let param5 = new ethereum.EventParam("maxPlaceInLine", ethereum.Value.fromUnsignedBigInt(maxPlaceInLine)); + let param6 = new ethereum.EventParam("minFillAmount", ethereum.Value.fromUnsignedBigInt(minFillAmount)); + let param7 = new ethereum.EventParam("pricingFunction", ethereum.Value.fromBytes(pricingFunction)); + let param8 = new ethereum.EventParam("pricingType", ethereum.Value.fromUnsignedBigInt(pricingType)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + event.parameters.push(param6); + event.parameters.push(param7); + event.parameters.push(param8); + + return event as PodOrderCreated_v2; +} + export function createPodOrderFilledEvent_v2( from: string, to: string, @@ -111,4 +164,52 @@ export function createPodOrderFilledEvent_v2( start: BigInt, amount: BigInt, costInBeans: BigInt -): void {} +): PodOrderFilled_v2 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("from", ethereum.Value.fromAddress(Address.fromString(from))); + let param2 = new ethereum.EventParam("to", ethereum.Value.fromAddress(Address.fromString(to))); + let param3 = new ethereum.EventParam("id", ethereum.Value.fromBytes(id)); + let param4 = new ethereum.EventParam("index", ethereum.Value.fromUnsignedBigInt(index)); + let param5 = new ethereum.EventParam("start", ethereum.Value.fromUnsignedBigInt(start)); + let param6 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param7 = new ethereum.EventParam("costInBeans", ethereum.Value.fromUnsignedBigInt(costInBeans)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + event.parameters.push(param6); + event.parameters.push(param7); + + return event as PodOrderFilled_v2; +} + +/* Cancellation events */ +export function createPodOrderCancelledEvent(account: string, id: Bytes): PodOrderCancelled { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); + let param2 = new ethereum.EventParam("id", ethereum.Value.fromBytes(id)); + + event.parameters.push(param1); + event.parameters.push(param2); + + return event as PodOrderCancelled; +} + +export function createPodListingCancelledEvent(account: string, index: BigInt): PodListingCancelled { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); + let param2 = new ethereum.EventParam("index", ethereum.Value.fromUnsignedBigInt(index)); + + event.parameters.push(param1); + event.parameters.push(param2); + + return event as PodListingCancelled; +} From 24f7f72094b10e7e44030d23995e045b3c313987 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Fri, 10 May 2024 20:11:07 -0700 Subject: [PATCH 02/89] more mock marketplace events --- .../tests/event-mocking/Marketplace.ts | 125 ++++++++++++++++-- 1 file changed, 117 insertions(+), 8 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts index d5ce61cde7..0eef1dd5e7 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts @@ -17,7 +17,6 @@ import { PodOrderFilled as PodOrderFilled_v2 } from "../../generated/BIP29-PodMarketplace/Beanstalk"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; -import { toStringBaseUnitBN } from "../../../ui/src/util"; // Default mock to include beanstalk address // TODO: update to use the subgraph-core one after merge @@ -27,7 +26,7 @@ const mockBeanstalkEvent = (): ethereum.Event => { return e; }; -/* V1 Marketplace events */ +/** ===== Marketplace V1 Events ===== */ export function createPodListingCreatedEvent( account: string, index: BigInt, @@ -35,12 +34,101 @@ export function createPodListingCreatedEvent( amount: BigInt, pricePerPod: BigInt, maxHarvestableIndex: BigInt, - toWallet: Boolean -): void {} + toWallet: boolean +): PodListingCreated_v1 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); + let param2 = new ethereum.EventParam("index", ethereum.Value.fromUnsignedBigInt(index)); + let param3 = new ethereum.EventParam("start", ethereum.Value.fromUnsignedBigInt(start)); + let param4 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param5 = new ethereum.EventParam("pricePerPod", ethereum.Value.fromUnsignedBigInt(pricePerPod)); + let param6 = new ethereum.EventParam("maxHarvestableIndex", ethereum.Value.fromUnsignedBigInt(maxHarvestableIndex)); + let param7 = new ethereum.EventParam("toWallet", ethereum.Value.fromBoolean(toWallet)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + event.parameters.push(param6); + event.parameters.push(param7); + + return event as PodListingCreated_v1; +} + +export function createPodListingFilledEvent(from: string, to: string, index: BigInt, start: BigInt, amount: BigInt): PodListingFilled_v1 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("from", ethereum.Value.fromAddress(Address.fromString(from))); + let param2 = new ethereum.EventParam("to", ethereum.Value.fromAddress(Address.fromString(to))); + let param3 = new ethereum.EventParam("index", ethereum.Value.fromUnsignedBigInt(index)); + let param4 = new ethereum.EventParam("start", ethereum.Value.fromUnsignedBigInt(start)); + let param5 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + + return event as PodListingFilled_v1; +} + +export function createPodOrderCreatedEvent( + account: string, + id: Bytes, + amount: BigInt, + pricePerPod: BigInt, + maxPlaceInLine: BigInt +): PodOrderCreated_v1 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); + let param2 = new ethereum.EventParam("id", ethereum.Value.fromBytes(id)); + let param3 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param4 = new ethereum.EventParam("pricePerPod", ethereum.Value.fromUnsignedBigInt(pricePerPod)); + let param5 = new ethereum.EventParam("maxPlaceInLine", ethereum.Value.fromUnsignedBigInt(maxPlaceInLine)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + + return event as PodOrderCreated_v1; +} + +export function createPodOrderFilledEvent( + from: string, + to: string, + id: Bytes, + index: BigInt, + start: BigInt, + amount: BigInt +): PodOrderFilled_v1 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); -export function createPodListingFilledEvent(from: string, to: string, index: BigInt, start: BigInt, amount: BigInt): void {} -export function createPodOrderCreatedEvent(account: string, id: Bytes, amount: BigInt, pricePerPod: BigInt, maxPlaceInLine: BigInt): void {} -export function createPodOrderFilledEvent(from: string, to: string, id: Bytes, index: BigInt, start: BigInt, amount: BigInt): void {} + let param1 = new ethereum.EventParam("from", ethereum.Value.fromAddress(Address.fromString(from))); + let param2 = new ethereum.EventParam("to", ethereum.Value.fromAddress(Address.fromString(to))); + let param3 = new ethereum.EventParam("id", ethereum.Value.fromBytes(id)); + let param4 = new ethereum.EventParam("index", ethereum.Value.fromUnsignedBigInt(index)); + let param5 = new ethereum.EventParam("start", ethereum.Value.fromUnsignedBigInt(start)); + let param6 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + event.parameters.push(param6); + + return event as PodOrderFilled_v1; +} /* V1_1 Marketplace events (on replant) */ export function createPodListingCreatedEvent_v1_1( @@ -51,7 +139,28 @@ export function createPodListingCreatedEvent_v1_1( pricePerPod: BigInt, maxHarvestableIndex: BigInt, mode: BigInt -): void {} +): PodListingCreated_v1_1 { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); + let param2 = new ethereum.EventParam("index", ethereum.Value.fromUnsignedBigInt(index)); + let param3 = new ethereum.EventParam("start", ethereum.Value.fromUnsignedBigInt(start)); + let param4 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param5 = new ethereum.EventParam("pricePerPod", ethereum.Value.fromUnsignedBigInt(pricePerPod)); + let param6 = new ethereum.EventParam("maxHarvestableIndex", ethereum.Value.fromUnsignedBigInt(maxHarvestableIndex)); + let param7 = new ethereum.EventParam("mode", ethereum.Value.fromUnsignedBigInt(mode)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + event.parameters.push(param4); + event.parameters.push(param5); + event.parameters.push(param6); + event.parameters.push(param7); + + return event as PodListingCreated_v1_1; +} /** ===== Marketplace V2 Events ===== */ export function createPodListingCreatedEvent_v2( From fd4981fedcad56522869236e7da0118c7d8380ff Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 15:27:43 -0700 Subject: [PATCH 03/89] pod listing created test --- .../src/MarketplaceHandler.ts | 2 +- .../tests/Marketplace.test.ts | 101 ++++++++++++++---- .../tests/PlotTransfer.test.ts | 12 +-- projects/subgraph-core/tests/Values.ts | 11 ++ 4 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 projects/subgraph-core/tests/Values.ts diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 860c141b01..7e037b9c23 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -76,7 +76,7 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { listing.pricePerPod = event.params.pricePerPod; // Amounts [Relative to Original] - listing.originalIndex = event.params.index; + listing.originalIndex = event.params.index; // TODO: I think this should be +start listing.originalAmount = event.params.amount; // Amounts [Relative to Child] diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index d6cb2d5491..cfbed5b268 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,32 +1,98 @@ import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; -import { afterEach, assert, beforeAll, clearStore, describe, test } from "matchstick-as/assembly/index"; +import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; import { handleSow } from "../src/FieldHandler"; import { handlePodListingCreated_v2 } from "../src/MarketplaceHandler"; -import { handleAddDeposit, handleRemoveDeposit } from "../src/SiloHandler"; import { createSowEvent } from "./event-mocking/Field"; import { createPodListingCreatedEvent_v2 } from "./event-mocking/Marketplace"; -import { createAddDepositEvent, createRemoveDepositEvent } from "./event-mocking/Silo"; +import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; +import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { PodListingCreated as PodListingCreated_v2 } from "../generated/BIP29-PodMarketplace/Beanstalk"; let account = "0x1234567890abcdef1234567890abcdef12345678".toLowerCase(); -let listingIndex = BigInt.fromString("1000000000000"); +let listingIndex = podlineMil_BI(1); let pricingFunction = Bytes.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" ); -describe("Mocked Events", () => { - beforeAll(() => { +let sowedBeans = beans_BI(5000); +// 3x temp +let sowedPods = sowedBeans.times(BigInt.fromString("3")); + +const assertListingCreated_v2 = (event: PodListingCreated_v2): void => { + let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.entityCount("PodListing", 1); + assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "farmer", event.params.account.toHexString()); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID, "originalIndex", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "originalAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "index", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "start", event.params.start.toString()); + assert.fieldEquals("PodListing", listingID, "amount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "pricePerPod", event.params.pricePerPod.toString()); + assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", event.params.maxHarvestableIndex.toString()); + assert.fieldEquals("PodListing", listingID, "minFillAmount", event.params.minFillAmount.toString()); + assert.fieldEquals("PodListing", listingID, "pricingFunction", event.params.pricingFunction.toHexString()); + assert.fieldEquals("PodListing", listingID, "mode", event.params.mode.toString()); + assert.fieldEquals("PodListing", listingID, "pricingType", event.params.pricingType.toString()); +}; + +describe("Marketplace", () => { + beforeEach(() => { // Create a plot with the listing index - let event = createSowEvent(account, listingIndex, BigInt.fromString("1000000000000"), BigInt.fromString("2000000000000")); + let event = createSowEvent(account, listingIndex, sowedBeans, sowedPods); handleSow(event); }); + afterEach(() => { + clearStore(); + }); + + // TODO tests: + // create listing - full + // create listing - partial + // cancel listing + // create order + // cancel order + // fill listing - full + // fill listing - partial + // fill order - full + // fill order - partial + + describe("Marketplace v1", () => { + test("Create a pod listing - full plot", () => { + // const + }); + + test("Create a pod listing - partial plot", () => {}); + }); + describe("Marketplace v2", () => { - test("Create a pod listing", () => { - let event = createPodListingCreatedEvent_v2( + test("Create a pod listing - full plot", () => { + const event = createPodListingCreatedEvent_v2( account, listingIndex, - BigInt.fromString("100000000000"), - BigInt.fromString("500000000000"), + ZERO_BI, + sowedBeans, + BigInt.fromString("550000"), + BigInt.fromString("200000000000000"), + BigInt.fromString("5000000"), + pricingFunction, + BigInt.fromI32(1), + BigInt.fromI32(0) + ); + handlePodListingCreated_v2(event); + assertListingCreated_v2(event); + }); + + test("Create a pod listing - partial plot", () => { + const start = beans_BI(500); + const event = createPodListingCreatedEvent_v2( + account, + listingIndex, + start, + sowedBeans.minus(start), BigInt.fromString("250000"), BigInt.fromString("300000000000000"), BigInt.fromString("10000000"), @@ -34,19 +100,8 @@ describe("Mocked Events", () => { BigInt.fromI32(0), BigInt.fromI32(1) ); - handlePodListingCreated_v2(event); - - let listingID = account + "-" + listingIndex.toString(); - - assert.fieldEquals("PodListing", listingID, "plot", listingIndex.toString()); - assert.fieldEquals("PodListing", listingID, "farmer", account); - assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); - assert.fieldEquals("PodListing", listingID, "originalIndex", listingIndex.toString()); - assert.fieldEquals("PodListing", listingID, "index", listingIndex.toString()); - assert.fieldEquals("PodListing", listingID, "start", "100000000000"); - assert.fieldEquals("PodListing", listingID, "start", "100000000000"); - assert.fieldEquals("PodListing", listingID, "pricingFunction", pricingFunction.toHexString()); + assertListingCreated_v2(event); }); }); }); diff --git a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts index b500e56636..c437c9ef6b 100644 --- a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts +++ b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts @@ -13,14 +13,11 @@ import { handleSow, handlePlotTransfer } from "../src/FieldHandler"; import { handleIncentive } from "../src/SeasonHandler"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { beans_BI as beans, podlineMil_BI as mil } from "../../subgraph-core/tests/Values"; const ANVIL_ADDR_1 = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const ANVIL_ADDR_2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); -// These functions may exist elsewhere but I dont know of them -const beans = (b: number): BigInt => BigInt.fromI32(b).times(BigInt.fromI32(10).pow(6)); -const mil = (m: number): BigInt => BigInt.fromI32(m).times(BigInt.fromI32(10).pow(12)); - // 2 plots: each sow 500 for 7500 at 10m and 15m in line. const plot1Start = mil(10); const plot2Start = mil(15); @@ -79,9 +76,9 @@ const assertFieldHas = (field: string, unharvestable: BigInt, harvestable: BigIn }; const setHarvestable = (harvestableIndex: BigInt): BigInt => { - createMockedFunction(BEANSTALK, "harvestableIndex", "harvestableIndex():(uint256)") - // @ts-expect-error:2322 - .returns([ethereum.Value.fromUnsignedBigInt(harvestableIndex)]); + createMockedFunction(BEANSTALK, "harvestableIndex", "harvestableIndex():(uint256)").returns([ + ethereum.Value.fromUnsignedBigInt(harvestableIndex) + ]); // Incentivization event triggers update of harvestable amount of each plot handleIncentive(createIncentivizationEvent(ANVIL_ADDR_1, BigInt.fromI32(123456))); @@ -106,7 +103,6 @@ describe("Field: Plot Transfer", () => { }); afterEach(() => { - log.debug("clearing the store", []); clearStore(); }); diff --git a/projects/subgraph-core/tests/Values.ts b/projects/subgraph-core/tests/Values.ts new file mode 100644 index 0000000000..6bc58bd935 --- /dev/null +++ b/projects/subgraph-core/tests/Values.ts @@ -0,0 +1,11 @@ +import { BigDecimal, BigInt } from "@graphprotocol/graph-ts"; + +/* Shorthand functions for constructing some common value types */ + +export function beans_BI(b: number): BigInt { + return BigInt.fromI32(b).times(BigInt.fromI32(10).pow(6)); +} + +export function podlineMil_BI(m: number): BigInt { + return BigInt.fromI32(m).times(BigInt.fromI32(10).pow(12)); +} From 23911e5619daca41b8d742bbdd9e0acda1fb22a7 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 16:12:47 -0700 Subject: [PATCH 04/89] assert market state and index fix --- .../src/MarketplaceHandler.ts | 18 ++- .../tests/Marketplace.test.ts | 136 +++++++++++++----- 2 files changed, 111 insertions(+), 43 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 7e037b9c23..6dcc3b3dd1 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -121,7 +121,7 @@ export function handlePodListingCancelled(event: PodListingCancelled): void { updateMarketListingBalances(event.address, event.params.index, ZERO_BI, ZERO_BI, ZERO_BI, listing.remainingAmount, event.block.timestamp); - listing.status = "CANCELLED"; + listing.status = "CANCELLED"; // TODO: consider whether this should be CANCELLED_PARTIAL similarly to pod orders listing.cancelledAmount = listing.remainingAmount; listing.remainingAmount = ZERO_BI; listing.updatedAt = event.block.timestamp; @@ -748,14 +748,16 @@ function updateMarketListingBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); + let marketIndexes = market.listingIndexes; + // Update Listing indexes if (newPodAmount > ZERO_BI) { - market.listingIndexes.push(plotIndex); - market.listingIndexes.sort(); + marketIndexes.push(plotIndex); + marketIndexes.sort(); } if (cancelledPodAmount > ZERO_BI || filledPodAmount > ZERO_BI) { let listingIndex = market.listingIndexes.indexOf(plotIndex); - market.listingIndexes.splice(listingIndex, 1); + marketIndexes.splice(listingIndex, 1); } market.listedPods = market.listedPods.plus(newPodAmount); market.availableListedPods = market.availableListedPods.plus(newPodAmount).minus(cancelledPodAmount).minus(filledPodAmount); @@ -763,6 +765,7 @@ function updateMarketListingBalances( market.filledListedPods = market.filledListedPods.plus(filledPodAmount); market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); + market.listingIndexes = marketIndexes; market.save(); marketHourly.season = market.season; @@ -821,18 +824,21 @@ function updateMarketOrderBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); + let marketOrders = market.orders; + if (newPodAmount > ZERO_BI) { - market.orders.push(orderID); + marketOrders.push(orderID); } if (cancelledPodAmount > ZERO_BI) { let orderIndex = market.orders.indexOf(orderID); - market.listingIndexes.splice(orderIndex, 1); + marketOrders.splice(orderIndex, 1); } market.orderedPods = market.orderedPods.plus(newPodAmount); market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); market.cancelledOrderedPods = market.cancelledOrderedPods.plus(cancelledPodAmount); + market.orders = marketOrders; market.save(); marketHourly.deltaOrderedPods = marketHourly.deltaOrderedPods.plus(newPodAmount); diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index cfbed5b268..247477a6d5 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,12 +1,14 @@ import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; import { handleSow } from "../src/FieldHandler"; -import { handlePodListingCreated_v2 } from "../src/MarketplaceHandler"; +import { handlePodListingCancelled, handlePodListingCreated_v2 } from "../src/MarketplaceHandler"; import { createSowEvent } from "./event-mocking/Field"; -import { createPodListingCreatedEvent_v2 } from "./event-mocking/Marketplace"; +import { createPodListingCancelledEvent, createPodListingCreatedEvent_v2 } from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; -import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { PodListingCreated as PodListingCreated_v2 } from "../generated/BIP29-PodMarketplace/Beanstalk"; +import { BEANSTALK } from "../../subgraph-core/utils/Constants"; +import { Sow } from "../generated/Field/Beanstalk"; let account = "0x1234567890abcdef1234567890abcdef12345678".toLowerCase(); let listingIndex = podlineMil_BI(1); @@ -18,9 +20,31 @@ let sowedBeans = beans_BI(5000); // 3x temp let sowedPods = sowedBeans.times(BigInt.fromString("3")); +const sow = (account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow => { + const event = createSowEvent(account, index, beans, pods); + handleSow(event); + return event; +}; + +const createListing_v2 = (account: string, index: BigInt, plotTotalPods: BigInt, start: BigInt): PodListingCreated_v2 => { + const event = createPodListingCreatedEvent_v2( + account, + index, + start, + plotTotalPods.minus(start), + BigInt.fromString("250000"), + BigInt.fromString("300000000000000"), + BigInt.fromString("10000000"), + pricingFunction, + BigInt.fromI32(0), + BigInt.fromI32(1) + ); + handlePodListingCreated_v2(event); + return event; +}; + const assertListingCreated_v2 = (event: PodListingCreated_v2): void => { let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); - assert.entityCount("PodListing", 1); assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); assert.fieldEquals("PodListing", listingID, "farmer", event.params.account.toHexString()); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -38,11 +62,28 @@ const assertListingCreated_v2 = (event: PodListingCreated_v2): void => { assert.fieldEquals("PodListing", listingID, "pricingType", event.params.pricingType.toString()); }; +const assertMarketState = ( + address: string, + listings: BigInt[], + listedPods: BigInt, + availableListedPods: BigInt, + cancelledListedPods: BigInt, + filledListedPods: BigInt, + podVolume: BigInt, + beanVolume: BigInt +): void => { + assert.fieldEquals("PodMarketplace", address, "listingIndexes", "[" + listings.join(", ") + "]"); + assert.fieldEquals("PodMarketplace", address, "listedPods", listedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "availableListedPods", availableListedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "cancelledListedPods", cancelledListedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "filledListedPods", filledListedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); + assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); +}; + describe("Marketplace", () => { beforeEach(() => { - // Create a plot with the listing index - let event = createSowEvent(account, listingIndex, sowedBeans, sowedPods); - handleSow(event); + sow(account, listingIndex, sowedBeans, sowedPods); }); afterEach(() => { @@ -50,11 +91,11 @@ describe("Marketplace", () => { }); // TODO tests: - // create listing - full - // create listing - partial - // cancel listing + // cancel listing - full + // cancel listing - partial // create order - // cancel order + // cancel order - full + // cancel order - partial // fill listing - full // fill listing - partial // fill order - full @@ -70,38 +111,59 @@ describe("Marketplace", () => { describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { - const event = createPodListingCreatedEvent_v2( - account, - listingIndex, + const event = createListing_v2(account, listingIndex, sowedPods, ZERO_BI); + assertListingCreated_v2(event); + assertMarketState(BEANSTALK.toHexString(), [listingIndex], sowedPods, sowedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + + // Create a second listing to assert the market state again + const listing2Index = listingIndex.times(BI_10); + sow(account, listing2Index, sowedBeans, sowedPods); + const event2 = createListing_v2(account, listing2Index, sowedPods, ZERO_BI); + assertListingCreated_v2(event2); + assertMarketState( + BEANSTALK.toHexString(), + [listingIndex, listing2Index], + sowedPods.times(BigInt.fromI32(2)), + sowedPods.times(BigInt.fromI32(2)), + ZERO_BI, + ZERO_BI, ZERO_BI, - sowedBeans, - BigInt.fromString("550000"), - BigInt.fromString("200000000000000"), - BigInt.fromString("5000000"), - pricingFunction, - BigInt.fromI32(1), - BigInt.fromI32(0) + ZERO_BI ); - handlePodListingCreated_v2(event); - assertListingCreated_v2(event); }); test("Create a pod listing - partial plot", () => { - const start = beans_BI(500); - const event = createPodListingCreatedEvent_v2( - account, - listingIndex, - start, - sowedBeans.minus(start), - BigInt.fromString("250000"), - BigInt.fromString("300000000000000"), - BigInt.fromString("10000000"), - pricingFunction, - BigInt.fromI32(0), - BigInt.fromI32(1) - ); - handlePodListingCreated_v2(event); + const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); + const listedPods = sowedPods.minus(beans_BI(500)); assertListingCreated_v2(event); + assertMarketState(BEANSTALK.toHexString(), [listingIndex], listedPods, listedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + }); + + describe("Tests requiring listing", () => { + beforeEach(() => { + const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); + }); + + test("Fill listing - full", () => {}); + + test("Fill listing - partial", () => {}); + + // Cancellation isnt unique to pod market v2, consider including in the v1 section + test("Cancel pod listing - full", () => { + const event = createPodListingCancelledEvent(account, listingIndex); + handlePodListingCancelled(event); + + const listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "CANCELLED"); + assert.fieldEquals("PodListing", listingID, "cancelledAmount", sowedPods.minus(beans_BI(500)).toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + }); + + test("Cancel pod listing - partial", () => { + // TODO: some sold already + const event = createPodListingCancelledEvent(account, listingIndex); + handlePodListingCancelled(event); + }); }); }); }); From 966d6a3d31d36b82f09788fbd3be54be12992e2b Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 16:30:56 -0700 Subject: [PATCH 05/89] fix listing cancellation amount --- projects/subgraph-beanstalk/src/MarketplaceHandler.ts | 2 +- projects/subgraph-beanstalk/tests/Marketplace.test.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 6dcc3b3dd1..d9241d4581 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -119,7 +119,7 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { export function handlePodListingCancelled(event: PodListingCancelled): void { let listing = loadPodListing(event.params.account, event.params.index); - updateMarketListingBalances(event.address, event.params.index, ZERO_BI, ZERO_BI, ZERO_BI, listing.remainingAmount, event.block.timestamp); + updateMarketListingBalances(event.address, event.params.index, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); listing.status = "CANCELLED"; // TODO: consider whether this should be CANCELLED_PARTIAL similarly to pod orders listing.cancelledAmount = listing.remainingAmount; diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 247477a6d5..9f5ed1914b 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -153,10 +153,13 @@ describe("Marketplace", () => { const event = createPodListingCancelledEvent(account, listingIndex); handlePodListingCancelled(event); + const cancelledAmount = sowedPods.minus(beans_BI(500)); const listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", listingID, "status", "CANCELLED"); - assert.fieldEquals("PodListing", listingID, "cancelledAmount", sowedPods.minus(beans_BI(500)).toString()); + assert.fieldEquals("PodListing", listingID, "cancelledAmount", cancelledAmount.toString()); assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + + assertMarketState(BEANSTALK.toHexString(), [], cancelledAmount, ZERO_BI, cancelledAmount, ZERO_BI, ZERO_BI, ZERO_BI); }); test("Cancel pod listing - partial", () => { From f43cee3c3140c84f1a7fb561d42e4cc32b35d795 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 17:32:16 -0700 Subject: [PATCH 06/89] pod fill tests --- .../src/MarketplaceHandler.ts | 10 +- .../tests/Marketplace.test.ts | 115 +++++++++++++++--- 2 files changed, 107 insertions(+), 18 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index d9241d4581..ad7c75ee84 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -177,7 +177,10 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { remainingListing.mode = listing.mode; remainingListing.creationHash = event.transaction.hash.toHexString(); remainingListing.save(); - market.listingIndexes.push(remainingListing.index); + + const marketListings = market.listingIndexes; + marketListings.push(remainingListing.index); + market.listingIndexes = marketListings; market.save(); } @@ -572,7 +575,10 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { remainingListing.creationHash = event.transaction.hash.toHexString(); remainingListing.minFillAmount = listing.minFillAmount; remainingListing.save(); - market.listingIndexes.push(remainingListing.index); + + const marketListings = market.listingIndexes; + marketListings.push(remainingListing.index); + market.listingIndexes = marketListings; market.save(); } diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 9f5ed1914b..28156458b4 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,16 +1,24 @@ import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; import { handleSow } from "../src/FieldHandler"; -import { handlePodListingCancelled, handlePodListingCreated_v2 } from "../src/MarketplaceHandler"; +import { handlePodListingCancelled, handlePodListingCreated_v2, handlePodListingFilled_v2 } from "../src/MarketplaceHandler"; import { createSowEvent } from "./event-mocking/Field"; -import { createPodListingCancelledEvent, createPodListingCreatedEvent_v2 } from "./event-mocking/Marketplace"; +import { + createPodListingCancelledEvent, + createPodListingCreatedEvent_v2, + createPodListingFilledEvent_v2 +} from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; -import { PodListingCreated as PodListingCreated_v2 } from "../generated/BIP29-PodMarketplace/Beanstalk"; +import { + PodListingCreated as PodListingCreated_v2, + PodListingFilled as PodListingFilled_v2 +} from "../generated/BIP29-PodMarketplace/Beanstalk"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; import { Sow } from "../generated/Field/Beanstalk"; -let account = "0x1234567890abcdef1234567890abcdef12345678".toLowerCase(); +const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); +const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); let listingIndex = podlineMil_BI(1); let pricingFunction = Bytes.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" @@ -43,6 +51,23 @@ const createListing_v2 = (account: string, index: BigInt, plotTotalPods: BigInt, return event; }; +const fillListing_v2 = (listingIndex: BigInt, listingStart: BigInt, podAmount: BigInt, costInBeans: BigInt): PodListingFilled_v2 => { + const event = createPodListingFilledEvent_v2(account, account2, listingIndex, listingStart, podAmount, costInBeans); + handlePodListingFilled_v2(event); + + // Assert PodFill + const podFillId = BEANSTALK.toHexString() + "-" + listingIndex.toString() + "-" + event.transaction.hash.toHexString(); + assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + listingIndex.toString()); + assert.fieldEquals("PodFill", podFillId, "from", account); + assert.fieldEquals("PodFill", podFillId, "to", account2); + assert.fieldEquals("PodFill", podFillId, "amount", podAmount.toString()); + assert.fieldEquals("PodFill", podFillId, "index", listingIndex.toString()); + assert.fieldEquals("PodFill", podFillId, "start", listingStart.toString()); + assert.fieldEquals("PodFill", podFillId, "costInBeans", costInBeans.toString()); + + return event; +}; + const assertListingCreated_v2 = (event: PodListingCreated_v2): void => { let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); @@ -91,23 +116,18 @@ describe("Marketplace", () => { }); // TODO tests: - // cancel listing - full // cancel listing - partial // create order // cancel order - full // cancel order - partial - // fill listing - full - // fill listing - partial // fill order - full // fill order - partial + // fill order with pods that are also listed - describe("Marketplace v1", () => { - test("Create a pod listing - full plot", () => { - // const - }); - - test("Create a pod listing - partial plot", () => {}); - }); + // describe("Marketplace v1", () => { + // test("Create a pod listing - full plot", () => {}); + // test("Create a pod listing - partial plot", () => {}); + // }); describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { @@ -144,9 +164,72 @@ describe("Marketplace", () => { const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); }); - test("Fill listing - full", () => {}); + test("Fill listing - full", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const filledBeans = beans_BI(7000); + const event = fillListing_v2(listingIndex, listingStart, listedPods, filledBeans); + + let listingID = event.params.from.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "FILLED"); + assert.fieldEquals("PodListing", listingID, "filledAmount", listedPods.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", listingID, "filled", listedPods.toString()); + assert.entityCount("PodListing", 1); - test("Fill listing - partial", () => {}); + assertMarketState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, listedPods, filledBeans); + }); + + test("Fill listing - partial, then full", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = beans_BI(2000); + const event = fillListing_v2(listingIndex, listingStart, filledPods, filledBeans); + + const remaining = listedPods.minus(filledPods); + const listingID = event.params.from.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "FILLED_PARTIAL"); + assert.fieldEquals("PodListing", listingID, "filledAmount", filledPods.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", remaining.toString()); + assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); + assert.entityCount("PodListing", 2); + + const newListingIndex = event.params.index.plus(listingStart).plus(filledPods); + const derivedListingID = event.params.from.toHexString() + "-" + newListingIndex.toString(); + assert.fieldEquals("PodListing", derivedListingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", derivedListingID, "filledAmount", "0"); + assert.fieldEquals("PodListing", derivedListingID, "remainingAmount", remaining.toString()); + assert.fieldEquals("PodListing", derivedListingID, "originalIndex", listingIndex.toString()); + assert.fieldEquals("PodListing", derivedListingID, "originalAmount", listedPods.toString()); + assert.fieldEquals("PodListing", derivedListingID, "filled", filledPods.toString()); + + assertMarketState(BEANSTALK.toHexString(), [newListingIndex], listedPods, remaining, ZERO_BI, filledPods, filledPods, filledBeans); + + // Now sell the rest + const newFilledBeans = beans_BI(4000); + const event2 = fillListing_v2(newListingIndex, ZERO_BI, remaining, newFilledBeans); + + assert.entityCount("PodListing", 2); + assert.fieldEquals("PodListing", derivedListingID, "status", "FILLED"); + assert.fieldEquals("PodListing", derivedListingID, "filledAmount", remaining.toString()); + assert.fieldEquals("PodListing", derivedListingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", derivedListingID, "filled", listedPods.toString()); + // Original should be unchanged + assert.fieldEquals("PodListing", listingID, "status", "FILLED_PARTIAL"); + assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); + + assertMarketState( + BEANSTALK.toHexString(), + [], + listedPods, + ZERO_BI, + ZERO_BI, + listedPods, + listedPods, + filledBeans.plus(newFilledBeans) + ); + }); // Cancellation isnt unique to pod market v2, consider including in the v1 section test("Cancel pod listing - full", () => { From 492cdee082f9d351d0a9d6fb596c36be5e5d8c3a Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 17:35:23 -0700 Subject: [PATCH 07/89] pod listing cancel test --- .../tests/Marketplace.test.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 28156458b4..7c3aa69fab 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -246,9 +246,24 @@ describe("Marketplace", () => { }); test("Cancel pod listing - partial", () => { - // TODO: some sold already - const event = createPodListingCancelledEvent(account, listingIndex); + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = beans_BI(2000); + const fillEvent = fillListing_v2(listingIndex, listingStart, filledPods, filledBeans); + + const remaining = listedPods.minus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + + const event = createPodListingCancelledEvent(account, newListingIndex); handlePodListingCancelled(event); + + const newListingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", newListingID, "status", "CANCELLED"); + assert.fieldEquals("PodListing", newListingID, "cancelledAmount", remaining.toString()); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", "0"); + + assertMarketState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, remaining, filledPods, filledPods, filledBeans); }); }); }); From 6a27d5cf5242a95284789aeff4830b2e322bc1b0 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 17:38:05 -0700 Subject: [PATCH 08/89] set partial cancellation status --- projects/subgraph-beanstalk/src/MarketplaceHandler.ts | 2 +- projects/subgraph-beanstalk/tests/Marketplace.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index ad7c75ee84..a0d806a4b7 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -121,7 +121,7 @@ export function handlePodListingCancelled(event: PodListingCancelled): void { updateMarketListingBalances(event.address, event.params.index, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); - listing.status = "CANCELLED"; // TODO: consider whether this should be CANCELLED_PARTIAL similarly to pod orders + listing.status = listing.filled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; listing.cancelledAmount = listing.remainingAmount; listing.remainingAmount = ZERO_BI; listing.updatedAt = event.block.timestamp; diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 7c3aa69fab..f14c28fd46 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -259,7 +259,7 @@ describe("Marketplace", () => { handlePodListingCancelled(event); const newListingID = event.params.account.toHexString() + "-" + event.params.index.toString(); - assert.fieldEquals("PodListing", newListingID, "status", "CANCELLED"); + assert.fieldEquals("PodListing", newListingID, "status", "CANCELLED_PARTIAL"); assert.fieldEquals("PodListing", newListingID, "cancelledAmount", remaining.toString()); assert.fieldEquals("PodListing", newListingID, "remainingAmount", "0"); From bffdde53ef15630abae71fcf1894953d0a16f80b Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 18:34:18 -0700 Subject: [PATCH 09/89] create order test --- .../src/MarketplaceHandler.ts | 3 +- .../tests/Marketplace.test.ts | 155 +++++++++++++----- .../tests/event-mocking/Marketplace.ts | 4 +- 3 files changed, 120 insertions(+), 42 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index a0d806a4b7..5e43ca8dad 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -825,6 +825,7 @@ function updateMarketOrderBalances( timestamp: BigInt ): void { // Need to account for v2 bean amounts + // TODO: remove newPodAmount/orderedPods entirely let market = loadPodMarketplace(marketAddress); let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); @@ -832,7 +833,7 @@ function updateMarketOrderBalances( let marketOrders = market.orders; - if (newPodAmount > ZERO_BI) { + if (newBeanAmount > ZERO_BI) { marketOrders.push(orderID); } if (cancelledPodAmount > ZERO_BI) { diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index f14c28fd46..90ed78c4e1 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,32 +1,43 @@ import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; import { handleSow } from "../src/FieldHandler"; -import { handlePodListingCancelled, handlePodListingCreated_v2, handlePodListingFilled_v2 } from "../src/MarketplaceHandler"; +import { + handlePodListingCancelled, + handlePodListingCreated_v2, + handlePodListingFilled_v2, + handlePodOrderCreated_v2 +} from "../src/MarketplaceHandler"; import { createSowEvent } from "./event-mocking/Field"; import { createPodListingCancelledEvent, createPodListingCreatedEvent_v2, - createPodListingFilledEvent_v2 + createPodListingFilledEvent_v2, + createPodOrderCreatedEvent_v2 } from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { PodListingCreated as PodListingCreated_v2, - PodListingFilled as PodListingFilled_v2 + PodListingFilled as PodListingFilled_v2, + PodOrderCreated as PodOrderCreated_v2, + PodOrderFilled as PodOrderFilled_v2 } from "../generated/BIP29-PodMarketplace/Beanstalk"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; import { Sow } from "../generated/Field/Beanstalk"; const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); -let listingIndex = podlineMil_BI(1); -let pricingFunction = Bytes.fromHexString( +const pricingFunction = Bytes.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" ); -let sowedBeans = beans_BI(5000); -// 3x temp -let sowedPods = sowedBeans.times(BigInt.fromString("3")); +const listingIndex = podlineMil_BI(1); +const maxHarvestableIndex = podlineMil_BI(100); +const sowedBeans = beans_BI(5000); +const sowedPods = sowedBeans.times(BigInt.fromString("3")); + +const orderBeans = beans_BI(80000); +const orderPricePerPod = BigInt.fromString("500000"); // 0.5 beans const sow = (account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow => { const event = createSowEvent(account, index, beans, pods); @@ -34,23 +45,6 @@ const sow = (account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow = return event; }; -const createListing_v2 = (account: string, index: BigInt, plotTotalPods: BigInt, start: BigInt): PodListingCreated_v2 => { - const event = createPodListingCreatedEvent_v2( - account, - index, - start, - plotTotalPods.minus(start), - BigInt.fromString("250000"), - BigInt.fromString("300000000000000"), - BigInt.fromString("10000000"), - pricingFunction, - BigInt.fromI32(0), - BigInt.fromI32(1) - ); - handlePodListingCreated_v2(event); - return event; -}; - const fillListing_v2 = (listingIndex: BigInt, listingStart: BigInt, podAmount: BigInt, costInBeans: BigInt): PodListingFilled_v2 => { const event = createPodListingFilledEvent_v2(account, account2, listingIndex, listingStart, podAmount, costInBeans); handlePodListingFilled_v2(event); @@ -87,7 +81,47 @@ const assertListingCreated_v2 = (event: PodListingCreated_v2): void => { assert.fieldEquals("PodListing", listingID, "pricingType", event.params.pricingType.toString()); }; -const assertMarketState = ( +const assertOrderCreated_v2 = (event: PodOrderCreated_v2): void => { + let orderID = event.params.id.toHexString(); + assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); + assert.fieldEquals("PodOrder", orderID, "farmer", account); + assert.fieldEquals("PodOrder", orderID, "status", "ACTIVE"); + assert.fieldEquals("PodOrder", orderID, "beanAmount", event.params.amount.toString()); + assert.fieldEquals("PodOrder", orderID, "beanAmountFilled", "0"); + assert.fieldEquals("PodOrder", orderID, "minFillAmount", event.params.minFillAmount.toString()); + assert.fieldEquals("PodOrder", orderID, "maxPlaceInLine", event.params.maxPlaceInLine.toString()); + assert.fieldEquals("PodOrder", orderID, "pricePerPod", event.params.pricePerPod.toString()); + assert.fieldEquals("PodOrder", orderID, "pricingFunction", event.params.pricingFunction.toHexString()); + assert.fieldEquals("PodOrder", orderID, "pricingType", event.params.priceType.toString()); +}; + +const createListing_v2 = (account: string, index: BigInt, plotTotalPods: BigInt, start: BigInt): PodListingCreated_v2 => { + const event = createPodListingCreatedEvent_v2( + account, + index, + start, + plotTotalPods.minus(start), + BigInt.fromString("250000"), + maxHarvestableIndex, + BigInt.fromString("10000000"), + pricingFunction, + BigInt.fromI32(0), + BigInt.fromI32(1) + ); + handlePodListingCreated_v2(event); + assertListingCreated_v2(event); + return event; +}; + +const createOrder_v2 = (beans: BigInt, pricePerPod: BigInt): PodOrderCreated_v2 => { + const id = Bytes.fromByteArray(Bytes.fromBigInt(beans.plus(pricePerPod))); + const event = createPodOrderCreatedEvent_v2(account, id, beans, pricePerPod, maxHarvestableIndex, ONE_BI, pricingFunction, ZERO_BI); + handlePodOrderCreated_v2(event); + assertOrderCreated_v2(event); + return event; +}; + +const assertMarketListingsState = ( address: string, listings: BigInt[], listedPods: BigInt, @@ -106,6 +140,26 @@ const assertMarketState = ( assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); }; +const assertMarketOrdersState = ( + address: string, + orders: string[], + orderBeans: BigInt, + filledOrderBeans: BigInt, + filledOrderedPods: BigInt, + cancelledOrderBeans: BigInt, + podVolume: BigInt, + beanVolume: BigInt +): void => { + assert.fieldEquals("PodMarketplace", address, "orders", "[" + orders.join(", ") + "]"); + // TODO: re-enable these once implemented + // assert.fieldEquals("PodMarketplace", address, "orderBeans", orderBeans.toString()); + // assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); + // assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); + assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); +}; + describe("Marketplace", () => { beforeEach(() => { sow(account, listingIndex, sowedBeans, sowedPods); @@ -116,13 +170,15 @@ describe("Marketplace", () => { }); // TODO tests: - // cancel listing - partial - // create order // cancel order - full // cancel order - partial // fill order - full // fill order - partial // fill order with pods that are also listed + // listing expires due to podline advancing + // order expires due to podline advancing + // re-list pods (historical listing) + // re-order pods (historical order) // describe("Marketplace v1", () => { // test("Create a pod listing - full plot", () => {}); @@ -132,15 +188,13 @@ describe("Marketplace", () => { describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { const event = createListing_v2(account, listingIndex, sowedPods, ZERO_BI); - assertListingCreated_v2(event); - assertMarketState(BEANSTALK.toHexString(), [listingIndex], sowedPods, sowedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], sowedPods, sowedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); // Create a second listing to assert the market state again const listing2Index = listingIndex.times(BI_10); sow(account, listing2Index, sowedBeans, sowedPods); const event2 = createListing_v2(account, listing2Index, sowedPods, ZERO_BI); - assertListingCreated_v2(event2); - assertMarketState( + assertMarketListingsState( BEANSTALK.toHexString(), [listingIndex, listing2Index], sowedPods.times(BigInt.fromI32(2)), @@ -155,8 +209,22 @@ describe("Marketplace", () => { test("Create a pod listing - partial plot", () => { const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); const listedPods = sowedPods.minus(beans_BI(500)); - assertListingCreated_v2(event); - assertMarketState(BEANSTALK.toHexString(), [listingIndex], listedPods, listedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], listedPods, listedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + }); + + test("Create a pod order", () => { + const event = createOrder_v2(orderBeans, orderPricePerPod); + assertMarketListingsState(BEANSTALK.toHexString(), [], ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketOrdersState( + BEANSTALK.toHexString(), + [event.params.id.toHexString()], + orderBeans, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); }); describe("Tests requiring listing", () => { @@ -177,7 +245,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "filled", listedPods.toString()); assert.entityCount("PodListing", 1); - assertMarketState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, listedPods, filledBeans); + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, listedPods, filledBeans); }); test("Fill listing - partial, then full", () => { @@ -204,7 +272,16 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", derivedListingID, "originalAmount", listedPods.toString()); assert.fieldEquals("PodListing", derivedListingID, "filled", filledPods.toString()); - assertMarketState(BEANSTALK.toHexString(), [newListingIndex], listedPods, remaining, ZERO_BI, filledPods, filledPods, filledBeans); + assertMarketListingsState( + BEANSTALK.toHexString(), + [newListingIndex], + listedPods, + remaining, + ZERO_BI, + filledPods, + filledPods, + filledBeans + ); // Now sell the rest const newFilledBeans = beans_BI(4000); @@ -219,7 +296,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "status", "FILLED_PARTIAL"); assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); - assertMarketState( + assertMarketListingsState( BEANSTALK.toHexString(), [], listedPods, @@ -242,7 +319,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "cancelledAmount", cancelledAmount.toString()); assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); - assertMarketState(BEANSTALK.toHexString(), [], cancelledAmount, ZERO_BI, cancelledAmount, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketListingsState(BEANSTALK.toHexString(), [], cancelledAmount, ZERO_BI, cancelledAmount, ZERO_BI, ZERO_BI, ZERO_BI); }); test("Cancel pod listing - partial", () => { @@ -263,7 +340,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", newListingID, "cancelledAmount", remaining.toString()); assert.fieldEquals("PodListing", newListingID, "remainingAmount", "0"); - assertMarketState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, remaining, filledPods, filledPods, filledBeans); + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, remaining, filledPods, filledPods, filledBeans); }); }); }); diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts index 0eef1dd5e7..70d5c77c0a 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts @@ -234,7 +234,7 @@ export function createPodListingFilledEvent_v2( export function createPodOrderCreatedEvent_v2( account: string, id: Bytes, - amount: BigInt, + beanAmount: BigInt, pricePerPod: BigInt, maxPlaceInLine: BigInt, minFillAmount: BigInt, @@ -246,7 +246,7 @@ export function createPodOrderCreatedEvent_v2( let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); let param2 = new ethereum.EventParam("id", ethereum.Value.fromBytes(id)); - let param3 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param3 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(beanAmount)); let param4 = new ethereum.EventParam("pricePerPod", ethereum.Value.fromUnsignedBigInt(pricePerPod)); let param5 = new ethereum.EventParam("maxPlaceInLine", ethereum.Value.fromUnsignedBigInt(maxPlaceInLine)); let param6 = new ethereum.EventParam("minFillAmount", ethereum.Value.fromUnsignedBigInt(minFillAmount)); From dc2be1b338b37264716f64478328944c289f4553 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 19:15:32 -0700 Subject: [PATCH 10/89] Fill order test --- .../tests/Marketplace.test.ts | 88 +++++++++++++++---- 1 file changed, 69 insertions(+), 19 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 90ed78c4e1..333dc4f624 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,18 +1,20 @@ -import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; import { handleSow } from "../src/FieldHandler"; import { handlePodListingCancelled, handlePodListingCreated_v2, handlePodListingFilled_v2, - handlePodOrderCreated_v2 + handlePodOrderCreated_v2, + handlePodOrderFilled_v2 } from "../src/MarketplaceHandler"; import { createSowEvent } from "./event-mocking/Field"; import { createPodListingCancelledEvent, createPodListingCreatedEvent_v2, createPodListingFilledEvent_v2, - createPodOrderCreatedEvent_v2 + createPodOrderCreatedEvent_v2, + createPodOrderFilledEvent_v2 } from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; @@ -38,6 +40,9 @@ const sowedPods = sowedBeans.times(BigInt.fromString("3")); const orderBeans = beans_BI(80000); const orderPricePerPod = BigInt.fromString("500000"); // 0.5 beans +const orderId = Bytes.fromHexString("0xabcd"); + +// TODO: organize these elsewhere const sow = (account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow => { const event = createSowEvent(account, index, beans, pods); @@ -45,19 +50,40 @@ const sow = (account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow = return event; }; +const getPodFillId = (index: BigInt, event: ethereum.Event): string => { + return BEANSTALK.toHexString() + "-" + index.toString() + "-" + event.transaction.hash.toHexString(); +}; + const fillListing_v2 = (listingIndex: BigInt, listingStart: BigInt, podAmount: BigInt, costInBeans: BigInt): PodListingFilled_v2 => { const event = createPodListingFilledEvent_v2(account, account2, listingIndex, listingStart, podAmount, costInBeans); handlePodListingFilled_v2(event); // Assert PodFill - const podFillId = BEANSTALK.toHexString() + "-" + listingIndex.toString() + "-" + event.transaction.hash.toHexString(); - assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + listingIndex.toString()); - assert.fieldEquals("PodFill", podFillId, "from", account); - assert.fieldEquals("PodFill", podFillId, "to", account2); - assert.fieldEquals("PodFill", podFillId, "amount", podAmount.toString()); - assert.fieldEquals("PodFill", podFillId, "index", listingIndex.toString()); - assert.fieldEquals("PodFill", podFillId, "start", listingStart.toString()); - assert.fieldEquals("PodFill", podFillId, "costInBeans", costInBeans.toString()); + const podFillId = getPodFillId(event.params.index, event); + assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); + assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); + assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); + assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); + assert.fieldEquals("PodFill", podFillId, "costInBeans", event.params.costInBeans.toString()); + + return event; +}; + +const fillOrder_v2 = (orderId: Bytes, index: BigInt, start: BigInt, podAmount: BigInt, costInBeans: BigInt): PodOrderFilled_v2 => { + const event = createPodOrderFilledEvent_v2(account2, account, orderId, index, start, podAmount, costInBeans); + handlePodOrderFilled_v2(event); + + // Assert PodFill + const podFillId = getPodFillId(index, event); + assert.fieldEquals("PodFill", podFillId, "order", event.params.id.toHexString()); + assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); + assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); + assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); + assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); + assert.fieldEquals("PodFill", podFillId, "costInBeans", event.params.costInBeans.toString()); return event; }; @@ -113,8 +139,7 @@ const createListing_v2 = (account: string, index: BigInt, plotTotalPods: BigInt, return event; }; -const createOrder_v2 = (beans: BigInt, pricePerPod: BigInt): PodOrderCreated_v2 => { - const id = Bytes.fromByteArray(Bytes.fromBigInt(beans.plus(pricePerPod))); +const createOrder_v2 = (id: Bytes, beans: BigInt, pricePerPod: BigInt): PodOrderCreated_v2 => { const event = createPodOrderCreatedEvent_v2(account, id, beans, pricePerPod, maxHarvestableIndex, ONE_BI, pricingFunction, ZERO_BI); handlePodOrderCreated_v2(event); assertOrderCreated_v2(event); @@ -213,8 +238,7 @@ describe("Marketplace", () => { }); test("Create a pod order", () => { - const event = createOrder_v2(orderBeans, orderPricePerPod); - assertMarketListingsState(BEANSTALK.toHexString(), [], ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + const event = createOrder_v2(orderId, orderBeans, orderPricePerPod); assertMarketOrdersState( BEANSTALK.toHexString(), [event.params.id.toHexString()], @@ -227,9 +251,9 @@ describe("Marketplace", () => { ); }); - describe("Tests requiring listing", () => { + describe("Tests requiring Listing", () => { beforeEach(() => { - const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); + createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); }); test("Fill listing - full", () => { @@ -309,7 +333,7 @@ describe("Marketplace", () => { }); // Cancellation isnt unique to pod market v2, consider including in the v1 section - test("Cancel pod listing - full", () => { + test("Cancel listing - full", () => { const event = createPodListingCancelledEvent(account, listingIndex); handlePodListingCancelled(event); @@ -322,7 +346,7 @@ describe("Marketplace", () => { assertMarketListingsState(BEANSTALK.toHexString(), [], cancelledAmount, ZERO_BI, cancelledAmount, ZERO_BI, ZERO_BI, ZERO_BI); }); - test("Cancel pod listing - partial", () => { + test("Cancel listing - partial", () => { const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledPods = listedPods.div(BigInt.fromString("4")); @@ -343,5 +367,31 @@ describe("Marketplace", () => { assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, remaining, filledPods, filledPods, filledBeans); }); }); + + describe("Tests requiring Order", () => { + beforeEach(() => { + createOrder_v2(orderId, orderBeans, orderPricePerPod); + }); + + test("Fill order - full", () => { + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + sow(account2, orderPlotIndex, sowedBeans, orderedPods); + const event = fillOrder_v2(orderId, orderPlotIndex, ZERO_BI, orderedPods, orderBeans); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "FILLED"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", orderedPods.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, event) + "]"); + + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, orderBeans, orderedPods, ZERO_BI, orderedPods, orderBeans); + }); + + // test("Fill order - partial", () => {}); + + test("Cancel order - full", () => {}); + + // test("Cancel order - partial", () => {}); + }); }); }); From 75b3af480a98e15b8d45e6bba7effed1050ac267 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 20:48:39 -0700 Subject: [PATCH 11/89] fix order fill not removing order --- projects/subgraph-beanstalk/src/MarketplaceHandler.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 5e43ca8dad..960211f0a9 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -308,7 +308,9 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { let orderIndex = market.orders.indexOf(order.id); if (orderIndex !== -1) { - market.orders.splice(orderIndex, 1); + let marketOrders = market.orders; + marketOrders.splice(orderIndex, 1); + market.orders = marketOrders; } market.save(); } @@ -713,7 +715,9 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { let orderIndex = market.orders.indexOf(order.id); if (orderIndex !== -1) { - market.orders.splice(orderIndex, 1); + let marketOrders = market.orders; + marketOrders.splice(orderIndex, 1); + market.orders = marketOrders; } market.save(); } From 8ae795aa9fab0e3b9ce9f089b10e1e8b4a526ab2 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 13 May 2024 20:55:54 -0700 Subject: [PATCH 12/89] cancel order test --- .../subgraph-beanstalk/tests/Marketplace.test.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 333dc4f624..f803ac4484 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -5,6 +5,7 @@ import { handlePodListingCancelled, handlePodListingCreated_v2, handlePodListingFilled_v2, + handlePodOrderCancelled, handlePodOrderCreated_v2, handlePodOrderFilled_v2 } from "../src/MarketplaceHandler"; @@ -13,6 +14,7 @@ import { createPodListingCancelledEvent, createPodListingCreatedEvent_v2, createPodListingFilledEvent_v2, + createPodOrderCancelledEvent, createPodOrderCreatedEvent_v2, createPodOrderFilledEvent_v2 } from "./event-mocking/Marketplace"; @@ -389,7 +391,17 @@ describe("Marketplace", () => { // test("Fill order - partial", () => {}); - test("Cancel order - full", () => {}); + test("Cancel order - full", () => { + const event = createPodOrderCancelledEvent(account, orderId); + handlePodOrderCancelled(event); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", "0"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", "0"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); + + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + }); // test("Cancel order - partial", () => {}); }); From 06db4167cceb5ae3b847bfba68280799d5e7ec55 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 10:58:26 -0700 Subject: [PATCH 13/89] partial order fill test --- .../tests/Marketplace.test.ts | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index f803ac4484..bf19a7e49e 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -197,10 +197,7 @@ describe("Marketplace", () => { }); // TODO tests: - // cancel order - full // cancel order - partial - // fill order - full - // fill order - partial // fill order with pods that are also listed // listing expires due to podline advancing // order expires due to podline advancing @@ -389,7 +386,48 @@ describe("Marketplace", () => { assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, orderBeans, orderedPods, ZERO_BI, orderedPods, orderBeans); }); - // test("Fill order - partial", () => {}); + test("Fill order - partial", () => { + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); + const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); + sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); + const event = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "ACTIVE"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", soldToOrder1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, event) + "]"); + + assertMarketOrdersState( + BEANSTALK.toHexString(), + [event.params.id.toHexString()], + orderBeans, + orderBeans1, + soldToOrder1, + ZERO_BI, + soldToOrder1, + orderBeans1 + ); + + // Now fill the rest + const newOrderPlotIndex = orderPlotIndex.plus(beans_BI(1000)).plus(soldToOrder1); + const soldToOrder2 = orderedPods.minus(soldToOrder1); + const orderBeans2 = orderBeans.minus(orderBeans1); + const event2 = fillOrder_v2(orderId, newOrderPlotIndex, ZERO_BI, soldToOrder2, orderBeans2); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "FILLED"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", orderedPods.toString()); + assert.fieldEquals( + "PodOrder", + orderId.toHexString(), + "fills", + "[" + getPodFillId(orderPlotIndex, event) + ", " + getPodFillId(newOrderPlotIndex, event2) + "]" + ); + + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, orderBeans, orderedPods, ZERO_BI, orderedPods, orderBeans); + }); test("Cancel order - full", () => { const event = createPodOrderCancelledEvent(account, orderId); From 276db8597f16e275c382eb02e2c6f91619609813 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 11:02:35 -0700 Subject: [PATCH 14/89] partial order cancellation test --- .../tests/Marketplace.test.ts | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index bf19a7e49e..0ab8b79ff7 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -441,7 +441,33 @@ describe("Marketplace", () => { assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); }); - // test("Cancel order - partial", () => {}); + test("Cancel order - partial", () => { + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); + const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); + sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); + const orderEvent = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + + const event = createPodOrderCancelledEvent(account, orderId); + handlePodOrderCancelled(event); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED_PARTIAL"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", soldToOrder1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, orderEvent) + "]"); + + assertMarketOrdersState( + BEANSTALK.toHexString(), + [], + orderBeans, + orderBeans1, + soldToOrder1, + orderBeans.minus(orderBeans1), + soldToOrder1, + orderBeans1 + ); + }); }); }); }); From 81b56729d5bf0436f341aaae203cfa5d8a00d4f6 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 11:20:42 -0700 Subject: [PATCH 15/89] re-order pods test --- .../tests/Marketplace.test.ts | 41 +++++++++++++++++-- .../tests/PlotTransfer.test.ts | 1 + 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 0ab8b79ff7..f5005e6445 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -197,12 +197,10 @@ describe("Marketplace", () => { }); // TODO tests: - // cancel order - partial // fill order with pods that are also listed // listing expires due to podline advancing // order expires due to podline advancing // re-list pods (historical listing) - // re-order pods (historical order) // describe("Marketplace v1", () => { // test("Create a pod listing - full plot", () => {}); @@ -447,7 +445,7 @@ describe("Marketplace", () => { const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); - const orderEvent = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + const fillEvent = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); const event = createPodOrderCancelledEvent(account, orderId); handlePodOrderCancelled(event); @@ -455,7 +453,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED_PARTIAL"); assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans1.toString()); assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", soldToOrder1.toString()); - assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, orderEvent) + "]"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, fillEvent) + "]"); assertMarketOrdersState( BEANSTALK.toHexString(), @@ -468,6 +466,41 @@ describe("Marketplace", () => { orderBeans1 ); }); + + test("Recreate order", () => { + createOrder_v2(orderId, orderBeans, orderPricePerPod); + + assert.fieldEquals("PodOrder", orderId.toHexString() + "-0", "fills", "[]"); + + assertMarketOrdersState(BEANSTALK.toHexString(), [orderId.toHexString()], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + + // Recreate after a partial fill + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); + const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); + sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); + const fillEvent = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + + createOrder_v2(orderId, orderBeans, orderPricePerPod); + + // The historical order has one fill + assert.fieldEquals("PodOrder", orderId.toHexString() + "-1", "fills", "[" + getPodFillId(orderPlotIndex, fillEvent) + "]"); + // The recreated order has no fills + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); + + // The same amount of beans were re-ordered, which is on net an increase in the beans ordered + assertMarketOrdersState( + BEANSTALK.toHexString(), + [orderId.toHexString()], + orderBeans.plus(orderBeans1), + orderBeans1, + soldToOrder1, + ZERO_BI, + soldToOrder1, + orderBeans1 + ); + }); }); }); }); diff --git a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts index c437c9ef6b..2964d60fa0 100644 --- a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts +++ b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts @@ -75,6 +75,7 @@ const assertFieldHas = (field: string, unharvestable: BigInt, harvestable: BigIn assert.fieldEquals("Field", field, "harvestablePods", harvestable.toString()); }; +// TODO: move this into a shared location const setHarvestable = (harvestableIndex: BigInt): BigInt => { createMockedFunction(BEANSTALK, "harvestableIndex", "harvestableIndex():(uint256)").returns([ ethereum.Value.fromUnsignedBigInt(harvestableIndex) From 4736e13cd720541f960ef786b733a997a2b6c1ed Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 11:51:52 -0700 Subject: [PATCH 16/89] refactor market order state to use beanAmount rather than podAmount --- projects/subgraph-beanstalk/schema.graphql | 54 ++++++++------ .../src/MarketplaceHandler.ts | 72 +++++-------------- .../src/utils/PodMarketplace.ts | 25 ++++--- .../tests/Marketplace.test.ts | 7 +- 4 files changed, 69 insertions(+), 89 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 3c2ae9a29f..cadef4c0ff 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -721,12 +721,14 @@ type PodMarketplace @entity { cancelledListedPods: BigInt! "Current amount of total pods listed" availableListedPods: BigInt! - "Current cumulative pod orders created" - orderedPods: BigInt! + "Current cumulative beans in pod orders created" + orderBeans: BigInt! + "Current cumulative filled beans in pod orders" + filledOrderBeans: BigInt! "Current cumulative pod orders filled" filledOrderedPods: BigInt! - "Current cumulative pod orders cancelled" - cancelledOrderedPods: BigInt! + "Current cumulative beans in pod orders cancelled" + cancelledOrderBeans: BigInt! "Cumulative pod volume between listings and orders" podVolume: BigInt! "Cumulative bean volume between listings and orders" @@ -754,12 +756,14 @@ type PodMarketplaceHourlySnapshot @entity { cancelledListedPods: BigInt! "Point in time current amount of total pods listed" availableListedPods: BigInt! - "Point in time current cumulative pod orders created" - orderedPods: BigInt! - "Point in time current cumulative pod orders filled" + "Current cumulative beans in pod orders created" + orderBeans: BigInt! + "Current cumulative filled beans in pod orders" + filledOrderBeans: BigInt! + "Current cumulative pod orders filled" filledOrderedPods: BigInt! - "Point in time current cumulative pod orders cancelled" - cancelledOrderedPods: BigInt! + "Current cumulative beans in pod orders cancelled" + cancelledOrderBeans: BigInt! "Point in time current cumulative pod volume between listings and orders" podVolume: BigInt! "Point in time current cumulative bean volume between listings and orders" @@ -774,12 +778,14 @@ type PodMarketplaceHourlySnapshot @entity { deltaCancelledListedPods: BigInt! "Point in time current delta of total pods listed" deltaAvailableListedPods: BigInt! - "Point in time current delta pod orders created" - deltaOrderedPods: BigInt! + "Point in time current delta ordered beans in pod orders created" + deltaOrderBeans: BigInt! + "Point in time current delta filled ordered beans in pod orders" + deltaFilledOrderBeans: BigInt! "Point in time current delta pod orders filled" deltaFilledOrderedPods: BigInt! - "Point in time current delta pod orders cancelled" - deltaCancelledOrderedPods: BigInt! + "Point in time current delta cancelled ordered beans in pod orders" + deltaCancelledOrderBeans: BigInt! "Point in time current delta pod volume between listings and orders" deltaPodVolume: BigInt! "Point in time current delta bean volume between listings and orders" @@ -807,12 +813,14 @@ type PodMarketplaceDailySnapshot @entity { cancelledListedPods: BigInt! "Point in time current amount of total pods listed" availableListedPods: BigInt! - "Point in time current cumulative pod orders created" - orderedPods: BigInt! - "Point in time current cumulative pod orders filled" + "Current cumulative beans in pod orders created" + orderBeans: BigInt! + "Current cumulative filled beans in pod orders" + filledOrderBeans: BigInt! + "Current cumulative pod orders filled" filledOrderedPods: BigInt! - "Point in time current cumulative pod orders cancelled" - cancelledOrderedPods: BigInt! + "Current cumulative beans in pod orders cancelled" + cancelledOrderBeans: BigInt! "Point in time current cumulative pod volume between listings and orders" podVolume: BigInt! "Point in time current cumulative bean volume between listings and orders" @@ -827,12 +835,14 @@ type PodMarketplaceDailySnapshot @entity { deltaCancelledListedPods: BigInt! "Point in time current delta of total pods listed" deltaAvailableListedPods: BigInt! - "Point in time current delta pod orders created" - deltaOrderedPods: BigInt! + "Point in time current delta ordered beans in pod orders created" + deltaOrderBeans: BigInt! + "Point in time current delta filled ordered beans in pod orders" + deltaFilledOrderBeans: BigInt! "Point in time current delta pod orders filled" deltaFilledOrderedPods: BigInt! - "Point in time current delta pod orders cancelled" - deltaCancelledOrderedPods: BigInt! + "Point in time current delta cancelled ordered beans in pod orders" + deltaCancelledOrderBeans: BigInt! "Point in time current delta pod volume between listings and orders" deltaPodVolume: BigInt! "Point in time current delta bean volume between listings and orders" diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 960211f0a9..42875b18d2 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -237,17 +237,7 @@ export function handlePodOrderCreated(event: PodOrderCreated_v1): void { order.creationHash = event.transaction.hash.toHexString(); order.save(); - updateMarketOrderBalances( - event.address, - order.id, - event.params.amount, - ZERO_BI, - ZERO_BI, - ZERO_BI, - ZERO_BI, - ZERO_BI, - event.block.timestamp - ); + updateMarketOrderBalances(event.address, order.id, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -291,17 +281,7 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { fill.costInBeans = beanAmount; fill.save(); - updateMarketOrderBalances( - event.address, - order.id, - ZERO_BI, - ZERO_BI, - ZERO_BI, - ZERO_BI, - event.params.amount, - beanAmount, - event.block.timestamp - ); + updateMarketOrderBalances(event.address, order.id, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); if (order.podAmountFilled == order.podAmount) { let market = loadPodMarketplace(event.address); @@ -347,8 +327,6 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { event.address, order.id, ZERO_BI, - order.podAmount.minus(order.podAmountFilled), - ZERO_BI, order.beanAmount.minus(order.beanAmountFilled), ZERO_BI, ZERO_BI, @@ -644,17 +622,7 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { order.creationHash = event.transaction.hash.toHexString(); order.save(); - updateMarketOrderBalances( - event.address, - order.id, - ZERO_BI, - ZERO_BI, - event.params.amount, - ZERO_BI, - ZERO_BI, - ZERO_BI, - event.block.timestamp - ); + updateMarketOrderBalances(event.address, order.id, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -703,8 +671,6 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { order.id, ZERO_BI, ZERO_BI, - ZERO_BI, - ZERO_BI, event.params.amount, event.params.costInBeans, event.block.timestamp @@ -820,17 +786,12 @@ function updateMarketListingBalances( function updateMarketOrderBalances( marketAddress: Address, orderID: string, - newPodAmount: BigInt, - cancelledPodAmount: BigInt, newBeanAmount: BigInt, cancelledBeanAmount: BigInt, filledPodAmount: BigInt, filledBeanAmount: BigInt, timestamp: BigInt ): void { - // Need to account for v2 bean amounts - // TODO: remove newPodAmount/orderedPods entirely - let market = loadPodMarketplace(marketAddress); let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); @@ -840,41 +801,46 @@ function updateMarketOrderBalances( if (newBeanAmount > ZERO_BI) { marketOrders.push(orderID); } - if (cancelledPodAmount > ZERO_BI) { + if (cancelledBeanAmount > ZERO_BI) { let orderIndex = market.orders.indexOf(orderID); marketOrders.splice(orderIndex, 1); } - market.orderedPods = market.orderedPods.plus(newPodAmount); + market.orderBeans = market.orderBeans.plus(newBeanAmount); market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); + market.filledOrderBeans = market.filledOrderBeans.plus(filledBeanAmount); market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); - market.cancelledOrderedPods = market.cancelledOrderedPods.plus(cancelledPodAmount); + market.cancelledOrderBeans = market.cancelledOrderBeans.plus(cancelledBeanAmount); market.orders = marketOrders; market.save(); - marketHourly.deltaOrderedPods = marketHourly.deltaOrderedPods.plus(newPodAmount); - marketHourly.orderedPods = market.orderedPods; + marketHourly.deltaOrderBeans = marketHourly.deltaOrderBeans.plus(newBeanAmount); + marketHourly.orderBeans = market.orderBeans; marketHourly.deltaFilledOrderedPods = marketHourly.deltaFilledOrderedPods.plus(filledPodAmount); marketHourly.filledOrderedPods = market.filledOrderedPods; + marketHourly.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); + marketHourly.filledOrderBeans = market.filledOrderBeans; marketHourly.deltaPodVolume = marketHourly.deltaPodVolume.plus(filledPodAmount); marketHourly.podVolume = market.podVolume; marketHourly.deltaBeanVolume = marketHourly.deltaBeanVolume.plus(filledBeanAmount); marketHourly.beanVolume = market.beanVolume; - marketHourly.deltaCancelledOrderedPods = marketHourly.deltaCancelledOrderedPods.plus(cancelledPodAmount); - marketHourly.cancelledOrderedPods = market.cancelledOrderedPods; + marketHourly.deltaCancelledOrderBeans = marketHourly.deltaCancelledOrderBeans.plus(cancelledBeanAmount); + marketHourly.cancelledOrderBeans = market.cancelledOrderBeans; marketHourly.updatedAt = timestamp; marketHourly.save(); - marketDaily.deltaOrderedPods = marketDaily.deltaOrderedPods.plus(newPodAmount); - marketDaily.orderedPods = market.orderedPods; + marketDaily.deltaOrderBeans = marketDaily.deltaOrderBeans.plus(newBeanAmount); + marketDaily.orderBeans = market.orderBeans; marketDaily.deltaFilledOrderedPods = marketDaily.deltaFilledOrderedPods.plus(filledPodAmount); marketDaily.filledOrderedPods = market.filledOrderedPods; + marketDaily.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); + marketDaily.filledOrderBeans = market.filledOrderBeans; marketDaily.deltaPodVolume = marketDaily.deltaPodVolume.plus(filledPodAmount); marketDaily.podVolume = market.podVolume; marketDaily.deltaBeanVolume = marketDaily.deltaBeanVolume.plus(filledBeanAmount); marketDaily.beanVolume = market.beanVolume; - marketDaily.deltaCancelledOrderedPods = marketDaily.deltaCancelledOrderedPods.plus(cancelledPodAmount); - marketDaily.cancelledOrderedPods = market.cancelledOrderedPods; + marketDaily.deltaCancelledOrderBeans = marketDaily.deltaCancelledOrderBeans.plus(cancelledBeanAmount); + marketDaily.cancelledOrderBeans = market.cancelledOrderBeans; marketDaily.updatedAt = timestamp; marketDaily.save(); } diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index 6f0d8e748a..62dd77ebd1 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -17,9 +17,10 @@ export function loadPodMarketplace(diamondAddress: Address): PodMarketplace { marketplace.expiredListedPods = ZERO_BI; marketplace.cancelledListedPods = ZERO_BI; marketplace.availableListedPods = ZERO_BI; - marketplace.orderedPods = ZERO_BI; + marketplace.orderBeans = ZERO_BI; marketplace.filledOrderedPods = ZERO_BI; - marketplace.cancelledOrderedPods = ZERO_BI; + marketplace.filledOrderBeans = ZERO_BI; + marketplace.cancelledOrderBeans = ZERO_BI; marketplace.podVolume = ZERO_BI; marketplace.beanVolume = ZERO_BI; marketplace.save(); @@ -47,12 +48,14 @@ export function loadPodMarketplaceHourlySnapshot(diamondAddress: Address, season snapshot.cancelledListedPods = marketplace.cancelledListedPods; snapshot.deltaAvailableListedPods = ZERO_BI; snapshot.availableListedPods = marketplace.availableListedPods; - snapshot.deltaOrderedPods = ZERO_BI; - snapshot.orderedPods = marketplace.orderedPods; + snapshot.deltaOrderBeans = ZERO_BI; + snapshot.orderBeans = marketplace.orderBeans; snapshot.deltaFilledOrderedPods = ZERO_BI; snapshot.filledOrderedPods = marketplace.filledOrderedPods; - snapshot.deltaCancelledOrderedPods = ZERO_BI; - snapshot.cancelledOrderedPods = marketplace.cancelledOrderedPods; + snapshot.deltaFilledOrderBeans = ZERO_BI; + snapshot.filledOrderBeans = marketplace.filledOrderBeans; + snapshot.deltaCancelledOrderBeans = ZERO_BI; + snapshot.cancelledOrderBeans = marketplace.cancelledOrderBeans; snapshot.deltaPodVolume = ZERO_BI; snapshot.podVolume = marketplace.podVolume; snapshot.deltaBeanVolume = ZERO_BI; @@ -83,12 +86,14 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta snapshot.cancelledListedPods = marketplace.cancelledListedPods; snapshot.deltaAvailableListedPods = ZERO_BI; snapshot.availableListedPods = marketplace.availableListedPods; - snapshot.deltaOrderedPods = ZERO_BI; - snapshot.orderedPods = marketplace.orderedPods; + snapshot.deltaOrderBeans = ZERO_BI; + snapshot.orderBeans = marketplace.orderBeans; snapshot.deltaFilledOrderedPods = ZERO_BI; snapshot.filledOrderedPods = marketplace.filledOrderedPods; - snapshot.deltaCancelledOrderedPods = ZERO_BI; - snapshot.cancelledOrderedPods = marketplace.cancelledOrderedPods; + snapshot.deltaFilledOrderBeans = ZERO_BI; + snapshot.filledOrderBeans = marketplace.filledOrderBeans; + snapshot.deltaCancelledOrderBeans = ZERO_BI; + snapshot.cancelledOrderBeans = marketplace.cancelledOrderBeans; snapshot.deltaPodVolume = ZERO_BI; snapshot.podVolume = marketplace.podVolume; snapshot.deltaBeanVolume = ZERO_BI; diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index f5005e6445..2bd8d63cca 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -178,11 +178,10 @@ const assertMarketOrdersState = ( beanVolume: BigInt ): void => { assert.fieldEquals("PodMarketplace", address, "orders", "[" + orders.join(", ") + "]"); - // TODO: re-enable these once implemented - // assert.fieldEquals("PodMarketplace", address, "orderBeans", orderBeans.toString()); - // assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "orderBeans", orderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); - // assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); }; From 63cd64d3f2a30ad9313268249183c3fd407f96cb Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 12:05:44 -0700 Subject: [PATCH 17/89] entirely remove podAmount --- projects/subgraph-beanstalk/schema.graphql | 29 ++++--------------- .../src/MarketplaceHandler.ts | 10 ++----- .../subgraph-beanstalk/src/utils/PodOrder.ts | 2 -- 3 files changed, 8 insertions(+), 33 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index cadef4c0ff..bb96b4a887 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -1079,21 +1079,16 @@ type PodOrder @entity { ######################## Amounts ######################## """ - The original number of Pods requested by this PodOrder. + The original number of Beans locked in the PodOrder. Does NOT change as Fills occur. - Not deterministic for PodOrders with pricingType = DYNAMIC. - - If pricingType = FIXED: - Set to the number of Pods which can be purchased by the Order. - If FIXED (V1): `amount` field emitted in PodOrderCreated. - If FIXED (V2): `amount / pricePerPod` fields emitted in PodOrderCreated. + Always deterministic, since the Farmer must lock Beans for PodOrder fulfillment. - If pricingType = DYNAMIC: - Set to `0`. The number of Pods that will be provided is unknown, since - the price is calculated based on the place in line of supplied Pods. + If FIXED (V1): `amount * pricePerPod` fields emitted in PodOrderCreated. + If FIXED (V2): `amount` field emitted in PodOrderCreated. + If DYNAMIC (V2): `amount` field emitted in PodOrderCreated. """ - podAmount: BigInt! + beanAmount: BigInt! """ The current number of Pods that have been purchased by this PodOrder. @@ -1106,18 +1101,6 @@ type PodOrder @entity { """ podAmountFilled: BigInt! - """ - The original number of Beans locked in the PodOrder. - - Does NOT change as Fills occur. - Always deterministic, since the Farmer must lock Beans for PodOrder fulfillment. - - If FIXED (V1): `amount * pricePerPod` fields emitted in PodOrderCreated. - If FIXED (V2): `amount` field emitted in PodOrderCreated. - If DYNAMIC (V2): `amount` field emitted in PodOrderCreated. - """ - beanAmount: BigInt! - """ The current number of Beans spent to acquire Pods. diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 42875b18d2..992d608b3d 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -229,7 +229,6 @@ export function handlePodOrderCreated(event: PodOrderCreated_v1): void { order.createdAt = event.block.timestamp; order.updatedAt = event.block.timestamp; order.status = "ACTIVE"; - order.podAmount = event.params.amount; order.beanAmount = event.params.amount.times(BigInt.fromI32(event.params.pricePerPod)).div(BigInt.fromString("1000000")); order.podAmountFilled = ZERO_BI; order.maxPlaceInLine = event.params.maxPlaceInLine; @@ -265,7 +264,7 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { order.updatedAt = event.block.timestamp; order.podAmountFilled = order.podAmountFilled.plus(event.params.amount); order.beanAmountFilled = order.beanAmountFilled.plus(beanAmount); - order.status = order.podAmount == order.podAmountFilled ? "FILLED" : "ACTIVE"; + order.status = order.beanAmount == order.beanAmountFilled ? "FILLED" : "ACTIVE"; let newFills = order.fills; newFills.push(fill.id); order.fills = newFills; @@ -283,7 +282,7 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { updateMarketOrderBalances(event.address, order.id, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); - if (order.podAmountFilled == order.podAmount) { + if (order.status == "FILLED") { let market = loadPodMarketplace(event.address); let orderIndex = market.orders.indexOf(order.id); @@ -602,11 +601,6 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { createHistoricalPodOrder(order); } - // Store the pod amount if the order is a FIXED pricingType - if (event.params.priceType == 0) { - order.podAmount = event.params.amount.times(BigInt.fromI32(1000000)).div(BigInt.fromI32(event.params.pricePerPod)); - } - order.historyID = order.id + "-" + event.block.timestamp.toString(); order.farmer = event.params.account.toHexString(); order.createdAt = event.block.timestamp; diff --git a/projects/subgraph-beanstalk/src/utils/PodOrder.ts b/projects/subgraph-beanstalk/src/utils/PodOrder.ts index a284760e78..31c8ed8b6c 100644 --- a/projects/subgraph-beanstalk/src/utils/PodOrder.ts +++ b/projects/subgraph-beanstalk/src/utils/PodOrder.ts @@ -13,7 +13,6 @@ export function loadPodOrder(orderID: Bytes): PodOrder { order.createdAt = ZERO_BI; order.updatedAt = ZERO_BI; order.status = ""; - order.podAmount = ZERO_BI; order.beanAmount = ZERO_BI; order.podAmountFilled = ZERO_BI; order.beanAmountFilled = ZERO_BI; @@ -41,7 +40,6 @@ export function createHistoricalPodOrder(order: PodOrder): void { newOrder.createdAt = order.createdAt; newOrder.updatedAt = order.updatedAt; newOrder.status = order.status; - newOrder.podAmount = order.podAmount; newOrder.beanAmount = order.beanAmount; newOrder.podAmountFilled = order.podAmountFilled; newOrder.beanAmountFilled = order.beanAmountFilled; From a32ac551ca1d03966ed031098d16f2c2e51b2e20 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 13:37:24 -0700 Subject: [PATCH 18/89] specify if pod order is new or relisted --- .../src/MarketplaceHandler.ts | 92 +++++++++++++------ .../subgraph-beanstalk/src/utils/PodOrder.ts | 12 +-- 2 files changed, 69 insertions(+), 35 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 992d608b3d..b1c86c1f6a 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -94,7 +94,7 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketListingBalances(event.address, plot.index, false, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -119,7 +119,16 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { export function handlePodListingCancelled(event: PodListingCancelled): void { let listing = loadPodListing(event.params.account, event.params.index); - updateMarketListingBalances(event.address, event.params.index, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketListingBalances( + event.address, + event.params.index, + false, + ZERO_BI, + listing.remainingAmount, + ZERO_BI, + ZERO_BI, + event.block.timestamp + ); listing.status = listing.filled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; listing.cancelledAmount = listing.remainingAmount; @@ -146,7 +155,16 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { let beanAmount = BigInt.fromI32(listing.pricePerPod).times(event.params.amount).div(BigInt.fromI32(1000000)); - updateMarketListingBalances(event.address, event.params.index, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); + updateMarketListingBalances( + event.address, + event.params.index, + false, + ZERO_BI, + ZERO_BI, + event.params.amount, + beanAmount, + event.block.timestamp + ); listing.filledAmount = event.params.amount; listing.remainingAmount = listing.remainingAmount.minus(event.params.amount); @@ -236,7 +254,7 @@ export function handlePodOrderCreated(event: PodOrderCreated_v1): void { order.creationHash = event.transaction.hash.toHexString(); order.save(); - updateMarketOrderBalances(event.address, order.id, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketOrderBalances(event.address, order.id, false, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -280,7 +298,7 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { fill.costInBeans = beanAmount; fill.save(); - updateMarketOrderBalances(event.address, order.id, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); + updateMarketOrderBalances(event.address, order.id, false, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); if (order.status == "FILLED") { let market = loadPodMarketplace(event.address); @@ -325,6 +343,7 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { updateMarketOrderBalances( event.address, order.id, + false, ZERO_BI, order.beanAmount.minus(order.beanAmountFilled), ZERO_BI, @@ -405,7 +424,7 @@ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): voi plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketListingBalances(event.address, plot.index, false, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -487,7 +506,7 @@ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketListingBalances(event.address, plot.index, false, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -517,6 +536,7 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { updateMarketListingBalances( event.address, event.params.index, + false, ZERO_BI, ZERO_BI, event.params.amount, @@ -597,8 +617,9 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { let order = loadPodOrder(event.params.id); let farmer = loadFarmer(event.params.account); + let historicalOrder: PodOrder | null = null; if (order.status != "") { - createHistoricalPodOrder(order); + historicalOrder = createHistoricalPodOrder(order); } order.historyID = order.id + "-" + event.block.timestamp.toString(); @@ -616,7 +637,16 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { order.creationHash = event.transaction.hash.toHexString(); order.save(); - updateMarketOrderBalances(event.address, order.id, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketOrderBalances( + event.address, + order.id, + historicalOrder !== null, + event.params.amount, + ZERO_BI, + ZERO_BI, + ZERO_BI, + event.block.timestamp + ); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -663,6 +693,7 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { updateMarketOrderBalances( event.address, order.id, + false, ZERO_BI, ZERO_BI, event.params.amount, @@ -708,6 +739,7 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { function updateMarketListingBalances( marketAddress: Address, plotIndex: BigInt, + isRelisting: boolean, newPodAmount: BigInt, cancelledPodAmount: BigInt, filledPodAmount: BigInt, @@ -718,16 +750,17 @@ function updateMarketListingBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - let marketIndexes = market.listingIndexes; - - // Update Listing indexes - if (newPodAmount > ZERO_BI) { - marketIndexes.push(plotIndex); - marketIndexes.sort(); - } - if (cancelledPodAmount > ZERO_BI || filledPodAmount > ZERO_BI) { - let listingIndex = market.listingIndexes.indexOf(plotIndex); - marketIndexes.splice(listingIndex, 1); + if (!isRelisting) { + // Update Listing indexes + let marketIndexes = market.listingIndexes; + if (newPodAmount > ZERO_BI) { + marketIndexes.push(plotIndex); + marketIndexes.sort(); + } + if (cancelledPodAmount > ZERO_BI || filledPodAmount > ZERO_BI) { + marketIndexes.splice(market.listingIndexes.indexOf(plotIndex), 1); + } + market.listingIndexes = marketIndexes; } market.listedPods = market.listedPods.plus(newPodAmount); market.availableListedPods = market.availableListedPods.plus(newPodAmount).minus(cancelledPodAmount).minus(filledPodAmount); @@ -735,7 +768,6 @@ function updateMarketListingBalances( market.filledListedPods = market.filledListedPods.plus(filledPodAmount); market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); - market.listingIndexes = marketIndexes; market.save(); marketHourly.season = market.season; @@ -780,6 +812,7 @@ function updateMarketListingBalances( function updateMarketOrderBalances( marketAddress: Address, orderID: string, + isReorder: boolean, newBeanAmount: BigInt, cancelledBeanAmount: BigInt, filledPodAmount: BigInt, @@ -790,14 +823,16 @@ function updateMarketOrderBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - let marketOrders = market.orders; - - if (newBeanAmount > ZERO_BI) { - marketOrders.push(orderID); - } - if (cancelledBeanAmount > ZERO_BI) { - let orderIndex = market.orders.indexOf(orderID); - marketOrders.splice(orderIndex, 1); + if (!isReorder) { + // Update Order indexes + let marketOrders = market.orders; + if (newBeanAmount > ZERO_BI) { + marketOrders.push(orderID); + } + if (cancelledBeanAmount > ZERO_BI) { + marketOrders.splice(market.orders.indexOf(orderID), 1); + } + market.orders = marketOrders; } market.orderBeans = market.orderBeans.plus(newBeanAmount); market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); @@ -805,7 +840,6 @@ function updateMarketOrderBalances( market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); market.cancelledOrderBeans = market.cancelledOrderBeans.plus(cancelledBeanAmount); - market.orders = marketOrders; market.save(); marketHourly.deltaOrderBeans = marketHourly.deltaOrderBeans.plus(newBeanAmount); diff --git a/projects/subgraph-beanstalk/src/utils/PodOrder.ts b/projects/subgraph-beanstalk/src/utils/PodOrder.ts index 31c8ed8b6c..af6491b8f8 100644 --- a/projects/subgraph-beanstalk/src/utils/PodOrder.ts +++ b/projects/subgraph-beanstalk/src/utils/PodOrder.ts @@ -26,11 +26,9 @@ export function loadPodOrder(orderID: Bytes): PodOrder { return order; } -export function createHistoricalPodOrder(order: PodOrder): void { - let created = false; - let id = order.id; - for (let i = 0; !created; i++) { - id = order.id + "-" + i.toString(); +export function createHistoricalPodOrder(order: PodOrder): PodOrder { + for (let i = 0; ; i++) { + let id = order.id + "-" + i.toString(); let newOrder = PodOrder.load(id); if (newOrder == null) { newOrder = new PodOrder(id); @@ -49,7 +47,9 @@ export function createHistoricalPodOrder(order: PodOrder): void { newOrder.creationHash = order.creationHash; newOrder.fills = order.fills; newOrder.save(); - created = true; + return newOrder; } } + // This unreachable error is required for compilation + throw new Error(); } From 120746043cacf08cb9fae5b4802d8f39a9b1b684 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 14:05:00 -0700 Subject: [PATCH 19/89] Revert "specify if pod order is new or relisted" This reverts commit a32ac551ca1d03966ed031098d16f2c2e51b2e20. --- .../src/MarketplaceHandler.ts | 92 ++++++------------- .../subgraph-beanstalk/src/utils/PodOrder.ts | 12 +-- 2 files changed, 35 insertions(+), 69 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index b1c86c1f6a..992d608b3d 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -94,7 +94,7 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, false, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -119,16 +119,7 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { export function handlePodListingCancelled(event: PodListingCancelled): void { let listing = loadPodListing(event.params.account, event.params.index); - updateMarketListingBalances( - event.address, - event.params.index, - false, - ZERO_BI, - listing.remainingAmount, - ZERO_BI, - ZERO_BI, - event.block.timestamp - ); + updateMarketListingBalances(event.address, event.params.index, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); listing.status = listing.filled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; listing.cancelledAmount = listing.remainingAmount; @@ -155,16 +146,7 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { let beanAmount = BigInt.fromI32(listing.pricePerPod).times(event.params.amount).div(BigInt.fromI32(1000000)); - updateMarketListingBalances( - event.address, - event.params.index, - false, - ZERO_BI, - ZERO_BI, - event.params.amount, - beanAmount, - event.block.timestamp - ); + updateMarketListingBalances(event.address, event.params.index, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); listing.filledAmount = event.params.amount; listing.remainingAmount = listing.remainingAmount.minus(event.params.amount); @@ -254,7 +236,7 @@ export function handlePodOrderCreated(event: PodOrderCreated_v1): void { order.creationHash = event.transaction.hash.toHexString(); order.save(); - updateMarketOrderBalances(event.address, order.id, false, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketOrderBalances(event.address, order.id, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -298,7 +280,7 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { fill.costInBeans = beanAmount; fill.save(); - updateMarketOrderBalances(event.address, order.id, false, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); + updateMarketOrderBalances(event.address, order.id, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); if (order.status == "FILLED") { let market = loadPodMarketplace(event.address); @@ -343,7 +325,6 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { updateMarketOrderBalances( event.address, order.id, - false, ZERO_BI, order.beanAmount.minus(order.beanAmountFilled), ZERO_BI, @@ -424,7 +405,7 @@ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): voi plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, false, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -506,7 +487,7 @@ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, false, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -536,7 +517,6 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { updateMarketListingBalances( event.address, event.params.index, - false, ZERO_BI, ZERO_BI, event.params.amount, @@ -617,9 +597,8 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { let order = loadPodOrder(event.params.id); let farmer = loadFarmer(event.params.account); - let historicalOrder: PodOrder | null = null; if (order.status != "") { - historicalOrder = createHistoricalPodOrder(order); + createHistoricalPodOrder(order); } order.historyID = order.id + "-" + event.block.timestamp.toString(); @@ -637,16 +616,7 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { order.creationHash = event.transaction.hash.toHexString(); order.save(); - updateMarketOrderBalances( - event.address, - order.id, - historicalOrder !== null, - event.params.amount, - ZERO_BI, - ZERO_BI, - ZERO_BI, - event.block.timestamp - ); + updateMarketOrderBalances(event.address, order.id, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -693,7 +663,6 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { updateMarketOrderBalances( event.address, order.id, - false, ZERO_BI, ZERO_BI, event.params.amount, @@ -739,7 +708,6 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { function updateMarketListingBalances( marketAddress: Address, plotIndex: BigInt, - isRelisting: boolean, newPodAmount: BigInt, cancelledPodAmount: BigInt, filledPodAmount: BigInt, @@ -750,17 +718,16 @@ function updateMarketListingBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - if (!isRelisting) { - // Update Listing indexes - let marketIndexes = market.listingIndexes; - if (newPodAmount > ZERO_BI) { - marketIndexes.push(plotIndex); - marketIndexes.sort(); - } - if (cancelledPodAmount > ZERO_BI || filledPodAmount > ZERO_BI) { - marketIndexes.splice(market.listingIndexes.indexOf(plotIndex), 1); - } - market.listingIndexes = marketIndexes; + let marketIndexes = market.listingIndexes; + + // Update Listing indexes + if (newPodAmount > ZERO_BI) { + marketIndexes.push(plotIndex); + marketIndexes.sort(); + } + if (cancelledPodAmount > ZERO_BI || filledPodAmount > ZERO_BI) { + let listingIndex = market.listingIndexes.indexOf(plotIndex); + marketIndexes.splice(listingIndex, 1); } market.listedPods = market.listedPods.plus(newPodAmount); market.availableListedPods = market.availableListedPods.plus(newPodAmount).minus(cancelledPodAmount).minus(filledPodAmount); @@ -768,6 +735,7 @@ function updateMarketListingBalances( market.filledListedPods = market.filledListedPods.plus(filledPodAmount); market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); + market.listingIndexes = marketIndexes; market.save(); marketHourly.season = market.season; @@ -812,7 +780,6 @@ function updateMarketListingBalances( function updateMarketOrderBalances( marketAddress: Address, orderID: string, - isReorder: boolean, newBeanAmount: BigInt, cancelledBeanAmount: BigInt, filledPodAmount: BigInt, @@ -823,16 +790,14 @@ function updateMarketOrderBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - if (!isReorder) { - // Update Order indexes - let marketOrders = market.orders; - if (newBeanAmount > ZERO_BI) { - marketOrders.push(orderID); - } - if (cancelledBeanAmount > ZERO_BI) { - marketOrders.splice(market.orders.indexOf(orderID), 1); - } - market.orders = marketOrders; + let marketOrders = market.orders; + + if (newBeanAmount > ZERO_BI) { + marketOrders.push(orderID); + } + if (cancelledBeanAmount > ZERO_BI) { + let orderIndex = market.orders.indexOf(orderID); + marketOrders.splice(orderIndex, 1); } market.orderBeans = market.orderBeans.plus(newBeanAmount); market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); @@ -840,6 +805,7 @@ function updateMarketOrderBalances( market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); market.cancelledOrderBeans = market.cancelledOrderBeans.plus(cancelledBeanAmount); + market.orders = marketOrders; market.save(); marketHourly.deltaOrderBeans = marketHourly.deltaOrderBeans.plus(newBeanAmount); diff --git a/projects/subgraph-beanstalk/src/utils/PodOrder.ts b/projects/subgraph-beanstalk/src/utils/PodOrder.ts index af6491b8f8..31c8ed8b6c 100644 --- a/projects/subgraph-beanstalk/src/utils/PodOrder.ts +++ b/projects/subgraph-beanstalk/src/utils/PodOrder.ts @@ -26,9 +26,11 @@ export function loadPodOrder(orderID: Bytes): PodOrder { return order; } -export function createHistoricalPodOrder(order: PodOrder): PodOrder { - for (let i = 0; ; i++) { - let id = order.id + "-" + i.toString(); +export function createHistoricalPodOrder(order: PodOrder): void { + let created = false; + let id = order.id; + for (let i = 0; !created; i++) { + id = order.id + "-" + i.toString(); let newOrder = PodOrder.load(id); if (newOrder == null) { newOrder = new PodOrder(id); @@ -47,9 +49,7 @@ export function createHistoricalPodOrder(order: PodOrder): PodOrder { newOrder.creationHash = order.creationHash; newOrder.fills = order.fills; newOrder.save(); - return newOrder; + created = true; } } - // This unreachable error is required for compilation - throw new Error(); } From 42a422b8f4b18622eb63951baf6c4a805c3953eb Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 14:11:23 -0700 Subject: [PATCH 20/89] recreate order fix --- .../src/MarketplaceHandler.ts | 1 + .../tests/Marketplace.test.ts | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 992d608b3d..34446ed329 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -614,6 +614,7 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { order.pricingFunction = event.params.pricingFunction; order.pricingType = event.params.priceType; order.creationHash = event.transaction.hash.toHexString(); + order.fills = []; order.save(); updateMarketOrderBalances(event.address, order.id, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 2bd8d63cca..20197f6dd0 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -467,11 +467,21 @@ describe("Marketplace", () => { }); test("Recreate order", () => { + handlePodOrderCancelled(createPodOrderCancelledEvent(account, orderId)); createOrder_v2(orderId, orderBeans, orderPricePerPod); assert.fieldEquals("PodOrder", orderId.toHexString() + "-0", "fills", "[]"); - assertMarketOrdersState(BEANSTALK.toHexString(), [orderId.toHexString()], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketOrdersState( + BEANSTALK.toHexString(), + [orderId.toHexString()], + orderBeans.times(BigInt.fromU32(2)), + ZERO_BI, + ZERO_BI, + orderBeans, + ZERO_BI, + ZERO_BI + ); // Recreate after a partial fill const orderPlotIndex = podlineMil_BI(15); @@ -481,6 +491,7 @@ describe("Marketplace", () => { sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); const fillEvent = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + handlePodOrderCancelled(createPodOrderCancelledEvent(account, orderId)); createOrder_v2(orderId, orderBeans, orderPricePerPod); // The historical order has one fill @@ -488,14 +499,14 @@ describe("Marketplace", () => { // The recreated order has no fills assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); - // The same amount of beans were re-ordered, which is on net an increase in the beans ordered + // The same amount of beans were re-ordered, but fewer were cancelled assertMarketOrdersState( BEANSTALK.toHexString(), [orderId.toHexString()], - orderBeans.plus(orderBeans1), + orderBeans.times(BigInt.fromU32(3)), orderBeans1, soldToOrder1, - ZERO_BI, + orderBeans.plus(orderBeans.minus(orderBeans1)), soldToOrder1, orderBeans1 ); From d29549a1459f7a9529a7911da8836f02e90f7e3c Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 15:03:01 -0700 Subject: [PATCH 21/89] relist pod test --- .../src/MarketplaceHandler.ts | 9 +-- .../tests/Marketplace.test.ts | 64 ++++++++++++++++++- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 34446ed329..df42797eb7 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -1,4 +1,4 @@ -import { Address, BigInt } from "@graphprotocol/graph-ts"; +import { Address, BigInt, log } from "@graphprotocol/graph-ts"; import { PodListingCancelled, PodListingCreated as PodListingCreated_v1, @@ -437,19 +437,16 @@ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): voi */ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { - let plotCheck = Plot.load(event.params.index.toString()); - if (plotCheck == null) { + let plot = Plot.load(event.params.index.toString()); + if (plot == null) { return; } - let plot = loadPlot(event.address, event.params.index); /// Upsert PodListing let listing = loadPodListing(event.params.account, event.params.index); if (listing.createdAt !== ZERO_BI) { // Re-listed prior plot with new info createHistoricalPodListing(listing); - listing.status = "ACTIVE"; - listing.createdAt = ZERO_BI; listing.fill = null; listing.filled = ZERO_BI; listing.filledAmount = ZERO_BI; diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 20197f6dd0..5a6eb18e04 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,6 +1,6 @@ import { BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; -import { handleSow } from "../src/FieldHandler"; +import { handlePlotTransfer, handleSow } from "../src/FieldHandler"; import { handlePodListingCancelled, handlePodListingCreated_v2, @@ -9,7 +9,7 @@ import { handlePodOrderCreated_v2, handlePodOrderFilled_v2 } from "../src/MarketplaceHandler"; -import { createSowEvent } from "./event-mocking/Field"; +import { createPlotTransferEvent, createSowEvent } from "./event-mocking/Field"; import { createPodListingCancelledEvent, createPodListingCreatedEvent_v2, @@ -60,6 +60,9 @@ const fillListing_v2 = (listingIndex: BigInt, listingStart: BigInt, podAmount: B const event = createPodListingFilledEvent_v2(account, account2, listingIndex, listingStart, podAmount, costInBeans); handlePodListingFilled_v2(event); + // Perform plot transfer (necessary for market - assumption is this is tested/working via PlotTransfer.test.ts) + handlePlotTransfer(createPlotTransferEvent(account, account2, listingIndex.plus(listingStart), podAmount)); + // Assert PodFill const podFillId = getPodFillId(event.params.index, event); assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + event.params.index.toString()); @@ -199,7 +202,6 @@ describe("Marketplace", () => { // fill order with pods that are also listed // listing expires due to podline advancing // order expires due to podline advancing - // re-list pods (historical listing) // describe("Marketplace v1", () => { // test("Create a pod listing - full plot", () => {}); @@ -362,6 +364,62 @@ describe("Marketplace", () => { assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, remaining, filledPods, filledPods, filledBeans); }); + + test("Recreate listing", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + handlePodListingCancelled(createPodListingCancelledEvent(account, listingIndex)); + const listEvent = createListing_v2(account, listingIndex, sowedPods, listingStart); + + const listingID = listEvent.params.account.toHexString() + "-" + listEvent.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID + "-0", "status", "CANCELLED"); + assert.fieldEquals("PodListing", listingID + "-0", "filled", "0"); + assert.fieldEquals("PodListing", listingID + "-0", "cancelledAmount", listedPods.toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [listingIndex], + listedPods.times(BigInt.fromU32(2)), + listedPods, + listedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + + // Partial fill, then recreate again + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = beans_BI(2000); + const fillEvent = fillListing_v2(listingIndex, listingStart, filledPods, filledBeans); + + const remaining = listedPods.minus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + const newListingAmount = listedPods.minus(filledPods); + handlePodListingCancelled(createPodListingCancelledEvent(account, newListingIndex)); + const newListEvent = createListing_v2(account, newListingIndex, remaining, ZERO_BI); + + const newListingID = newListEvent.params.account.toHexString() + "-" + newListEvent.params.index.toString(); + assert.notInStore("PodListing", listingID + "-1"); + assert.notInStore("PodListing", newListingID + "-1"); + assert.fieldEquals("PodListing", newListingID + "-0", "status", "CANCELLED_PARTIAL"); + assert.fieldEquals("PodListing", newListingID + "-0", "filled", filledPods.toString()); + assert.fieldEquals("PodListing", newListingID + "-0", "cancelledAmount", newListingAmount.toString()); + assert.fieldEquals("PodListing", newListingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", newListingID, "filled", "0"); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", newListingAmount.toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [newListingIndex], + listedPods.times(BigInt.fromU32(2)).plus(newListingAmount), + newListingAmount, + listedPods.plus(newListingAmount), + filledPods, + filledPods, + filledBeans + ); + }); }); describe("Tests requiring Order", () => { From 78836ca9542969452849adb3be8f3062c647f414 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 15:24:08 -0700 Subject: [PATCH 22/89] marketplace test refactor --- .../tests/Marketplace.test.ts | 229 +++--------------- .../subgraph-beanstalk/tests/utils/Pods.ts | 199 +++++++++++++++ projects/subgraph-core/utils/Decimals.ts | 1 - 3 files changed, 233 insertions(+), 196 deletions(-) create mode 100644 projects/subgraph-beanstalk/tests/utils/Pods.ts diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 5a6eb18e04..75cf377340 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,39 +1,23 @@ -import { BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; +import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; -import { handlePlotTransfer, handleSow } from "../src/FieldHandler"; -import { - handlePodListingCancelled, - handlePodListingCreated_v2, - handlePodListingFilled_v2, - handlePodOrderCancelled, - handlePodOrderCreated_v2, - handlePodOrderFilled_v2 -} from "../src/MarketplaceHandler"; -import { createPlotTransferEvent, createSowEvent } from "./event-mocking/Field"; -import { - createPodListingCancelledEvent, - createPodListingCreatedEvent_v2, - createPodListingFilledEvent_v2, - createPodOrderCancelledEvent, - createPodOrderCreatedEvent_v2, - createPodOrderFilledEvent_v2 -} from "./event-mocking/Marketplace"; +import { handlePodListingCancelled, handlePodOrderCancelled } from "../src/MarketplaceHandler"; +import { createPodListingCancelledEvent, createPodOrderCancelledEvent } from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; -import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; -import { - PodListingCreated as PodListingCreated_v2, - PodListingFilled as PodListingFilled_v2, - PodOrderCreated as PodOrderCreated_v2, - PodOrderFilled as PodOrderFilled_v2 -} from "../generated/BIP29-PodMarketplace/Beanstalk"; +import { BI_10, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; -import { Sow } from "../generated/Field/Beanstalk"; +import { + assertMarketListingsState, + assertMarketOrdersState, + createListing_v2, + createOrder_v2, + fillListing_v2, + fillOrder_v2, + getPodFillId, + sow +} from "./utils/Pods"; const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); -const pricingFunction = Bytes.fromHexString( - "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" -); const listingIndex = podlineMil_BI(1); const maxHarvestableIndex = podlineMil_BI(100); @@ -44,151 +28,6 @@ const orderBeans = beans_BI(80000); const orderPricePerPod = BigInt.fromString("500000"); // 0.5 beans const orderId = Bytes.fromHexString("0xabcd"); -// TODO: organize these elsewhere - -const sow = (account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow => { - const event = createSowEvent(account, index, beans, pods); - handleSow(event); - return event; -}; - -const getPodFillId = (index: BigInt, event: ethereum.Event): string => { - return BEANSTALK.toHexString() + "-" + index.toString() + "-" + event.transaction.hash.toHexString(); -}; - -const fillListing_v2 = (listingIndex: BigInt, listingStart: BigInt, podAmount: BigInt, costInBeans: BigInt): PodListingFilled_v2 => { - const event = createPodListingFilledEvent_v2(account, account2, listingIndex, listingStart, podAmount, costInBeans); - handlePodListingFilled_v2(event); - - // Perform plot transfer (necessary for market - assumption is this is tested/working via PlotTransfer.test.ts) - handlePlotTransfer(createPlotTransferEvent(account, account2, listingIndex.plus(listingStart), podAmount)); - - // Assert PodFill - const podFillId = getPodFillId(event.params.index, event); - assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + event.params.index.toString()); - assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); - assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); - assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); - assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); - assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); - assert.fieldEquals("PodFill", podFillId, "costInBeans", event.params.costInBeans.toString()); - - return event; -}; - -const fillOrder_v2 = (orderId: Bytes, index: BigInt, start: BigInt, podAmount: BigInt, costInBeans: BigInt): PodOrderFilled_v2 => { - const event = createPodOrderFilledEvent_v2(account2, account, orderId, index, start, podAmount, costInBeans); - handlePodOrderFilled_v2(event); - - // Assert PodFill - const podFillId = getPodFillId(index, event); - assert.fieldEquals("PodFill", podFillId, "order", event.params.id.toHexString()); - assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); - assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); - assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); - assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); - assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); - assert.fieldEquals("PodFill", podFillId, "costInBeans", event.params.costInBeans.toString()); - - return event; -}; - -const assertListingCreated_v2 = (event: PodListingCreated_v2): void => { - let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); - assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); - assert.fieldEquals("PodListing", listingID, "farmer", event.params.account.toHexString()); - assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); - assert.fieldEquals("PodListing", listingID, "originalIndex", event.params.index.toString()); - assert.fieldEquals("PodListing", listingID, "originalAmount", event.params.amount.toString()); - assert.fieldEquals("PodListing", listingID, "index", event.params.index.toString()); - assert.fieldEquals("PodListing", listingID, "start", event.params.start.toString()); - assert.fieldEquals("PodListing", listingID, "amount", event.params.amount.toString()); - assert.fieldEquals("PodListing", listingID, "remainingAmount", event.params.amount.toString()); - assert.fieldEquals("PodListing", listingID, "pricePerPod", event.params.pricePerPod.toString()); - assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", event.params.maxHarvestableIndex.toString()); - assert.fieldEquals("PodListing", listingID, "minFillAmount", event.params.minFillAmount.toString()); - assert.fieldEquals("PodListing", listingID, "pricingFunction", event.params.pricingFunction.toHexString()); - assert.fieldEquals("PodListing", listingID, "mode", event.params.mode.toString()); - assert.fieldEquals("PodListing", listingID, "pricingType", event.params.pricingType.toString()); -}; - -const assertOrderCreated_v2 = (event: PodOrderCreated_v2): void => { - let orderID = event.params.id.toHexString(); - assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); - assert.fieldEquals("PodOrder", orderID, "farmer", account); - assert.fieldEquals("PodOrder", orderID, "status", "ACTIVE"); - assert.fieldEquals("PodOrder", orderID, "beanAmount", event.params.amount.toString()); - assert.fieldEquals("PodOrder", orderID, "beanAmountFilled", "0"); - assert.fieldEquals("PodOrder", orderID, "minFillAmount", event.params.minFillAmount.toString()); - assert.fieldEquals("PodOrder", orderID, "maxPlaceInLine", event.params.maxPlaceInLine.toString()); - assert.fieldEquals("PodOrder", orderID, "pricePerPod", event.params.pricePerPod.toString()); - assert.fieldEquals("PodOrder", orderID, "pricingFunction", event.params.pricingFunction.toHexString()); - assert.fieldEquals("PodOrder", orderID, "pricingType", event.params.priceType.toString()); -}; - -const createListing_v2 = (account: string, index: BigInt, plotTotalPods: BigInt, start: BigInt): PodListingCreated_v2 => { - const event = createPodListingCreatedEvent_v2( - account, - index, - start, - plotTotalPods.minus(start), - BigInt.fromString("250000"), - maxHarvestableIndex, - BigInt.fromString("10000000"), - pricingFunction, - BigInt.fromI32(0), - BigInt.fromI32(1) - ); - handlePodListingCreated_v2(event); - assertListingCreated_v2(event); - return event; -}; - -const createOrder_v2 = (id: Bytes, beans: BigInt, pricePerPod: BigInt): PodOrderCreated_v2 => { - const event = createPodOrderCreatedEvent_v2(account, id, beans, pricePerPod, maxHarvestableIndex, ONE_BI, pricingFunction, ZERO_BI); - handlePodOrderCreated_v2(event); - assertOrderCreated_v2(event); - return event; -}; - -const assertMarketListingsState = ( - address: string, - listings: BigInt[], - listedPods: BigInt, - availableListedPods: BigInt, - cancelledListedPods: BigInt, - filledListedPods: BigInt, - podVolume: BigInt, - beanVolume: BigInt -): void => { - assert.fieldEquals("PodMarketplace", address, "listingIndexes", "[" + listings.join(", ") + "]"); - assert.fieldEquals("PodMarketplace", address, "listedPods", listedPods.toString()); - assert.fieldEquals("PodMarketplace", address, "availableListedPods", availableListedPods.toString()); - assert.fieldEquals("PodMarketplace", address, "cancelledListedPods", cancelledListedPods.toString()); - assert.fieldEquals("PodMarketplace", address, "filledListedPods", filledListedPods.toString()); - assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); - assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); -}; - -const assertMarketOrdersState = ( - address: string, - orders: string[], - orderBeans: BigInt, - filledOrderBeans: BigInt, - filledOrderedPods: BigInt, - cancelledOrderBeans: BigInt, - podVolume: BigInt, - beanVolume: BigInt -): void => { - assert.fieldEquals("PodMarketplace", address, "orders", "[" + orders.join(", ") + "]"); - assert.fieldEquals("PodMarketplace", address, "orderBeans", orderBeans.toString()); - assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); - assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); - assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); - assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); - assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); -}; - describe("Marketplace", () => { beforeEach(() => { sow(account, listingIndex, sowedBeans, sowedPods); @@ -210,13 +49,13 @@ describe("Marketplace", () => { describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { - const event = createListing_v2(account, listingIndex, sowedPods, ZERO_BI); + const event = createListing_v2(account, listingIndex, sowedPods, ZERO_BI, maxHarvestableIndex); assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], sowedPods, sowedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); // Create a second listing to assert the market state again const listing2Index = listingIndex.times(BI_10); sow(account, listing2Index, sowedBeans, sowedPods); - const event2 = createListing_v2(account, listing2Index, sowedPods, ZERO_BI); + const event2 = createListing_v2(account, listing2Index, sowedPods, ZERO_BI, maxHarvestableIndex); assertMarketListingsState( BEANSTALK.toHexString(), [listingIndex, listing2Index], @@ -230,13 +69,13 @@ describe("Marketplace", () => { }); test("Create a pod listing - partial plot", () => { - const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); + const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); const listedPods = sowedPods.minus(beans_BI(500)); assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], listedPods, listedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); }); test("Create a pod order", () => { - const event = createOrder_v2(orderId, orderBeans, orderPricePerPod); + const event = createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); assertMarketOrdersState( BEANSTALK.toHexString(), [event.params.id.toHexString()], @@ -251,14 +90,14 @@ describe("Marketplace", () => { describe("Tests requiring Listing", () => { beforeEach(() => { - createListing_v2(account, listingIndex, sowedPods, beans_BI(500)); + createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); }); test("Fill listing - full", () => { const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledBeans = beans_BI(7000); - const event = fillListing_v2(listingIndex, listingStart, listedPods, filledBeans); + const event = fillListing_v2(account, account2, listingIndex, listingStart, listedPods, filledBeans); let listingID = event.params.from.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", listingID, "status", "FILLED"); @@ -275,7 +114,7 @@ describe("Marketplace", () => { const listedPods = sowedPods.minus(listingStart); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = beans_BI(2000); - const event = fillListing_v2(listingIndex, listingStart, filledPods, filledBeans); + const event = fillListing_v2(account, account2, listingIndex, listingStart, filledPods, filledBeans); const remaining = listedPods.minus(filledPods); const listingID = event.params.from.toHexString() + "-" + event.params.index.toString(); @@ -307,7 +146,7 @@ describe("Marketplace", () => { // Now sell the rest const newFilledBeans = beans_BI(4000); - const event2 = fillListing_v2(newListingIndex, ZERO_BI, remaining, newFilledBeans); + const event2 = fillListing_v2(account, account2, newListingIndex, ZERO_BI, remaining, newFilledBeans); assert.entityCount("PodListing", 2); assert.fieldEquals("PodListing", derivedListingID, "status", "FILLED"); @@ -349,7 +188,7 @@ describe("Marketplace", () => { const listedPods = sowedPods.minus(listingStart); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = beans_BI(2000); - const fillEvent = fillListing_v2(listingIndex, listingStart, filledPods, filledBeans); + const fillEvent = fillListing_v2(account, account2, listingIndex, listingStart, filledPods, filledBeans); const remaining = listedPods.minus(filledPods); const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); @@ -369,7 +208,7 @@ describe("Marketplace", () => { const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); handlePodListingCancelled(createPodListingCancelledEvent(account, listingIndex)); - const listEvent = createListing_v2(account, listingIndex, sowedPods, listingStart); + const listEvent = createListing_v2(account, listingIndex, sowedPods, listingStart, maxHarvestableIndex); const listingID = listEvent.params.account.toHexString() + "-" + listEvent.params.index.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -391,13 +230,13 @@ describe("Marketplace", () => { // Partial fill, then recreate again const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = beans_BI(2000); - const fillEvent = fillListing_v2(listingIndex, listingStart, filledPods, filledBeans); + const fillEvent = fillListing_v2(account, account2, listingIndex, listingStart, filledPods, filledBeans); const remaining = listedPods.minus(filledPods); const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); const newListingAmount = listedPods.minus(filledPods); handlePodListingCancelled(createPodListingCancelledEvent(account, newListingIndex)); - const newListEvent = createListing_v2(account, newListingIndex, remaining, ZERO_BI); + const newListEvent = createListing_v2(account, newListingIndex, remaining, ZERO_BI, maxHarvestableIndex); const newListingID = newListEvent.params.account.toHexString() + "-" + newListEvent.params.index.toString(); assert.notInStore("PodListing", listingID + "-1"); @@ -424,14 +263,14 @@ describe("Marketplace", () => { describe("Tests requiring Order", () => { beforeEach(() => { - createOrder_v2(orderId, orderBeans, orderPricePerPod); + createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); }); test("Fill order - full", () => { const orderPlotIndex = podlineMil_BI(15); const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); sow(account2, orderPlotIndex, sowedBeans, orderedPods); - const event = fillOrder_v2(orderId, orderPlotIndex, ZERO_BI, orderedPods, orderBeans); + const event = fillOrder_v2(account2, account, orderId, orderPlotIndex, ZERO_BI, orderedPods, orderBeans); assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "FILLED"); assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans.toString()); @@ -447,7 +286,7 @@ describe("Marketplace", () => { const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); - const event = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + const event = fillOrder_v2(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "ACTIVE"); assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans1.toString()); @@ -469,7 +308,7 @@ describe("Marketplace", () => { const newOrderPlotIndex = orderPlotIndex.plus(beans_BI(1000)).plus(soldToOrder1); const soldToOrder2 = orderedPods.minus(soldToOrder1); const orderBeans2 = orderBeans.minus(orderBeans1); - const event2 = fillOrder_v2(orderId, newOrderPlotIndex, ZERO_BI, soldToOrder2, orderBeans2); + const event2 = fillOrder_v2(account2, account, orderId, newOrderPlotIndex, ZERO_BI, soldToOrder2, orderBeans2); assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "FILLED"); assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans.toString()); @@ -502,7 +341,7 @@ describe("Marketplace", () => { const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); - const fillEvent = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + const fillEvent = fillOrder_v2(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); const event = createPodOrderCancelledEvent(account, orderId); handlePodOrderCancelled(event); @@ -526,7 +365,7 @@ describe("Marketplace", () => { test("Recreate order", () => { handlePodOrderCancelled(createPodOrderCancelledEvent(account, orderId)); - createOrder_v2(orderId, orderBeans, orderPricePerPod); + createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); assert.fieldEquals("PodOrder", orderId.toHexString() + "-0", "fills", "[]"); @@ -547,10 +386,10 @@ describe("Marketplace", () => { const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); - const fillEvent = fillOrder_v2(orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); + const fillEvent = fillOrder_v2(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); handlePodOrderCancelled(createPodOrderCancelledEvent(account, orderId)); - createOrder_v2(orderId, orderBeans, orderPricePerPod); + createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); // The historical order has one fill assert.fieldEquals("PodOrder", orderId.toHexString() + "-1", "fills", "[" + getPodFillId(orderPlotIndex, fillEvent) + "]"); diff --git a/projects/subgraph-beanstalk/tests/utils/Pods.ts b/projects/subgraph-beanstalk/tests/utils/Pods.ts new file mode 100644 index 0000000000..ab1f07d40e --- /dev/null +++ b/projects/subgraph-beanstalk/tests/utils/Pods.ts @@ -0,0 +1,199 @@ +import { BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; +import { assert } from "matchstick-as/assembly/index"; +import { handlePlotTransfer, handleSow } from "../../src/FieldHandler"; +import { + handlePodListingCreated_v2, + handlePodListingFilled_v2, + handlePodOrderCreated_v2, + handlePodOrderFilled_v2 +} from "../../src/MarketplaceHandler"; +import { createPlotTransferEvent, createSowEvent } from "../event-mocking/Field"; +import { + createPodListingCreatedEvent_v2, + createPodListingFilledEvent_v2, + createPodOrderCreatedEvent_v2, + createPodOrderFilledEvent_v2 +} from "../event-mocking/Marketplace"; +import { ONE_BI, ZERO_BI } from "../../../subgraph-core/utils/Decimals"; +import { + PodListingCreated as PodListingCreated_v2, + PodListingFilled as PodListingFilled_v2, + PodOrderCreated as PodOrderCreated_v2, + PodOrderFilled as PodOrderFilled_v2 +} from "../../generated/BIP29-PodMarketplace/Beanstalk"; +import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; +import { Sow } from "../../generated/Field/Beanstalk"; + +const pricingFunction = Bytes.fromHexString( + "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" +); + +export function sow(account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow { + const event = createSowEvent(account, index, beans, pods); + handleSow(event); + return event; +} + +export function getPodFillId(index: BigInt, event: ethereum.Event): string { + return BEANSTALK.toHexString() + "-" + index.toString() + "-" + event.transaction.hash.toHexString(); +} + +export function fillListing_v2( + from: string, + to: string, + listingIndex: BigInt, + listingStart: BigInt, + podAmount: BigInt, + costInBeans: BigInt +): PodListingFilled_v2 { + const event = createPodListingFilledEvent_v2(from, to, listingIndex, listingStart, podAmount, costInBeans); + handlePodListingFilled_v2(event); + + // Perform plot transfer (necessary for market - assumption is this is tested/working via PlotTransfer.test.ts) + handlePlotTransfer(createPlotTransferEvent(from, to, listingIndex.plus(listingStart), podAmount)); + + // Assert PodFill + const podFillId = getPodFillId(event.params.index, event); + assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); + assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); + assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); + assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); + assert.fieldEquals("PodFill", podFillId, "costInBeans", event.params.costInBeans.toString()); + + return event; +} + +export function fillOrder_v2( + from: string, + to: string, + orderId: Bytes, + index: BigInt, + start: BigInt, + podAmount: BigInt, + costInBeans: BigInt +): PodOrderFilled_v2 { + const event = createPodOrderFilledEvent_v2(from, to, orderId, index, start, podAmount, costInBeans); + handlePodOrderFilled_v2(event); + + // Assert PodFill + const podFillId = getPodFillId(index, event); + assert.fieldEquals("PodFill", podFillId, "order", event.params.id.toHexString()); + assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); + assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); + assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); + assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); + assert.fieldEquals("PodFill", podFillId, "costInBeans", event.params.costInBeans.toString()); + + return event; +} + +export function assertListingCreated_v2(event: PodListingCreated_v2): void { + let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "farmer", event.params.account.toHexString()); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID, "originalIndex", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "originalAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "index", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "start", event.params.start.toString()); + assert.fieldEquals("PodListing", listingID, "amount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "pricePerPod", event.params.pricePerPod.toString()); + assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", event.params.maxHarvestableIndex.toString()); + assert.fieldEquals("PodListing", listingID, "minFillAmount", event.params.minFillAmount.toString()); + assert.fieldEquals("PodListing", listingID, "pricingFunction", event.params.pricingFunction.toHexString()); + assert.fieldEquals("PodListing", listingID, "mode", event.params.mode.toString()); + assert.fieldEquals("PodListing", listingID, "pricingType", event.params.pricingType.toString()); +} + +export function assertOrderCreated_v2(account: string, event: PodOrderCreated_v2): void { + let orderID = event.params.id.toHexString(); + assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); + assert.fieldEquals("PodOrder", orderID, "farmer", account); + assert.fieldEquals("PodOrder", orderID, "status", "ACTIVE"); + assert.fieldEquals("PodOrder", orderID, "beanAmount", event.params.amount.toString()); + assert.fieldEquals("PodOrder", orderID, "beanAmountFilled", "0"); + assert.fieldEquals("PodOrder", orderID, "minFillAmount", event.params.minFillAmount.toString()); + assert.fieldEquals("PodOrder", orderID, "maxPlaceInLine", event.params.maxPlaceInLine.toString()); + assert.fieldEquals("PodOrder", orderID, "pricePerPod", event.params.pricePerPod.toString()); + assert.fieldEquals("PodOrder", orderID, "pricingFunction", event.params.pricingFunction.toHexString()); + assert.fieldEquals("PodOrder", orderID, "pricingType", event.params.priceType.toString()); +} + +export function createListing_v2( + account: string, + index: BigInt, + plotTotalPods: BigInt, + start: BigInt, + maxHarvestableIndex: BigInt +): PodListingCreated_v2 { + const event = createPodListingCreatedEvent_v2( + account, + index, + start, + plotTotalPods.minus(start), + BigInt.fromString("250000"), + maxHarvestableIndex, + BigInt.fromString("10000000"), + pricingFunction, + BigInt.fromI32(0), + BigInt.fromI32(1) + ); + handlePodListingCreated_v2(event); + assertListingCreated_v2(event); + return event; +} + +export function createOrder_v2( + account: string, + id: Bytes, + beans: BigInt, + pricePerPod: BigInt, + maxHarvestableIndex: BigInt +): PodOrderCreated_v2 { + const event = createPodOrderCreatedEvent_v2(account, id, beans, pricePerPod, maxHarvestableIndex, ONE_BI, pricingFunction, ZERO_BI); + handlePodOrderCreated_v2(event); + assertOrderCreated_v2(account, event); + return event; +} + +export function assertMarketListingsState( + address: string, + listings: BigInt[], + listedPods: BigInt, + availableListedPods: BigInt, + cancelledListedPods: BigInt, + filledListedPods: BigInt, + podVolume: BigInt, + beanVolume: BigInt +): void { + assert.fieldEquals("PodMarketplace", address, "listingIndexes", "[" + listings.join(", ") + "]"); + assert.fieldEquals("PodMarketplace", address, "listedPods", listedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "availableListedPods", availableListedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "cancelledListedPods", cancelledListedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "filledListedPods", filledListedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); + assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); +} + +export function assertMarketOrdersState( + address: string, + orders: string[], + orderBeans: BigInt, + filledOrderBeans: BigInt, + filledOrderedPods: BigInt, + cancelledOrderBeans: BigInt, + podVolume: BigInt, + beanVolume: BigInt +): void { + assert.fieldEquals("PodMarketplace", address, "orders", "[" + orders.join(", ") + "]"); + assert.fieldEquals("PodMarketplace", address, "orderBeans", orderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); + assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); +} diff --git a/projects/subgraph-core/utils/Decimals.ts b/projects/subgraph-core/utils/Decimals.ts index 33954db8f1..c2b6a50988 100644 --- a/projects/subgraph-core/utils/Decimals.ts +++ b/projects/subgraph-core/utils/Decimals.ts @@ -6,7 +6,6 @@ export const ZERO_BI = BigInt.fromI32(0); export const ONE_BI = BigInt.fromI32(1); export const BI_6 = BigInt.fromI32(6); export const BI_10 = BigInt.fromI32(10); -export const BI_18 = BigInt.fromI32(18); export const BI_MAX = BigInt.fromUnsignedBytes(Bytes.fromHexString("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); export const ZERO_BD = BigDecimal.fromString("0"); export const ONE_BD = BigDecimal.fromString("1"); From 1b22ac3c41da7110fced36dd65b0d2ad5b1acb7c Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 15:33:00 -0700 Subject: [PATCH 23/89] refactor shared test methods --- .../tests/Marketplace.test.ts | 6 +- .../tests/PlotTransfer.test.ts | 97 +++---------------- .../subgraph-beanstalk/tests/utils/Field.ts | 54 +++++++++++ .../tests/utils/{Pods.ts => Marketplace.ts} | 12 +-- 4 files changed, 74 insertions(+), 95 deletions(-) create mode 100644 projects/subgraph-beanstalk/tests/utils/Field.ts rename projects/subgraph-beanstalk/tests/utils/{Pods.ts => Marketplace.ts} (95%) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 75cf377340..467f9d4476 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -12,9 +12,9 @@ import { createOrder_v2, fillListing_v2, fillOrder_v2, - getPodFillId, - sow -} from "./utils/Pods"; + getPodFillId +} from "./utils/Marketplace"; +import { sow } from "./utils/Field"; const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); diff --git a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts index 2964d60fa0..7d41cc044c 100644 --- a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts +++ b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts @@ -2,18 +2,12 @@ import { beforeEach, afterEach, assert, clearStore, describe, test, createMockedFunction } from "matchstick-as/assembly/index"; import { log } from "matchstick-as/assembly/log"; -import { logStore } from "matchstick-as/assembly/store"; -import { BigInt, ethereum } from "@graphprotocol/graph-ts"; -import { createSowEvent, createPlotTransferEvent } from "./event-mocking/Field"; -import { createIncentivizationEvent } from "./event-mocking/Season"; +import { BigInt } from "@graphprotocol/graph-ts"; -import { loadSeason } from "../src/utils/Season"; - -import { handleSow, handlePlotTransfer } from "../src/FieldHandler"; -import { handleIncentive } from "../src/SeasonHandler"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { beans_BI as beans, podlineMil_BI as mil } from "../../subgraph-core/tests/Values"; +import { assertFarmerHasPlot, assertFieldHas, setHarvestable, sow, transferPlot } from "./utils/Field"; const ANVIL_ADDR_1 = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const ANVIL_ADDR_2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); @@ -50,49 +44,12 @@ const initialPlots: Plot[] = [ } ]; -const assertFarmerHasPlot = ( - farmer: string, - index: BigInt, - numPods: BigInt, - numHarvestable: BigInt = ZERO_BI, - debug: boolean = false -): void => { - if (debug) { - log.debug("about to assert plot {}", [farmer]); - } - assert.fieldEquals("Plot", index.toString(), "farmer", farmer); - assert.fieldEquals("Plot", index.toString(), "pods", numPods.toString()); - // log.debug("about to assert harvestable {}", [numHarvestable.toString()]); - assert.fieldEquals("Plot", index.toString(), "harvestablePods", numHarvestable.toString()); -}; - -// Field can be either a farmer or beanstalk address -const assertFieldHas = (field: string, unharvestable: BigInt, harvestable: BigInt, debug: boolean = false): void => { - if (debug) { - log.debug("about to assert field {}", [field]); - } - assert.fieldEquals("Field", field, "unharvestablePods", unharvestable.toString()); - assert.fieldEquals("Field", field, "harvestablePods", harvestable.toString()); -}; - -// TODO: move this into a shared location -const setHarvestable = (harvestableIndex: BigInt): BigInt => { - createMockedFunction(BEANSTALK, "harvestableIndex", "harvestableIndex():(uint256)").returns([ - ethereum.Value.fromUnsignedBigInt(harvestableIndex) - ]); - - // Incentivization event triggers update of harvestable amount of each plot - handleIncentive(createIncentivizationEvent(ANVIL_ADDR_1, BigInt.fromI32(123456))); - - return harvestableIndex; -}; - // Begin tests describe("Field: Plot Transfer", () => { beforeEach(() => { // Create two equally sized plots next to each other for (let i = 0; i < initialPlots.length; ++i) { - handleSow(createSowEvent(ANVIL_ADDR_1, initialPlots[i].plotStart, initialPlots[i].beansSown, initialPlots[i].pods)); + sow(ANVIL_ADDR_1, initialPlots[i].plotStart, initialPlots[i].beansSown, initialPlots[i].pods); } // Ensure setup was done correctly assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, initialPlots[0].pods); @@ -110,7 +67,7 @@ describe("Field: Plot Transfer", () => { // Transfers entire first plot describe("Full Plot", () => { test("F: Unharvestable", () => { - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); assertFarmerHasPlot(ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, ZERO_BI); @@ -121,11 +78,8 @@ describe("Field: Plot Transfer", () => { test("F: Harvestable (Full)", () => { // Entire first plot is harvestable setHarvestable(initialPlots[0].plotStart.plus(initialPlots[0].pods)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(initialPlots[0].pods); - // season.save(); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); assertFarmerHasPlot(ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods, initialPlots[0].pods); assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, ZERO_BI); @@ -137,11 +91,8 @@ describe("Field: Plot Transfer", () => { // 1/3 of first plot is harvestable const harvestableAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); setHarvestable(initialPlots[0].plotStart.plus(harvestableAmount)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(harvestableAmount); - // season.save(); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); assertFarmerHasPlot(ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods, harvestableAmount); assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, ZERO_BI); @@ -155,7 +106,7 @@ describe("Field: Plot Transfer", () => { test("S: Unharvestable", () => { const transferredIndex = initialPlots[0].plotStart; const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); assertFarmerHasPlot(ANVIL_ADDR_1, transferredIndex.plus(transferredAmount), initialPlots[0].pods.minus(transferredAmount)); assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount); @@ -167,13 +118,10 @@ describe("Field: Plot Transfer", () => { test("S: Harvestable (Full)", () => { // Entire first plot is harvestable setHarvestable(initialPlots[0].plotStart.plus(initialPlots[0].pods)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(initialPlots[0].pods); - // season.save(); const transferredIndex = initialPlots[0].plotStart; const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); assertFarmerHasPlot( ANVIL_ADDR_1, @@ -191,14 +139,11 @@ describe("Field: Plot Transfer", () => { // 1/4 of first plot is harvestable const harvestableAmount = initialPlots[0].pods.div(BigInt.fromI32(4)); setHarvestable(initialPlots[0].plotStart.plus(harvestableAmount)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(harvestableAmount); - // season.save(); // Transfers first third of plot (only some of which is harvestable) const transferredIndex = initialPlots[0].plotStart; const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); const transferredUnharvestable = transferredAmount.minus(harvestableAmount); assertFarmerHasPlot(ANVIL_ADDR_1, transferredIndex.plus(transferredAmount), initialPlots[0].pods.minus(transferredAmount), ZERO_BI); @@ -214,7 +159,7 @@ describe("Field: Plot Transfer", () => { test("E: Unharvestable", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, initialPlots[0].pods.minus(transferredAmount)); assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount); @@ -226,13 +171,10 @@ describe("Field: Plot Transfer", () => { test("E: Harvestable (Full)", () => { // Entire first plot is harvestable setHarvestable(initialPlots[0].plotStart.plus(initialPlots[0].pods)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(initialPlots[0].pods); - // season.save(); const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); assertFarmerHasPlot( ANVIL_ADDR_1, @@ -250,13 +192,10 @@ describe("Field: Plot Transfer", () => { // 3/4 of first plot is harvestable const harvestableAmount = initialPlots[0].pods.times(BigInt.fromI32(3)).div(BigInt.fromI32(4)); const harvestableIndex = setHarvestable(initialPlots[0].plotStart.plus(harvestableAmount)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(harvestableAmount); - // season.save(); const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); const transferredHarvestable = harvestableIndex.minus(transferredIndex); assertFarmerHasPlot( @@ -277,7 +216,7 @@ describe("Field: Plot Transfer", () => { test("M: Unharvestable", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, transferredAmount); assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount); @@ -290,13 +229,10 @@ describe("Field: Plot Transfer", () => { test("M: Harvestable (Full)", () => { // Entire first plot is harvestable setHarvestable(initialPlots[0].plotStart.plus(initialPlots[0].pods)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(initialPlots[0].pods); - // season.save(); const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, transferredAmount, transferredAmount); assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount, transferredAmount); @@ -310,13 +246,10 @@ describe("Field: Plot Transfer", () => { // 1/2 of first plot is harvestable const harvestableAmount = initialPlots[0].pods.div(BigInt.fromI32(2)); setHarvestable(initialPlots[0].plotStart.plus(harvestableAmount)); - // const season = loadSeason(BEANSTALK, BigInt.fromU32(1)); - // season.harvestableIndex = initialPlots[0].plotStart.plus(harvestableAmount); - // season.save(); const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); - handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); const transferredHarvestable = harvestableAmount.minus(transferredAmount); assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, transferredAmount, harvestableAmount.minus(transferredHarvestable)); diff --git a/projects/subgraph-beanstalk/tests/utils/Field.ts b/projects/subgraph-beanstalk/tests/utils/Field.ts new file mode 100644 index 0000000000..e51030b9e6 --- /dev/null +++ b/projects/subgraph-beanstalk/tests/utils/Field.ts @@ -0,0 +1,54 @@ +import { BigInt, ethereum, log } from "@graphprotocol/graph-ts"; +import { assert, createMockedFunction } from "matchstick-as/assembly/index"; +import { createPlotTransferEvent, createSowEvent } from "../event-mocking/Field"; +import { handlePlotTransfer, handleSow } from "../../src/FieldHandler"; +import { createIncentivizationEvent } from "../event-mocking/Season"; +import { handleIncentive } from "../../src/SeasonHandler"; +import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; +import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; + +const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); + +export function sow(account: string, index: BigInt, beans: BigInt, pods: BigInt): void { + handleSow(createSowEvent(account, index, beans, pods)); +} + +export function transferPlot(from: string, to: string, id: BigInt, amount: BigInt): void { + handlePlotTransfer(createPlotTransferEvent(from, to, id, amount)); +} + +export function setHarvestable(harvestableIndex: BigInt): BigInt { + createMockedFunction(BEANSTALK, "harvestableIndex", "harvestableIndex():(uint256)").returns([ + ethereum.Value.fromUnsignedBigInt(harvestableIndex) + ]); + + // Incentivization event triggers update of harvestable amount of each plot + handleIncentive(createIncentivizationEvent(account, BigInt.fromI32(123456))); + + return harvestableIndex; +} + +export function assertFarmerHasPlot( + farmer: string, + index: BigInt, + numPods: BigInt, + numHarvestable: BigInt = ZERO_BI, + debug: boolean = false +): void { + if (debug) { + log.debug("about to assert plot {}", [farmer]); + } + assert.fieldEquals("Plot", index.toString(), "farmer", farmer); + assert.fieldEquals("Plot", index.toString(), "pods", numPods.toString()); + // log.debug("about to assert harvestable {}", [numHarvestable.toString()]); + assert.fieldEquals("Plot", index.toString(), "harvestablePods", numHarvestable.toString()); +} + +// Field can be either a farmer or beanstalk address +export function assertFieldHas(field: string, unharvestable: BigInt, harvestable: BigInt, debug: boolean = false): void { + if (debug) { + log.debug("about to assert field {}", [field]); + } + assert.fieldEquals("Field", field, "unharvestablePods", unharvestable.toString()); + assert.fieldEquals("Field", field, "harvestablePods", harvestable.toString()); +} diff --git a/projects/subgraph-beanstalk/tests/utils/Pods.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts similarity index 95% rename from projects/subgraph-beanstalk/tests/utils/Pods.ts rename to projects/subgraph-beanstalk/tests/utils/Marketplace.ts index ab1f07d40e..7f13b48e57 100644 --- a/projects/subgraph-beanstalk/tests/utils/Pods.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -1,13 +1,11 @@ import { BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; import { assert } from "matchstick-as/assembly/index"; -import { handlePlotTransfer, handleSow } from "../../src/FieldHandler"; import { handlePodListingCreated_v2, handlePodListingFilled_v2, handlePodOrderCreated_v2, handlePodOrderFilled_v2 } from "../../src/MarketplaceHandler"; -import { createPlotTransferEvent, createSowEvent } from "../event-mocking/Field"; import { createPodListingCreatedEvent_v2, createPodListingFilledEvent_v2, @@ -22,18 +20,12 @@ import { PodOrderFilled as PodOrderFilled_v2 } from "../../generated/BIP29-PodMarketplace/Beanstalk"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; -import { Sow } from "../../generated/Field/Beanstalk"; +import { transferPlot } from "./Field"; const pricingFunction = Bytes.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" ); -export function sow(account: string, index: BigInt, beans: BigInt, pods: BigInt): Sow { - const event = createSowEvent(account, index, beans, pods); - handleSow(event); - return event; -} - export function getPodFillId(index: BigInt, event: ethereum.Event): string { return BEANSTALK.toHexString() + "-" + index.toString() + "-" + event.transaction.hash.toHexString(); } @@ -50,7 +42,7 @@ export function fillListing_v2( handlePodListingFilled_v2(event); // Perform plot transfer (necessary for market - assumption is this is tested/working via PlotTransfer.test.ts) - handlePlotTransfer(createPlotTransferEvent(from, to, listingIndex.plus(listingStart), podAmount)); + transferPlot(from, to, listingIndex.plus(listingStart), podAmount); // Assert PodFill const podFillId = getPodFillId(event.params.index, event); From d44eac8d7e3ba4696278c3c48bcc6c731ecd6410 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 15:39:44 -0700 Subject: [PATCH 24/89] change reference to mockBeanstalkEvent --- .../subgraph-beanstalk/tests/SeedGauge.test.ts | 2 +- .../tests/YieldHandler.test.ts | 2 +- .../tests/event-mocking/Field.ts | 10 +--------- .../tests/event-mocking/Marketplace.ts | 11 +---------- .../tests/event-mocking/Season.ts | 17 +---------------- .../tests/event-mocking/SeedGauge.ts | 11 +---------- .../tests/event-mocking/Whitelist.ts | 10 +--------- .../subgraph-beanstalk/tests/utils/Season.ts | 8 ++++++++ 8 files changed, 15 insertions(+), 56 deletions(-) create mode 100644 projects/subgraph-beanstalk/tests/utils/Season.ts diff --git a/projects/subgraph-beanstalk/tests/SeedGauge.test.ts b/projects/subgraph-beanstalk/tests/SeedGauge.test.ts index b12640ffaf..df2ee215fd 100644 --- a/projects/subgraph-beanstalk/tests/SeedGauge.test.ts +++ b/projects/subgraph-beanstalk/tests/SeedGauge.test.ts @@ -32,7 +32,7 @@ import { simpleMockPrice } from "../../subgraph-core/tests/event-mocking/Prices" import { loadSilo } from "../src/utils/SiloEntities"; import { mockBlock } from "../../subgraph-core/tests/event-mocking/Block"; import { dayFromTimestamp } from "../src/utils/Dates"; -import { setSeason } from "./event-mocking/Season"; +import { setSeason } from "./utils/Season"; const ANVIL_ADDR_1 = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); diff --git a/projects/subgraph-beanstalk/tests/YieldHandler.test.ts b/projects/subgraph-beanstalk/tests/YieldHandler.test.ts index 275985a4e1..511b8d768b 100644 --- a/projects/subgraph-beanstalk/tests/YieldHandler.test.ts +++ b/projects/subgraph-beanstalk/tests/YieldHandler.test.ts @@ -12,7 +12,7 @@ import { UNRIPE_BEAN_3CRV, LUSD_3POOL } from "../../subgraph-core/utils/Constants"; -import { setSeason } from "./event-mocking/Season"; +import { setSeason } from "./utils/Season"; describe("APY Calculations", () => { describe("Pre-Gauge", () => { diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Field.ts b/projects/subgraph-beanstalk/tests/event-mocking/Field.ts index ec7fa946c4..affbd01807 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Field.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Field.ts @@ -1,16 +1,8 @@ import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; -import { newMockEvent } from "matchstick-as/assembly/index"; import { Sow, PlotTransfer } from "../../generated/Field/Beanstalk"; import { TemperatureChange } from "../../generated/BIP44-SeedGauge/Beanstalk"; -import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; - -// Default mock to include beanstalk address -const mockBeanstalkEvent = (): ethereum.Event => { - let e = changetype(newMockEvent()); - e.address = BEANSTALK; - return e; -}; +import { mockBeanstalkEvent } from "../../../subgraph-core/tests/event-mocking/Util"; export function createWeatherChangeEvent(season: BigInt, caseID: BigInt, change: i32): void {} diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts index 70d5c77c0a..0882940329 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts @@ -1,5 +1,4 @@ import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; -import { newMockEvent } from "matchstick-as/assembly/index"; import { PodListingCancelled, @@ -16,15 +15,7 @@ import { PodOrderCreated as PodOrderCreated_v2, PodOrderFilled as PodOrderFilled_v2 } from "../../generated/BIP29-PodMarketplace/Beanstalk"; -import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; - -// Default mock to include beanstalk address -// TODO: update to use the subgraph-core one after merge -const mockBeanstalkEvent = (): ethereum.Event => { - let e = changetype(newMockEvent()); - e.address = BEANSTALK; - return e; -}; +import { mockBeanstalkEvent } from "../../../subgraph-core/tests/event-mocking/Util"; /** ===== Marketplace V1 Events ===== */ export function createPodListingCreatedEvent( diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Season.ts b/projects/subgraph-beanstalk/tests/event-mocking/Season.ts index 4c409ec282..0b197f8f32 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Season.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Season.ts @@ -1,22 +1,7 @@ import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts"; -import { newMockEvent } from "matchstick-as/assembly/index"; import { Incentivization } from "../../generated/Season-Replanted/Beanstalk"; -import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; -import { loadBeanstalk } from "../../src/utils/Beanstalk"; - -// Default mock to include beanstalk address -const mockBeanstalkEvent = (): ethereum.Event => { - let e = changetype(newMockEvent()); - e.address = BEANSTALK; - return e; -}; - -export function setSeason(season: u32): void { - let beanstalk = loadBeanstalk(BEANSTALK); - beanstalk.lastSeason = season; - beanstalk.save(); -} +import { mockBeanstalkEvent } from "../../../subgraph-core/tests/event-mocking/Util"; export function createSunriseEvent(season: BigInt): void {} export function createSeasonSnapshotEvent( diff --git a/projects/subgraph-beanstalk/tests/event-mocking/SeedGauge.ts b/projects/subgraph-beanstalk/tests/event-mocking/SeedGauge.ts index b188925dc8..f1de2c25e8 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/SeedGauge.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/SeedGauge.ts @@ -1,5 +1,4 @@ import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; -import { newMockEvent } from "matchstick-as/assembly/index"; import { BeanToMaxLpGpPerBdvRatioChange, GaugePointChange, @@ -10,15 +9,7 @@ import { TotalGerminatingStalkChanged, TotalStalkChangedFromGermination } from "../../generated/BIP44-SeedGauge/Beanstalk"; - -import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; - -// Default mock to include beanstalk address -const mockBeanstalkEvent = (): ethereum.Event => { - let e = changetype(newMockEvent()); - e.address = BEANSTALK; - return e; -}; +import { mockBeanstalkEvent } from "../../../subgraph-core/tests/event-mocking/Util"; export function createBeanToMaxLpGpPerBdvRatioChangeEvent( season: BigInt, diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Whitelist.ts b/projects/subgraph-beanstalk/tests/event-mocking/Whitelist.ts index 555d88c136..b496233dc1 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Whitelist.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Whitelist.ts @@ -1,17 +1,9 @@ import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; -import { newMockEvent } from "matchstick-as/assembly/index"; -import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; import { WhitelistToken as WhitelistToken_V2, DewhitelistToken } from "../../generated/Silo-Replanted/Beanstalk"; import { WhitelistToken as WhitelistToken_V3 } from "../../generated/Silo-V3/Beanstalk"; import { WhitelistToken as WhitelistToken_V4 } from "../../generated/BIP44-SeedGauge/Beanstalk"; - -// Default mock to include beanstalk address -const mockBeanstalkEvent = (): ethereum.Event => { - let e = changetype(newMockEvent()); - e.address = BEANSTALK; - return e; -}; +import { mockBeanstalkEvent } from "../../../subgraph-core/tests/event-mocking/Util"; export function createWhitelistTokenV2Event(token: string, selector: string, seeds: BigInt, stalk: BigInt): WhitelistToken_V2 { let event = changetype(mockBeanstalkEvent()); diff --git a/projects/subgraph-beanstalk/tests/utils/Season.ts b/projects/subgraph-beanstalk/tests/utils/Season.ts new file mode 100644 index 0000000000..775486c734 --- /dev/null +++ b/projects/subgraph-beanstalk/tests/utils/Season.ts @@ -0,0 +1,8 @@ +import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; +import { loadBeanstalk } from "../../src/utils/Beanstalk"; + +export function setSeason(season: u32): void { + let beanstalk = loadBeanstalk(BEANSTALK); + beanstalk.lastSeason = season; + beanstalk.save(); +} From a5979bf1878784324bc4a0f001b025ba490d98f6 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 16:16:37 -0700 Subject: [PATCH 25/89] listing expiry test and fixes --- .../src/MarketplaceHandler.ts | 2 + .../subgraph-beanstalk/src/SeasonHandler.ts | 29 ++------ .../src/utils/PodMarketplace.ts | 24 ++++++ .../tests/Marketplace.test.ts | 73 ++++++++++++++++--- .../tests/utils/Marketplace.ts | 2 + 5 files changed, 96 insertions(+), 34 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index df42797eb7..859ce35829 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -180,6 +180,7 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { const marketListings = market.listingIndexes; marketListings.push(remainingListing.index); + marketListings.sort(); market.listingIndexes = marketListings; market.save(); } @@ -554,6 +555,7 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { const marketListings = market.listingIndexes; marketListings.push(remainingListing.index); + marketListings.sort(); market.listingIndexes = marketListings; market.save(); } diff --git a/projects/subgraph-beanstalk/src/SeasonHandler.ts b/projects/subgraph-beanstalk/src/SeasonHandler.ts index f111690587..3b385fe0d8 100644 --- a/projects/subgraph-beanstalk/src/SeasonHandler.ts +++ b/projects/subgraph-beanstalk/src/SeasonHandler.ts @@ -10,7 +10,12 @@ import { BEANSTALK, BEANSTALK_PRICE, BEAN_ERC20, CURVE_PRICE } from "../../subgr import { ONE_BI, toDecimal, ZERO_BD, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { loadField, loadFieldDaily, loadFieldHourly } from "./utils/Field"; import { expirePodListing, loadPodListing } from "./utils/PodListing"; -import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, loadPodMarketplaceHourlySnapshot } from "./utils/PodMarketplace"; +import { + loadPodMarketplace, + loadPodMarketplaceDailySnapshot, + loadPodMarketplaceHourlySnapshot, + updateExpiredPlots +} from "./utils/PodMarketplace"; import { loadSeason } from "./utils/Season"; import { addDepositToSiloAsset, updateStalkWithCalls } from "./SiloHandler"; import { updateBeanEMA } from "./YieldHandler"; @@ -31,7 +36,6 @@ export function handleSunrise(event: Sunrise): void { updateStalkWithCalls(currentSeason - 1, event.block.timestamp, event.block.number); // Update season metrics - //season.harvestableIndex = beanstalkContract.harvestableIndex() if (event.params.season == BigInt.fromI32(6075)) { season.price = BigDecimal.fromString("1.07"); } // Replant oracle initialization @@ -66,26 +70,6 @@ export function handleSunrise(event: Sunrise): void { marketHourly.save(); marketDaily.save(); - let remainingListings = market.listingIndexes; - - // Cancel any pod marketplace listings beyond the index - for (let i = 0; i < market.listingIndexes.length; i++) { - if (market.listingIndexes[i] < season.harvestableIndex) { - expirePodListing(event.address, event.block.timestamp, market.listingIndexes[i]); - remainingListings.shift(); - } else { - let listing = loadPodListing(event.address, market.listingIndexes[i]); - if (listing.maxHarvestableIndex < season.harvestableIndex) { - expirePodListing(event.address, event.block.timestamp, market.listingIndexes[i]); - let listingIndex = market.listingIndexes.indexOf(listing.index); - remainingListings.splice(listingIndex, 1); - } - } - } - - market.listingIndexes = remainingListings; - market.save(); - // Create silo entities for the protocol let silo = loadSilo(event.address); loadSiloHourlySnapshot(event.address, currentSeason, event.block.timestamp); @@ -255,5 +239,6 @@ export function handleIncentive(event: Incentivization): void { season.harvestableIndex = beanstalk_contract.harvestableIndex(); season.save(); + updateExpiredPlots(season.harvestableIndex, event.address, event.block.timestamp); updateHarvestablePlots(season.harvestableIndex, event.block.timestamp, event.block.number); } diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index 62dd77ebd1..0df5e2587f 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -3,6 +3,7 @@ import { PodMarketplace, PodMarketplaceHourlySnapshot, PodMarketplaceDailySnapsh import { dayFromTimestamp, hourFromTimestamp } from "./Dates"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; import { loadField } from "./Field"; +import { expirePodListing, loadPodListing } from "./PodListing"; export function loadPodMarketplace(diamondAddress: Address): PodMarketplace { let marketplace = PodMarketplace.load(diamondAddress.toHexString()); @@ -104,3 +105,26 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta } return snapshot; } + +export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Address, timestamp: BigInt): void { + let market = loadPodMarketplace(diamondAddress); + let remainingListings = market.listingIndexes; + + // Cancel any pod marketplace listings beyond the index + for (let i = 0; i < remainingListings.length; i++) { + if (remainingListings[i] < harvestableIndex) { + expirePodListing(diamondAddress, timestamp, remainingListings[i]); + remainingListings.splice(i--, 1); + } else { + let listing = loadPodListing(diamondAddress, remainingListings[i]); + if (listing.maxHarvestableIndex < harvestableIndex) { + expirePodListing(diamondAddress, timestamp, remainingListings[i]); + remainingListings.splice(i--, 1); + } + } + } + + remainingListings.sort(); + market.listingIndexes = remainingListings; + market.save(); +} diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 467f9d4476..a778bde1a0 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -3,7 +3,7 @@ import { afterEach, assert, beforeEach, clearStore, describe, test } from "match import { handlePodListingCancelled, handlePodOrderCancelled } from "../src/MarketplaceHandler"; import { createPodListingCancelledEvent, createPodOrderCancelledEvent } from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; -import { BI_10, ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; import { assertMarketListingsState, @@ -14,7 +14,7 @@ import { fillOrder_v2, getPodFillId } from "./utils/Marketplace"; -import { sow } from "./utils/Field"; +import { setHarvestable, sow } from "./utils/Field"; const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); @@ -42,15 +42,10 @@ describe("Marketplace", () => { // listing expires due to podline advancing // order expires due to podline advancing - // describe("Marketplace v1", () => { - // test("Create a pod listing - full plot", () => {}); - // test("Create a pod listing - partial plot", () => {}); - // }); - describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { const event = createListing_v2(account, listingIndex, sowedPods, ZERO_BI, maxHarvestableIndex); - assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], sowedPods, sowedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], sowedPods, sowedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); // Create a second listing to assert the market state again const listing2Index = listingIndex.times(BI_10); @@ -64,6 +59,7 @@ describe("Marketplace", () => { ZERO_BI, ZERO_BI, ZERO_BI, + ZERO_BI, ZERO_BI ); }); @@ -71,7 +67,17 @@ describe("Marketplace", () => { test("Create a pod listing - partial plot", () => { const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); const listedPods = sowedPods.minus(beans_BI(500)); - assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], listedPods, listedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketListingsState( + BEANSTALK.toHexString(), + [listingIndex], + listedPods, + listedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); }); test("Create a pod order", () => { @@ -106,7 +112,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "filled", listedPods.toString()); assert.entityCount("PodListing", 1); - assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, listedPods, filledBeans); + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, ZERO_BI, listedPods, listedPods, filledBeans); }); test("Fill listing - partial, then full", () => { @@ -139,6 +145,7 @@ describe("Marketplace", () => { listedPods, remaining, ZERO_BI, + ZERO_BI, filledPods, filledPods, filledBeans @@ -163,6 +170,7 @@ describe("Marketplace", () => { listedPods, ZERO_BI, ZERO_BI, + ZERO_BI, listedPods, listedPods, filledBeans.plus(newFilledBeans) @@ -180,7 +188,17 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "cancelledAmount", cancelledAmount.toString()); assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); - assertMarketListingsState(BEANSTALK.toHexString(), [], cancelledAmount, ZERO_BI, cancelledAmount, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketListingsState( + BEANSTALK.toHexString(), + [], + cancelledAmount, + ZERO_BI, + cancelledAmount, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); }); test("Cancel listing - partial", () => { @@ -201,7 +219,17 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", newListingID, "cancelledAmount", remaining.toString()); assert.fieldEquals("PodListing", newListingID, "remainingAmount", "0"); - assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, remaining, filledPods, filledPods, filledBeans); + assertMarketListingsState( + BEANSTALK.toHexString(), + [], + listedPods, + ZERO_BI, + remaining, + ZERO_BI, + filledPods, + filledPods, + filledBeans + ); }); test("Recreate listing", () => { @@ -224,6 +252,7 @@ describe("Marketplace", () => { listedPods, ZERO_BI, ZERO_BI, + ZERO_BI, ZERO_BI ); @@ -254,11 +283,31 @@ describe("Marketplace", () => { listedPods.times(BigInt.fromU32(2)).plus(newListingAmount), newListingAmount, listedPods.plus(newListingAmount), + ZERO_BI, filledPods, filledPods, filledBeans ); }); + + test("Listing expires due to moving podline", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const listingID = account + "-" + listingIndex.toString(); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + + // Expires due to listed becoming harvestable + setHarvestable(listingIndex); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + setHarvestable(listingIndex.plus(ONE_BI)); + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); + + // TODO: partial expire + // TODO: expire due to exceeding maxHarvestableIndex + }); }); describe("Tests requiring Order", () => { diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index 7f13b48e57..fd58fe2070 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -158,6 +158,7 @@ export function assertMarketListingsState( listedPods: BigInt, availableListedPods: BigInt, cancelledListedPods: BigInt, + expiredListedPods: BigInt, filledListedPods: BigInt, podVolume: BigInt, beanVolume: BigInt @@ -166,6 +167,7 @@ export function assertMarketListingsState( assert.fieldEquals("PodMarketplace", address, "listedPods", listedPods.toString()); assert.fieldEquals("PodMarketplace", address, "availableListedPods", availableListedPods.toString()); assert.fieldEquals("PodMarketplace", address, "cancelledListedPods", cancelledListedPods.toString()); + assert.fieldEquals("PodMarketplace", address, "expiredListedPods", expiredListedPods.toString()); assert.fieldEquals("PodMarketplace", address, "filledListedPods", filledListedPods.toString()); assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); From a5dabf598b0f25019cdf2b8fa80103b8639aa9f7 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 17:14:35 -0700 Subject: [PATCH 26/89] minor refactor and notes --- projects/subgraph-beanstalk/schema.graphql | 4 ++-- .../subgraph-beanstalk/src/MarketplaceHandler.ts | 4 ++-- .../src/utils/PodMarketplace.ts | 16 ++++++++-------- .../subgraph-beanstalk/tests/Marketplace.test.ts | 7 ++++--- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index bb96b4a887..7d0f5197d0 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -1142,9 +1142,9 @@ type PodFill @entity { listing: PodListing "Associated order, if any" order: PodOrder - "Account fulfilling the order" + "Account that is sending pods" from: String! # These are already referenced via the listing and order entities. - "Account filling the order" + "Account that is receiving pods" to: Farmer! "Number of pods filled" amount: BigInt! diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 859ce35829..77303a9eae 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -312,9 +312,9 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { rawEvent.save(); } -let historyID = ""; - export function handlePodOrderCancelled(event: PodOrderCancelled): void { + let historyID = ""; + let orderCheck = PodOrder.load(event.params.id.toHexString()); if (orderCheck !== null) { let order = loadPodOrder(event.params.id); diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index 0df5e2587f..ebd43e4373 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -1,4 +1,4 @@ -import { Address, BigInt } from "@graphprotocol/graph-ts"; +import { Address, BigInt, log } from "@graphprotocol/graph-ts"; import { PodMarketplace, PodMarketplaceHourlySnapshot, PodMarketplaceDailySnapshot } from "../../generated/schema"; import { dayFromTimestamp, hourFromTimestamp } from "./Dates"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; @@ -110,17 +110,17 @@ export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Add let market = loadPodMarketplace(diamondAddress); let remainingListings = market.listingIndexes; + // TODO: expire plot upon harvest rather than the line moving past the start index + // TODO: consider saving either a separate list or within this list, the indices that they expire + // this will prevent having to load every listing upon each season + // Cancel any pod marketplace listings beyond the index for (let i = 0; i < remainingListings.length; i++) { - if (remainingListings[i] < harvestableIndex) { + // TODO: this needs to be the user account + let listing = loadPodListing(diamondAddress, remainingListings[i]); + if (harvestableIndex > listing.maxHarvestableIndex) { expirePodListing(diamondAddress, timestamp, remainingListings[i]); remainingListings.splice(i--, 1); - } else { - let listing = loadPodListing(diamondAddress, remainingListings[i]); - if (listing.maxHarvestableIndex < harvestableIndex) { - expirePodListing(diamondAddress, timestamp, remainingListings[i]); - remainingListings.splice(i--, 1); - } } } diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index a778bde1a0..e936e94931 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -295,8 +295,9 @@ describe("Marketplace", () => { const listedPods = sowedPods.minus(listingStart); const listingID = account + "-" + listingIndex.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", maxHarvestableIndex.toString()); - // Expires due to listed becoming harvestable + // Expires due to exceeding max harvestable index setHarvestable(listingIndex); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); setHarvestable(listingIndex.plus(ONE_BI)); @@ -305,8 +306,8 @@ describe("Marketplace", () => { assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); - // TODO: partial expire - // TODO: expire due to exceeding maxHarvestableIndex + // TODO: expire after a partial sale + // TODO: expire due to listed being harvested }); }); From 9cef39a01319ab5e743f67fbe2edbe0c2b0b9e9e Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 20:29:42 -0700 Subject: [PATCH 27/89] refactor stored listing/order format --- projects/subgraph-beanstalk/package.json | 4 +- projects/subgraph-beanstalk/schema.graphql | 8 +- .../src/MarketplaceHandler.ts | 181 ++++++++++-------- .../src/utils/PodMarketplace.ts | 99 ++++++++-- .../tests/Marketplace.test.ts | 33 +++- .../tests/utils/Marketplace.ts | 15 +- yarn.lock | 20 +- 7 files changed, 226 insertions(+), 134 deletions(-) diff --git a/projects/subgraph-beanstalk/package.json b/projects/subgraph-beanstalk/package.json index 16a7de0a96..58e04229d5 100644 --- a/projects/subgraph-beanstalk/package.json +++ b/projects/subgraph-beanstalk/package.json @@ -27,8 +27,8 @@ "deploy-hosted-test": "graph deploy --node http://graph.node.bean.money:8020/ --ipfs http://graph.node.bean.money:5001 beanstalk-testing" }, "dependencies": { - "@graphprotocol/graph-cli": "0.69.0", - "@graphprotocol/graph-ts": "0.34.0", + "@graphprotocol/graph-cli": "0.71.2", + "@graphprotocol/graph-ts": "0.35.1", "matchstick-as": "^0.6.0" }, "private": true diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 7d0f5197d0..7a5b71625f 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -701,10 +701,10 @@ type PodMarketplace @entity { id: ID! "Current season of the marketplace" season: Int! - "Indexes of actively listed plots" - listingIndexes: [BigInt!]! - "Active pod order IDs" - orders: [PodOrder!]! + "Information about the active pod listings. Each entry of the form 'account-index-expiry'" + activeListings: [String!]! + "Information about the active pod orders. Each entry of the form 'account-index-expiry'" + activeOrders: [String!]! "All historical listings" allListings: [PodListing!]! @derivedFrom(field: "podMarketplace") "All historical orders" diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 77303a9eae..b5e41fd773 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -30,7 +30,14 @@ import { loadFarmer } from "./utils/Farmer"; import { loadPlot } from "./utils/Plot"; import { loadPodFill } from "./utils/PodFill"; import { createHistoricalPodListing, loadPodListing } from "./utils/PodListing"; -import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, loadPodMarketplaceHourlySnapshot } from "./utils/PodMarketplace"; +import { + loadPodMarketplace, + loadPodMarketplaceDailySnapshot, + loadPodMarketplaceHourlySnapshot, + MarketplaceAction, + updateActiveListings, + updateActiveOrders +} from "./utils/PodMarketplace"; import { createHistoricalPodOrder, loadPodOrder } from "./utils/PodOrder"; /* ------------------------------------ @@ -94,7 +101,14 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateActiveListings( + event.address, + MarketplaceAction.CREATED, + event.params.account.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateMarketListingBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -119,7 +133,14 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { export function handlePodListingCancelled(event: PodListingCancelled): void { let listing = loadPodListing(event.params.account, event.params.index); - updateMarketListingBalances(event.address, event.params.index, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); + updateActiveListings( + event.address, + MarketplaceAction.CANCELLED, + event.params.account.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateMarketListingBalances(event.address, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); listing.status = listing.filled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; listing.cancelledAmount = listing.remainingAmount; @@ -146,7 +167,7 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { let beanAmount = BigInt.fromI32(listing.pricePerPod).times(event.params.amount).div(BigInt.fromI32(1000000)); - updateMarketListingBalances(event.address, event.params.index, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); + updateMarketListingBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); listing.filledAmount = event.params.amount; listing.remainingAmount = listing.remainingAmount.minus(event.params.amount); @@ -156,6 +177,13 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { let originalHistoryID = listing.historyID; if (listing.remainingAmount == ZERO_BI) { listing.status = "FILLED"; + updateActiveListings( + event.address, + MarketplaceAction.FILLED_FULL, + event.params.from.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); } else { let market = loadPodMarketplace(event.address); @@ -178,11 +206,20 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { remainingListing.creationHash = event.transaction.hash.toHexString(); remainingListing.save(); - const marketListings = market.listingIndexes; - marketListings.push(remainingListing.index); - marketListings.sort(); - market.listingIndexes = marketListings; - market.save(); + updateActiveListings( + event.address, + MarketplaceAction.FILLED_PARTIAL, + event.params.from.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateActiveListings( + event.address, + MarketplaceAction.CREATED, + event.params.from.toHexString(), + remainingListing.index, + remainingListing.maxHarvestableIndex + ); } /// Save pod fill @@ -237,7 +274,8 @@ export function handlePodOrderCreated(event: PodOrderCreated_v1): void { order.creationHash = event.transaction.hash.toHexString(); order.save(); - updateMarketOrderBalances(event.address, order.id, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateActiveOrders(event.address, MarketplaceAction.CREATED, order.id, order.maxPlaceInLine); + updateMarketOrderBalances(event.address, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -281,19 +319,10 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { fill.costInBeans = beanAmount; fill.save(); - updateMarketOrderBalances(event.address, order.id, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); - if (order.status == "FILLED") { - let market = loadPodMarketplace(event.address); - - let orderIndex = market.orders.indexOf(order.id); - if (orderIndex !== -1) { - let marketOrders = market.orders; - marketOrders.splice(orderIndex, 1); - market.orders = marketOrders; - } - market.save(); + updateActiveOrders(event.address, MarketplaceAction.FILLED_FULL, order.id, order.maxPlaceInLine); } + updateMarketOrderBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); // Save the raw event data let id = "podOrderFilled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -323,9 +352,9 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { order.updatedAt = event.block.timestamp; order.save(); + updateActiveOrders(event.address, MarketplaceAction.CANCELLED, order.id, order.maxPlaceInLine); updateMarketOrderBalances( event.address, - order.id, ZERO_BI, order.beanAmount.minus(order.beanAmountFilled), ZERO_BI, @@ -406,7 +435,14 @@ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): voi plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateActiveListings( + event.address, + MarketplaceAction.CREATED, + event.params.account.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateMarketListingBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -485,7 +521,14 @@ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { plot.save(); /// Update market totals - updateMarketListingBalances(event.address, plot.index, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateActiveListings( + event.address, + MarketplaceAction.CREATED, + event.params.account.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateMarketListingBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); /// Save raw event data let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -512,15 +555,7 @@ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { let listing = loadPodListing(event.params.from, event.params.index); - updateMarketListingBalances( - event.address, - event.params.index, - ZERO_BI, - ZERO_BI, - event.params.amount, - event.params.costInBeans, - event.block.timestamp - ); + updateMarketListingBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, event.params.costInBeans, event.block.timestamp); listing.filledAmount = event.params.amount; listing.remainingAmount = listing.remainingAmount.minus(event.params.amount); @@ -530,12 +565,17 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { let originalHistoryID = listing.historyID; if (listing.remainingAmount == ZERO_BI) { listing.status = "FILLED"; + updateActiveListings( + event.address, + MarketplaceAction.FILLED_FULL, + event.params.from.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); } else { - let market = loadPodMarketplace(event.address); - listing.status = "FILLED_PARTIAL"; - let remainingListing = loadPodListing(Address.fromString(listing.farmer), listing.index.plus(event.params.amount).plus(listing.start)); + let remainingListing = loadPodListing(Address.fromString(listing.farmer), listing.index.plus(event.params.amount).plus(listing.start)); remainingListing.historyID = remainingListing.id + "-" + event.block.timestamp.toString(); remainingListing.plot = listing.index.plus(event.params.amount).plus(listing.start).toString(); remainingListing.createdAt = listing.createdAt; @@ -553,11 +593,21 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { remainingListing.minFillAmount = listing.minFillAmount; remainingListing.save(); - const marketListings = market.listingIndexes; - marketListings.push(remainingListing.index); - marketListings.sort(); - market.listingIndexes = marketListings; - market.save(); + // Process the partial fill on the prev listing, and the new listing + updateActiveListings( + event.address, + MarketplaceAction.FILLED_PARTIAL, + event.params.from.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateActiveListings( + event.address, + MarketplaceAction.CREATED, + event.params.from.toHexString(), + remainingListing.index, + remainingListing.maxHarvestableIndex + ); } let fill = loadPodFill(event.address, event.params.index, event.transaction.hash.toHexString()); @@ -616,7 +666,8 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { order.fills = []; order.save(); - updateMarketOrderBalances(event.address, order.id, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); + updateActiveOrders(event.address, MarketplaceAction.CREATED, order.id, order.maxPlaceInLine); + updateMarketOrderBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); // Save the raw event data let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); @@ -660,28 +711,12 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { fill.costInBeans = event.params.costInBeans; fill.save(); - updateMarketOrderBalances( - event.address, - order.id, - ZERO_BI, - ZERO_BI, - event.params.amount, - event.params.costInBeans, - event.block.timestamp - ); - if (order.beanAmountFilled == order.beanAmount) { - let market = loadPodMarketplace(event.address); - - let orderIndex = market.orders.indexOf(order.id); - if (orderIndex !== -1) { - let marketOrders = market.orders; - marketOrders.splice(orderIndex, 1); - market.orders = marketOrders; - } - market.save(); + updateActiveOrders(event.address, MarketplaceAction.FILLED_FULL, order.id, order.maxPlaceInLine); } + updateMarketOrderBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, event.params.costInBeans, event.block.timestamp); + // Save the raw event data let id = "podOrderFilled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); let rawEvent = new PodOrderFilledEvent(id); @@ -707,7 +742,6 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { function updateMarketListingBalances( marketAddress: Address, - plotIndex: BigInt, newPodAmount: BigInt, cancelledPodAmount: BigInt, filledPodAmount: BigInt, @@ -718,24 +752,12 @@ function updateMarketListingBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - let marketIndexes = market.listingIndexes; - - // Update Listing indexes - if (newPodAmount > ZERO_BI) { - marketIndexes.push(plotIndex); - marketIndexes.sort(); - } - if (cancelledPodAmount > ZERO_BI || filledPodAmount > ZERO_BI) { - let listingIndex = market.listingIndexes.indexOf(plotIndex); - marketIndexes.splice(listingIndex, 1); - } market.listedPods = market.listedPods.plus(newPodAmount); market.availableListedPods = market.availableListedPods.plus(newPodAmount).minus(cancelledPodAmount).minus(filledPodAmount); market.cancelledListedPods = market.cancelledListedPods.plus(cancelledPodAmount); market.filledListedPods = market.filledListedPods.plus(filledPodAmount); market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); - market.listingIndexes = marketIndexes; market.save(); marketHourly.season = market.season; @@ -779,7 +801,6 @@ function updateMarketListingBalances( function updateMarketOrderBalances( marketAddress: Address, - orderID: string, newBeanAmount: BigInt, cancelledBeanAmount: BigInt, filledPodAmount: BigInt, @@ -790,22 +811,12 @@ function updateMarketOrderBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - let marketOrders = market.orders; - - if (newBeanAmount > ZERO_BI) { - marketOrders.push(orderID); - } - if (cancelledBeanAmount > ZERO_BI) { - let orderIndex = market.orders.indexOf(orderID); - marketOrders.splice(orderIndex, 1); - } market.orderBeans = market.orderBeans.plus(newBeanAmount); market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); market.filledOrderBeans = market.filledOrderBeans.plus(filledBeanAmount); market.podVolume = market.podVolume.plus(filledPodAmount); market.beanVolume = market.beanVolume.plus(filledBeanAmount); market.cancelledOrderBeans = market.cancelledOrderBeans.plus(cancelledBeanAmount); - market.orders = marketOrders; market.save(); marketHourly.deltaOrderBeans = marketHourly.deltaOrderBeans.plus(newBeanAmount); diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index ebd43e4373..106898e766 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -1,9 +1,16 @@ -import { Address, BigInt, log } from "@graphprotocol/graph-ts"; +import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { PodMarketplace, PodMarketplaceHourlySnapshot, PodMarketplaceDailySnapshot } from "../../generated/schema"; -import { dayFromTimestamp, hourFromTimestamp } from "./Dates"; +import { dayFromTimestamp } from "./Dates"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; import { loadField } from "./Field"; -import { expirePodListing, loadPodListing } from "./PodListing"; + +export enum MarketplaceAction { + CREATED, + FILLED_PARTIAL, + FILLED_FULL, + CANCELLED, + EXPIRED +} export function loadPodMarketplace(diamondAddress: Address): PodMarketplace { let marketplace = PodMarketplace.load(diamondAddress.toHexString()); @@ -11,8 +18,8 @@ export function loadPodMarketplace(diamondAddress: Address): PodMarketplace { let field = loadField(diamondAddress); marketplace = new PodMarketplace(diamondAddress.toHexString()); marketplace.season = field.season; - marketplace.listingIndexes = []; - marketplace.orders = []; + marketplace.activeListings = []; + marketplace.activeOrders = []; marketplace.listedPods = ZERO_BI; marketplace.filledListedPods = ZERO_BI; marketplace.expiredListedPods = ZERO_BI; @@ -106,25 +113,79 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta return snapshot; } +// TODO: reimplement with new format export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Address, timestamp: BigInt): void { + // let market = loadPodMarketplace(diamondAddress); + // let remainingListings = market.listingIndexes; + // // TODO: expire plot upon harvest rather than the line moving past the start index + // // TODO: consider saving either a separate list or within this list, the indices that they expire + // // this will prevent having to load every listing upon each season + // // Cancel any pod marketplace listings beyond the index + // for (let i = 0; i < remainingListings.length; i++) { + // // TODO: this needs to be the user account + // let listing = loadPodListing(diamondAddress, remainingListings[i]); + // if (harvestableIndex > listing.maxHarvestableIndex) { + // expirePodListing(diamondAddress, timestamp, remainingListings[i]); + // remainingListings.splice(i--, 1); + // } + // } + // remainingListings.sort(); + // market.listingIndexes = remainingListings; + // market.save(); +} + +export function updateActiveListings( + diamondAddress: Address, + action: MarketplaceAction, + farmer: string, + plotIndex: BigInt, + expiryIndex: BigInt +): void { let market = loadPodMarketplace(diamondAddress); - let remainingListings = market.listingIndexes; + let listings = market.activeListings; - // TODO: expire plot upon harvest rather than the line moving past the start index - // TODO: consider saving either a separate list or within this list, the indices that they expire - // this will prevent having to load every listing upon each season + if (action == MarketplaceAction.CREATED) { + listings.push(farmer + "-" + plotIndex.toString() + "-" + expiryIndex.toString()); + } + if ([MarketplaceAction.CANCELLED, MarketplaceAction.FILLED_PARTIAL, MarketplaceAction.FILLED_FULL].includes(action)) { + listings.splice(Marketplace_findIndex_listing(listings, plotIndex), 1); + } - // Cancel any pod marketplace listings beyond the index - for (let i = 0; i < remainingListings.length; i++) { - // TODO: this needs to be the user account - let listing = loadPodListing(diamondAddress, remainingListings[i]); - if (harvestableIndex > listing.maxHarvestableIndex) { - expirePodListing(diamondAddress, timestamp, remainingListings[i]); - remainingListings.splice(i--, 1); - } + market.activeListings = listings; + market.save(); +} + +export function updateActiveOrders(diamondAddress: Address, action: MarketplaceAction, orderId: string, expiryIndex: BigInt): void { + let market = loadPodMarketplace(diamondAddress); + let orders = market.activeOrders; + + if (action == MarketplaceAction.CREATED) { + orders.push(orderId + "-" + expiryIndex.toString()); + } + if ([MarketplaceAction.CANCELLED, MarketplaceAction.FILLED_FULL].includes(action)) { + orders.splice(Marketplace_findIndex_order(orders, orderId), 1); } - remainingListings.sort(); - market.listingIndexes = remainingListings; + market.activeOrders = orders; market.save(); } + +export function Marketplace_findIndex_listing(listings: string[], plotIndex: BigInt): i32 { + for (let i = 0; i < listings.length; i++) { + const values = listings[i].split("-"); + if (BigInt.fromString(values[1]) == plotIndex) { + return i; + } + } + return -1; +} + +export function Marketplace_findIndex_order(orders: string[], orderId: string): i32 { + for (let i = 0; i < orders.length; i++) { + const values = orders[i].split("-"); + if (values[0] == orderId) { + return i; + } + } + return -1; +} diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index e936e94931..134c6b14c1 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -45,7 +45,17 @@ describe("Marketplace", () => { describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { const event = createListing_v2(account, listingIndex, sowedPods, ZERO_BI, maxHarvestableIndex); - assertMarketListingsState(BEANSTALK.toHexString(), [listingIndex], sowedPods, sowedPods, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], + sowedPods, + sowedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); // Create a second listing to assert the market state again const listing2Index = listingIndex.times(BI_10); @@ -53,7 +63,10 @@ describe("Marketplace", () => { const event2 = createListing_v2(account, listing2Index, sowedPods, ZERO_BI, maxHarvestableIndex); assertMarketListingsState( BEANSTALK.toHexString(), - [listingIndex, listing2Index], + [ + account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString(), + account + "-" + listing2Index.toString() + "-" + maxHarvestableIndex.toString() + ], sowedPods.times(BigInt.fromI32(2)), sowedPods.times(BigInt.fromI32(2)), ZERO_BI, @@ -69,7 +82,7 @@ describe("Marketplace", () => { const listedPods = sowedPods.minus(beans_BI(500)); assertMarketListingsState( BEANSTALK.toHexString(), - [listingIndex], + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], listedPods, listedPods, ZERO_BI, @@ -84,7 +97,7 @@ describe("Marketplace", () => { const event = createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); assertMarketOrdersState( BEANSTALK.toHexString(), - [event.params.id.toHexString()], + [event.params.id.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans, ZERO_BI, ZERO_BI, @@ -141,7 +154,7 @@ describe("Marketplace", () => { assertMarketListingsState( BEANSTALK.toHexString(), - [newListingIndex], + [account + "-" + newListingIndex.toString() + "-" + maxHarvestableIndex.toString()], listedPods, remaining, ZERO_BI, @@ -246,7 +259,7 @@ describe("Marketplace", () => { assertMarketListingsState( BEANSTALK.toHexString(), - [listingIndex], + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], listedPods.times(BigInt.fromU32(2)), listedPods, listedPods, @@ -279,7 +292,7 @@ describe("Marketplace", () => { assertMarketListingsState( BEANSTALK.toHexString(), - [newListingIndex], + [account + "-" + newListingIndex.toString() + "-" + maxHarvestableIndex.toString()], listedPods.times(BigInt.fromU32(2)).plus(newListingAmount), newListingAmount, listedPods.plus(newListingAmount), @@ -345,7 +358,7 @@ describe("Marketplace", () => { assertMarketOrdersState( BEANSTALK.toHexString(), - [event.params.id.toHexString()], + [event.params.id.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans, orderBeans1, soldToOrder1, @@ -421,7 +434,7 @@ describe("Marketplace", () => { assertMarketOrdersState( BEANSTALK.toHexString(), - [orderId.toHexString()], + [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans.times(BigInt.fromU32(2)), ZERO_BI, ZERO_BI, @@ -449,7 +462,7 @@ describe("Marketplace", () => { // The same amount of beans were re-ordered, but fewer were cancelled assertMarketOrdersState( BEANSTALK.toHexString(), - [orderId.toHexString()], + [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans.times(BigInt.fromU32(3)), orderBeans1, soldToOrder1, diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index fd58fe2070..b87cf0d731 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -41,7 +41,7 @@ export function fillListing_v2( const event = createPodListingFilledEvent_v2(from, to, listingIndex, listingStart, podAmount, costInBeans); handlePodListingFilled_v2(event); - // Perform plot transfer (necessary for market - assumption is this is tested/working via PlotTransfer.test.ts) + // Perform plot transfer transferPlot(from, to, listingIndex.plus(listingStart), podAmount); // Assert PodFill @@ -69,6 +69,9 @@ export function fillOrder_v2( const event = createPodOrderFilledEvent_v2(from, to, orderId, index, start, podAmount, costInBeans); handlePodOrderFilled_v2(event); + // Perform plot transfer + transferPlot(from, to, index.plus(start), podAmount); + // Assert PodFill const podFillId = getPodFillId(index, event); assert.fieldEquals("PodFill", podFillId, "order", event.params.id.toHexString()); @@ -154,7 +157,7 @@ export function createOrder_v2( export function assertMarketListingsState( address: string, - listings: BigInt[], + listings: string[], listedPods: BigInt, availableListedPods: BigInt, cancelledListedPods: BigInt, @@ -163,7 +166,7 @@ export function assertMarketListingsState( podVolume: BigInt, beanVolume: BigInt ): void { - assert.fieldEquals("PodMarketplace", address, "listingIndexes", "[" + listings.join(", ") + "]"); + assert.fieldEquals("PodMarketplace", address, "activeListings", arrayToString(listings)); assert.fieldEquals("PodMarketplace", address, "listedPods", listedPods.toString()); assert.fieldEquals("PodMarketplace", address, "availableListedPods", availableListedPods.toString()); assert.fieldEquals("PodMarketplace", address, "cancelledListedPods", cancelledListedPods.toString()); @@ -183,7 +186,7 @@ export function assertMarketOrdersState( podVolume: BigInt, beanVolume: BigInt ): void { - assert.fieldEquals("PodMarketplace", address, "orders", "[" + orders.join(", ") + "]"); + assert.fieldEquals("PodMarketplace", address, "activeOrders", arrayToString(orders)); assert.fieldEquals("PodMarketplace", address, "orderBeans", orderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); @@ -191,3 +194,7 @@ export function assertMarketOrdersState( assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); } + +function arrayToString(a: string[]): string { + return "[" + a.join(", ") + "]"; +} diff --git a/yarn.lock b/yarn.lock index c88684b356..0eddecd328 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5380,9 +5380,9 @@ __metadata: languageName: node linkType: hard -"@graphprotocol/graph-cli@npm:0.69.0": - version: 0.69.0 - resolution: "@graphprotocol/graph-cli@npm:0.69.0" +"@graphprotocol/graph-cli@npm:0.71.2": + version: 0.71.2 + resolution: "@graphprotocol/graph-cli@npm:0.71.2" dependencies: "@float-capital/float-subgraph-uncrashable": "npm:^0.0.0-alpha.4" "@oclif/core": "npm:2.8.6" @@ -5413,7 +5413,7 @@ __metadata: yaml: "npm:1.10.2" bin: graph: bin/run - checksum: 10/55c1dcc2396530171ade4dde5444395f0a78755292237a67fdd5122b3390bcbc547bf5509427950ccdfb41ed22de7455aecb4573a4faa643c793633ee8535765 + checksum: 10/a6268236ecac2fac890221dc6414e7bc837f63168c329d13a7cf1c3607571823e9f9ab57a079ac8dd6e0c0be00ede5b178f4caa5733e841c9028ee0ddbae08d3 languageName: node linkType: hard @@ -5426,12 +5426,12 @@ __metadata: languageName: node linkType: hard -"@graphprotocol/graph-ts@npm:0.34.0": - version: 0.34.0 - resolution: "@graphprotocol/graph-ts@npm:0.34.0" +"@graphprotocol/graph-ts@npm:0.35.1": + version: 0.35.1 + resolution: "@graphprotocol/graph-ts@npm:0.35.1" dependencies: assemblyscript: "npm:0.19.10" - checksum: 10/0aa26453002bb7b5342010877ba1148b9173603f4a3ce6db00afe77da5982f1d9a964ea86a79218c9b0615e2b3b459ed036eabc8e0d866ed9524c93396bf37de + checksum: 10/a1c83c689c96748c0565693eceb388a0a10872b71fe1daa4c0cf41504374fe8fdb227f92183353f3429361541771b6cabc0c213d7ebcbd94112c89a483435476 languageName: node linkType: hard @@ -40881,8 +40881,8 @@ __metadata: version: 0.0.0-use.local resolution: "subgraph-beanstalk@workspace:projects/subgraph-beanstalk" dependencies: - "@graphprotocol/graph-cli": "npm:0.69.0" - "@graphprotocol/graph-ts": "npm:0.34.0" + "@graphprotocol/graph-cli": "npm:0.71.2" + "@graphprotocol/graph-ts": "npm:0.35.1" matchstick-as: "npm:^0.6.0" languageName: unknown linkType: soft From 433e7513192f9c71a64e6162afe4d811c4c73607 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 14 May 2024 21:09:02 -0700 Subject: [PATCH 28/89] fix expire on exceed max harvestable --- .../subgraph-beanstalk/src/SeasonHandler.ts | 1 - .../src/utils/PodListing.ts | 19 ++++++---- .../src/utils/PodMarketplace.ts | 35 +++++++++---------- .../tests/Marketplace.test.ts | 4 +-- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/projects/subgraph-beanstalk/src/SeasonHandler.ts b/projects/subgraph-beanstalk/src/SeasonHandler.ts index 3b385fe0d8..d6252f46e1 100644 --- a/projects/subgraph-beanstalk/src/SeasonHandler.ts +++ b/projects/subgraph-beanstalk/src/SeasonHandler.ts @@ -9,7 +9,6 @@ import { Reward as RewardEntity, MetapoolOracle as MetapoolOracleEntity, WellOra import { BEANSTALK, BEANSTALK_PRICE, BEAN_ERC20, CURVE_PRICE } from "../../subgraph-core/utils/Constants"; import { ONE_BI, toDecimal, ZERO_BD, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { loadField, loadFieldDaily, loadFieldHourly } from "./utils/Field"; -import { expirePodListing, loadPodListing } from "./utils/PodListing"; import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, diff --git a/projects/subgraph-beanstalk/src/utils/PodListing.ts b/projects/subgraph-beanstalk/src/utils/PodListing.ts index 22f5d37233..c318eaf783 100644 --- a/projects/subgraph-beanstalk/src/utils/PodListing.ts +++ b/projects/subgraph-beanstalk/src/utils/PodListing.ts @@ -1,8 +1,7 @@ -import { Address, BigInt } from "@graphprotocol/graph-ts"; +import { Address, BigInt, log } from "@graphprotocol/graph-ts"; import { PodListing } from "../../generated/schema"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; -import { loadPlot } from "./Plot"; import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, loadPodMarketplaceHourlySnapshot } from "./PodMarketplace"; export function loadPodListing(account: Address, index: BigInt): PodListing { @@ -45,16 +44,24 @@ export function loadPodListing(account: Address, index: BigInt): PodListing { return listing; } -export function expirePodListing(diamondAddress: Address, timestamp: BigInt, listingIndex: BigInt): void { +export function expirePodListing( + diamondAddress: Address, + farmer: string, + listedPlotIndex: BigInt, + activeListingIndex: i32, + timestamp: BigInt +): void { let market = loadPodMarketplace(diamondAddress); let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); - //farmer info - let plot = loadPlot(diamondAddress, listingIndex); - let listing = loadPodListing(Address.fromString(plot.farmer), listingIndex); + + let listing = loadPodListing(Address.fromString(farmer), listedPlotIndex); market.expiredListedPods = market.expiredListedPods.plus(listing.remainingAmount); market.availableListedPods = market.availableListedPods.minus(listing.remainingAmount); + let activeListings = market.activeListings; + activeListings.splice(activeListingIndex, 1); + market.activeListings = activeListings; market.save(); marketHourly.season = market.season; diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index 106898e766..cc2b03dcf7 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -3,6 +3,7 @@ import { PodMarketplace, PodMarketplaceHourlySnapshot, PodMarketplaceDailySnapsh import { dayFromTimestamp } from "./Dates"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; import { loadField } from "./Field"; +import { expirePodListing, loadPodListing } from "./PodListing"; export enum MarketplaceAction { CREATED, @@ -113,25 +114,23 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta return snapshot; } -// TODO: reimplement with new format export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Address, timestamp: BigInt): void { - // let market = loadPodMarketplace(diamondAddress); - // let remainingListings = market.listingIndexes; - // // TODO: expire plot upon harvest rather than the line moving past the start index - // // TODO: consider saving either a separate list or within this list, the indices that they expire - // // this will prevent having to load every listing upon each season - // // Cancel any pod marketplace listings beyond the index - // for (let i = 0; i < remainingListings.length; i++) { - // // TODO: this needs to be the user account - // let listing = loadPodListing(diamondAddress, remainingListings[i]); - // if (harvestableIndex > listing.maxHarvestableIndex) { - // expirePodListing(diamondAddress, timestamp, remainingListings[i]); - // remainingListings.splice(i--, 1); - // } - // } - // remainingListings.sort(); - // market.listingIndexes = remainingListings; - // market.save(); + let market = loadPodMarketplace(diamondAddress); + let remainingListings = market.activeListings; + + // TODO: expire listing upon harvest + + // Cancel any pod marketplace listings beyond the index + for (let i = 0; i < remainingListings.length; i++) { + const destructured = remainingListings[i].split("-"); + const maxHarvestableIndex = BigInt.fromString(destructured[2]); + if (harvestableIndex > maxHarvestableIndex) { + // This method updates the marketplace entity, so it will perform the splice. + expirePodListing(diamondAddress, destructured[0], BigInt.fromString(destructured[1]), i, timestamp); + // A similar splice is done here also to track the updated index on the underlying array. + remainingListings.splice(i--, 1); + } + } } export function updateActiveListings( diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 134c6b14c1..bab5b97052 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -311,9 +311,9 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", maxHarvestableIndex.toString()); // Expires due to exceeding max harvestable index - setHarvestable(listingIndex); + setHarvestable(maxHarvestableIndex); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); - setHarvestable(listingIndex.plus(ONE_BI)); + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); From 206190d243dd1e3c5a26306a4e1e52844f2e2f27 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 10:50:52 -0700 Subject: [PATCH 29/89] expand moving podline test --- .../tests/Marketplace.test.ts | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index bab5b97052..08a39626e3 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -319,9 +319,41 @@ describe("Marketplace", () => { assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); - // TODO: expire after a partial sale - // TODO: expire due to listed being harvested + // Test expiration after a partial sale + setHarvestable(maxHarvestableIndex); + createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); + + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = beans_BI(2000); + const fillEvent = fillListing_v2(account, account2, listingIndex, listingStart, filledPods, filledBeans); + + const remaining = listedPods.minus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + const newListingID = account + "-" + newListingIndex.toString(); + + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); + assert.fieldEquals("PodListing", listingID, "status", "FILLED_PARTIAL"); + assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); + assert.fieldEquals("PodListing", newListingID, "status", "EXPIRED"); + assert.fieldEquals("PodListing", newListingID, "filled", filledPods.toString()); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", "0"); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [], + listedPods.times(BigInt.fromU32(2)), + ZERO_BI, + ZERO_BI, + listedPods.plus(remaining), + filledPods, + filledPods, + filledBeans + ); }); + + // test("Listing expires due to plot harvesting", () => { + // // TODO: expire due to listed being harvested + // }); }); describe("Tests requiring Order", () => { From d569484e9ceef63d20eabcaa255538f2b02b4fe8 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 11:07:07 -0700 Subject: [PATCH 30/89] harvest listed plot test --- .../src/utils/PodMarketplace.ts | 2 -- .../tests/Marketplace.test.ts | 20 ++++++++++++---- .../tests/event-mocking/Field.ts | 23 +++++++++++++++++-- .../subgraph-beanstalk/tests/utils/Field.ts | 8 +++++-- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index cc2b03dcf7..0dea97952d 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -118,8 +118,6 @@ export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Add let market = loadPodMarketplace(diamondAddress); let remainingListings = market.activeListings; - // TODO: expire listing upon harvest - // Cancel any pod marketplace listings beyond the index for (let i = 0; i < remainingListings.length; i++) { const destructured = remainingListings[i].split("-"); diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 08a39626e3..a04363d237 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -14,7 +14,7 @@ import { fillOrder_v2, getPodFillId } from "./utils/Marketplace"; -import { setHarvestable, sow } from "./utils/Field"; +import { harvest, setHarvestable, sow } from "./utils/Field"; const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); @@ -39,7 +39,6 @@ describe("Marketplace", () => { // TODO tests: // fill order with pods that are also listed - // listing expires due to podline advancing // order expires due to podline advancing describe("Marketplace v2", () => { @@ -351,9 +350,20 @@ describe("Marketplace", () => { ); }); - // test("Listing expires due to plot harvesting", () => { - // // TODO: expire due to listed being harvested - // }); + test("Listing expires due to plot harvesting", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const listingID = account + "-" + listingIndex.toString(); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + + // Plot is harvestable, but still active + setHarvestable(listingIndex.plus(sowedPods)); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + // Plot harvests, now expired + harvest(account, [listingIndex], sowedPods); + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + }); }); describe("Tests requiring Order", () => { diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Field.ts b/projects/subgraph-beanstalk/tests/event-mocking/Field.ts index affbd01807..0b0b78f249 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Field.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Field.ts @@ -1,5 +1,5 @@ import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; -import { Sow, PlotTransfer } from "../../generated/Field/Beanstalk"; +import { Sow, PlotTransfer, Harvest } from "../../generated/Field/Beanstalk"; import { TemperatureChange } from "../../generated/BIP44-SeedGauge/Beanstalk"; import { mockBeanstalkEvent } from "../../../subgraph-core/tests/event-mocking/Util"; @@ -38,7 +38,26 @@ export function createSowEvent(account: string, index: BigInt, beans: BigInt, po return event as Sow; } -export function createHarvestEvent(account: string, plots: BigInt[], beans: BigInt): void {} +export function createHarvestEvent(account: string, plots: BigInt[], beans: BigInt): Harvest { + let event = changetype(mockBeanstalkEvent()); + event.parameters = new Array(); + + let plotsArray: ethereum.Value[] = []; + for (let i = 0; i < plots.length; ++i) { + plotsArray.push(ethereum.Value.fromUnsignedBigInt(plots[i])); + } + + let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); + let param2 = new ethereum.EventParam("plots", ethereum.Value.fromArray(plotsArray)); + let param3 = new ethereum.EventParam("beans", ethereum.Value.fromUnsignedBigInt(beans)); + + event.parameters.push(param1); + event.parameters.push(param2); + event.parameters.push(param3); + + return event as Harvest; +} + export function createPlotTransferEvent(from: string, to: string, id: BigInt, pods: BigInt): PlotTransfer { let event = changetype(mockBeanstalkEvent()); event.parameters = new Array(); diff --git a/projects/subgraph-beanstalk/tests/utils/Field.ts b/projects/subgraph-beanstalk/tests/utils/Field.ts index e51030b9e6..31103182ec 100644 --- a/projects/subgraph-beanstalk/tests/utils/Field.ts +++ b/projects/subgraph-beanstalk/tests/utils/Field.ts @@ -1,7 +1,7 @@ import { BigInt, ethereum, log } from "@graphprotocol/graph-ts"; import { assert, createMockedFunction } from "matchstick-as/assembly/index"; -import { createPlotTransferEvent, createSowEvent } from "../event-mocking/Field"; -import { handlePlotTransfer, handleSow } from "../../src/FieldHandler"; +import { createHarvestEvent, createPlotTransferEvent, createSowEvent } from "../event-mocking/Field"; +import { handleHarvest, handlePlotTransfer, handleSow } from "../../src/FieldHandler"; import { createIncentivizationEvent } from "../event-mocking/Season"; import { handleIncentive } from "../../src/SeasonHandler"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; @@ -13,6 +13,10 @@ export function sow(account: string, index: BigInt, beans: BigInt, pods: BigInt) handleSow(createSowEvent(account, index, beans, pods)); } +export function harvest(account: string, plotIndexex: BigInt[], beans: BigInt): void { + handleHarvest(createHarvestEvent(account, plotIndexex, beans)); +} + export function transferPlot(from: string, to: string, id: BigInt, amount: BigInt): void { handlePlotTransfer(createPlotTransferEvent(from, to, id, amount)); } From 6accc87e7080c4513727d255e83e88259ec6dbc6 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 11:17:53 -0700 Subject: [PATCH 31/89] Fix expire listing on harvest --- .../subgraph-beanstalk/src/FieldHandler.ts | 3 +++ .../src/utils/PodListing.ts | 26 +++++++++++++++---- .../src/utils/PodMarketplace.ts | 4 +-- .../tests/Marketplace.test.ts | 2 ++ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/projects/subgraph-beanstalk/src/FieldHandler.ts b/projects/subgraph-beanstalk/src/FieldHandler.ts index 6e5d37d6d6..9dc8b04832 100644 --- a/projects/subgraph-beanstalk/src/FieldHandler.ts +++ b/projects/subgraph-beanstalk/src/FieldHandler.ts @@ -18,6 +18,7 @@ import { loadPlot } from "./utils/Plot"; import { savePodTransfer } from "./utils/PodTransfer"; import { loadSeason } from "./utils/Season"; import { loadBeanstalk } from "./utils/Beanstalk"; +import { expirePodListingIfExists } from "./utils/PodListing"; export function handleWeatherChange(event: WeatherChange): void { handleRateChange(event.address, event.block, event.params.season, event.params.caseId, event.params.change); @@ -103,6 +104,8 @@ export function handleHarvest(event: Harvest): void { // Plot should exist let plot = loadPlot(event.address, event.params.plots[i]); + expirePodListingIfExists(event.address, plot.farmer, plot.index, event.block.timestamp); + let harvestablePods = season.harvestableIndex.minus(plot.index); if (harvestablePods >= plot.pods) { diff --git a/projects/subgraph-beanstalk/src/utils/PodListing.ts b/projects/subgraph-beanstalk/src/utils/PodListing.ts index c318eaf783..fd2de02aff 100644 --- a/projects/subgraph-beanstalk/src/utils/PodListing.ts +++ b/projects/subgraph-beanstalk/src/utils/PodListing.ts @@ -44,19 +44,35 @@ export function loadPodListing(account: Address, index: BigInt): PodListing { return listing; } -export function expirePodListing( +export function expirePodListingIfExists( diamondAddress: Address, farmer: string, listedPlotIndex: BigInt, - activeListingIndex: i32, - timestamp: BigInt + timestamp: BigInt, + activeListingIndex: i32 = -1 // If provided, avoids having to lookup the index ): void { + let listing = PodListing.load(farmer + "-" + listedPlotIndex.toString()); + if (listing == null || listing.status != "ACTIVE") { + return; + } + let market = loadPodMarketplace(diamondAddress); + + if (activeListingIndex == -1) { + // There should always be a matching entry in this list because it is verified that the listing is ACTIVE + for (let i = 0; i < market.activeListings.length; i++) { + const destructured = market.activeListings[i].split("-"); + // Unnecessary to check if the account matches. + if (destructured[1] == listedPlotIndex.toString()) { + activeListingIndex = i; + break; + } + } + } + let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); - let listing = loadPodListing(Address.fromString(farmer), listedPlotIndex); - market.expiredListedPods = market.expiredListedPods.plus(listing.remainingAmount); market.availableListedPods = market.availableListedPods.minus(listing.remainingAmount); let activeListings = market.activeListings; diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index 0dea97952d..d18bc18c84 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -3,7 +3,7 @@ import { PodMarketplace, PodMarketplaceHourlySnapshot, PodMarketplaceDailySnapsh import { dayFromTimestamp } from "./Dates"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; import { loadField } from "./Field"; -import { expirePodListing, loadPodListing } from "./PodListing"; +import { expirePodListingIfExists, loadPodListing } from "./PodListing"; export enum MarketplaceAction { CREATED, @@ -124,7 +124,7 @@ export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Add const maxHarvestableIndex = BigInt.fromString(destructured[2]); if (harvestableIndex > maxHarvestableIndex) { // This method updates the marketplace entity, so it will perform the splice. - expirePodListing(diamondAddress, destructured[0], BigInt.fromString(destructured[1]), i, timestamp); + expirePodListingIfExists(diamondAddress, destructured[0], BigInt.fromString(destructured[1]), timestamp, i); // A similar splice is done here also to track the updated index on the underlying array. remainingListings.splice(i--, 1); } diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index a04363d237..695d4f2061 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -363,6 +363,8 @@ describe("Marketplace", () => { harvest(account, [listingIndex], sowedPods); assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); }); }); From b2941d9a7d9662e3a0403f44850f43193c8fb567 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 11:34:54 -0700 Subject: [PATCH 32/89] add expiredOrderBeans field --- projects/subgraph-beanstalk/schema.graphql | 10 ++++ .../src/utils/PodMarketplace.ts | 5 ++ .../tests/Marketplace.test.ts | 55 +++++++++++++++---- .../tests/utils/Marketplace.ts | 11 ++++ 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 7a5b71625f..4b156e157f 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -729,6 +729,8 @@ type PodMarketplace @entity { filledOrderedPods: BigInt! "Current cumulative beans in pod orders cancelled" cancelledOrderBeans: BigInt! + "Current cumulative beans in pod orders expired" + expiredOrderBeans: BigInt! "Cumulative pod volume between listings and orders" podVolume: BigInt! "Cumulative bean volume between listings and orders" @@ -764,6 +766,8 @@ type PodMarketplaceHourlySnapshot @entity { filledOrderedPods: BigInt! "Current cumulative beans in pod orders cancelled" cancelledOrderBeans: BigInt! + "Current cumulative beans in pod orders expired" + expiredOrderBeans: BigInt! "Point in time current cumulative pod volume between listings and orders" podVolume: BigInt! "Point in time current cumulative bean volume between listings and orders" @@ -786,6 +790,8 @@ type PodMarketplaceHourlySnapshot @entity { deltaFilledOrderedPods: BigInt! "Point in time current delta cancelled ordered beans in pod orders" deltaCancelledOrderBeans: BigInt! + "Point in time current delta expired ordered beans in pod orders" + deltaExpiredOrderBeans: BigInt! "Point in time current delta pod volume between listings and orders" deltaPodVolume: BigInt! "Point in time current delta bean volume between listings and orders" @@ -821,6 +827,8 @@ type PodMarketplaceDailySnapshot @entity { filledOrderedPods: BigInt! "Current cumulative beans in pod orders cancelled" cancelledOrderBeans: BigInt! + "Current cumulative beans in pod orders expired" + expiredOrderBeans: BigInt! "Point in time current cumulative pod volume between listings and orders" podVolume: BigInt! "Point in time current cumulative bean volume between listings and orders" @@ -843,6 +851,8 @@ type PodMarketplaceDailySnapshot @entity { deltaFilledOrderedPods: BigInt! "Point in time current delta cancelled ordered beans in pod orders" deltaCancelledOrderBeans: BigInt! + "Point in time current delta expired ordered beans in pod orders" + deltaExpiredOrderBeans: BigInt! "Point in time current delta pod volume between listings and orders" deltaPodVolume: BigInt! "Point in time current delta bean volume between listings and orders" diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index d18bc18c84..cbb1c1beaf 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -30,6 +30,7 @@ export function loadPodMarketplace(diamondAddress: Address): PodMarketplace { marketplace.filledOrderedPods = ZERO_BI; marketplace.filledOrderBeans = ZERO_BI; marketplace.cancelledOrderBeans = ZERO_BI; + marketplace.expiredOrderBeans = ZERO_BI; marketplace.podVolume = ZERO_BI; marketplace.beanVolume = ZERO_BI; marketplace.save(); @@ -65,6 +66,8 @@ export function loadPodMarketplaceHourlySnapshot(diamondAddress: Address, season snapshot.filledOrderBeans = marketplace.filledOrderBeans; snapshot.deltaCancelledOrderBeans = ZERO_BI; snapshot.cancelledOrderBeans = marketplace.cancelledOrderBeans; + snapshot.deltaExpiredOrderBeans = ZERO_BI; + snapshot.expiredOrderBeans = marketplace.expiredOrderBeans; snapshot.deltaPodVolume = ZERO_BI; snapshot.podVolume = marketplace.podVolume; snapshot.deltaBeanVolume = ZERO_BI; @@ -103,6 +106,8 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta snapshot.filledOrderBeans = marketplace.filledOrderBeans; snapshot.deltaCancelledOrderBeans = ZERO_BI; snapshot.cancelledOrderBeans = marketplace.cancelledOrderBeans; + snapshot.deltaExpiredOrderBeans = ZERO_BI; + snapshot.expiredOrderBeans = marketplace.expiredOrderBeans; snapshot.deltaPodVolume = ZERO_BI; snapshot.podVolume = marketplace.podVolume; snapshot.deltaBeanVolume = ZERO_BI; diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 695d4f2061..2d9e28d7d6 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,13 +1,14 @@ import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; -import { handlePodListingCancelled, handlePodOrderCancelled } from "../src/MarketplaceHandler"; -import { createPodListingCancelledEvent, createPodOrderCancelledEvent } from "./event-mocking/Marketplace"; +import { handlePodListingCancelled } from "../src/MarketplaceHandler"; +import { createPodListingCancelledEvent } from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; import { assertMarketListingsState, assertMarketOrdersState, + cancelOrder, createListing_v2, createOrder_v2, fillListing_v2, @@ -102,6 +103,7 @@ describe("Marketplace", () => { ZERO_BI, ZERO_BI, ZERO_BI, + ZERO_BI, ZERO_BI ); }); @@ -384,7 +386,17 @@ describe("Marketplace", () => { assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", orderedPods.toString()); assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, event) + "]"); - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, orderBeans, orderedPods, ZERO_BI, orderedPods, orderBeans); + assertMarketOrdersState( + BEANSTALK.toHexString(), + [], + orderBeans, + orderBeans, + orderedPods, + ZERO_BI, + ZERO_BI, + orderedPods, + orderBeans + ); }); test("Fill order - partial", () => { @@ -407,6 +419,7 @@ describe("Marketplace", () => { orderBeans1, soldToOrder1, ZERO_BI, + ZERO_BI, soldToOrder1, orderBeans1 ); @@ -427,19 +440,28 @@ describe("Marketplace", () => { "[" + getPodFillId(orderPlotIndex, event) + ", " + getPodFillId(newOrderPlotIndex, event2) + "]" ); - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, orderBeans, orderedPods, ZERO_BI, orderedPods, orderBeans); + assertMarketOrdersState( + BEANSTALK.toHexString(), + [], + orderBeans, + orderBeans, + orderedPods, + ZERO_BI, + ZERO_BI, + orderedPods, + orderBeans + ); }); test("Cancel order - full", () => { - const event = createPodOrderCancelledEvent(account, orderId); - handlePodOrderCancelled(event); + cancelOrder(account, orderId); assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED"); assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", "0"); assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", "0"); assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI, ZERO_BI); }); test("Cancel order - partial", () => { @@ -450,8 +472,7 @@ describe("Marketplace", () => { sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); const fillEvent = fillOrder_v2(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); - const event = createPodOrderCancelledEvent(account, orderId); - handlePodOrderCancelled(event); + cancelOrder(account, orderId); assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED_PARTIAL"); assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans1.toString()); @@ -465,13 +486,14 @@ describe("Marketplace", () => { orderBeans1, soldToOrder1, orderBeans.minus(orderBeans1), + ZERO_BI, soldToOrder1, orderBeans1 ); }); test("Recreate order", () => { - handlePodOrderCancelled(createPodOrderCancelledEvent(account, orderId)); + cancelOrder(account, orderId); createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); assert.fieldEquals("PodOrder", orderId.toHexString() + "-0", "fills", "[]"); @@ -484,6 +506,7 @@ describe("Marketplace", () => { ZERO_BI, orderBeans, ZERO_BI, + ZERO_BI, ZERO_BI ); @@ -495,7 +518,7 @@ describe("Marketplace", () => { sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); const fillEvent = fillOrder_v2(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderBeans1); - handlePodOrderCancelled(createPodOrderCancelledEvent(account, orderId)); + cancelOrder(account, orderId); createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); // The historical order has one fill @@ -511,10 +534,20 @@ describe("Marketplace", () => { orderBeans1, soldToOrder1, orderBeans.plus(orderBeans.minus(orderBeans1)), + ZERO_BI, soldToOrder1, orderBeans1 ); }); + + test("Order expires due to moving podline", () => { + setHarvestable(maxHarvestableIndex); + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "ACTIVE"); + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "EXPIRED"); + + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + }); }); }); }); diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index b87cf0d731..9ba1412e14 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -3,12 +3,14 @@ import { assert } from "matchstick-as/assembly/index"; import { handlePodListingCreated_v2, handlePodListingFilled_v2, + handlePodOrderCancelled, handlePodOrderCreated_v2, handlePodOrderFilled_v2 } from "../../src/MarketplaceHandler"; import { createPodListingCreatedEvent_v2, createPodListingFilledEvent_v2, + createPodOrderCancelledEvent, createPodOrderCreatedEvent_v2, createPodOrderFilledEvent_v2 } from "../event-mocking/Marketplace"; @@ -21,6 +23,7 @@ import { } from "../../generated/BIP29-PodMarketplace/Beanstalk"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; import { transferPlot } from "./Field"; +import { PodOrderCancelled } from "../../generated/Field/Beanstalk"; const pricingFunction = Bytes.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" @@ -85,6 +88,12 @@ export function fillOrder_v2( return event; } +export function cancelOrder(account: string, orderId: Bytes): PodOrderCancelled { + const event = createPodOrderCancelledEvent(account, orderId); + handlePodOrderCancelled(event); + return event; +} + export function assertListingCreated_v2(event: PodListingCreated_v2): void { let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); @@ -183,6 +192,7 @@ export function assertMarketOrdersState( filledOrderBeans: BigInt, filledOrderedPods: BigInt, cancelledOrderBeans: BigInt, + expiredOrderBeans: BigInt, podVolume: BigInt, beanVolume: BigInt ): void { @@ -191,6 +201,7 @@ export function assertMarketOrdersState( assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "expiredOrderBeans", expiredOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); } From 63f9f9ff2c8776d6ace6721b06137868680a5a27 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 11:58:57 -0700 Subject: [PATCH 33/89] add availableOrderBeans field --- projects/subgraph-beanstalk/schema.graphql | 30 ++++--- .../src/MarketplaceHandler.ts | 25 +++--- .../subgraph-beanstalk/src/SeasonHandler.ts | 2 + .../src/utils/PodMarketplace.ts | 33 ++++++-- .../subgraph-beanstalk/src/utils/PodOrder.ts | 81 ++++++++++++++++++- .../tests/Marketplace.test.ts | 13 ++- .../tests/utils/Marketplace.ts | 2 + 7 files changed, 157 insertions(+), 29 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 4b156e157f..041d042020 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -713,16 +713,18 @@ type PodMarketplace @entity { fills: [PodFill!]! @derivedFrom(field: "podMarketplace") "Current cumulative pods listed for sale" listedPods: BigInt! + "Current amount of total pods listed" + availableListedPods: BigInt! "Current cumulative pod listings filled" filledListedPods: BigInt! "Current cumulative pod listings that expired" expiredListedPods: BigInt! "Current cumulative pod listings that were cancelled" cancelledListedPods: BigInt! - "Current amount of total pods listed" - availableListedPods: BigInt! "Current cumulative beans in pod orders created" orderBeans: BigInt! + "Current amount of total beans in pod orders" + availableOrderBeans: BigInt! "Current cumulative filled beans in pod orders" filledOrderBeans: BigInt! "Current cumulative pod orders filled" @@ -750,16 +752,18 @@ type PodMarketplaceHourlySnapshot @entity { podMarketplace: PodMarketplace! "Point in time current cumulative pods listed for sale" listedPods: BigInt! + "Point in time current amount of total pods listed" + availableListedPods: BigInt! "Point in time current cumulative pod listings filled" filledListedPods: BigInt! "Point in time current cumulative pod listings that expired" expiredListedPods: BigInt! "Point in time current cumulative pod listings that were cancelled" cancelledListedPods: BigInt! - "Point in time current amount of total pods listed" - availableListedPods: BigInt! "Current cumulative beans in pod orders created" orderBeans: BigInt! + "Current amount of total beans in pod orders" + availableOrderBeans: BigInt! "Current cumulative filled beans in pod orders" filledOrderBeans: BigInt! "Current cumulative pod orders filled" @@ -774,16 +778,18 @@ type PodMarketplaceHourlySnapshot @entity { beanVolume: BigInt! "Point in time current delta pods listed for sale" deltaListedPods: BigInt! + "Point in time current delta of total pods listed" + deltaAvailableListedPods: BigInt! "Point in time current delta pod listings filled" deltaFilledListedPods: BigInt! "Point in time current delta pod listings that expired" deltaExpiredListedPods: BigInt! "Point in time current delta pod listings that were cancelled" deltaCancelledListedPods: BigInt! - "Point in time current delta of total pods listed" - deltaAvailableListedPods: BigInt! "Point in time current delta ordered beans in pod orders created" deltaOrderBeans: BigInt! + "Point in time current delta available ordered beans in pod orders" + deltaAvailableOrderBeans: BigInt! "Point in time current delta filled ordered beans in pod orders" deltaFilledOrderBeans: BigInt! "Point in time current delta pod orders filled" @@ -811,16 +817,18 @@ type PodMarketplaceDailySnapshot @entity { podMarketplace: PodMarketplace! "Point in time current cumulative pods listed for sale" listedPods: BigInt! + "Point in time current amount of total pods listed" + availableListedPods: BigInt! "Point in time current cumulative pod listings filled" filledListedPods: BigInt! "Point in time current cumulative pod listings that expired" expiredListedPods: BigInt! "Point in time current cumulative pod listings that were cancelled" cancelledListedPods: BigInt! - "Point in time current amount of total pods listed" - availableListedPods: BigInt! "Current cumulative beans in pod orders created" orderBeans: BigInt! + "Current amount of total beans in pod orders" + availableOrderBeans: BigInt! "Current cumulative filled beans in pod orders" filledOrderBeans: BigInt! "Current cumulative pod orders filled" @@ -835,16 +843,18 @@ type PodMarketplaceDailySnapshot @entity { beanVolume: BigInt! "Point in time current delta pods listed for sale" deltaListedPods: BigInt! + "Point in time current delta of total pods listed" + deltaAvailableListedPods: BigInt! "Point in time current delta pod listings filled" deltaFilledListedPods: BigInt! "Point in time current delta pod listings that expired" deltaExpiredListedPods: BigInt! "Point in time current delta pod listings that were cancelled" deltaCancelledListedPods: BigInt! - "Point in time current delta of total pods listed" - deltaAvailableListedPods: BigInt! "Point in time current delta ordered beans in pod orders created" deltaOrderBeans: BigInt! + "Point in time current delta available ordered beans in pod orders" + deltaAvailableOrderBeans: BigInt! "Point in time current delta filled ordered beans in pod orders" deltaFilledOrderBeans: BigInt! "Point in time current delta pod orders filled" diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index b5e41fd773..195a5ccf9f 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -752,8 +752,10 @@ function updateMarketListingBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); + const netListingChange = newPodAmount.minus(cancelledPodAmount).minus(filledPodAmount); + market.listedPods = market.listedPods.plus(newPodAmount); - market.availableListedPods = market.availableListedPods.plus(newPodAmount).minus(cancelledPodAmount).minus(filledPodAmount); + market.availableListedPods = market.availableListedPods.plus(netListingChange); market.cancelledListedPods = market.cancelledListedPods.plus(cancelledPodAmount); market.filledListedPods = market.filledListedPods.plus(filledPodAmount); market.podVolume = market.podVolume.plus(filledPodAmount); @@ -763,13 +765,10 @@ function updateMarketListingBalances( marketHourly.season = market.season; marketHourly.deltaListedPods = marketHourly.deltaListedPods.plus(newPodAmount); marketHourly.listedPods = market.listedPods; + marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods.plus(netListingChange); + marketHourly.availableListedPods = market.availableListedPods; marketHourly.deltaCancelledListedPods = marketHourly.deltaCancelledListedPods.plus(cancelledPodAmount); marketHourly.cancelledListedPods = market.cancelledListedPods; - marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods - .plus(newPodAmount) - .minus(cancelledPodAmount) - .minus(filledPodAmount); - marketHourly.availableListedPods = market.availableListedPods; marketHourly.deltaFilledListedPods = marketHourly.deltaFilledListedPods.plus(filledPodAmount); marketHourly.filledListedPods = market.filledListedPods; marketHourly.deltaPodVolume = marketHourly.deltaPodVolume.plus(filledPodAmount); @@ -782,13 +781,10 @@ function updateMarketListingBalances( marketDaily.season = market.season; marketDaily.deltaListedPods = marketDaily.deltaListedPods.plus(newPodAmount); marketDaily.listedPods = market.listedPods; + marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.plus(netListingChange); + marketDaily.availableListedPods = market.availableListedPods; marketDaily.deltaCancelledListedPods = marketDaily.deltaCancelledListedPods.plus(cancelledPodAmount); marketDaily.cancelledListedPods = market.cancelledListedPods; - marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods - .plus(newPodAmount) - .minus(cancelledPodAmount) - .minus(filledPodAmount); - marketDaily.availableListedPods = market.availableListedPods; marketDaily.deltaFilledListedPods = marketDaily.deltaFilledListedPods.plus(filledPodAmount); marketDaily.filledListedPods = market.filledListedPods; marketDaily.deltaPodVolume = marketDaily.deltaPodVolume.plus(filledPodAmount); @@ -811,7 +807,10 @@ function updateMarketOrderBalances( let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); + const netOrderChange = newBeanAmount.minus(cancelledBeanAmount).minus(filledBeanAmount); + market.orderBeans = market.orderBeans.plus(newBeanAmount); + market.availableOrderBeans = market.availableOrderBeans.plus(netOrderChange); market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); market.filledOrderBeans = market.filledOrderBeans.plus(filledBeanAmount); market.podVolume = market.podVolume.plus(filledPodAmount); @@ -821,6 +820,8 @@ function updateMarketOrderBalances( marketHourly.deltaOrderBeans = marketHourly.deltaOrderBeans.plus(newBeanAmount); marketHourly.orderBeans = market.orderBeans; + marketHourly.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.plus(netOrderChange); + marketHourly.availableOrderBeans = market.availableOrderBeans; marketHourly.deltaFilledOrderedPods = marketHourly.deltaFilledOrderedPods.plus(filledPodAmount); marketHourly.filledOrderedPods = market.filledOrderedPods; marketHourly.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); @@ -836,6 +837,8 @@ function updateMarketOrderBalances( marketDaily.deltaOrderBeans = marketDaily.deltaOrderBeans.plus(newBeanAmount); marketDaily.orderBeans = market.orderBeans; + marketDaily.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.plus(netOrderChange); + marketDaily.availableOrderBeans = market.availableOrderBeans; marketDaily.deltaFilledOrderedPods = marketDaily.deltaFilledOrderedPods.plus(filledPodAmount); marketDaily.filledOrderedPods = market.filledOrderedPods; marketDaily.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); diff --git a/projects/subgraph-beanstalk/src/SeasonHandler.ts b/projects/subgraph-beanstalk/src/SeasonHandler.ts index d6252f46e1..acd156107d 100644 --- a/projects/subgraph-beanstalk/src/SeasonHandler.ts +++ b/projects/subgraph-beanstalk/src/SeasonHandler.ts @@ -13,6 +13,7 @@ import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, loadPodMarketplaceHourlySnapshot, + updateExpiredOrders, updateExpiredPlots } from "./utils/PodMarketplace"; import { loadSeason } from "./utils/Season"; @@ -239,5 +240,6 @@ export function handleIncentive(event: Incentivization): void { season.save(); updateExpiredPlots(season.harvestableIndex, event.address, event.block.timestamp); + updateExpiredOrders(season.harvestableIndex, event.address, event.block.timestamp); updateHarvestablePlots(season.harvestableIndex, event.block.timestamp, event.block.number); } diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index cbb1c1beaf..4a4fff0c8f 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -4,6 +4,7 @@ import { dayFromTimestamp } from "./Dates"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; import { loadField } from "./Field"; import { expirePodListingIfExists, loadPodListing } from "./PodListing"; +import { expirePodOrder } from "./PodOrder"; export enum MarketplaceAction { CREATED, @@ -22,11 +23,12 @@ export function loadPodMarketplace(diamondAddress: Address): PodMarketplace { marketplace.activeListings = []; marketplace.activeOrders = []; marketplace.listedPods = ZERO_BI; + marketplace.availableListedPods = ZERO_BI; marketplace.filledListedPods = ZERO_BI; marketplace.expiredListedPods = ZERO_BI; marketplace.cancelledListedPods = ZERO_BI; - marketplace.availableListedPods = ZERO_BI; marketplace.orderBeans = ZERO_BI; + marketplace.availableOrderBeans = ZERO_BI; marketplace.filledOrderedPods = ZERO_BI; marketplace.filledOrderBeans = ZERO_BI; marketplace.cancelledOrderBeans = ZERO_BI; @@ -50,16 +52,18 @@ export function loadPodMarketplaceHourlySnapshot(diamondAddress: Address, season snapshot.podMarketplace = diamondAddress.toHexString(); snapshot.deltaListedPods = ZERO_BI; snapshot.listedPods = marketplace.listedPods; + snapshot.deltaAvailableListedPods = ZERO_BI; + snapshot.availableListedPods = marketplace.availableListedPods; snapshot.deltaFilledListedPods = ZERO_BI; snapshot.filledListedPods = marketplace.filledListedPods; snapshot.deltaExpiredListedPods = ZERO_BI; snapshot.expiredListedPods = marketplace.expiredListedPods; snapshot.deltaCancelledListedPods = ZERO_BI; snapshot.cancelledListedPods = marketplace.cancelledListedPods; - snapshot.deltaAvailableListedPods = ZERO_BI; - snapshot.availableListedPods = marketplace.availableListedPods; snapshot.deltaOrderBeans = ZERO_BI; snapshot.orderBeans = marketplace.orderBeans; + snapshot.deltaAvailableOrderBeans = ZERO_BI; + snapshot.availableOrderBeans = marketplace.availableOrderBeans; snapshot.deltaFilledOrderedPods = ZERO_BI; snapshot.filledOrderedPods = marketplace.filledOrderedPods; snapshot.deltaFilledOrderBeans = ZERO_BI; @@ -90,16 +94,18 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta snapshot.podMarketplace = diamondAddress.toHexString(); snapshot.deltaListedPods = ZERO_BI; snapshot.listedPods = marketplace.listedPods; + snapshot.deltaAvailableListedPods = ZERO_BI; + snapshot.availableListedPods = marketplace.availableListedPods; snapshot.deltaFilledListedPods = ZERO_BI; snapshot.filledListedPods = marketplace.filledListedPods; snapshot.deltaExpiredListedPods = ZERO_BI; snapshot.expiredListedPods = marketplace.expiredListedPods; snapshot.deltaCancelledListedPods = ZERO_BI; snapshot.cancelledListedPods = marketplace.cancelledListedPods; - snapshot.deltaAvailableListedPods = ZERO_BI; - snapshot.availableListedPods = marketplace.availableListedPods; snapshot.deltaOrderBeans = ZERO_BI; snapshot.orderBeans = marketplace.orderBeans; + snapshot.deltaAvailableOrderBeans = ZERO_BI; + snapshot.availableOrderBeans = marketplace.availableOrderBeans; snapshot.deltaFilledOrderedPods = ZERO_BI; snapshot.filledOrderedPods = marketplace.filledOrderedPods; snapshot.deltaFilledOrderBeans = ZERO_BI; @@ -136,6 +142,23 @@ export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Add } } +export function updateExpiredOrders(harvestableIndex: BigInt, diamondAddress: Address, timestamp: BigInt): void { + let market = loadPodMarketplace(diamondAddress); + let remainingOrders = market.activeOrders; + + // Cancel any pod marketplace orders beyond the index + for (let i = 0; i < remainingOrders.length; i++) { + const destructured = remainingOrders[i].split("-"); + const maxHarvestableIndex = BigInt.fromString(destructured[1]); + if (harvestableIndex > maxHarvestableIndex) { + // This method updates the marketplace entity, so it will perform the splice. + expirePodOrder(diamondAddress, destructured[0], timestamp, i); + // A similar splice is done here also to track the updated index on the underlying array. + remainingOrders.splice(i--, 1); + } + } +} + export function updateActiveListings( diamondAddress: Address, action: MarketplaceAction, diff --git a/projects/subgraph-beanstalk/src/utils/PodOrder.ts b/projects/subgraph-beanstalk/src/utils/PodOrder.ts index 31c8ed8b6c..15f806ee9c 100644 --- a/projects/subgraph-beanstalk/src/utils/PodOrder.ts +++ b/projects/subgraph-beanstalk/src/utils/PodOrder.ts @@ -1,7 +1,8 @@ -import { Bytes } from "@graphprotocol/graph-ts"; +import { Bytes, BigInt, Address } from "@graphprotocol/graph-ts"; import { PodOrder } from "../../generated/schema"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; +import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, loadPodMarketplaceHourlySnapshot } from "./PodMarketplace"; export function loadPodOrder(orderID: Bytes): PodOrder { let order = PodOrder.load(orderID.toHexString()); @@ -53,3 +54,81 @@ export function createHistoricalPodOrder(order: PodOrder): void { } } } + +export function expirePodOrder(diamondAddress: Address, orderId: string, timestamp: BigInt, activeListingIndex: i32): void { + // let order = loadPodOrder(Bytes.fromHexString(orderId)); + // let market = loadPodMarketplace(diamondAddress); + // let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); + // let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); + // const expiredBeans = order.beanAmount.minus(order.beanAmountFilled); + // market.expiredOrderBeans = market.expiredOrderBeans.plus(expiredBeans); + // /// + // market.availableListedPods = market.availableListedPods.minus(listing.remainingAmount); + // let activeListings = market.activeListings; + // activeListings.splice(activeListingIndex, 1); + // market.activeListings = activeListings; + // market.save(); + // marketHourly.season = market.season; + // marketHourly.deltaExpiredListedPods = marketHourly.deltaExpiredListedPods.plus(listing.remainingAmount); + // marketHourly.expiredListedPods = market.expiredListedPods; + // marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods.minus(listing.remainingAmount); + // marketHourly.availableListedPods = market.availableListedPods; + // marketHourly.save(); + // marketDaily.season = market.season; + // marketDaily.deltaExpiredListedPods = marketDaily.deltaExpiredListedPods.plus(listing.remainingAmount); + // marketDaily.expiredListedPods = market.expiredListedPods; + // marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.minus(listing.remainingAmount); + // marketDaily.availableListedPods = market.availableListedPods; + // marketDaily.save(); + // listing.status = "EXPIRED"; + // listing.remainingAmount = ZERO_BI; + // listing.save(); + /** + * let listing = PodListing.load(farmer + "-" + listedPlotIndex.toString()); + if (listing == null || listing.status != "ACTIVE") { + return; + } + + let market = loadPodMarketplace(diamondAddress); + + if (activeListingIndex == -1) { + // There should always be a matching entry in this list because it is verified that the listing is ACTIVE + for (let i = 0; i < market.activeListings.length; i++) { + const destructured = market.activeListings[i].split("-"); + // Unnecessary to check if the account matches. + if (destructured[1] == listedPlotIndex.toString()) { + activeListingIndex = i; + break; + } + } + } + + let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); + let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); + + market.expiredListedPods = market.expiredListedPods.plus(listing.remainingAmount); + market.availableListedPods = market.availableListedPods.minus(listing.remainingAmount); + let activeListings = market.activeListings; + activeListings.splice(activeListingIndex, 1); + market.activeListings = activeListings; + market.save(); + + marketHourly.season = market.season; + marketHourly.deltaExpiredListedPods = marketHourly.deltaExpiredListedPods.plus(listing.remainingAmount); + marketHourly.expiredListedPods = market.expiredListedPods; + marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods.minus(listing.remainingAmount); + marketHourly.availableListedPods = market.availableListedPods; + marketHourly.save(); + + marketDaily.season = market.season; + marketDaily.deltaExpiredListedPods = marketDaily.deltaExpiredListedPods.plus(listing.remainingAmount); + marketDaily.expiredListedPods = market.expiredListedPods; + marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.minus(listing.remainingAmount); + marketDaily.availableListedPods = market.availableListedPods; + marketDaily.save(); + + listing.status = "EXPIRED"; + listing.remainingAmount = ZERO_BI; + listing.save(); + */ +} diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 2d9e28d7d6..e27ce4afda 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -99,6 +99,7 @@ describe("Marketplace", () => { BEANSTALK.toHexString(), [event.params.id.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans, + orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, @@ -390,6 +391,7 @@ describe("Marketplace", () => { BEANSTALK.toHexString(), [], orderBeans, + ZERO_BI, orderBeans, orderedPods, ZERO_BI, @@ -416,6 +418,7 @@ describe("Marketplace", () => { BEANSTALK.toHexString(), [event.params.id.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans, + orderBeans.minus(orderBeans1), orderBeans1, soldToOrder1, ZERO_BI, @@ -444,6 +447,7 @@ describe("Marketplace", () => { BEANSTALK.toHexString(), [], orderBeans, + ZERO_BI, orderBeans, orderedPods, ZERO_BI, @@ -461,7 +465,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", "0"); assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI, ZERO_BI); }); test("Cancel order - partial", () => { @@ -483,6 +487,7 @@ describe("Marketplace", () => { BEANSTALK.toHexString(), [], orderBeans, + ZERO_BI, orderBeans1, soldToOrder1, orderBeans.minus(orderBeans1), @@ -502,6 +507,7 @@ describe("Marketplace", () => { BEANSTALK.toHexString(), [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans.times(BigInt.fromU32(2)), + orderBeans, ZERO_BI, ZERO_BI, orderBeans, @@ -531,6 +537,7 @@ describe("Marketplace", () => { BEANSTALK.toHexString(), [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], orderBeans.times(BigInt.fromU32(3)), + orderBeans, orderBeans1, soldToOrder1, orderBeans.plus(orderBeans.minus(orderBeans1)), @@ -546,7 +553,9 @@ describe("Marketplace", () => { setHarvestable(maxHarvestableIndex.plus(ONE_BI)); assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "EXPIRED"); - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + + // TODO: need to test the situation when the user cancels the expired order to retrieve their beans }); }); }); diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index 9ba1412e14..0f4b4b1c8e 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -189,6 +189,7 @@ export function assertMarketOrdersState( address: string, orders: string[], orderBeans: BigInt, + availableOrderBeans: BigInt, filledOrderBeans: BigInt, filledOrderedPods: BigInt, cancelledOrderBeans: BigInt, @@ -198,6 +199,7 @@ export function assertMarketOrdersState( ): void { assert.fieldEquals("PodMarketplace", address, "activeOrders", arrayToString(orders)); assert.fieldEquals("PodMarketplace", address, "orderBeans", orderBeans.toString()); + assert.fieldEquals("PodMarketplace", address, "availableOrderBeans", availableOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); From af85ecccf605e70044025d488f1db6683a3de477 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 12:23:17 -0700 Subject: [PATCH 34/89] refactor remainingAmount to contain the amount in a plot at cancellation/expiry --- projects/subgraph-beanstalk/schema.graphql | 5 -- .../src/MarketplaceHandler.ts | 5 -- .../src/utils/PodListing.ts | 8 +- .../subgraph-beanstalk/src/utils/PodOrder.ts | 82 ++++--------------- .../tests/Marketplace.test.ts | 14 ++-- 5 files changed, 25 insertions(+), 89 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 041d042020..c40788d661 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -1008,11 +1008,6 @@ type PodListing @entity { """ filledAmount: BigInt! - """ - The number of Pods that were remaining in *this* PodListing when it was Cancelled. - """ - cancelledAmount: BigInt! - ######################## Activity ######################## "Any Fills associated with this PodListing." diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 195a5ccf9f..ed2b43ea54 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -65,7 +65,6 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { listing.fill = null; listing.filled = ZERO_BI; listing.filledAmount = ZERO_BI; - listing.cancelledAmount = ZERO_BI; } // Identifiers @@ -143,8 +142,6 @@ export function handlePodListingCancelled(event: PodListingCancelled): void { updateMarketListingBalances(event.address, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); listing.status = listing.filled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; - listing.cancelledAmount = listing.remainingAmount; - listing.remainingAmount = ZERO_BI; listing.updatedAt = event.block.timestamp; listing.save(); @@ -405,7 +402,6 @@ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): voi listing.fill = null; listing.filled = ZERO_BI; listing.filledAmount = ZERO_BI; - listing.cancelledAmount = ZERO_BI; } listing.historyID = listing.id + "-" + event.block.timestamp.toString(); @@ -487,7 +483,6 @@ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { listing.fill = null; listing.filled = ZERO_BI; listing.filledAmount = ZERO_BI; - listing.cancelledAmount = ZERO_BI; } listing.historyID = listing.id + "-" + event.block.timestamp.toString(); diff --git a/projects/subgraph-beanstalk/src/utils/PodListing.ts b/projects/subgraph-beanstalk/src/utils/PodListing.ts index fd2de02aff..ee94cec930 100644 --- a/projects/subgraph-beanstalk/src/utils/PodListing.ts +++ b/projects/subgraph-beanstalk/src/utils/PodListing.ts @@ -31,7 +31,6 @@ export function loadPodListing(account: Address, index: BigInt): PodListing { listing.amount = ZERO_BI; listing.remainingAmount = ZERO_BI; listing.filledAmount = ZERO_BI; - listing.cancelledAmount = ZERO_BI; listing.status = "ACTIVE"; listing.createdAt = ZERO_BI; @@ -55,6 +54,8 @@ export function expirePodListingIfExists( if (listing == null || listing.status != "ACTIVE") { return; } + listing.status = "EXPIRED"; + listing.save(); let market = loadPodMarketplace(diamondAddress); @@ -93,10 +94,6 @@ export function expirePodListingIfExists( marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.minus(listing.remainingAmount); marketDaily.availableListedPods = market.availableListedPods; marketDaily.save(); - - listing.status = "EXPIRED"; - listing.remainingAmount = ZERO_BI; - listing.save(); } export function createHistoricalPodListing(listing: PodListing): void { @@ -128,7 +125,6 @@ export function createHistoricalPodListing(listing: PodListing): void { newListing.amount = listing.amount; newListing.remainingAmount = listing.remainingAmount; newListing.filledAmount = listing.filledAmount; - newListing.cancelledAmount = listing.cancelledAmount; newListing.fill = listing.fill; diff --git a/projects/subgraph-beanstalk/src/utils/PodOrder.ts b/projects/subgraph-beanstalk/src/utils/PodOrder.ts index 15f806ee9c..691e01a83f 100644 --- a/projects/subgraph-beanstalk/src/utils/PodOrder.ts +++ b/projects/subgraph-beanstalk/src/utils/PodOrder.ts @@ -55,80 +55,34 @@ export function createHistoricalPodOrder(order: PodOrder): void { } } -export function expirePodOrder(diamondAddress: Address, orderId: string, timestamp: BigInt, activeListingIndex: i32): void { - // let order = loadPodOrder(Bytes.fromHexString(orderId)); - // let market = loadPodMarketplace(diamondAddress); - // let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); - // let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); - // const expiredBeans = order.beanAmount.minus(order.beanAmountFilled); - // market.expiredOrderBeans = market.expiredOrderBeans.plus(expiredBeans); - // /// - // market.availableListedPods = market.availableListedPods.minus(listing.remainingAmount); - // let activeListings = market.activeListings; - // activeListings.splice(activeListingIndex, 1); - // market.activeListings = activeListings; - // market.save(); - // marketHourly.season = market.season; - // marketHourly.deltaExpiredListedPods = marketHourly.deltaExpiredListedPods.plus(listing.remainingAmount); - // marketHourly.expiredListedPods = market.expiredListedPods; - // marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods.minus(listing.remainingAmount); - // marketHourly.availableListedPods = market.availableListedPods; - // marketHourly.save(); - // marketDaily.season = market.season; - // marketDaily.deltaExpiredListedPods = marketDaily.deltaExpiredListedPods.plus(listing.remainingAmount); - // marketDaily.expiredListedPods = market.expiredListedPods; - // marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.minus(listing.remainingAmount); - // marketDaily.availableListedPods = market.availableListedPods; - // marketDaily.save(); - // listing.status = "EXPIRED"; - // listing.remainingAmount = ZERO_BI; - // listing.save(); - /** - * let listing = PodListing.load(farmer + "-" + listedPlotIndex.toString()); - if (listing == null || listing.status != "ACTIVE") { - return; - } +export function expirePodOrder(diamondAddress: Address, orderId: string, timestamp: BigInt, activeOrderIndex: i32): void { + let order = loadPodOrder(Bytes.fromHexString(orderId)); + order.status = "EXPIRED"; + order.save(); let market = loadPodMarketplace(diamondAddress); - - if (activeListingIndex == -1) { - // There should always be a matching entry in this list because it is verified that the listing is ACTIVE - for (let i = 0; i < market.activeListings.length; i++) { - const destructured = market.activeListings[i].split("-"); - // Unnecessary to check if the account matches. - if (destructured[1] == listedPlotIndex.toString()) { - activeListingIndex = i; - break; - } - } - } - let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); - market.expiredListedPods = market.expiredListedPods.plus(listing.remainingAmount); - market.availableListedPods = market.availableListedPods.minus(listing.remainingAmount); - let activeListings = market.activeListings; - activeListings.splice(activeListingIndex, 1); - market.activeListings = activeListings; + const expiredBeans = order.beanAmount.minus(order.beanAmountFilled); + market.expiredOrderBeans = market.expiredOrderBeans.plus(expiredBeans); + market.availableOrderBeans = market.availableOrderBeans.minus(expiredBeans); + let activeOrders = market.activeOrders; + activeOrders.splice(activeOrderIndex, 1); + market.activeOrders = activeOrders; market.save(); marketHourly.season = market.season; - marketHourly.deltaExpiredListedPods = marketHourly.deltaExpiredListedPods.plus(listing.remainingAmount); - marketHourly.expiredListedPods = market.expiredListedPods; - marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods.minus(listing.remainingAmount); - marketHourly.availableListedPods = market.availableListedPods; + marketHourly.deltaExpiredOrderBeans = marketHourly.deltaExpiredOrderBeans.plus(expiredBeans); + marketHourly.expiredOrderBeans = market.expiredListedPods; + marketHourly.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.minus(expiredBeans); + marketHourly.availableOrderBeans = market.availableOrderBeans; marketHourly.save(); marketDaily.season = market.season; - marketDaily.deltaExpiredListedPods = marketDaily.deltaExpiredListedPods.plus(listing.remainingAmount); - marketDaily.expiredListedPods = market.expiredListedPods; - marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.minus(listing.remainingAmount); - marketDaily.availableListedPods = market.availableListedPods; + marketDaily.deltaExpiredOrderBeans = marketDaily.deltaExpiredOrderBeans.plus(expiredBeans); + marketDaily.expiredOrderBeans = market.expiredListedPods; + marketDaily.deltaAvailableOrderBeans = marketDaily.deltaAvailableOrderBeans.minus(expiredBeans); + marketDaily.availableOrderBeans = market.availableOrderBeans; marketDaily.save(); - - listing.status = "EXPIRED"; - listing.remainingAmount = ZERO_BI; - listing.save(); - */ } diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index e27ce4afda..313f0c4b21 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -200,8 +200,7 @@ describe("Marketplace", () => { const cancelledAmount = sowedPods.minus(beans_BI(500)); const listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", listingID, "status", "CANCELLED"); - assert.fieldEquals("PodListing", listingID, "cancelledAmount", cancelledAmount.toString()); - assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", cancelledAmount.toString()); assertMarketListingsState( BEANSTALK.toHexString(), @@ -231,8 +230,7 @@ describe("Marketplace", () => { const newListingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", newListingID, "status", "CANCELLED_PARTIAL"); - assert.fieldEquals("PodListing", newListingID, "cancelledAmount", remaining.toString()); - assert.fieldEquals("PodListing", newListingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", remaining.toString()); assertMarketListingsState( BEANSTALK.toHexString(), @@ -257,7 +255,6 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); assert.fieldEquals("PodListing", listingID + "-0", "status", "CANCELLED"); assert.fieldEquals("PodListing", listingID + "-0", "filled", "0"); - assert.fieldEquals("PodListing", listingID + "-0", "cancelledAmount", listedPods.toString()); assertMarketListingsState( BEANSTALK.toHexString(), @@ -287,7 +284,6 @@ describe("Marketplace", () => { assert.notInStore("PodListing", newListingID + "-1"); assert.fieldEquals("PodListing", newListingID + "-0", "status", "CANCELLED_PARTIAL"); assert.fieldEquals("PodListing", newListingID + "-0", "filled", filledPods.toString()); - assert.fieldEquals("PodListing", newListingID + "-0", "cancelledAmount", newListingAmount.toString()); assert.fieldEquals("PodListing", newListingID, "status", "ACTIVE"); assert.fieldEquals("PodListing", newListingID, "filled", "0"); assert.fieldEquals("PodListing", newListingID, "remainingAmount", newListingAmount.toString()); @@ -317,7 +313,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); setHarvestable(maxHarvestableIndex.plus(ONE_BI)); assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); - assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", listedPods.toString()); assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); @@ -338,7 +334,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); assert.fieldEquals("PodListing", newListingID, "status", "EXPIRED"); assert.fieldEquals("PodListing", newListingID, "filled", filledPods.toString()); - assert.fieldEquals("PodListing", newListingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", listedPods.minus(filledPods).toString()); assertMarketListingsState( BEANSTALK.toHexString(), @@ -365,7 +361,7 @@ describe("Marketplace", () => { // Plot harvests, now expired harvest(account, [listingIndex], sowedPods); assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); - assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", listedPods.toString()); assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); }); From 96d0956cd9669bc43f28dc00d5e66f74a6c5f869 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 13:48:15 -0700 Subject: [PATCH 35/89] fix cancel nonexisting listing/order --- .../subgraph-beanstalk/src/FieldHandler.ts | 2 +- .../src/MarketplaceHandler.ts | 42 ++++++++++--------- .../src/utils/PodMarketplace.ts | 8 +++- .../tests/Marketplace.test.ts | 38 ++++++++++++----- .../tests/utils/Marketplace.ts | 10 ++++- 5 files changed, 66 insertions(+), 34 deletions(-) diff --git a/projects/subgraph-beanstalk/src/FieldHandler.ts b/projects/subgraph-beanstalk/src/FieldHandler.ts index 9dc8b04832..8fe72b2e04 100644 --- a/projects/subgraph-beanstalk/src/FieldHandler.ts +++ b/projects/subgraph-beanstalk/src/FieldHandler.ts @@ -309,7 +309,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.farmer = event.params.to.toHexString(); sourcePlot.updatedAt = event.block.timestamp; sourcePlot.save(); - log.debug("\nPodTransfer: Sending full plot\n", []); + // log.debug("\nPodTransfer: Sending full plot\n", []); } else if (sourceIndex == event.params.id) { // We are only needing to split this plot once to send // Start value of zero diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index ed2b43ea54..c497bc7805 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -23,7 +23,8 @@ import { PodOrderCreated as PodOrderCreatedEvent, PodOrderFilled as PodOrderFilledEvent, PodOrderCancelled as PodOrderCancelledEvent, - PodOrder + PodOrder, + PodListing } from "../generated/schema"; import { toDecimal, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { loadFarmer } from "./utils/Farmer"; @@ -130,28 +131,33 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { } export function handlePodListingCancelled(event: PodListingCancelled): void { - let listing = loadPodListing(event.params.account, event.params.index); + let historyID = ""; + let listing = PodListing.load(event.params.account.toHexString() + "-" + event.params.index.toString()); + if (listing !== null && listing.status == "ACTIVE") { + updateActiveListings( + event.address, + MarketplaceAction.CANCELLED, + event.params.account.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateMarketListingBalances(event.address, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); - updateActiveListings( - event.address, - MarketplaceAction.CANCELLED, - event.params.account.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - updateMarketListingBalances(event.address, ZERO_BI, listing.remainingAmount, ZERO_BI, ZERO_BI, event.block.timestamp); + listing.status = listing.filled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; + listing.updatedAt = event.block.timestamp; + listing.save(); - listing.status = listing.filled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; - listing.updatedAt = event.block.timestamp; - listing.save(); + historyID = listing.historyID; + } + // Unclear whether this should possibly be omitted if the listing was invalid // Save the raw event data let id = "podListingCancelled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); let rawEvent = new PodListingCancelledEvent(id); rawEvent.hash = event.transaction.hash.toHexString(); rawEvent.logIndex = event.logIndex.toI32(); rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = listing.historyID; + rawEvent.historyID = historyID; rawEvent.account = event.params.account.toHexString(); rawEvent.index = event.params.index; rawEvent.blockNumber = event.block.number; @@ -340,11 +346,8 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { export function handlePodOrderCancelled(event: PodOrderCancelled): void { let historyID = ""; - - let orderCheck = PodOrder.load(event.params.id.toHexString()); - if (orderCheck !== null) { - let order = loadPodOrder(event.params.id); - + let order = PodOrder.load(event.params.id.toHexString()); + if (order !== null && order.status == "ACTIVE") { order.status = order.podAmountFilled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; order.updatedAt = event.block.timestamp; order.save(); @@ -361,6 +364,7 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { historyID = order.historyID; } + // Unclear whether this should possibly be omitted if the listing was invalid // Save the raw event data let id = "podOrderCancelled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); let rawEvent = new PodOrderCancelledEvent(id); diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index 4a4fff0c8f..fd30bee461 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -172,7 +172,11 @@ export function updateActiveListings( if (action == MarketplaceAction.CREATED) { listings.push(farmer + "-" + plotIndex.toString() + "-" + expiryIndex.toString()); } - if ([MarketplaceAction.CANCELLED, MarketplaceAction.FILLED_PARTIAL, MarketplaceAction.FILLED_FULL].includes(action)) { + if ( + [MarketplaceAction.CANCELLED, MarketplaceAction.FILLED_PARTIAL, MarketplaceAction.FILLED_FULL, MarketplaceAction.EXPIRED].includes( + action + ) + ) { listings.splice(Marketplace_findIndex_listing(listings, plotIndex), 1); } @@ -187,7 +191,7 @@ export function updateActiveOrders(diamondAddress: Address, action: MarketplaceA if (action == MarketplaceAction.CREATED) { orders.push(orderId + "-" + expiryIndex.toString()); } - if ([MarketplaceAction.CANCELLED, MarketplaceAction.FILLED_FULL].includes(action)) { + if ([MarketplaceAction.CANCELLED, MarketplaceAction.FILLED_FULL, MarketplaceAction.EXPIRED].includes(action)) { orders.splice(Marketplace_findIndex_order(orders, orderId), 1); } diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 313f0c4b21..664df1b693 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -1,13 +1,12 @@ import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; -import { handlePodListingCancelled } from "../src/MarketplaceHandler"; -import { createPodListingCancelledEvent } from "./event-mocking/Marketplace"; import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; import { assertMarketListingsState, assertMarketOrdersState, + cancelListing, cancelOrder, createListing_v2, createOrder_v2, @@ -40,7 +39,6 @@ describe("Marketplace", () => { // TODO tests: // fill order with pods that are also listed - // order expires due to podline advancing describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { @@ -194,9 +192,7 @@ describe("Marketplace", () => { // Cancellation isnt unique to pod market v2, consider including in the v1 section test("Cancel listing - full", () => { - const event = createPodListingCancelledEvent(account, listingIndex); - handlePodListingCancelled(event); - + const event = cancelListing(account, listingIndex); const cancelledAmount = sowedPods.minus(beans_BI(500)); const listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", listingID, "status", "CANCELLED"); @@ -225,8 +221,7 @@ describe("Marketplace", () => { const remaining = listedPods.minus(filledPods); const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); - const event = createPodListingCancelledEvent(account, newListingIndex); - handlePodListingCancelled(event); + const event = cancelListing(account, newListingIndex); const newListingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", newListingID, "status", "CANCELLED_PARTIAL"); @@ -248,7 +243,7 @@ describe("Marketplace", () => { test("Recreate listing", () => { const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); - handlePodListingCancelled(createPodListingCancelledEvent(account, listingIndex)); + cancelListing(account, listingIndex); const listEvent = createListing_v2(account, listingIndex, sowedPods, listingStart, maxHarvestableIndex); const listingID = listEvent.params.account.toHexString() + "-" + listEvent.params.index.toString(); @@ -276,7 +271,7 @@ describe("Marketplace", () => { const remaining = listedPods.minus(filledPods); const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); const newListingAmount = listedPods.minus(filledPods); - handlePodListingCancelled(createPodListingCancelledEvent(account, newListingIndex)); + cancelListing(account, newListingIndex); const newListEvent = createListing_v2(account, newListingIndex, remaining, ZERO_BI, maxHarvestableIndex); const newListingID = newListEvent.params.account.toHexString() + "-" + newListEvent.params.index.toString(); @@ -365,6 +360,20 @@ describe("Marketplace", () => { assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); }); + + test("Cancel expired/nonexistent listing", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); + const listingID = account + "-" + listingIndex.toString(); + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + + // Cancelling listing is still possible, nothing should change in market + cancelListing(account, listingIndex); + + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); + }); }); describe("Tests requiring Order", () => { @@ -550,8 +559,15 @@ describe("Marketplace", () => { assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "EXPIRED"); assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + }); - // TODO: need to test the situation when the user cancels the expired order to retrieve their beans + test("Cancel expired/nonexistent order", () => { + // User may still cancel the order to retrieve their beans. Nothing should change in market + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); + cancelOrder(account, orderId); + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "EXPIRED"); + + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); }); }); }); diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index 0f4b4b1c8e..4678f14536 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -1,6 +1,7 @@ import { BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; import { assert } from "matchstick-as/assembly/index"; import { + handlePodListingCancelled, handlePodListingCreated_v2, handlePodListingFilled_v2, handlePodOrderCancelled, @@ -8,6 +9,7 @@ import { handlePodOrderFilled_v2 } from "../../src/MarketplaceHandler"; import { + createPodListingCancelledEvent, createPodListingCreatedEvent_v2, createPodListingFilledEvent_v2, createPodOrderCancelledEvent, @@ -23,7 +25,7 @@ import { } from "../../generated/BIP29-PodMarketplace/Beanstalk"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; import { transferPlot } from "./Field"; -import { PodOrderCancelled } from "../../generated/Field/Beanstalk"; +import { PodOrderCancelled, PodListingCancelled } from "../../generated/Field/Beanstalk"; const pricingFunction = Bytes.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" @@ -88,6 +90,12 @@ export function fillOrder_v2( return event; } +export function cancelListing(account: string, listingIndex: BigInt): PodListingCancelled { + const event = createPodListingCancelledEvent(account, listingIndex); + handlePodListingCancelled(event); + return event; +} + export function cancelOrder(account: string, orderId: Bytes): PodOrderCancelled { const event = createPodOrderCancelledEvent(account, orderId); handlePodOrderCancelled(event); From 354679e8fa0086fd686c3f94b6f64a20128fd649 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 14:11:17 -0700 Subject: [PATCH 36/89] refactor - orders dont expire --- projects/subgraph-beanstalk/schema.graphql | 12 +--- .../subgraph-beanstalk/src/SeasonHandler.ts | 2 - .../src/utils/PodMarketplace.ts | 29 +-------- .../subgraph-beanstalk/src/utils/PodOrder.ts | 64 +++++++++---------- .../tests/Marketplace.test.ts | 43 +++++-------- .../tests/utils/Marketplace.ts | 2 - 6 files changed, 53 insertions(+), 99 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index c40788d661..c1c061a5f3 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -703,7 +703,7 @@ type PodMarketplace @entity { season: Int! "Information about the active pod listings. Each entry of the form 'account-index-expiry'" activeListings: [String!]! - "Information about the active pod orders. Each entry of the form 'account-index-expiry'" + "Information about the active pod orders. Each entry of the form 'orderId-maxPlaceInLine'" activeOrders: [String!]! "All historical listings" allListings: [PodListing!]! @derivedFrom(field: "podMarketplace") @@ -731,8 +731,6 @@ type PodMarketplace @entity { filledOrderedPods: BigInt! "Current cumulative beans in pod orders cancelled" cancelledOrderBeans: BigInt! - "Current cumulative beans in pod orders expired" - expiredOrderBeans: BigInt! "Cumulative pod volume between listings and orders" podVolume: BigInt! "Cumulative bean volume between listings and orders" @@ -770,8 +768,6 @@ type PodMarketplaceHourlySnapshot @entity { filledOrderedPods: BigInt! "Current cumulative beans in pod orders cancelled" cancelledOrderBeans: BigInt! - "Current cumulative beans in pod orders expired" - expiredOrderBeans: BigInt! "Point in time current cumulative pod volume between listings and orders" podVolume: BigInt! "Point in time current cumulative bean volume between listings and orders" @@ -796,8 +792,6 @@ type PodMarketplaceHourlySnapshot @entity { deltaFilledOrderedPods: BigInt! "Point in time current delta cancelled ordered beans in pod orders" deltaCancelledOrderBeans: BigInt! - "Point in time current delta expired ordered beans in pod orders" - deltaExpiredOrderBeans: BigInt! "Point in time current delta pod volume between listings and orders" deltaPodVolume: BigInt! "Point in time current delta bean volume between listings and orders" @@ -835,8 +829,6 @@ type PodMarketplaceDailySnapshot @entity { filledOrderedPods: BigInt! "Current cumulative beans in pod orders cancelled" cancelledOrderBeans: BigInt! - "Current cumulative beans in pod orders expired" - expiredOrderBeans: BigInt! "Point in time current cumulative pod volume between listings and orders" podVolume: BigInt! "Point in time current cumulative bean volume between listings and orders" @@ -861,8 +853,6 @@ type PodMarketplaceDailySnapshot @entity { deltaFilledOrderedPods: BigInt! "Point in time current delta cancelled ordered beans in pod orders" deltaCancelledOrderBeans: BigInt! - "Point in time current delta expired ordered beans in pod orders" - deltaExpiredOrderBeans: BigInt! "Point in time current delta pod volume between listings and orders" deltaPodVolume: BigInt! "Point in time current delta bean volume between listings and orders" diff --git a/projects/subgraph-beanstalk/src/SeasonHandler.ts b/projects/subgraph-beanstalk/src/SeasonHandler.ts index acd156107d..d6252f46e1 100644 --- a/projects/subgraph-beanstalk/src/SeasonHandler.ts +++ b/projects/subgraph-beanstalk/src/SeasonHandler.ts @@ -13,7 +13,6 @@ import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, loadPodMarketplaceHourlySnapshot, - updateExpiredOrders, updateExpiredPlots } from "./utils/PodMarketplace"; import { loadSeason } from "./utils/Season"; @@ -240,6 +239,5 @@ export function handleIncentive(event: Incentivization): void { season.save(); updateExpiredPlots(season.harvestableIndex, event.address, event.block.timestamp); - updateExpiredOrders(season.harvestableIndex, event.address, event.block.timestamp); updateHarvestablePlots(season.harvestableIndex, event.block.timestamp, event.block.number); } diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index fd30bee461..88e4db7ffb 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -1,10 +1,9 @@ -import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { Address, BigInt, log } from "@graphprotocol/graph-ts"; import { PodMarketplace, PodMarketplaceHourlySnapshot, PodMarketplaceDailySnapshot } from "../../generated/schema"; import { dayFromTimestamp } from "./Dates"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; import { loadField } from "./Field"; import { expirePodListingIfExists, loadPodListing } from "./PodListing"; -import { expirePodOrder } from "./PodOrder"; export enum MarketplaceAction { CREATED, @@ -32,7 +31,6 @@ export function loadPodMarketplace(diamondAddress: Address): PodMarketplace { marketplace.filledOrderedPods = ZERO_BI; marketplace.filledOrderBeans = ZERO_BI; marketplace.cancelledOrderBeans = ZERO_BI; - marketplace.expiredOrderBeans = ZERO_BI; marketplace.podVolume = ZERO_BI; marketplace.beanVolume = ZERO_BI; marketplace.save(); @@ -70,8 +68,6 @@ export function loadPodMarketplaceHourlySnapshot(diamondAddress: Address, season snapshot.filledOrderBeans = marketplace.filledOrderBeans; snapshot.deltaCancelledOrderBeans = ZERO_BI; snapshot.cancelledOrderBeans = marketplace.cancelledOrderBeans; - snapshot.deltaExpiredOrderBeans = ZERO_BI; - snapshot.expiredOrderBeans = marketplace.expiredOrderBeans; snapshot.deltaPodVolume = ZERO_BI; snapshot.podVolume = marketplace.podVolume; snapshot.deltaBeanVolume = ZERO_BI; @@ -112,8 +108,6 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta snapshot.filledOrderBeans = marketplace.filledOrderBeans; snapshot.deltaCancelledOrderBeans = ZERO_BI; snapshot.cancelledOrderBeans = marketplace.cancelledOrderBeans; - snapshot.deltaExpiredOrderBeans = ZERO_BI; - snapshot.expiredOrderBeans = marketplace.expiredOrderBeans; snapshot.deltaPodVolume = ZERO_BI; snapshot.podVolume = marketplace.podVolume; snapshot.deltaBeanVolume = ZERO_BI; @@ -142,23 +136,6 @@ export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Add } } -export function updateExpiredOrders(harvestableIndex: BigInt, diamondAddress: Address, timestamp: BigInt): void { - let market = loadPodMarketplace(diamondAddress); - let remainingOrders = market.activeOrders; - - // Cancel any pod marketplace orders beyond the index - for (let i = 0; i < remainingOrders.length; i++) { - const destructured = remainingOrders[i].split("-"); - const maxHarvestableIndex = BigInt.fromString(destructured[1]); - if (harvestableIndex > maxHarvestableIndex) { - // This method updates the marketplace entity, so it will perform the splice. - expirePodOrder(diamondAddress, destructured[0], timestamp, i); - // A similar splice is done here also to track the updated index on the underlying array. - remainingOrders.splice(i--, 1); - } - } -} - export function updateActiveListings( diamondAddress: Address, action: MarketplaceAction, @@ -184,12 +161,12 @@ export function updateActiveListings( market.save(); } -export function updateActiveOrders(diamondAddress: Address, action: MarketplaceAction, orderId: string, expiryIndex: BigInt): void { +export function updateActiveOrders(diamondAddress: Address, action: MarketplaceAction, orderId: string, maxPlaceInLine: BigInt): void { let market = loadPodMarketplace(diamondAddress); let orders = market.activeOrders; if (action == MarketplaceAction.CREATED) { - orders.push(orderId + "-" + expiryIndex.toString()); + orders.push(orderId + "-" + maxPlaceInLine.toString()); } if ([MarketplaceAction.CANCELLED, MarketplaceAction.FILLED_FULL, MarketplaceAction.EXPIRED].includes(action)) { orders.splice(Marketplace_findIndex_order(orders, orderId), 1); diff --git a/projects/subgraph-beanstalk/src/utils/PodOrder.ts b/projects/subgraph-beanstalk/src/utils/PodOrder.ts index 691e01a83f..3f8cee0fe2 100644 --- a/projects/subgraph-beanstalk/src/utils/PodOrder.ts +++ b/projects/subgraph-beanstalk/src/utils/PodOrder.ts @@ -2,7 +2,6 @@ import { Bytes, BigInt, Address } from "@graphprotocol/graph-ts"; import { PodOrder } from "../../generated/schema"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; import { ZERO_BI } from "../../../subgraph-core/utils/Decimals"; -import { loadPodMarketplace, loadPodMarketplaceDailySnapshot, loadPodMarketplaceHourlySnapshot } from "./PodMarketplace"; export function loadPodOrder(orderID: Bytes): PodOrder { let order = PodOrder.load(orderID.toHexString()); @@ -55,34 +54,35 @@ export function createHistoricalPodOrder(order: PodOrder): void { } } -export function expirePodOrder(diamondAddress: Address, orderId: string, timestamp: BigInt, activeOrderIndex: i32): void { - let order = loadPodOrder(Bytes.fromHexString(orderId)); - order.status = "EXPIRED"; - order.save(); - - let market = loadPodMarketplace(diamondAddress); - let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); - let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); - - const expiredBeans = order.beanAmount.minus(order.beanAmountFilled); - market.expiredOrderBeans = market.expiredOrderBeans.plus(expiredBeans); - market.availableOrderBeans = market.availableOrderBeans.minus(expiredBeans); - let activeOrders = market.activeOrders; - activeOrders.splice(activeOrderIndex, 1); - market.activeOrders = activeOrders; - market.save(); - - marketHourly.season = market.season; - marketHourly.deltaExpiredOrderBeans = marketHourly.deltaExpiredOrderBeans.plus(expiredBeans); - marketHourly.expiredOrderBeans = market.expiredListedPods; - marketHourly.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.minus(expiredBeans); - marketHourly.availableOrderBeans = market.availableOrderBeans; - marketHourly.save(); - - marketDaily.season = market.season; - marketDaily.deltaExpiredOrderBeans = marketDaily.deltaExpiredOrderBeans.plus(expiredBeans); - marketDaily.expiredOrderBeans = market.expiredListedPods; - marketDaily.deltaAvailableOrderBeans = marketDaily.deltaAvailableOrderBeans.minus(expiredBeans); - marketDaily.availableOrderBeans = market.availableOrderBeans; - marketDaily.save(); -} +// Currently there is no concept of an expired pod order, but there may be in the future +// export function expirePodOrder(diamondAddress: Address, orderId: string, timestamp: BigInt, activeOrderIndex: i32): void { +// let order = loadPodOrder(Bytes.fromHexString(orderId)); +// order.status = "EXPIRED"; +// order.save(); +// +// let market = loadPodMarketplace(diamondAddress); +// let marketHourly = loadPodMarketplaceHourlySnapshot(diamondAddress, market.season, timestamp); +// let marketDaily = loadPodMarketplaceDailySnapshot(diamondAddress, timestamp); +// +// const expiredBeans = order.beanAmount.minus(order.beanAmountFilled); +// market.expiredOrderBeans = market.expiredOrderBeans.plus(expiredBeans); +// market.availableOrderBeans = market.availableOrderBeans.minus(expiredBeans); +// let activeOrders = market.activeOrders; +// activeOrders.splice(activeOrderIndex, 1); +// market.activeOrders = activeOrders; +// market.save(); +// +// marketHourly.season = market.season; +// marketHourly.deltaExpiredOrderBeans = marketHourly.deltaExpiredOrderBeans.plus(expiredBeans); +// marketHourly.expiredOrderBeans = market.expiredListedPods; +// marketHourly.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.minus(expiredBeans); +// marketHourly.availableOrderBeans = market.availableOrderBeans; +// marketHourly.save(); +// +// marketDaily.season = market.season; +// marketDaily.deltaExpiredOrderBeans = marketDaily.deltaExpiredOrderBeans.plus(expiredBeans); +// marketDaily.expiredOrderBeans = market.expiredListedPods; +// marketDaily.deltaAvailableOrderBeans = marketDaily.deltaAvailableOrderBeans.minus(expiredBeans); +// marketDaily.availableOrderBeans = market.availableOrderBeans; +// marketDaily.save(); +// } diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 664df1b693..4832d85a02 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -37,9 +37,6 @@ describe("Marketplace", () => { clearStore(); }); - // TODO tests: - // fill order with pods that are also listed - describe("Marketplace v2", () => { test("Create a pod listing - full plot", () => { const event = createListing_v2(account, listingIndex, sowedPods, ZERO_BI, maxHarvestableIndex); @@ -102,7 +99,6 @@ describe("Marketplace", () => { ZERO_BI, ZERO_BI, ZERO_BI, - ZERO_BI, ZERO_BI ); }); @@ -400,7 +396,6 @@ describe("Marketplace", () => { orderBeans, orderedPods, ZERO_BI, - ZERO_BI, orderedPods, orderBeans ); @@ -427,7 +422,6 @@ describe("Marketplace", () => { orderBeans1, soldToOrder1, ZERO_BI, - ZERO_BI, soldToOrder1, orderBeans1 ); @@ -456,7 +450,6 @@ describe("Marketplace", () => { orderBeans, orderedPods, ZERO_BI, - ZERO_BI, orderedPods, orderBeans ); @@ -470,7 +463,7 @@ describe("Marketplace", () => { assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", "0"); assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI, ZERO_BI); + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); }); test("Cancel order - partial", () => { @@ -496,7 +489,6 @@ describe("Marketplace", () => { orderBeans1, soldToOrder1, orderBeans.minus(orderBeans1), - ZERO_BI, soldToOrder1, orderBeans1 ); @@ -517,7 +509,6 @@ describe("Marketplace", () => { ZERO_BI, orderBeans, ZERO_BI, - ZERO_BI, ZERO_BI ); @@ -546,29 +537,29 @@ describe("Marketplace", () => { orderBeans1, soldToOrder1, orderBeans.plus(orderBeans.minus(orderBeans1)), - ZERO_BI, soldToOrder1, orderBeans1 ); }); - test("Order expires due to moving podline", () => { - setHarvestable(maxHarvestableIndex); - assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "ACTIVE"); - setHarvestable(maxHarvestableIndex.plus(ONE_BI)); - assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "EXPIRED"); - - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + test("Cancel nonexistent order", () => { + const nonexistent = Bytes.fromHexString("0x1234"); + cancelOrder(account, nonexistent); + assert.notInStore("PodOrder", nonexistent.toHexString()); + assertMarketOrdersState( + BEANSTALK.toHexString(), + [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], + orderBeans, + orderBeans, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); }); - test("Cancel expired/nonexistent order", () => { - // User may still cancel the order to retrieve their beans. Nothing should change in market - setHarvestable(maxHarvestableIndex.plus(ONE_BI)); - cancelOrder(account, orderId); - assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "EXPIRED"); - - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); - }); + test("Fill order with pods that are also listed", () => {}); }); }); }); diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index 4678f14536..c4045d9759 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -201,7 +201,6 @@ export function assertMarketOrdersState( filledOrderBeans: BigInt, filledOrderedPods: BigInt, cancelledOrderBeans: BigInt, - expiredOrderBeans: BigInt, podVolume: BigInt, beanVolume: BigInt ): void { @@ -211,7 +210,6 @@ export function assertMarketOrdersState( assert.fieldEquals("PodMarketplace", address, "filledOrderBeans", filledOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "filledOrderedPods", filledOrderedPods.toString()); assert.fieldEquals("PodMarketplace", address, "cancelledOrderBeans", cancelledOrderBeans.toString()); - assert.fieldEquals("PodMarketplace", address, "expiredOrderBeans", expiredOrderBeans.toString()); assert.fieldEquals("PodMarketplace", address, "podVolume", podVolume.toString()); assert.fieldEquals("PodMarketplace", address, "beanVolume", beanVolume.toString()); } From 662d858d2d7e2ceaa99034c69c6a98c595f02c9e Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 14:20:14 -0700 Subject: [PATCH 37/89] remove unnecessary test --- projects/subgraph-beanstalk/src/MarketplaceHandler.ts | 2 +- projects/subgraph-beanstalk/src/YieldHandler.ts | 1 - projects/subgraph-beanstalk/tests/Marketplace.test.ts | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index c497bc7805..7e50ced13c 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -83,7 +83,7 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { listing.pricePerPod = event.params.pricePerPod; // Amounts [Relative to Original] - listing.originalIndex = event.params.index; // TODO: I think this should be +start + listing.originalIndex = event.params.index; listing.originalAmount = event.params.amount; // Amounts [Relative to Child] diff --git a/projects/subgraph-beanstalk/src/YieldHandler.ts b/projects/subgraph-beanstalk/src/YieldHandler.ts index c2c3b6c9b2..d1d6067761 100644 --- a/projects/subgraph-beanstalk/src/YieldHandler.ts +++ b/projects/subgraph-beanstalk/src/YieldHandler.ts @@ -209,7 +209,6 @@ export function updateSiloVAPYs(t: i32, timestamp: BigInt, window: i32): void { // Save the apys for (let i = 0; i < apys.length; ++i) { - //FIXME let tokenYield = loadTokenYield(Address.fromBytes(whitelistSettings[i].id), t, window); tokenYield.beanAPY = apys[i][0]; tokenYield.stalkAPY = apys[i][1]; diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/Marketplace.test.ts index 4832d85a02..2baf47fa41 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/Marketplace.test.ts @@ -558,8 +558,6 @@ describe("Marketplace", () => { ZERO_BI ); }); - - test("Fill order with pods that are also listed", () => {}); }); }); }); From c57b3d0003530517db99b8a66de67a3dbdb3a658 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 15:14:59 -0700 Subject: [PATCH 38/89] add mock events for v1 --- .../src/MarketplaceHandler.ts | 23 ++- .../tests/utils/Marketplace.ts | 183 ++++++++++++++++-- 2 files changed, 193 insertions(+), 13 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 7e50ced13c..c23bb0e37c 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -1,4 +1,4 @@ -import { Address, BigInt, log } from "@graphprotocol/graph-ts"; +import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { PodListingCancelled, PodListingCreated as PodListingCreated_v1, @@ -41,6 +41,27 @@ import { } from "./utils/PodMarketplace"; import { createHistoricalPodOrder, loadPodOrder } from "./utils/PodOrder"; +// TODO: write v1 tests first +/* +class PodListingCreatedParams { + account: Address; + index: BigInt; + start: BigInt; + amount: BigInt; + pricePerPod: i32; + maxHarvestableIndex: BigInt; + + toWallet: boolean; // v1 + mode: i32; // v1.1 + + // v2 + minFillAmount: BigInt; + pricingFunction: Bytes; + // mode: i32; + pricingType: i32; +} +*/ + /* ------------------------------------ * POD MARKETPLACE V1 * diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index c4045d9759..e59d56d61c 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -2,21 +2,31 @@ import { BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; import { assert } from "matchstick-as/assembly/index"; import { handlePodListingCancelled, + handlePodListingCreated, + handlePodListingCreated_v1_1, handlePodListingCreated_v2, + handlePodListingFilled, handlePodListingFilled_v2, handlePodOrderCancelled, + handlePodOrderCreated, handlePodOrderCreated_v2, + handlePodOrderFilled, handlePodOrderFilled_v2 } from "../../src/MarketplaceHandler"; import { createPodListingCancelledEvent, + createPodListingCreatedEvent, + createPodListingCreatedEvent_v1_1, createPodListingCreatedEvent_v2, + createPodListingFilledEvent, createPodListingFilledEvent_v2, createPodOrderCancelledEvent, + createPodOrderCreatedEvent, createPodOrderCreatedEvent_v2, + createPodOrderFilledEvent, createPodOrderFilledEvent_v2 } from "../event-mocking/Marketplace"; -import { ONE_BI, ZERO_BI } from "../../../subgraph-core/utils/Decimals"; +import { BI_10, ONE_BI, ZERO_BI } from "../../../subgraph-core/utils/Decimals"; import { PodListingCreated as PodListingCreated_v2, PodListingFilled as PodListingFilled_v2, @@ -25,7 +35,15 @@ import { } from "../../generated/BIP29-PodMarketplace/Beanstalk"; import { BEANSTALK } from "../../../subgraph-core/utils/Constants"; import { transferPlot } from "./Field"; -import { PodOrderCancelled, PodListingCancelled } from "../../generated/Field/Beanstalk"; +import { + PodOrderCancelled, + PodListingCancelled, + PodListingCreated as PodListingCreated_v1, + PodListingFilled as PodListingFilled_v1, + PodOrderCreated as PodOrderCreated_v1, + PodOrderFilled as PodOrderFilled_v1 +} from "../../generated/Field/Beanstalk"; +import { PodListingCreated as PodListingCreated_v1_1 } from "../../generated/Marketplace-Replanted/Beanstalk"; const pricingFunction = Bytes.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010000" @@ -35,6 +53,33 @@ export function getPodFillId(index: BigInt, event: ethereum.Event): string { return BEANSTALK.toHexString() + "-" + index.toString() + "-" + event.transaction.hash.toHexString(); } +export function fillListing_v1( + from: string, + to: string, + listingIndex: BigInt, + listingStart: BigInt, + podAmount: BigInt, + pricePerPod: BigInt +): PodListingFilled_v1 { + const event = createPodListingFilledEvent(from, to, listingIndex, listingStart, podAmount); + handlePodListingFilled(event); + + // Perform plot transfer + transferPlot(from, to, listingIndex.plus(listingStart), podAmount); + + // Assert PodFill + const podFillId = getPodFillId(event.params.index, event); + assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); + assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); + assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); + assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); + assert.fieldEquals("PodFill", podFillId, "costInBeans", podAmount.times(pricePerPod).div(BI_10.pow(6)).toString()); + + return event; +} + export function fillListing_v2( from: string, to: string, @@ -62,6 +107,34 @@ export function fillListing_v2( return event; } +export function fillOrder_v1( + from: string, + to: string, + orderId: Bytes, + index: BigInt, + start: BigInt, + podAmount: BigInt, + pricePerPod: BigInt +): PodOrderFilled_v1 { + const event = createPodOrderFilledEvent(from, to, orderId, index, start, podAmount); + handlePodOrderFilled(event); + + // Perform plot transfer + transferPlot(from, to, index.plus(start), podAmount); + + // Assert PodFill + const podFillId = getPodFillId(index, event); + assert.fieldEquals("PodFill", podFillId, "order", event.params.id.toHexString()); + assert.fieldEquals("PodFill", podFillId, "from", event.params.from.toHexString()); + assert.fieldEquals("PodFill", podFillId, "to", event.params.to.toHexString()); + assert.fieldEquals("PodFill", podFillId, "amount", event.params.amount.toString()); + assert.fieldEquals("PodFill", podFillId, "index", event.params.index.toString()); + assert.fieldEquals("PodFill", podFillId, "start", event.params.start.toString()); + assert.fieldEquals("PodFill", podFillId, "costInBeans", podAmount.times(pricePerPod).div(BI_10.pow(6)).toString()); + + return event; +} + export function fillOrder_v2( from: string, to: string, @@ -102,7 +175,39 @@ export function cancelOrder(account: string, orderId: Bytes): PodOrderCancelled return event; } -export function assertListingCreated_v2(event: PodListingCreated_v2): void { +function assertListingCreated_v1(event: PodListingCreated_v1): void { + let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "farmer", event.params.account.toHexString()); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID, "originalIndex", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "originalAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "index", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "start", event.params.start.toString()); + assert.fieldEquals("PodListing", listingID, "amount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "pricePerPod", event.params.pricePerPod.toString()); + assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", event.params.maxHarvestableIndex.toString()); + assert.fieldEquals("PodListing", listingID, "mode", event.params.toWallet ? "0" : "1"); +} + +function assertListingCreated_v1_1(event: PodListingCreated_v1_1): void { + let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "farmer", event.params.account.toHexString()); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID, "originalIndex", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "originalAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "index", event.params.index.toString()); + assert.fieldEquals("PodListing", listingID, "start", event.params.start.toString()); + assert.fieldEquals("PodListing", listingID, "amount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", event.params.amount.toString()); + assert.fieldEquals("PodListing", listingID, "pricePerPod", event.params.pricePerPod.toString()); + assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", event.params.maxHarvestableIndex.toString()); + assert.fieldEquals("PodListing", listingID, "mode", event.params.mode.toString()); +} + +function assertListingCreated_v2(event: PodListingCreated_v2): void { let listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); assert.fieldEquals("PodListing", listingID, "plot", event.params.index.toString()); assert.fieldEquals("PodListing", listingID, "farmer", event.params.account.toHexString()); @@ -121,7 +226,18 @@ export function assertListingCreated_v2(event: PodListingCreated_v2): void { assert.fieldEquals("PodListing", listingID, "pricingType", event.params.pricingType.toString()); } -export function assertOrderCreated_v2(account: string, event: PodOrderCreated_v2): void { +function assertOrderCreated_v1(account: string, event: PodOrderCreated_v1): void { + let orderID = event.params.id.toHexString(); + assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); + assert.fieldEquals("PodOrder", orderID, "farmer", account); + assert.fieldEquals("PodOrder", orderID, "status", "ACTIVE"); + assert.fieldEquals("PodOrder", orderID, "beanAmount", event.params.amount.toString()); + assert.fieldEquals("PodOrder", orderID, "beanAmountFilled", "0"); + assert.fieldEquals("PodOrder", orderID, "maxPlaceInLine", event.params.maxPlaceInLine.toString()); + assert.fieldEquals("PodOrder", orderID, "pricePerPod", event.params.pricePerPod.toString()); +} + +function assertOrderCreated_v2(account: string, event: PodOrderCreated_v2): void { let orderID = event.params.id.toHexString(); assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); assert.fieldEquals("PodOrder", orderID, "farmer", account); @@ -135,6 +251,48 @@ export function assertOrderCreated_v2(account: string, event: PodOrderCreated_v2 assert.fieldEquals("PodOrder", orderID, "pricingType", event.params.priceType.toString()); } +export function createListing_v1( + account: string, + index: BigInt, + plotTotalPods: BigInt, + start: BigInt, + maxHarvestableIndex: BigInt +): PodListingCreated_v1 { + const event = createPodListingCreatedEvent( + account, + index, + start, + plotTotalPods.minus(start), + BigInt.fromString("250000"), + maxHarvestableIndex, + true + ); + handlePodListingCreated(event); + assertListingCreated_v1(event); + return event; +} + +export function createListing_v1_1( + account: string, + index: BigInt, + plotTotalPods: BigInt, + start: BigInt, + maxHarvestableIndex: BigInt +): PodListingCreated_v1_1 { + const event = createPodListingCreatedEvent_v1_1( + account, + index, + start, + plotTotalPods.minus(start), + BigInt.fromString("250000"), + maxHarvestableIndex, + 0 + ); + handlePodListingCreated_v1_1(event); + assertListingCreated_v1_1(event); + return event; +} + export function createListing_v2( account: string, index: BigInt, @@ -159,14 +317,15 @@ export function createListing_v2( return event; } -export function createOrder_v2( - account: string, - id: Bytes, - beans: BigInt, - pricePerPod: BigInt, - maxHarvestableIndex: BigInt -): PodOrderCreated_v2 { - const event = createPodOrderCreatedEvent_v2(account, id, beans, pricePerPod, maxHarvestableIndex, ONE_BI, pricingFunction, ZERO_BI); +export function createOrder_v1(account: string, id: Bytes, beans: BigInt, pricePerPod: BigInt, maxPlaceInLine: BigInt): PodOrderCreated_v1 { + const event = createPodOrderCreatedEvent(account, id, beans, pricePerPod, maxPlaceInLine); + handlePodOrderCreated(event); + assertOrderCreated_v1(account, event); + return event; +} + +export function createOrder_v2(account: string, id: Bytes, beans: BigInt, pricePerPod: BigInt, maxPlaceInLine: BigInt): PodOrderCreated_v2 { + const event = createPodOrderCreatedEvent_v2(account, id, beans, pricePerPod, maxPlaceInLine, ONE_BI, pricingFunction, ZERO_BI); handlePodOrderCreated_v2(event); assertOrderCreated_v2(account, event); return event; From 81fa5039c9ee256a21afcb179c52cc226e817e55 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 16:09:16 -0700 Subject: [PATCH 39/89] add market v1 tests --- .../src/MarketplaceHandler.ts | 2 + .../tests/MarketplaceV1.test.ts | 633 ++++++++++++++++++ ...ketplace.test.ts => MarketplaceV2.test.ts} | 32 - .../tests/event-mocking/Marketplace.ts | 4 +- .../tests/utils/Marketplace.ts | 25 +- 5 files changed, 649 insertions(+), 47 deletions(-) create mode 100644 projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts rename projects/subgraph-beanstalk/tests/{Marketplace.test.ts => MarketplaceV2.test.ts} (94%) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index c23bb0e37c..772ebec7ba 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -292,10 +292,12 @@ export function handlePodOrderCreated(event: PodOrderCreated_v1): void { order.updatedAt = event.block.timestamp; order.status = "ACTIVE"; order.beanAmount = event.params.amount.times(BigInt.fromI32(event.params.pricePerPod)).div(BigInt.fromString("1000000")); + order.beanAmountFilled = ZERO_BI; order.podAmountFilled = ZERO_BI; order.maxPlaceInLine = event.params.maxPlaceInLine; order.pricePerPod = event.params.pricePerPod; order.creationHash = event.transaction.hash.toHexString(); + order.fills = []; order.save(); updateActiveOrders(event.address, MarketplaceAction.CREATED, order.id, order.maxPlaceInLine); diff --git a/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts b/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts new file mode 100644 index 0000000000..619b1bf335 --- /dev/null +++ b/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts @@ -0,0 +1,633 @@ +import { BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { afterEach, assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index"; +import { beans_BI, podlineMil_BI } from "../../subgraph-core/tests/Values"; +import { BI_10, ONE_BI, ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { BEANSTALK } from "../../subgraph-core/utils/Constants"; +import { + assertMarketListingsState, + assertMarketOrdersState, + cancelListing, + cancelOrder, + createListing_v1, + createListing_v1_1, + createOrder_v1, + fillListing_v1, + fillOrder_v1, + getPodFillId +} from "./utils/Marketplace"; +import { harvest, setHarvestable, sow } from "./utils/Field"; + +const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); +const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); + +const listingIndex = podlineMil_BI(1); +const listingPricePerPod = BigInt.fromString("250000"); +const maxHarvestableIndex = podlineMil_BI(100); +const sowedBeans = beans_BI(5000); +const sowedPods = sowedBeans.times(BigInt.fromString("3")); + +const orderBeans = beans_BI(80000); +const orderPricePerPod = BigInt.fromString("500000"); // 0.5 beans +const orderId = Bytes.fromHexString("0xabcd"); + +describe("Marketplace", () => { + beforeEach(() => { + sow(account, listingIndex, sowedBeans, sowedPods); + }); + + afterEach(() => { + clearStore(); + }); + + describe("Marketplace v1", () => { + test("Create a pod listing - full plot", () => { + const event = createListing_v1(account, listingIndex, sowedPods, ZERO_BI, listingPricePerPod, maxHarvestableIndex); + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], + sowedPods, + sowedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + + // Create a second listing to assert the market state again + const listing2Index = listingIndex.times(BI_10); + sow(account, listing2Index, sowedBeans, sowedPods); + const event2 = createListing_v1(account, listing2Index, sowedPods, ZERO_BI, listingPricePerPod, maxHarvestableIndex); + assertMarketListingsState( + BEANSTALK.toHexString(), + [ + account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString(), + account + "-" + listing2Index.toString() + "-" + maxHarvestableIndex.toString() + ], + sowedPods.times(BigInt.fromI32(2)), + sowedPods.times(BigInt.fromI32(2)), + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + + test("Create a pod listing - partial plot", () => { + const event = createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); + const listedPods = sowedPods.minus(beans_BI(500)); + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], + listedPods, + listedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + + test("Create a pod listing - partial plot", () => { + const event = createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); + const listedPods = sowedPods.minus(beans_BI(500)); + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], + listedPods, + listedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + + test("Create a pod order", () => { + const event = createOrder_v1(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); + assertMarketOrdersState( + BEANSTALK.toHexString(), + [event.params.id.toHexString() + "-" + maxHarvestableIndex.toString()], + orderBeans, + orderBeans, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + + describe("Tests requiring Listing", () => { + beforeEach(() => { + createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); + }); + + test("Fill listing - full", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const filledBeans = listedPods.times(listingPricePerPod).div(BI_10.pow(6)); + const event = fillListing_v1(account, account2, listingIndex, listingStart, listedPods, listingPricePerPod); + + let listingID = event.params.from.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "FILLED"); + assert.fieldEquals("PodListing", listingID, "filledAmount", listedPods.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", listingID, "filled", listedPods.toString()); + assert.entityCount("PodListing", 1); + + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, ZERO_BI, listedPods, listedPods, filledBeans); + }); + + test("Fill listing - partial, then full", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = filledPods.times(listingPricePerPod).div(BI_10.pow(6)); + const event = fillListing_v1(account, account2, listingIndex, listingStart, filledPods, listingPricePerPod); + + const remaining = listedPods.minus(filledPods); + const listingID = event.params.from.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "FILLED_PARTIAL"); + assert.fieldEquals("PodListing", listingID, "filledAmount", filledPods.toString()); + assert.fieldEquals("PodListing", listingID, "remainingAmount", remaining.toString()); + assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); + assert.entityCount("PodListing", 2); + + const newListingIndex = event.params.index.plus(listingStart).plus(filledPods); + const derivedListingID = event.params.from.toHexString() + "-" + newListingIndex.toString(); + assert.fieldEquals("PodListing", derivedListingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", derivedListingID, "filledAmount", "0"); + assert.fieldEquals("PodListing", derivedListingID, "remainingAmount", remaining.toString()); + assert.fieldEquals("PodListing", derivedListingID, "originalIndex", listingIndex.toString()); + assert.fieldEquals("PodListing", derivedListingID, "originalAmount", listedPods.toString()); + assert.fieldEquals("PodListing", derivedListingID, "filled", filledPods.toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + newListingIndex.toString() + "-" + maxHarvestableIndex.toString()], + listedPods, + remaining, + ZERO_BI, + ZERO_BI, + filledPods, + filledPods, + filledBeans + ); + + // Now sell the rest + const newFilledBeans = remaining.times(listingPricePerPod).div(BI_10.pow(6)); + const event2 = fillListing_v1(account, account2, newListingIndex, ZERO_BI, remaining, listingPricePerPod); + + assert.entityCount("PodListing", 2); + assert.fieldEquals("PodListing", derivedListingID, "status", "FILLED"); + assert.fieldEquals("PodListing", derivedListingID, "filledAmount", remaining.toString()); + assert.fieldEquals("PodListing", derivedListingID, "remainingAmount", "0"); + assert.fieldEquals("PodListing", derivedListingID, "filled", listedPods.toString()); + // Original should be unchanged + assert.fieldEquals("PodListing", listingID, "status", "FILLED_PARTIAL"); + assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [], + listedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + listedPods, + listedPods, + filledBeans.plus(newFilledBeans) + ); + }); + + test("Cancel listing - full", () => { + const event = cancelListing(account, listingIndex); + const cancelledAmount = sowedPods.minus(beans_BI(500)); + const listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "CANCELLED"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", cancelledAmount.toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [], + cancelledAmount, + ZERO_BI, + cancelledAmount, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + + test("Cancel listing - partial", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = filledPods.times(listingPricePerPod).div(BI_10.pow(6)); + const fillEvent = fillListing_v1(account, account2, listingIndex, listingStart, filledPods, listingPricePerPod); + + const remaining = listedPods.minus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + + const event = cancelListing(account, newListingIndex); + + const newListingID = event.params.account.toHexString() + "-" + event.params.index.toString(); + assert.fieldEquals("PodListing", newListingID, "status", "CANCELLED_PARTIAL"); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", remaining.toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [], + listedPods, + ZERO_BI, + remaining, + ZERO_BI, + filledPods, + filledPods, + filledBeans + ); + }); + + test("Recreate listing", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + cancelListing(account, listingIndex); + const listEvent = createListing_v1(account, listingIndex, sowedPods, listingStart, listingPricePerPod, maxHarvestableIndex); + + const listingID = listEvent.params.account.toHexString() + "-" + listEvent.params.index.toString(); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID + "-0", "status", "CANCELLED"); + assert.fieldEquals("PodListing", listingID + "-0", "filled", "0"); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], + listedPods.times(BigInt.fromU32(2)), + listedPods, + listedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + + // Partial fill, then recreate again + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = filledPods.times(listingPricePerPod).div(BI_10.pow(6)); + const fillEvent = fillListing_v1(account, account2, listingIndex, listingStart, filledPods, listingPricePerPod); + + const remaining = listedPods.minus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + const newListingAmount = listedPods.minus(filledPods); + cancelListing(account, newListingIndex); + const newListEvent = createListing_v1(account, newListingIndex, remaining, ZERO_BI, listingPricePerPod, maxHarvestableIndex); + + const newListingID = newListEvent.params.account.toHexString() + "-" + newListEvent.params.index.toString(); + assert.notInStore("PodListing", listingID + "-1"); + assert.notInStore("PodListing", newListingID + "-1"); + assert.fieldEquals("PodListing", newListingID + "-0", "status", "CANCELLED_PARTIAL"); + assert.fieldEquals("PodListing", newListingID + "-0", "filled", filledPods.toString()); + assert.fieldEquals("PodListing", newListingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", newListingID, "filled", "0"); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", newListingAmount.toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + newListingIndex.toString() + "-" + maxHarvestableIndex.toString()], + listedPods.times(BigInt.fromU32(2)).plus(newListingAmount), + newListingAmount, + listedPods.plus(newListingAmount), + ZERO_BI, + filledPods, + filledPods, + filledBeans + ); + }); + + test("Listing expires due to moving podline", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const listingID = account + "-" + listingIndex.toString(); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + assert.fieldEquals("PodListing", listingID, "maxHarvestableIndex", maxHarvestableIndex.toString()); + + // Expires due to exceeding max harvestable index + setHarvestable(maxHarvestableIndex); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", listedPods.toString()); + + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); + + // Test expiration after a partial sale + setHarvestable(maxHarvestableIndex); + createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); + + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = filledPods.times(listingPricePerPod).div(BI_10.pow(6)); + const fillEvent = fillListing_v1(account, account2, listingIndex, listingStart, filledPods, listingPricePerPod); + + const remaining = listedPods.minus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + const newListingID = account + "-" + newListingIndex.toString(); + + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); + assert.fieldEquals("PodListing", listingID, "status", "FILLED_PARTIAL"); + assert.fieldEquals("PodListing", listingID, "filled", filledPods.toString()); + assert.fieldEquals("PodListing", newListingID, "status", "EXPIRED"); + assert.fieldEquals("PodListing", newListingID, "filled", filledPods.toString()); + assert.fieldEquals("PodListing", newListingID, "remainingAmount", listedPods.minus(filledPods).toString()); + + assertMarketListingsState( + BEANSTALK.toHexString(), + [], + listedPods.times(BigInt.fromU32(2)), + ZERO_BI, + ZERO_BI, + listedPods.plus(remaining), + filledPods, + filledPods, + filledBeans + ); + }); + + test("Listing expires due to plot harvesting", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + const listingID = account + "-" + listingIndex.toString(); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + + // Plot is harvestable, but still active + setHarvestable(listingIndex.plus(sowedPods)); + assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); + // Plot harvests, now expired + harvest(account, [listingIndex], sowedPods); + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + assert.fieldEquals("PodListing", listingID, "remainingAmount", listedPods.toString()); + + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); + }); + + test("Cancel expired/nonexistent listing", () => { + const listingStart = beans_BI(500); + const listedPods = sowedPods.minus(listingStart); + setHarvestable(maxHarvestableIndex.plus(ONE_BI)); + const listingID = account + "-" + listingIndex.toString(); + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + + // Cancelling listing is still possible, nothing should change in market + cancelListing(account, listingIndex); + + assert.fieldEquals("PodListing", listingID, "status", "EXPIRED"); + assertMarketListingsState(BEANSTALK.toHexString(), [], listedPods, ZERO_BI, ZERO_BI, listedPods, ZERO_BI, ZERO_BI, ZERO_BI); + }); + }); + + describe("Tests requiring Order", () => { + beforeEach(() => { + createOrder_v1(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); + }); + + test("Fill order - full", () => { + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + sow(account2, orderPlotIndex, sowedBeans, orderedPods); + const event = fillOrder_v1(account2, account, orderId, orderPlotIndex, ZERO_BI, orderedPods, orderPricePerPod); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "FILLED"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", orderedPods.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, event) + "]"); + + assertMarketOrdersState( + BEANSTALK.toHexString(), + [], + orderBeans, + ZERO_BI, + orderBeans, + orderedPods, + ZERO_BI, + orderedPods, + orderBeans + ); + }); + + test("Fill order - partial", () => { + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); + const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); + sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); + const event = fillOrder_v1(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderPricePerPod); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "ACTIVE"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", soldToOrder1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, event) + "]"); + + assertMarketOrdersState( + BEANSTALK.toHexString(), + [event.params.id.toHexString() + "-" + maxHarvestableIndex.toString()], + orderBeans, + orderBeans.minus(orderBeans1), + orderBeans1, + soldToOrder1, + ZERO_BI, + soldToOrder1, + orderBeans1 + ); + + // Now fill the rest + const newOrderPlotIndex = orderPlotIndex.plus(beans_BI(1000)).plus(soldToOrder1); + const soldToOrder2 = orderedPods.minus(soldToOrder1); + const orderBeans2 = orderBeans.minus(orderBeans1); + const event2 = fillOrder_v1(account2, account, orderId, newOrderPlotIndex, ZERO_BI, soldToOrder2, orderPricePerPod); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "FILLED"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", orderedPods.toString()); + assert.fieldEquals( + "PodOrder", + orderId.toHexString(), + "fills", + "[" + getPodFillId(orderPlotIndex, event) + ", " + getPodFillId(newOrderPlotIndex, event2) + "]" + ); + + assertMarketOrdersState( + BEANSTALK.toHexString(), + [], + orderBeans, + ZERO_BI, + orderBeans, + orderedPods, + ZERO_BI, + orderedPods, + orderBeans + ); + }); + + test("Cancel order - full", () => { + cancelOrder(account, orderId); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", "0"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", "0"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); + + assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); + }); + + test("Cancel order - partial", () => { + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); + const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); + sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); + const fillEvent = fillOrder_v1(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderPricePerPod); + + cancelOrder(account, orderId); + + assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED_PARTIAL"); + assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", orderBeans1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", soldToOrder1.toString()); + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[" + getPodFillId(orderPlotIndex, fillEvent) + "]"); + + assertMarketOrdersState( + BEANSTALK.toHexString(), + [], + orderBeans, + ZERO_BI, + orderBeans1, + soldToOrder1, + orderBeans.minus(orderBeans1), + soldToOrder1, + orderBeans1 + ); + }); + + test("Recreate order", () => { + cancelOrder(account, orderId); + createOrder_v1(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); + + assert.fieldEquals("PodOrder", orderId.toHexString() + "-0", "fills", "[]"); + + assertMarketOrdersState( + BEANSTALK.toHexString(), + [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], + orderBeans.times(BigInt.fromU32(2)), + orderBeans, + ZERO_BI, + ZERO_BI, + orderBeans, + ZERO_BI, + ZERO_BI + ); + + // Recreate after a partial fill + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + const soldToOrder1 = orderedPods.div(BigInt.fromU32(5)); + const orderBeans1 = orderBeans.div(BigInt.fromU32(5)); + sow(account2, orderPlotIndex, sowedBeans, orderedPods.times(BigInt.fromU32(2))); + const fillEvent = fillOrder_v1(account2, account, orderId, orderPlotIndex, beans_BI(1000), soldToOrder1, orderPricePerPod); + + cancelOrder(account, orderId); + createOrder_v1(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); + + // The historical order has one fill + assert.fieldEquals("PodOrder", orderId.toHexString() + "-1", "fills", "[" + getPodFillId(orderPlotIndex, fillEvent) + "]"); + // The recreated order has no fills + assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); + + // The same amount of beans were re-ordered, but fewer were cancelled + assertMarketOrdersState( + BEANSTALK.toHexString(), + [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], + orderBeans.times(BigInt.fromU32(3)), + orderBeans, + orderBeans1, + soldToOrder1, + orderBeans.plus(orderBeans.minus(orderBeans1)), + soldToOrder1, + orderBeans1 + ); + }); + + test("Cancel nonexistent order", () => { + const nonexistent = Bytes.fromHexString("0x1234"); + cancelOrder(account, nonexistent); + assert.notInStore("PodOrder", nonexistent.toHexString()); + assertMarketOrdersState( + BEANSTALK.toHexString(), + [orderId.toHexString() + "-" + maxHarvestableIndex.toString()], + orderBeans, + orderBeans, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + }); + }); + + // At replant, but before v2, there was a slight change in the listing event + describe("Marketplace v1_1", () => { + test("Create a pod listing - full plot", () => { + const event = createListing_v1_1(account, listingIndex, sowedPods, ZERO_BI, listingPricePerPod, maxHarvestableIndex); + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], + sowedPods, + sowedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + + // Create a second listing to assert the market state again + const listing2Index = listingIndex.times(BI_10); + sow(account, listing2Index, sowedBeans, sowedPods); + const event2 = createListing_v1_1(account, listing2Index, sowedPods, ZERO_BI, listingPricePerPod, maxHarvestableIndex); + assertMarketListingsState( + BEANSTALK.toHexString(), + [ + account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString(), + account + "-" + listing2Index.toString() + "-" + maxHarvestableIndex.toString() + ], + sowedPods.times(BigInt.fromI32(2)), + sowedPods.times(BigInt.fromI32(2)), + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + + test("Create a pod listing - partial plot", () => { + const event = createListing_v1_1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); + const listedPods = sowedPods.minus(beans_BI(500)); + assertMarketListingsState( + BEANSTALK.toHexString(), + [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], + listedPods, + listedPods, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI, + ZERO_BI + ); + }); + }); +}); diff --git a/projects/subgraph-beanstalk/tests/Marketplace.test.ts b/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts similarity index 94% rename from projects/subgraph-beanstalk/tests/Marketplace.test.ts rename to projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts index 2baf47fa41..6c06f2f6b3 100644 --- a/projects/subgraph-beanstalk/tests/Marketplace.test.ts +++ b/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts @@ -186,27 +186,6 @@ describe("Marketplace", () => { ); }); - // Cancellation isnt unique to pod market v2, consider including in the v1 section - test("Cancel listing - full", () => { - const event = cancelListing(account, listingIndex); - const cancelledAmount = sowedPods.minus(beans_BI(500)); - const listingID = event.params.account.toHexString() + "-" + event.params.index.toString(); - assert.fieldEquals("PodListing", listingID, "status", "CANCELLED"); - assert.fieldEquals("PodListing", listingID, "remainingAmount", cancelledAmount.toString()); - - assertMarketListingsState( - BEANSTALK.toHexString(), - [], - cancelledAmount, - ZERO_BI, - cancelledAmount, - ZERO_BI, - ZERO_BI, - ZERO_BI, - ZERO_BI - ); - }); - test("Cancel listing - partial", () => { const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); @@ -455,17 +434,6 @@ describe("Marketplace", () => { ); }); - test("Cancel order - full", () => { - cancelOrder(account, orderId); - - assert.fieldEquals("PodOrder", orderId.toHexString(), "status", "CANCELLED"); - assert.fieldEquals("PodOrder", orderId.toHexString(), "beanAmountFilled", "0"); - assert.fieldEquals("PodOrder", orderId.toHexString(), "podAmountFilled", "0"); - assert.fieldEquals("PodOrder", orderId.toHexString(), "fills", "[]"); - - assertMarketOrdersState(BEANSTALK.toHexString(), [], orderBeans, ZERO_BI, ZERO_BI, ZERO_BI, orderBeans, ZERO_BI, ZERO_BI); - }); - test("Cancel order - partial", () => { const orderPlotIndex = podlineMil_BI(15); const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); diff --git a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts index 0882940329..030e7c42e6 100644 --- a/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/event-mocking/Marketplace.ts @@ -71,7 +71,7 @@ export function createPodListingFilledEvent(from: string, to: string, index: Big export function createPodOrderCreatedEvent( account: string, id: Bytes, - amount: BigInt, + podsOrdered: BigInt, pricePerPod: BigInt, maxPlaceInLine: BigInt ): PodOrderCreated_v1 { @@ -80,7 +80,7 @@ export function createPodOrderCreatedEvent( let param1 = new ethereum.EventParam("account", ethereum.Value.fromAddress(Address.fromString(account))); let param2 = new ethereum.EventParam("id", ethereum.Value.fromBytes(id)); - let param3 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(amount)); + let param3 = new ethereum.EventParam("amount", ethereum.Value.fromUnsignedBigInt(podsOrdered)); let param4 = new ethereum.EventParam("pricePerPod", ethereum.Value.fromUnsignedBigInt(pricePerPod)); let param5 = new ethereum.EventParam("maxPlaceInLine", ethereum.Value.fromUnsignedBigInt(maxPlaceInLine)); diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index e59d56d61c..ee8c0b8369 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -231,7 +231,12 @@ function assertOrderCreated_v1(account: string, event: PodOrderCreated_v1): void assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); assert.fieldEquals("PodOrder", orderID, "farmer", account); assert.fieldEquals("PodOrder", orderID, "status", "ACTIVE"); - assert.fieldEquals("PodOrder", orderID, "beanAmount", event.params.amount.toString()); + assert.fieldEquals( + "PodOrder", + orderID, + "beanAmount", + event.params.amount.times(BigInt.fromU32(event.params.pricePerPod)).div(BI_10.pow(6)).toString() + ); assert.fieldEquals("PodOrder", orderID, "beanAmountFilled", "0"); assert.fieldEquals("PodOrder", orderID, "maxPlaceInLine", event.params.maxPlaceInLine.toString()); assert.fieldEquals("PodOrder", orderID, "pricePerPod", event.params.pricePerPod.toString()); @@ -256,17 +261,10 @@ export function createListing_v1( index: BigInt, plotTotalPods: BigInt, start: BigInt, + pricePerPod: BigInt, maxHarvestableIndex: BigInt ): PodListingCreated_v1 { - const event = createPodListingCreatedEvent( - account, - index, - start, - plotTotalPods.minus(start), - BigInt.fromString("250000"), - maxHarvestableIndex, - true - ); + const event = createPodListingCreatedEvent(account, index, start, plotTotalPods.minus(start), pricePerPod, maxHarvestableIndex, true); handlePodListingCreated(event); assertListingCreated_v1(event); return event; @@ -277,6 +275,7 @@ export function createListing_v1_1( index: BigInt, plotTotalPods: BigInt, start: BigInt, + pricePerPod: BigInt, maxHarvestableIndex: BigInt ): PodListingCreated_v1_1 { const event = createPodListingCreatedEvent_v1_1( @@ -284,9 +283,9 @@ export function createListing_v1_1( index, start, plotTotalPods.minus(start), - BigInt.fromString("250000"), + pricePerPod, maxHarvestableIndex, - 0 + ZERO_BI ); handlePodListingCreated_v1_1(event); assertListingCreated_v1_1(event); @@ -318,7 +317,7 @@ export function createListing_v2( } export function createOrder_v1(account: string, id: Bytes, beans: BigInt, pricePerPod: BigInt, maxPlaceInLine: BigInt): PodOrderCreated_v1 { - const event = createPodOrderCreatedEvent(account, id, beans, pricePerPod, maxPlaceInLine); + const event = createPodOrderCreatedEvent(account, id, beans.times(BI_10.pow(6)).div(pricePerPod), pricePerPod, maxPlaceInLine); handlePodOrderCreated(event); assertOrderCreated_v1(account, event); return event; From 5e92987837047b00b04462dab66879e9f1815c9f Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 16:25:59 -0700 Subject: [PATCH 40/89] generalized listing fill --- .../src/MarketplaceHandler.ts | 321 ++++++++---------- 1 file changed, 141 insertions(+), 180 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 772ebec7ba..b59f003e29 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -1,4 +1,4 @@ -import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { Address, BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"; import { PodListingCancelled, PodListingCreated as PodListingCreated_v1, @@ -26,7 +26,7 @@ import { PodOrder, PodListing } from "../generated/schema"; -import { toDecimal, ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { loadFarmer } from "./utils/Farmer"; import { loadPlot } from "./utils/Plot"; import { loadPodFill } from "./utils/PodFill"; @@ -41,9 +41,8 @@ import { } from "./utils/PodMarketplace"; import { createHistoricalPodOrder, loadPodOrder } from "./utils/PodOrder"; -// TODO: write v1 tests first -/* class PodListingCreatedParams { + event: ethereum.Event; account: Address; index: BigInt; start: BigInt; @@ -60,7 +59,33 @@ class PodListingCreatedParams { // mode: i32; pricingType: i32; } -*/ + +class PodOrderCreatedParams { + event: ethereum.Event; + account: Address; + id: Bytes; + amount: BigInt; + pricePerPod: i32; + maxPlaceInLine: BigInt; + + // v2 + minFillAmount: BigInt; + pricingFunction: Bytes; + pricingType: i32; +} + +// This one is the same for both listing/order fills. +class MarketFillParams { + event: ethereum.Event; + from: Address; + to: Address; + index: BigInt; + start: BigInt; + amount: BigInt; + + //v2 + costInBeans: BigInt; +} /* ------------------------------------ * POD MARKETPLACE V1 @@ -188,94 +213,17 @@ export function handlePodListingCancelled(event: PodListingCancelled): void { export function handlePodListingFilled(event: PodListingFilled_v1): void { let listing = loadPodListing(event.params.from, event.params.index); - - let beanAmount = BigInt.fromI32(listing.pricePerPod).times(event.params.amount).div(BigInt.fromI32(1000000)); - - updateMarketListingBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); - - listing.filledAmount = event.params.amount; - listing.remainingAmount = listing.remainingAmount.minus(event.params.amount); - listing.filled = listing.filled.plus(event.params.amount); - listing.updatedAt = event.block.timestamp; - - let originalHistoryID = listing.historyID; - if (listing.remainingAmount == ZERO_BI) { - listing.status = "FILLED"; - updateActiveListings( - event.address, - MarketplaceAction.FILLED_FULL, - event.params.from.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - } else { - let market = loadPodMarketplace(event.address); - - listing.status = "FILLED_PARTIAL"; - let remainingListing = loadPodListing(Address.fromString(listing.farmer), listing.index.plus(event.params.amount).plus(listing.start)); - - remainingListing.historyID = remainingListing.id + "-" + event.block.timestamp.toString(); - remainingListing.plot = listing.index.plus(event.params.amount).plus(listing.start).toString(); - remainingListing.createdAt = listing.createdAt; - remainingListing.updatedAt = event.block.timestamp; - remainingListing.originalIndex = listing.originalIndex; - remainingListing.start = ZERO_BI; - remainingListing.amount = listing.remainingAmount; - remainingListing.originalAmount = listing.originalAmount; - remainingListing.filled = listing.filled; - remainingListing.remainingAmount = listing.remainingAmount; - remainingListing.pricePerPod = listing.pricePerPod; - remainingListing.maxHarvestableIndex = listing.maxHarvestableIndex; - remainingListing.mode = listing.mode; - remainingListing.creationHash = event.transaction.hash.toHexString(); - remainingListing.save(); - - updateActiveListings( - event.address, - MarketplaceAction.FILLED_PARTIAL, - event.params.from.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - updateActiveListings( - event.address, - MarketplaceAction.CREATED, - event.params.from.toHexString(), - remainingListing.index, - remainingListing.maxHarvestableIndex - ); - } - - /// Save pod fill - let fill = loadPodFill(event.address, event.params.index, event.transaction.hash.toHexString()); - fill.createdAt = event.block.timestamp; - fill.listing = listing.id; - fill.from = event.params.from.toHexString(); - fill.to = event.params.to.toHexString(); - fill.amount = event.params.amount; - fill.index = event.params.index; - fill.start = event.params.start; - fill.costInBeans = beanAmount; - fill.save(); - - listing.fill = fill.id; - listing.save(); - - // Save the raw event data - let id = "podListingFilled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodListingFilledEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = originalHistoryID; - rawEvent.from = event.params.from.toHexString(); - rawEvent.to = event.params.to.toHexString(); - rawEvent.index = event.params.index; - rawEvent.start = event.params.start; - rawEvent.amount = event.params.amount; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + const beanAmount = BigInt.fromI32(listing.pricePerPod).times(event.params.amount).div(BigInt.fromI32(1000000)); + + podListingFilled({ + event: event, + from: event.params.from, + to: event.params.to, + index: event.params.index, + start: event.params.start, + amount: event.params.amount, + costInBeans: beanAmount + }); } export function handlePodOrderCreated(event: PodOrderCreated_v1): void { @@ -575,93 +523,15 @@ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { } export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { - let listing = loadPodListing(event.params.from, event.params.index); - - updateMarketListingBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, event.params.costInBeans, event.block.timestamp); - - listing.filledAmount = event.params.amount; - listing.remainingAmount = listing.remainingAmount.minus(event.params.amount); - listing.filled = listing.filled.plus(event.params.amount); - listing.updatedAt = event.block.timestamp; - - let originalHistoryID = listing.historyID; - if (listing.remainingAmount == ZERO_BI) { - listing.status = "FILLED"; - updateActiveListings( - event.address, - MarketplaceAction.FILLED_FULL, - event.params.from.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - } else { - listing.status = "FILLED_PARTIAL"; - - let remainingListing = loadPodListing(Address.fromString(listing.farmer), listing.index.plus(event.params.amount).plus(listing.start)); - remainingListing.historyID = remainingListing.id + "-" + event.block.timestamp.toString(); - remainingListing.plot = listing.index.plus(event.params.amount).plus(listing.start).toString(); - remainingListing.createdAt = listing.createdAt; - remainingListing.updatedAt = event.block.timestamp; - remainingListing.originalIndex = listing.originalIndex; - remainingListing.start = ZERO_BI; - remainingListing.amount = listing.remainingAmount; - remainingListing.originalAmount = listing.originalAmount; - remainingListing.filled = listing.filled; - remainingListing.remainingAmount = listing.remainingAmount; - remainingListing.pricePerPod = listing.pricePerPod; - remainingListing.maxHarvestableIndex = listing.maxHarvestableIndex; - remainingListing.mode = listing.mode; - remainingListing.creationHash = event.transaction.hash.toHexString(); - remainingListing.minFillAmount = listing.minFillAmount; - remainingListing.save(); - - // Process the partial fill on the prev listing, and the new listing - updateActiveListings( - event.address, - MarketplaceAction.FILLED_PARTIAL, - event.params.from.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - updateActiveListings( - event.address, - MarketplaceAction.CREATED, - event.params.from.toHexString(), - remainingListing.index, - remainingListing.maxHarvestableIndex - ); - } - - let fill = loadPodFill(event.address, event.params.index, event.transaction.hash.toHexString()); - fill.createdAt = event.block.timestamp; - fill.listing = listing.id; - fill.from = event.params.from.toHexString(); - fill.to = event.params.to.toHexString(); - fill.amount = event.params.amount; - fill.index = event.params.index; - fill.start = event.params.start; - fill.costInBeans = event.params.costInBeans; - fill.save(); - - listing.fill = fill.id; - listing.save(); - - // Save the raw event data - let id = "podListingFilled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodListingFilledEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = originalHistoryID; - rawEvent.from = event.params.from.toHexString(); - rawEvent.to = event.params.to.toHexString(); - rawEvent.index = event.params.index; - rawEvent.start = event.params.start; - rawEvent.amount = event.params.amount; - rawEvent.costInBeans = event.params.costInBeans; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + podListingFilled({ + event: event, + from: event.params.from, + to: event.params.to, + index: event.params.index, + start: event.params.start, + amount: event.params.amount, + costInBeans: event.params.costInBeans + }); } export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { @@ -762,6 +632,97 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { * ------------------------------------ */ +function podListingFilled(params: MarketFillParams): void { + let listing = loadPodListing(params.from, params.index); + + updateMarketListingBalances(params.event.address, ZERO_BI, ZERO_BI, params.amount, params.costInBeans, params.event.block.timestamp); + + listing.filledAmount = params.amount; + listing.remainingAmount = listing.remainingAmount.minus(params.amount); + listing.filled = listing.filled.plus(params.amount); + listing.updatedAt = params.event.block.timestamp; + + let originalHistoryID = listing.historyID; + if (listing.remainingAmount == ZERO_BI) { + listing.status = "FILLED"; + updateActiveListings( + params.event.address, + MarketplaceAction.FILLED_FULL, + params.from.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + } else { + listing.status = "FILLED_PARTIAL"; + + let remainingListing = loadPodListing(Address.fromString(listing.farmer), listing.index.plus(params.amount).plus(listing.start)); + remainingListing.historyID = remainingListing.id + "-" + params.event.block.timestamp.toString(); + remainingListing.plot = listing.index.plus(params.amount).plus(listing.start).toString(); + remainingListing.createdAt = listing.createdAt; + remainingListing.updatedAt = params.event.block.timestamp; + remainingListing.originalIndex = listing.originalIndex; + remainingListing.start = ZERO_BI; + remainingListing.amount = listing.remainingAmount; + remainingListing.originalAmount = listing.originalAmount; + remainingListing.filled = listing.filled; + remainingListing.remainingAmount = listing.remainingAmount; + remainingListing.pricePerPod = listing.pricePerPod; + remainingListing.maxHarvestableIndex = listing.maxHarvestableIndex; + remainingListing.mode = listing.mode; + remainingListing.creationHash = params.event.transaction.hash.toHexString(); + remainingListing.minFillAmount = listing.minFillAmount; + remainingListing.save(); + + // Process the partial fill on the prev listing, and the new listing + updateActiveListings( + params.event.address, + MarketplaceAction.FILLED_PARTIAL, + params.from.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateActiveListings( + params.event.address, + MarketplaceAction.CREATED, + params.from.toHexString(), + remainingListing.index, + remainingListing.maxHarvestableIndex + ); + } + + let fill = loadPodFill(params.event.address, params.index, params.event.transaction.hash.toHexString()); + fill.createdAt = params.event.block.timestamp; + fill.listing = listing.id; + fill.from = params.from.toHexString(); + fill.to = params.to.toHexString(); + fill.amount = params.amount; + fill.index = params.index; + fill.start = params.start; + fill.costInBeans = params.costInBeans; + fill.save(); + + listing.fill = fill.id; + listing.save(); + + // Save the raw event data + let id = "podListingFilled-" + params.event.transaction.hash.toHexString() + "-" + params.event.logIndex.toString(); + let rawEvent = new PodListingFilledEvent(id); + rawEvent.hash = params.event.transaction.hash.toHexString(); + rawEvent.logIndex = params.event.logIndex.toI32(); + rawEvent.protocol = params.event.address.toHexString(); + rawEvent.historyID = originalHistoryID; + rawEvent.from = params.from.toHexString(); + rawEvent.to = params.to.toHexString(); + rawEvent.index = params.index; + rawEvent.start = params.start; + rawEvent.amount = params.amount; + rawEvent.costInBeans = params.costInBeans; + rawEvent.blockNumber = params.event.block.number; + rawEvent.createdAt = params.event.block.timestamp; + rawEvent.save(); +} + +// TODO: move these final 2 elsewhere. function updateMarketListingBalances( marketAddress: Address, newPodAmount: BigInt, From ac3edb271c680a5e18568541ffd96e303e39c5df Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 16:35:13 -0700 Subject: [PATCH 41/89] generalize pod order fill handler --- .../src/MarketplaceHandler.ts | 273 +++++------------- .../src/utils/PodMarketplace.ts | 113 ++++++++ 2 files changed, 184 insertions(+), 202 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index b59f003e29..84ab52a0d7 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -32,12 +32,11 @@ import { loadPlot } from "./utils/Plot"; import { loadPodFill } from "./utils/PodFill"; import { createHistoricalPodListing, loadPodListing } from "./utils/PodListing"; import { - loadPodMarketplace, - loadPodMarketplaceDailySnapshot, - loadPodMarketplaceHourlySnapshot, MarketplaceAction, updateActiveListings, - updateActiveOrders + updateActiveOrders, + updateMarketListingBalances, + updateMarketOrderBalances } from "./utils/PodMarketplace"; import { createHistoricalPodOrder, loadPodOrder } from "./utils/PodOrder"; @@ -79,11 +78,11 @@ class MarketFillParams { event: ethereum.Event; from: Address; to: Address; + id: Bytes | null; // For pod order index: BigInt; start: BigInt; amount: BigInt; - - //v2 + // v2; for v1, it can be computed and provided that way costInBeans: BigInt; } @@ -219,6 +218,7 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { event: event, from: event.params.from, to: event.params.to, + id: null, index: event.params.index, start: event.params.start, amount: event.params.amount, @@ -270,49 +270,18 @@ export function handlePodOrderCreated(event: PodOrderCreated_v1): void { export function handlePodOrderFilled(event: PodOrderFilled_v1): void { let order = loadPodOrder(event.params.id); - let fill = loadPodFill(event.address, event.params.index, event.transaction.hash.toHexString()); - let beanAmount = BigInt.fromI32(order.pricePerPod).times(event.params.amount).div(BigInt.fromI32(1000000)); - order.updatedAt = event.block.timestamp; - order.podAmountFilled = order.podAmountFilled.plus(event.params.amount); - order.beanAmountFilled = order.beanAmountFilled.plus(beanAmount); - order.status = order.beanAmount == order.beanAmountFilled ? "FILLED" : "ACTIVE"; - let newFills = order.fills; - newFills.push(fill.id); - order.fills = newFills; - order.save(); - - fill.createdAt = event.block.timestamp; - fill.order = order.id; - fill.from = event.params.from.toHexString(); - fill.to = event.params.to.toHexString(); - fill.amount = event.params.amount; - fill.index = event.params.index; - fill.start = event.params.start; - fill.costInBeans = beanAmount; - fill.save(); - - if (order.status == "FILLED") { - updateActiveOrders(event.address, MarketplaceAction.FILLED_FULL, order.id, order.maxPlaceInLine); - } - updateMarketOrderBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, beanAmount, event.block.timestamp); - - // Save the raw event data - let id = "podOrderFilled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodOrderFilledEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = order.historyID; - rawEvent.from = event.params.from.toHexString(); - rawEvent.to = event.params.to.toHexString(); - rawEvent.index = event.params.index; - rawEvent.start = event.params.start; - rawEvent.amount = event.params.amount; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + podOrderFilled({ + event: event, + from: event.params.from, + to: event.params.to, + id: event.params.id, + index: event.params.index, + start: event.params.start, + amount: event.params.amount, + costInBeans: beanAmount + }); } export function handlePodOrderCancelled(event: PodOrderCancelled): void { @@ -527,6 +496,7 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { event: event, from: event.params.from, to: event.params.to, + id: null, index: event.params.index, start: event.params.start, amount: event.params.amount, @@ -581,50 +551,16 @@ export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { } export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { - let order = loadPodOrder(event.params.id); - let fill = loadPodFill(event.address, event.params.index, event.transaction.hash.toHexString()); - - order.updatedAt = event.block.timestamp; - order.beanAmountFilled = order.beanAmountFilled.plus(event.params.costInBeans); - order.podAmountFilled = order.podAmountFilled.plus(event.params.amount); - order.status = order.beanAmount == order.beanAmountFilled ? "FILLED" : "ACTIVE"; - let newFills = order.fills; - newFills.push(fill.id); - order.fills = newFills; - order.save(); - - fill.createdAt = event.block.timestamp; - fill.order = order.id; - fill.from = event.params.from.toHexString(); - fill.to = event.params.to.toHexString(); - fill.amount = event.params.amount; - fill.index = event.params.index; - fill.start = event.params.start; - fill.costInBeans = event.params.costInBeans; - fill.save(); - - if (order.beanAmountFilled == order.beanAmount) { - updateActiveOrders(event.address, MarketplaceAction.FILLED_FULL, order.id, order.maxPlaceInLine); - } - - updateMarketOrderBalances(event.address, ZERO_BI, ZERO_BI, event.params.amount, event.params.costInBeans, event.block.timestamp); - - // Save the raw event data - let id = "podOrderFilled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodOrderFilledEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = order.historyID; - rawEvent.from = event.params.from.toHexString(); - rawEvent.to = event.params.to.toHexString(); - rawEvent.index = event.params.index; - rawEvent.start = event.params.start; - rawEvent.amount = event.params.amount; - rawEvent.costInBeans = event.params.costInBeans; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + podOrderFilled({ + event: event, + from: event.params.from, + to: event.params.to, + id: event.params.id, + index: event.params.index, + start: event.params.start, + amount: event.params.amount, + costInBeans: event.params.costInBeans + }); } /* ------------------------------------ @@ -722,116 +658,49 @@ function podListingFilled(params: MarketFillParams): void { rawEvent.save(); } -// TODO: move these final 2 elsewhere. -function updateMarketListingBalances( - marketAddress: Address, - newPodAmount: BigInt, - cancelledPodAmount: BigInt, - filledPodAmount: BigInt, - filledBeanAmount: BigInt, - timestamp: BigInt -): void { - let market = loadPodMarketplace(marketAddress); - let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); - let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - - const netListingChange = newPodAmount.minus(cancelledPodAmount).minus(filledPodAmount); - - market.listedPods = market.listedPods.plus(newPodAmount); - market.availableListedPods = market.availableListedPods.plus(netListingChange); - market.cancelledListedPods = market.cancelledListedPods.plus(cancelledPodAmount); - market.filledListedPods = market.filledListedPods.plus(filledPodAmount); - market.podVolume = market.podVolume.plus(filledPodAmount); - market.beanVolume = market.beanVolume.plus(filledBeanAmount); - market.save(); - - marketHourly.season = market.season; - marketHourly.deltaListedPods = marketHourly.deltaListedPods.plus(newPodAmount); - marketHourly.listedPods = market.listedPods; - marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods.plus(netListingChange); - marketHourly.availableListedPods = market.availableListedPods; - marketHourly.deltaCancelledListedPods = marketHourly.deltaCancelledListedPods.plus(cancelledPodAmount); - marketHourly.cancelledListedPods = market.cancelledListedPods; - marketHourly.deltaFilledListedPods = marketHourly.deltaFilledListedPods.plus(filledPodAmount); - marketHourly.filledListedPods = market.filledListedPods; - marketHourly.deltaPodVolume = marketHourly.deltaPodVolume.plus(filledPodAmount); - marketHourly.podVolume = market.podVolume; - marketHourly.deltaBeanVolume = marketHourly.deltaBeanVolume.plus(filledBeanAmount); - marketHourly.beanVolume = market.beanVolume; - marketHourly.updatedAt = timestamp; - marketHourly.save(); - - marketDaily.season = market.season; - marketDaily.deltaListedPods = marketDaily.deltaListedPods.plus(newPodAmount); - marketDaily.listedPods = market.listedPods; - marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.plus(netListingChange); - marketDaily.availableListedPods = market.availableListedPods; - marketDaily.deltaCancelledListedPods = marketDaily.deltaCancelledListedPods.plus(cancelledPodAmount); - marketDaily.cancelledListedPods = market.cancelledListedPods; - marketDaily.deltaFilledListedPods = marketDaily.deltaFilledListedPods.plus(filledPodAmount); - marketDaily.filledListedPods = market.filledListedPods; - marketDaily.deltaPodVolume = marketDaily.deltaPodVolume.plus(filledPodAmount); - marketDaily.podVolume = market.podVolume; - marketDaily.deltaBeanVolume = marketDaily.deltaBeanVolume.plus(filledBeanAmount); - marketDaily.beanVolume = market.beanVolume; - marketDaily.updatedAt = timestamp; - marketDaily.save(); -} +function podOrderFilled(params: MarketFillParams): void { + let order = loadPodOrder(params.id!); + let fill = loadPodFill(params.event.address, params.index, params.event.transaction.hash.toHexString()); -function updateMarketOrderBalances( - marketAddress: Address, - newBeanAmount: BigInt, - cancelledBeanAmount: BigInt, - filledPodAmount: BigInt, - filledBeanAmount: BigInt, - timestamp: BigInt -): void { - let market = loadPodMarketplace(marketAddress); - let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); - let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); - - const netOrderChange = newBeanAmount.minus(cancelledBeanAmount).minus(filledBeanAmount); - - market.orderBeans = market.orderBeans.plus(newBeanAmount); - market.availableOrderBeans = market.availableOrderBeans.plus(netOrderChange); - market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); - market.filledOrderBeans = market.filledOrderBeans.plus(filledBeanAmount); - market.podVolume = market.podVolume.plus(filledPodAmount); - market.beanVolume = market.beanVolume.plus(filledBeanAmount); - market.cancelledOrderBeans = market.cancelledOrderBeans.plus(cancelledBeanAmount); - market.save(); - - marketHourly.deltaOrderBeans = marketHourly.deltaOrderBeans.plus(newBeanAmount); - marketHourly.orderBeans = market.orderBeans; - marketHourly.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.plus(netOrderChange); - marketHourly.availableOrderBeans = market.availableOrderBeans; - marketHourly.deltaFilledOrderedPods = marketHourly.deltaFilledOrderedPods.plus(filledPodAmount); - marketHourly.filledOrderedPods = market.filledOrderedPods; - marketHourly.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); - marketHourly.filledOrderBeans = market.filledOrderBeans; - marketHourly.deltaPodVolume = marketHourly.deltaPodVolume.plus(filledPodAmount); - marketHourly.podVolume = market.podVolume; - marketHourly.deltaBeanVolume = marketHourly.deltaBeanVolume.plus(filledBeanAmount); - marketHourly.beanVolume = market.beanVolume; - marketHourly.deltaCancelledOrderBeans = marketHourly.deltaCancelledOrderBeans.plus(cancelledBeanAmount); - marketHourly.cancelledOrderBeans = market.cancelledOrderBeans; - marketHourly.updatedAt = timestamp; - marketHourly.save(); - - marketDaily.deltaOrderBeans = marketDaily.deltaOrderBeans.plus(newBeanAmount); - marketDaily.orderBeans = market.orderBeans; - marketDaily.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.plus(netOrderChange); - marketDaily.availableOrderBeans = market.availableOrderBeans; - marketDaily.deltaFilledOrderedPods = marketDaily.deltaFilledOrderedPods.plus(filledPodAmount); - marketDaily.filledOrderedPods = market.filledOrderedPods; - marketDaily.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); - marketDaily.filledOrderBeans = market.filledOrderBeans; - marketDaily.deltaPodVolume = marketDaily.deltaPodVolume.plus(filledPodAmount); - marketDaily.podVolume = market.podVolume; - marketDaily.deltaBeanVolume = marketDaily.deltaBeanVolume.plus(filledBeanAmount); - marketDaily.beanVolume = market.beanVolume; - marketDaily.deltaCancelledOrderBeans = marketDaily.deltaCancelledOrderBeans.plus(cancelledBeanAmount); - marketDaily.cancelledOrderBeans = market.cancelledOrderBeans; - marketDaily.updatedAt = timestamp; - marketDaily.save(); + order.updatedAt = params.event.block.timestamp; + order.beanAmountFilled = order.beanAmountFilled.plus(params.costInBeans); + order.podAmountFilled = order.podAmountFilled.plus(params.amount); + order.status = order.beanAmount == order.beanAmountFilled ? "FILLED" : "ACTIVE"; + let newFills = order.fills; + newFills.push(fill.id); + order.fills = newFills; + order.save(); + + fill.createdAt = params.event.block.timestamp; + fill.order = order.id; + fill.from = params.from.toHexString(); + fill.to = params.to.toHexString(); + fill.amount = params.amount; + fill.index = params.index; + fill.start = params.start; + fill.costInBeans = params.costInBeans; + fill.save(); + + if (order.status == "FILLED") { + updateActiveOrders(params.event.address, MarketplaceAction.FILLED_FULL, order.id, order.maxPlaceInLine); + } + + updateMarketOrderBalances(params.event.address, ZERO_BI, ZERO_BI, params.amount, params.costInBeans, params.event.block.timestamp); + + // Save the raw event data + let id = "podOrderFilled-" + params.event.transaction.hash.toHexString() + "-" + params.event.logIndex.toString(); + let rawEvent = new PodOrderFilledEvent(id); + rawEvent.hash = params.event.transaction.hash.toHexString(); + rawEvent.logIndex = params.event.logIndex.toI32(); + rawEvent.protocol = params.event.address.toHexString(); + rawEvent.historyID = order.historyID; + rawEvent.from = params.from.toHexString(); + rawEvent.to = params.to.toHexString(); + rawEvent.index = params.index; + rawEvent.start = params.start; + rawEvent.amount = params.amount; + rawEvent.costInBeans = params.costInBeans; + rawEvent.blockNumber = params.event.block.number; + rawEvent.createdAt = params.event.block.timestamp; + rawEvent.save(); } diff --git a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts index 88e4db7ffb..9489441d47 100644 --- a/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts +++ b/projects/subgraph-beanstalk/src/utils/PodMarketplace.ts @@ -119,6 +119,119 @@ export function loadPodMarketplaceDailySnapshot(diamondAddress: Address, timesta return snapshot; } +export function updateMarketListingBalances( + marketAddress: Address, + newPodAmount: BigInt, + cancelledPodAmount: BigInt, + filledPodAmount: BigInt, + filledBeanAmount: BigInt, + timestamp: BigInt +): void { + let market = loadPodMarketplace(marketAddress); + let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); + let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); + + const netListingChange = newPodAmount.minus(cancelledPodAmount).minus(filledPodAmount); + + market.listedPods = market.listedPods.plus(newPodAmount); + market.availableListedPods = market.availableListedPods.plus(netListingChange); + market.cancelledListedPods = market.cancelledListedPods.plus(cancelledPodAmount); + market.filledListedPods = market.filledListedPods.plus(filledPodAmount); + market.podVolume = market.podVolume.plus(filledPodAmount); + market.beanVolume = market.beanVolume.plus(filledBeanAmount); + market.save(); + + marketHourly.season = market.season; + marketHourly.deltaListedPods = marketHourly.deltaListedPods.plus(newPodAmount); + marketHourly.listedPods = market.listedPods; + marketHourly.deltaAvailableListedPods = marketHourly.deltaAvailableListedPods.plus(netListingChange); + marketHourly.availableListedPods = market.availableListedPods; + marketHourly.deltaCancelledListedPods = marketHourly.deltaCancelledListedPods.plus(cancelledPodAmount); + marketHourly.cancelledListedPods = market.cancelledListedPods; + marketHourly.deltaFilledListedPods = marketHourly.deltaFilledListedPods.plus(filledPodAmount); + marketHourly.filledListedPods = market.filledListedPods; + marketHourly.deltaPodVolume = marketHourly.deltaPodVolume.plus(filledPodAmount); + marketHourly.podVolume = market.podVolume; + marketHourly.deltaBeanVolume = marketHourly.deltaBeanVolume.plus(filledBeanAmount); + marketHourly.beanVolume = market.beanVolume; + marketHourly.updatedAt = timestamp; + marketHourly.save(); + + marketDaily.season = market.season; + marketDaily.deltaListedPods = marketDaily.deltaListedPods.plus(newPodAmount); + marketDaily.listedPods = market.listedPods; + marketDaily.deltaAvailableListedPods = marketDaily.deltaAvailableListedPods.plus(netListingChange); + marketDaily.availableListedPods = market.availableListedPods; + marketDaily.deltaCancelledListedPods = marketDaily.deltaCancelledListedPods.plus(cancelledPodAmount); + marketDaily.cancelledListedPods = market.cancelledListedPods; + marketDaily.deltaFilledListedPods = marketDaily.deltaFilledListedPods.plus(filledPodAmount); + marketDaily.filledListedPods = market.filledListedPods; + marketDaily.deltaPodVolume = marketDaily.deltaPodVolume.plus(filledPodAmount); + marketDaily.podVolume = market.podVolume; + marketDaily.deltaBeanVolume = marketDaily.deltaBeanVolume.plus(filledBeanAmount); + marketDaily.beanVolume = market.beanVolume; + marketDaily.updatedAt = timestamp; + marketDaily.save(); +} + +export function updateMarketOrderBalances( + marketAddress: Address, + newBeanAmount: BigInt, + cancelledBeanAmount: BigInt, + filledPodAmount: BigInt, + filledBeanAmount: BigInt, + timestamp: BigInt +): void { + let market = loadPodMarketplace(marketAddress); + let marketHourly = loadPodMarketplaceHourlySnapshot(marketAddress, market.season, timestamp); + let marketDaily = loadPodMarketplaceDailySnapshot(marketAddress, timestamp); + + const netOrderChange = newBeanAmount.minus(cancelledBeanAmount).minus(filledBeanAmount); + + market.orderBeans = market.orderBeans.plus(newBeanAmount); + market.availableOrderBeans = market.availableOrderBeans.plus(netOrderChange); + market.filledOrderedPods = market.filledOrderedPods.plus(filledPodAmount); + market.filledOrderBeans = market.filledOrderBeans.plus(filledBeanAmount); + market.podVolume = market.podVolume.plus(filledPodAmount); + market.beanVolume = market.beanVolume.plus(filledBeanAmount); + market.cancelledOrderBeans = market.cancelledOrderBeans.plus(cancelledBeanAmount); + market.save(); + + marketHourly.deltaOrderBeans = marketHourly.deltaOrderBeans.plus(newBeanAmount); + marketHourly.orderBeans = market.orderBeans; + marketHourly.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.plus(netOrderChange); + marketHourly.availableOrderBeans = market.availableOrderBeans; + marketHourly.deltaFilledOrderedPods = marketHourly.deltaFilledOrderedPods.plus(filledPodAmount); + marketHourly.filledOrderedPods = market.filledOrderedPods; + marketHourly.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); + marketHourly.filledOrderBeans = market.filledOrderBeans; + marketHourly.deltaPodVolume = marketHourly.deltaPodVolume.plus(filledPodAmount); + marketHourly.podVolume = market.podVolume; + marketHourly.deltaBeanVolume = marketHourly.deltaBeanVolume.plus(filledBeanAmount); + marketHourly.beanVolume = market.beanVolume; + marketHourly.deltaCancelledOrderBeans = marketHourly.deltaCancelledOrderBeans.plus(cancelledBeanAmount); + marketHourly.cancelledOrderBeans = market.cancelledOrderBeans; + marketHourly.updatedAt = timestamp; + marketHourly.save(); + + marketDaily.deltaOrderBeans = marketDaily.deltaOrderBeans.plus(newBeanAmount); + marketDaily.orderBeans = market.orderBeans; + marketDaily.deltaAvailableOrderBeans = marketHourly.deltaAvailableOrderBeans.plus(netOrderChange); + marketDaily.availableOrderBeans = market.availableOrderBeans; + marketDaily.deltaFilledOrderedPods = marketDaily.deltaFilledOrderedPods.plus(filledPodAmount); + marketDaily.filledOrderedPods = market.filledOrderedPods; + marketDaily.deltaFilledOrderBeans = marketHourly.deltaFilledOrderBeans.plus(filledBeanAmount); + marketDaily.filledOrderBeans = market.filledOrderBeans; + marketDaily.deltaPodVolume = marketDaily.deltaPodVolume.plus(filledPodAmount); + marketDaily.podVolume = market.podVolume; + marketDaily.deltaBeanVolume = marketDaily.deltaBeanVolume.plus(filledBeanAmount); + marketDaily.beanVolume = market.beanVolume; + marketDaily.deltaCancelledOrderBeans = marketDaily.deltaCancelledOrderBeans.plus(cancelledBeanAmount); + marketDaily.cancelledOrderBeans = market.cancelledOrderBeans; + marketDaily.updatedAt = timestamp; + marketDaily.save(); +} + export function updateExpiredPlots(harvestableIndex: BigInt, diamondAddress: Address, timestamp: BigInt): void { let market = loadPodMarketplace(diamondAddress); let remainingListings = market.activeListings; From 3c6a6b79d5a150b24d58ec8ac3736fddeed1ccb1 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 16:52:35 -0700 Subject: [PATCH 42/89] generalize pod order create handler --- .../src/MarketplaceHandler.ts | 161 ++++++++---------- 1 file changed, 74 insertions(+), 87 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 84ab52a0d7..4d9a7538de 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -63,14 +63,13 @@ class PodOrderCreatedParams { event: ethereum.Event; account: Address; id: Bytes; - amount: BigInt; + beanAmount: BigInt; pricePerPod: i32; maxPlaceInLine: BigInt; - // v2 - minFillAmount: BigInt; - pricingFunction: Bytes; - pricingType: i32; + minFillAmount: BigInt; // for v1, always 0 + pricingFunction: Bytes | null; + pricingType: i32; // for v1, always 0 } // This one is the same for both listing/order fills. @@ -227,45 +226,18 @@ export function handlePodListingFilled(event: PodListingFilled_v1): void { } export function handlePodOrderCreated(event: PodOrderCreated_v1): void { - let order = loadPodOrder(event.params.id); - let farmer = loadFarmer(event.params.account); - - if (order.status != "") { - createHistoricalPodOrder(order); - } - - order.historyID = order.id + "-" + event.block.timestamp.toString(); - order.farmer = event.params.account.toHexString(); - order.createdAt = event.block.timestamp; - order.updatedAt = event.block.timestamp; - order.status = "ACTIVE"; - order.beanAmount = event.params.amount.times(BigInt.fromI32(event.params.pricePerPod)).div(BigInt.fromString("1000000")); - order.beanAmountFilled = ZERO_BI; - order.podAmountFilled = ZERO_BI; - order.maxPlaceInLine = event.params.maxPlaceInLine; - order.pricePerPod = event.params.pricePerPod; - order.creationHash = event.transaction.hash.toHexString(); - order.fills = []; - order.save(); - - updateActiveOrders(event.address, MarketplaceAction.CREATED, order.id, order.maxPlaceInLine); - updateMarketOrderBalances(event.address, order.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); - - // Save the raw event data - let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodOrderCreatedEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = order.historyID; - rawEvent.account = event.params.account.toHexString(); - rawEvent.orderId = event.params.id.toHexString(); - rawEvent.amount = event.params.amount; - rawEvent.pricePerPod = event.params.pricePerPod; - rawEvent.maxPlaceInLine = event.params.maxPlaceInLine; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + const beanAmount = event.params.amount.times(BigInt.fromI32(event.params.pricePerPod)).div(BigInt.fromString("1000000")); + podOrderCreated({ + event: event, + account: event.params.account, + id: event.params.id, + beanAmount: beanAmount, + pricePerPod: event.params.pricePerPod, + maxPlaceInLine: event.params.maxPlaceInLine, + minFillAmount: ZERO_BI, + pricingFunction: null, + pricingType: 0 + }); } export function handlePodOrderFilled(event: PodOrderFilled_v1): void { @@ -505,49 +477,17 @@ export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { } export function handlePodOrderCreated_v2(event: PodOrderCreated_v2): void { - let order = loadPodOrder(event.params.id); - let farmer = loadFarmer(event.params.account); - - if (order.status != "") { - createHistoricalPodOrder(order); - } - - order.historyID = order.id + "-" + event.block.timestamp.toString(); - order.farmer = event.params.account.toHexString(); - order.createdAt = event.block.timestamp; - order.updatedAt = event.block.timestamp; - order.status = "ACTIVE"; - order.beanAmount = event.params.amount; - order.beanAmountFilled = ZERO_BI; - order.minFillAmount = event.params.minFillAmount; - order.maxPlaceInLine = event.params.maxPlaceInLine; - order.pricePerPod = event.params.pricePerPod; - order.pricingFunction = event.params.pricingFunction; - order.pricingType = event.params.priceType; - order.creationHash = event.transaction.hash.toHexString(); - order.fills = []; - order.save(); - - updateActiveOrders(event.address, MarketplaceAction.CREATED, order.id, order.maxPlaceInLine); - updateMarketOrderBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); - - // Save the raw event data - let id = "podOrderCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodOrderCreatedEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = order.historyID; - rawEvent.account = event.params.account.toHexString(); - rawEvent.orderId = event.params.id.toHexString(); - rawEvent.amount = event.params.amount; - rawEvent.pricePerPod = event.params.pricePerPod; - rawEvent.maxPlaceInLine = event.params.maxPlaceInLine; - rawEvent.pricingFunction = event.params.pricingFunction; - rawEvent.pricingType = event.params.priceType; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + podOrderCreated({ + event: event, + account: event.params.account, + id: event.params.id, + beanAmount: event.params.amount, + pricePerPod: event.params.pricePerPod, + maxPlaceInLine: event.params.maxPlaceInLine, + minFillAmount: event.params.minFillAmount, + pricingFunction: event.params.pricingFunction, + pricingType: event.params.priceType + }); } export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { @@ -658,6 +598,53 @@ function podListingFilled(params: MarketFillParams): void { rawEvent.save(); } +function podOrderCreated(params: PodOrderCreatedParams): void { + let order = loadPodOrder(params.id); + loadFarmer(params.account); + + if (order.status != "") { + createHistoricalPodOrder(order); + } + + order.historyID = order.id + "-" + params.event.block.timestamp.toString(); + order.farmer = params.account.toHexString(); + order.createdAt = params.event.block.timestamp; + order.updatedAt = params.event.block.timestamp; + order.status = "ACTIVE"; + order.beanAmount = params.beanAmount; + order.beanAmountFilled = ZERO_BI; + order.podAmountFilled = ZERO_BI; + order.minFillAmount = params.minFillAmount; + order.maxPlaceInLine = params.maxPlaceInLine; + order.pricePerPod = params.pricePerPod; + order.pricingFunction = params.pricingFunction; + order.pricingType = params.pricingType; + order.creationHash = params.event.transaction.hash.toHexString(); + order.fills = []; + order.save(); + + updateActiveOrders(params.event.address, MarketplaceAction.CREATED, order.id, order.maxPlaceInLine); + updateMarketOrderBalances(params.event.address, params.beanAmount, ZERO_BI, ZERO_BI, ZERO_BI, params.event.block.timestamp); + + // Save the raw event data + let id = "podOrderCreated-" + params.event.transaction.hash.toHexString() + "-" + params.event.logIndex.toString(); + let rawEvent = new PodOrderCreatedEvent(id); + rawEvent.hash = params.event.transaction.hash.toHexString(); + rawEvent.logIndex = params.event.logIndex.toI32(); + rawEvent.protocol = params.event.address.toHexString(); + rawEvent.historyID = order.historyID; + rawEvent.account = params.account.toHexString(); + rawEvent.orderId = params.id.toHexString(); + rawEvent.amount = params.beanAmount; + rawEvent.pricePerPod = params.pricePerPod; + rawEvent.maxPlaceInLine = params.maxPlaceInLine; + rawEvent.pricingFunction = params.pricingFunction; + rawEvent.pricingType = params.pricingType; + rawEvent.blockNumber = params.event.block.number; + rawEvent.createdAt = params.event.block.timestamp; + rawEvent.save(); +} + function podOrderFilled(params: MarketFillParams): void { let order = loadPodOrder(params.id!); let fill = loadPodFill(params.event.address, params.index, params.event.transaction.hash.toHexString()); From 5411d15fcb57ab42af8de25ec9f9bdb1cf5cb828 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 17:06:24 -0700 Subject: [PATCH 43/89] generalize pod listing create handler --- .../src/MarketplaceHandler.ts | 353 ++++++------------ 1 file changed, 121 insertions(+), 232 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 4d9a7538de..9b6ac6354b 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -48,15 +48,11 @@ class PodListingCreatedParams { amount: BigInt; pricePerPod: i32; maxHarvestableIndex: BigInt; - - toWallet: boolean; // v1 - mode: i32; // v1.1 - + mode: i32; // in v1, its called toWallet // v2 - minFillAmount: BigInt; - pricingFunction: Bytes; - // mode: i32; - pricingType: i32; + minFillAmount: BigInt; // for v1, always 0 + pricingFunction: Bytes | null; + pricingType: i32; // for v1, always 0 } class PodOrderCreatedParams { @@ -95,83 +91,19 @@ class MarketFillParams { */ export function handlePodListingCreated(event: PodListingCreated_v1): void { - let plotCheck = Plot.load(event.params.index.toString()); - if (plotCheck == null) { - return; - } - let plot = loadPlot(event.address, event.params.index); - - /// Upsert pod listing - let listing = loadPodListing(event.params.account, event.params.index); - if (listing.createdAt !== ZERO_BI) { - createHistoricalPodListing(listing); - listing.status = "ACTIVE"; - listing.createdAt = ZERO_BI; - listing.fill = null; - listing.filled = ZERO_BI; - listing.filledAmount = ZERO_BI; - } - - // Identifiers - listing.historyID = listing.id + "-" + event.block.timestamp.toString(); - listing.plot = plot.id; - - // Configuration - listing.start = event.params.start; - listing.mode = event.params.toWallet === true ? 0 : 1; - - // Constraints - listing.maxHarvestableIndex = event.params.maxHarvestableIndex; - - // Pricing - listing.pricePerPod = event.params.pricePerPod; - - // Amounts [Relative to Original] - listing.originalIndex = event.params.index; - listing.originalAmount = event.params.amount; - - // Amounts [Relative to Child] - listing.amount = event.params.amount; // in Pods - listing.remainingAmount = listing.originalAmount; - - // Metadata - listing.createdAt = listing.createdAt == ZERO_BI ? event.block.timestamp : listing.createdAt; - listing.updatedAt = event.block.timestamp; - listing.creationHash = event.transaction.hash.toHexString(); - listing.save(); - - /// Update plot - plot.listing = listing.id; - plot.save(); - - /// Update market totals - updateActiveListings( - event.address, - MarketplaceAction.CREATED, - event.params.account.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - updateMarketListingBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); - - /// Save raw event data - let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodListingCreatedEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = listing.historyID; - rawEvent.account = event.params.account.toHexString(); - rawEvent.index = event.params.index; - rawEvent.start = event.params.start; - rawEvent.amount = event.params.amount; - rawEvent.pricePerPod = event.params.pricePerPod; - rawEvent.maxHarvestableIndex = event.params.maxHarvestableIndex; - rawEvent.minFillAmount = ZERO_BI; - rawEvent.mode = event.params.toWallet; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + podListingCreated({ + event: event, + account: event.params.account, + index: event.params.index, + start: event.params.start, + amount: event.params.amount, + pricePerPod: event.params.pricePerPod, + maxHarvestableIndex: event.params.maxHarvestableIndex, + mode: event.params.toWallet ? 0 : 1, + minFillAmount: ZERO_BI, + pricingFunction: null, + pricingType: 0 + }); } export function handlePodListingCancelled(event: PodListingCancelled): void { @@ -303,78 +235,19 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { */ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): void { - let plotCheck = Plot.load(event.params.index.toString()); - if (plotCheck == null) { - return; - } - let plot = loadPlot(event.address, event.params.index); - - /// Upsert pod listing - let listing = loadPodListing(event.params.account, event.params.index); - if (listing.createdAt !== ZERO_BI) { - createHistoricalPodListing(listing); - listing.status = "ACTIVE"; - listing.createdAt = ZERO_BI; - listing.fill = null; - listing.filled = ZERO_BI; - listing.filledAmount = ZERO_BI; - } - - listing.historyID = listing.id + "-" + event.block.timestamp.toString(); - listing.plot = plot.id; - - listing.start = event.params.start; - listing.mode = event.params.mode; - - listing.pricePerPod = event.params.pricePerPod; - listing.maxHarvestableIndex = event.params.maxHarvestableIndex; - - listing.originalIndex = event.params.index; - listing.originalAmount = event.params.amount; - - listing.amount = event.params.amount; - listing.remainingAmount = listing.originalAmount; - - listing.status = "ACTIVE"; - listing.createdAt = listing.createdAt == ZERO_BI ? event.block.timestamp : listing.createdAt; - listing.updatedAt = event.block.timestamp; - listing.creationHash = event.transaction.hash.toHexString(); - - listing.save(); - - /// Update plot - plot.listing = listing.id; - plot.save(); - - /// Update market totals - updateActiveListings( - event.address, - MarketplaceAction.CREATED, - event.params.account.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - updateMarketListingBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); - - /// Save raw event data - let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodListingCreatedEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = listing.historyID; - rawEvent.account = event.params.account.toHexString(); - rawEvent.index = event.params.index; - rawEvent.start = event.params.start; - rawEvent.amount = event.params.amount; - rawEvent.pricePerPod = event.params.pricePerPod; - rawEvent.maxHarvestableIndex = event.params.maxHarvestableIndex; - rawEvent.maxHarvestableIndex = ZERO_BI; - rawEvent.minFillAmount = ZERO_BI; - rawEvent.mode = event.params.mode; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + podListingCreated({ + event: event, + account: event.params.account, + index: event.params.index, + start: event.params.start, + amount: event.params.amount, + pricePerPod: event.params.pricePerPod, + maxHarvestableIndex: event.params.maxHarvestableIndex, + mode: event.params.mode, + minFillAmount: ZERO_BI, + pricingFunction: null, + pricingType: 0 + }); } /* ------------------------------------ @@ -386,81 +259,19 @@ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): voi */ export function handlePodListingCreated_v2(event: PodListingCreated_v2): void { - let plot = Plot.load(event.params.index.toString()); - if (plot == null) { - return; - } - - /// Upsert PodListing - let listing = loadPodListing(event.params.account, event.params.index); - if (listing.createdAt !== ZERO_BI) { - // Re-listed prior plot with new info - createHistoricalPodListing(listing); - listing.fill = null; - listing.filled = ZERO_BI; - listing.filledAmount = ZERO_BI; - } - - listing.historyID = listing.id + "-" + event.block.timestamp.toString(); - listing.plot = plot.id; - - listing.start = event.params.start; - listing.mode = event.params.mode; - - listing.minFillAmount = event.params.minFillAmount; - listing.maxHarvestableIndex = event.params.maxHarvestableIndex; - - listing.pricingType = event.params.pricingType; - listing.pricePerPod = event.params.pricePerPod; - listing.pricingFunction = event.params.pricingFunction; - - listing.originalIndex = event.params.index; - listing.originalAmount = event.params.amount; - - listing.amount = event.params.amount; - listing.remainingAmount = listing.originalAmount; - - listing.status = "ACTIVE"; - listing.createdAt = listing.createdAt == ZERO_BI ? event.block.timestamp : listing.createdAt; - listing.updatedAt = event.block.timestamp; - listing.creationHash = event.transaction.hash.toHexString(); - - listing.save(); - - /// Update plot - plot.listing = listing.id; - plot.save(); - - /// Update market totals - updateActiveListings( - event.address, - MarketplaceAction.CREATED, - event.params.account.toHexString(), - listing.index, - listing.maxHarvestableIndex - ); - updateMarketListingBalances(event.address, event.params.amount, ZERO_BI, ZERO_BI, ZERO_BI, event.block.timestamp); - - /// Save raw event data - let id = "podListingCreated-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodListingCreatedEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = listing.historyID; - rawEvent.account = event.params.account.toHexString(); - rawEvent.index = event.params.index; - rawEvent.start = event.params.start; - rawEvent.amount = event.params.amount; - rawEvent.pricePerPod = event.params.pricePerPod; - rawEvent.maxHarvestableIndex = event.params.maxHarvestableIndex; - rawEvent.minFillAmount = event.params.minFillAmount; - rawEvent.mode = event.params.mode; - rawEvent.pricingFunction = event.params.pricingFunction; - rawEvent.pricingType = event.params.pricingType; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); + podListingCreated({ + event: event, + account: event.params.account, + index: event.params.index, + start: event.params.start, + amount: event.params.amount, + pricePerPod: event.params.pricePerPod, + maxHarvestableIndex: event.params.maxHarvestableIndex, + mode: event.params.mode, + minFillAmount: event.params.minFillAmount, + pricingFunction: event.params.pricingFunction, + pricingType: event.params.pricingType + }); } export function handlePodListingFilled_v2(event: PodListingFilled_v2): void { @@ -508,6 +319,84 @@ export function handlePodOrderFilled_v2(event: PodOrderFilled_v2): void { * ------------------------------------ */ +function podListingCreated(params: PodListingCreatedParams): void { + let plot = Plot.load(params.index.toString()); + if (plot == null) { + return; + } + + /// Upsert PodListing + let listing = loadPodListing(params.account, params.index); + if (listing.createdAt !== ZERO_BI) { + // Re-listed prior plot with new info + createHistoricalPodListing(listing); + listing.fill = null; + listing.filled = ZERO_BI; + listing.filledAmount = ZERO_BI; + } + + listing.historyID = listing.id + "-" + params.event.block.timestamp.toString(); + listing.plot = plot.id; + + listing.start = params.start; + listing.mode = params.mode; + + listing.minFillAmount = params.minFillAmount; + listing.maxHarvestableIndex = params.maxHarvestableIndex; + + listing.pricingType = params.pricingType; + listing.pricePerPod = params.pricePerPod; + listing.pricingFunction = params.pricingFunction; + + listing.originalIndex = params.index; + listing.originalAmount = params.amount; + + listing.amount = params.amount; + listing.remainingAmount = listing.originalAmount; + + listing.status = "ACTIVE"; + listing.createdAt = listing.createdAt == ZERO_BI ? params.event.block.timestamp : listing.createdAt; + listing.updatedAt = params.event.block.timestamp; + listing.creationHash = params.event.transaction.hash.toHexString(); + + listing.save(); + + /// Update plot + plot.listing = listing.id; + plot.save(); + + /// Update market totals + updateActiveListings( + params.event.address, + MarketplaceAction.CREATED, + params.account.toHexString(), + listing.index, + listing.maxHarvestableIndex + ); + updateMarketListingBalances(params.event.address, params.amount, ZERO_BI, ZERO_BI, ZERO_BI, params.event.block.timestamp); + + /// Save raw event data + let id = "podListingCreated-" + params.event.transaction.hash.toHexString() + "-" + params.event.logIndex.toString(); + let rawEvent = new PodListingCreatedEvent(id); + rawEvent.hash = params.event.transaction.hash.toHexString(); + rawEvent.logIndex = params.event.logIndex.toI32(); + rawEvent.protocol = params.event.address.toHexString(); + rawEvent.historyID = listing.historyID; + rawEvent.account = params.account.toHexString(); + rawEvent.index = params.index; + rawEvent.start = params.start; + rawEvent.amount = params.amount; + rawEvent.pricePerPod = params.pricePerPod; + rawEvent.maxHarvestableIndex = params.maxHarvestableIndex; + rawEvent.minFillAmount = params.minFillAmount; + rawEvent.mode = params.mode; + rawEvent.pricingFunction = params.pricingFunction; + rawEvent.pricingType = params.pricingType; + rawEvent.blockNumber = params.event.block.number; + rawEvent.createdAt = params.event.block.timestamp; + rawEvent.save(); +} + function podListingFilled(params: MarketFillParams): void { let listing = loadPodListing(params.from, params.index); From 39197d4061ba91b0fdd19ac44e99e695ed11e6c2 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 17:08:56 -0700 Subject: [PATCH 44/89] update comment --- projects/subgraph-beanstalk/src/MarketplaceHandler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 9b6ac6354b..e166569a22 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -229,8 +229,8 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { * When Beanstalk was Replanted, `event.params.mode` was changed from * `bool` to `uint8`. * - * Proposal: ... - * Deployed: ... at block 15277986 + * Proposal: BIP-21 + * Deployed: 08/05/2022 at block 15278963 * ------------------------------------ */ @@ -254,7 +254,7 @@ export function handlePodListingCreated_v1_1(event: PodListingCreated_v1_1): voi * POD MARKETPLACE V2 * * Proposal: BIP-29 https://bean.money/bip-29 - * Deployed: 11/12/2022 @ block 15277986 + * Deployed: 11/12/2022 @ block 15951072 * ------------------------------------ */ From d4ae60902d9734fb1de2ddb3a5ad35f96f15a2d9 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 17:31:44 -0700 Subject: [PATCH 45/89] add fields and method for current harvestable index --- projects/subgraph-beanstalk/schema.graphql | 10 +++++++ .../subgraph-beanstalk/src/FieldHandler.ts | 30 +++++++++---------- .../subgraph-beanstalk/src/utils/Season.ts | 6 ++++ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index c1c061a5f3..4131008c9d 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -1153,6 +1153,8 @@ type PodFill @entity { to: Farmer! "Number of pods filled" amount: BigInt! + "Where these pods were in line when filled" + placeInLine: BigInt! "Index of plot transferred" index: BigInt! "Start of plot transferred" @@ -1543,6 +1545,8 @@ type PodListingCreated implements MarketplaceEvent @entity(immutable: true) { historyID: String! " Account creating the listing" account: String! + "Where these pods were in line when listed" + placeInLine: BigInt! " Index of the plot listed" index: BigInt! " Start value of the plot listed " @@ -1582,6 +1586,8 @@ type PodListingFilled implements MarketplaceEvent @entity(immutable: true) { from: String! "Account buying pods" to: String! + "Where these pods were in line when filled" + placeInLine: BigInt! "Index of the plot transferred" index: BigInt! "Start of the plot transferred" @@ -1609,6 +1615,8 @@ type PodListingCancelled implements MarketplaceEvent @entity(immutable: true) { historyID: String! " Account cancelling listing" account: String! + "Where these pods were in line when cancelled" + placeInLine: BigInt! " Index of plot listing being cancelled" index: BigInt! " Block number of this event " @@ -1667,6 +1675,8 @@ type PodOrderFilled implements MarketplaceEvent @entity(immutable: true) { from: String! "Account buying pods" to: String! + "Where these pods were in line when filled" + placeInLine: BigInt! "Index of the plot transferred" index: BigInt! "Start of the plot transferred" diff --git a/projects/subgraph-beanstalk/src/FieldHandler.ts b/projects/subgraph-beanstalk/src/FieldHandler.ts index 8fe72b2e04..eb96592812 100644 --- a/projects/subgraph-beanstalk/src/FieldHandler.ts +++ b/projects/subgraph-beanstalk/src/FieldHandler.ts @@ -16,7 +16,7 @@ import { loadFarmer } from "./utils/Farmer"; import { handleRateChange, loadField, loadFieldDaily, loadFieldHourly } from "./utils/Field"; import { loadPlot } from "./utils/Plot"; import { savePodTransfer } from "./utils/PodTransfer"; -import { loadSeason } from "./utils/Season"; +import { getCurrentSeason, getHarvestableIndex, loadSeason } from "./utils/Season"; import { loadBeanstalk } from "./utils/Beanstalk"; import { expirePodListingIfExists } from "./utils/PodListing"; @@ -217,8 +217,8 @@ export function handleHarvest(event: Harvest): void { } export function handlePlotTransfer(event: PlotTransfer): void { - let beanstalk = loadBeanstalk(BEANSTALK); - let season = loadSeason(event.address, BigInt.fromI32(beanstalk.lastSeason)); + const currentSeason = getCurrentSeason(event.address); + const currentHarvestable = getHarvestableIndex(event.address); // Ensure both farmer entites exist loadFarmer(event.params.from); @@ -227,7 +227,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { // Update farmer field data updateFieldTotals( event.params.from, - beanstalk.lastSeason, + currentSeason, ZERO_BI, ZERO_BI, ZERO_BI, @@ -239,7 +239,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { ); updateFieldTotals( event.params.to, - beanstalk.lastSeason, + currentSeason, ZERO_BI, ZERO_BI, ZERO_BI, @@ -290,7 +290,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { } }; - let transferredHarvestable = calcHarvestable(event.params.id, event.params.pods, season.harvestableIndex); + let transferredHarvestable = calcHarvestable(event.params.id, event.params.pods, currentHarvestable); // log.debug("\nPodTransfer: ===================\n", []); // log.debug("\nPodTransfer: Transfer Season - {}\n", [field.season.toString()]); @@ -320,7 +320,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.farmer = event.params.to.toHexString(); sourcePlot.updatedAt = event.block.timestamp; sourcePlot.pods = event.params.pods; - sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, season.harvestableIndex); + sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); remainderPlot.farmer = event.params.from.toHexString(); @@ -331,7 +331,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { remainderPlot.updatedAt = event.block.timestamp; remainderPlot.index = remainderIndex; remainderPlot.pods = sourceEndIndex.minus(transferEndIndex); - remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, season.harvestableIndex); + remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, currentHarvestable); remainderPlot.temperature = sourcePlot.temperature; remainderPlot.save(); @@ -347,7 +347,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.updatedAt = event.block.timestamp; sourcePlot.pods = sourcePlot.pods.minus(event.params.pods); - sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, season.harvestableIndex); + sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); toPlot.farmer = event.params.to.toHexString(); @@ -358,7 +358,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.updatedAt = event.block.timestamp; toPlot.index = event.params.id; toPlot.pods = event.params.pods; - toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, season.harvestableIndex); + toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); toPlot.temperature = sourcePlot.temperature; toPlot.save(); @@ -375,7 +375,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.updatedAt = event.block.timestamp; sourcePlot.pods = event.params.id.minus(sourcePlot.index); - sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, season.harvestableIndex); + sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); toPlot.farmer = event.params.to.toHexString(); @@ -386,7 +386,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.updatedAt = event.block.timestamp; toPlot.index = event.params.id; toPlot.pods = event.params.pods; - toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, season.harvestableIndex); + toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); toPlot.temperature = sourcePlot.temperature; toPlot.save(); @@ -398,7 +398,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { remainderPlot.updatedAt = event.block.timestamp; remainderPlot.index = remainderIndex; remainderPlot.pods = sourceEndIndex.minus(transferEndIndex); - remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, season.harvestableIndex); + remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, currentHarvestable); remainderPlot.temperature = sourcePlot.temperature; remainderPlot.save(); @@ -416,7 +416,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { if (transferredHarvestable != ZERO_BI) { updateFieldTotals( event.params.from, - beanstalk.lastSeason, + currentSeason, ZERO_BI, ZERO_BI, ZERO_BI, @@ -428,7 +428,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { ); updateFieldTotals( event.params.to, - beanstalk.lastSeason, + currentSeason, ZERO_BI, ZERO_BI, ZERO_BI, diff --git a/projects/subgraph-beanstalk/src/utils/Season.ts b/projects/subgraph-beanstalk/src/utils/Season.ts index 6030fb8bf7..53987b8621 100644 --- a/projects/subgraph-beanstalk/src/utils/Season.ts +++ b/projects/subgraph-beanstalk/src/utils/Season.ts @@ -38,3 +38,9 @@ export function getCurrentSeason(beanstalk: Address): i32 { let beanstalkEntity = loadBeanstalk(beanstalk); return beanstalkEntity.lastSeason; } + +export function getHarvestableIndex(beanstalk: Address): BigInt { + let bs = loadBeanstalk(beanstalk); + let season = loadSeason(beanstalk, BigInt.fromI32(bs.lastSeason)); + return season.harvestableIndex; +} From 9130e98cb2447786fb6043b7242fc320ebdec56f Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 17:39:35 -0700 Subject: [PATCH 46/89] set place in line on market txn --- .../src/MarketplaceHandler.ts | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index e166569a22..2f4a4bbda4 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -39,6 +39,7 @@ import { updateMarketOrderBalances } from "./utils/PodMarketplace"; import { createHistoricalPodOrder, loadPodOrder } from "./utils/PodOrder"; +import { getHarvestableIndex } from "./utils/Season"; class PodListingCreatedParams { event: ethereum.Event; @@ -107,7 +108,6 @@ export function handlePodListingCreated(event: PodListingCreated_v1): void { } export function handlePodListingCancelled(event: PodListingCancelled): void { - let historyID = ""; let listing = PodListing.load(event.params.account.toHexString() + "-" + event.params.index.toString()); if (listing !== null && listing.status == "ACTIVE") { updateActiveListings( @@ -123,22 +123,20 @@ export function handlePodListingCancelled(event: PodListingCancelled): void { listing.updatedAt = event.block.timestamp; listing.save(); - historyID = listing.historyID; + // Save the raw event data + let id = "podListingCancelled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); + let rawEvent = new PodListingCancelledEvent(id); + rawEvent.hash = event.transaction.hash.toHexString(); + rawEvent.logIndex = event.logIndex.toI32(); + rawEvent.protocol = event.address.toHexString(); + rawEvent.historyID = listing.historyID; + rawEvent.account = event.params.account.toHexString(); + rawEvent.placeInLine = event.params.index.plus(listing.start).minus(getHarvestableIndex(event.address)); + rawEvent.index = event.params.index; + rawEvent.blockNumber = event.block.number; + rawEvent.createdAt = event.block.timestamp; + rawEvent.save(); } - - // Unclear whether this should possibly be omitted if the listing was invalid - // Save the raw event data - let id = "podListingCancelled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodListingCancelledEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = historyID; - rawEvent.account = event.params.account.toHexString(); - rawEvent.index = event.params.index; - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); } export function handlePodListingFilled(event: PodListingFilled_v1): void { @@ -189,7 +187,6 @@ export function handlePodOrderFilled(event: PodOrderFilled_v1): void { } export function handlePodOrderCancelled(event: PodOrderCancelled): void { - let historyID = ""; let order = PodOrder.load(event.params.id.toHexString()); if (order !== null && order.status == "ACTIVE") { order.status = order.podAmountFilled == ZERO_BI ? "CANCELLED" : "CANCELLED_PARTIAL"; @@ -206,21 +203,19 @@ export function handlePodOrderCancelled(event: PodOrderCancelled): void { event.block.timestamp ); - historyID = order.historyID; + // Save the raw event data + let id = "podOrderCancelled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); + let rawEvent = new PodOrderCancelledEvent(id); + rawEvent.hash = event.transaction.hash.toHexString(); + rawEvent.logIndex = event.logIndex.toI32(); + rawEvent.protocol = event.address.toHexString(); + rawEvent.historyID = order.historyID; + rawEvent.account = event.params.account.toHexString(); + rawEvent.orderId = event.params.id.toHexString(); + rawEvent.blockNumber = event.block.number; + rawEvent.createdAt = event.block.timestamp; + rawEvent.save(); } - // Unclear whether this should possibly be omitted if the listing was invalid - // Save the raw event data - let id = "podOrderCancelled-" + event.transaction.hash.toHexString() + "-" + event.logIndex.toString(); - let rawEvent = new PodOrderCancelledEvent(id); - rawEvent.hash = event.transaction.hash.toHexString(); - rawEvent.logIndex = event.logIndex.toI32(); - rawEvent.protocol = event.address.toHexString(); - rawEvent.historyID = historyID; - rawEvent.account = event.params.account.toHexString(); - rawEvent.orderId = event.params.id.toHexString(); - rawEvent.blockNumber = event.block.number; - rawEvent.createdAt = event.block.timestamp; - rawEvent.save(); } /* ------------------------------------ @@ -383,6 +378,7 @@ function podListingCreated(params: PodListingCreatedParams): void { rawEvent.protocol = params.event.address.toHexString(); rawEvent.historyID = listing.historyID; rawEvent.account = params.account.toHexString(); + rawEvent.placeInLine = params.index.plus(params.start).minus(getHarvestableIndex(params.event.address)); rawEvent.index = params.index; rawEvent.start = params.start; rawEvent.amount = params.amount; @@ -461,6 +457,7 @@ function podListingFilled(params: MarketFillParams): void { fill.from = params.from.toHexString(); fill.to = params.to.toHexString(); fill.amount = params.amount; + fill.placeInLine = params.index.plus(params.start).minus(getHarvestableIndex(params.event.address)); fill.index = params.index; fill.start = params.start; fill.costInBeans = params.costInBeans; @@ -478,6 +475,7 @@ function podListingFilled(params: MarketFillParams): void { rawEvent.historyID = originalHistoryID; rawEvent.from = params.from.toHexString(); rawEvent.to = params.to.toHexString(); + rawEvent.placeInLine = fill.placeInLine; rawEvent.index = params.index; rawEvent.start = params.start; rawEvent.amount = params.amount; @@ -552,6 +550,7 @@ function podOrderFilled(params: MarketFillParams): void { fill.from = params.from.toHexString(); fill.to = params.to.toHexString(); fill.amount = params.amount; + fill.placeInLine = params.index.plus(params.start).minus(getHarvestableIndex(params.event.address)); fill.index = params.index; fill.start = params.start; fill.costInBeans = params.costInBeans; @@ -572,6 +571,7 @@ function podOrderFilled(params: MarketFillParams): void { rawEvent.historyID = order.historyID; rawEvent.from = params.from.toHexString(); rawEvent.to = params.to.toHexString(); + rawEvent.placeInLine = params.index.plus(params.start).minus(getHarvestableIndex(params.event.address)); rawEvent.index = params.index; rawEvent.start = params.start; rawEvent.amount = params.amount; From a667536d59f871ff911f665a5ad8573394700eee Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 18:08:20 -0700 Subject: [PATCH 47/89] test pod events tracking place in line --- .../subgraph-beanstalk/src/utils/PodFill.ts | 1 + .../tests/MarketplaceV1.test.ts | 50 ++++++++++++++--- .../tests/MarketplaceV2.test.ts | 54 +++++++++++++++---- 3 files changed, 87 insertions(+), 18 deletions(-) diff --git a/projects/subgraph-beanstalk/src/utils/PodFill.ts b/projects/subgraph-beanstalk/src/utils/PodFill.ts index 56cd9f4c71..08382de1f4 100644 --- a/projects/subgraph-beanstalk/src/utils/PodFill.ts +++ b/projects/subgraph-beanstalk/src/utils/PodFill.ts @@ -11,6 +11,7 @@ export function loadPodFill(diamondAddress: Address, index: BigInt, hash: String fill.createdAt = ZERO_BI; fill.from = ""; fill.to = ""; + fill.placeInLine = ZERO_BI; fill.amount = ZERO_BI; fill.index = ZERO_BI; fill.start = ZERO_BI; diff --git a/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts b/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts index 619b1bf335..037818ca74 100644 --- a/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts +++ b/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts @@ -20,7 +20,9 @@ import { harvest, setHarvestable, sow } from "./utils/Field"; const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); -const listingIndex = podlineMil_BI(1); +const listingIndex = podlineMil_BI(10); +const listingStart = beans_BI(500); +const currentHarvestable = podlineMil_BI(4); const listingPricePerPod = BigInt.fromString("250000"); const maxHarvestableIndex = podlineMil_BI(100); const sowedBeans = beans_BI(5000); @@ -32,6 +34,7 @@ const orderId = Bytes.fromHexString("0xabcd"); describe("Marketplace", () => { beforeEach(() => { + setHarvestable(currentHarvestable); sow(account, listingIndex, sowedBeans, sowedPods); }); @@ -121,13 +124,50 @@ describe("Marketplace", () => { ); }); + test("Market events correctly track place in line", () => { + let placeInLine = listingIndex.plus(listingStart).minus(currentHarvestable); + const listedPods = sowedPods.minus(listingStart); + const createEvent = createListing_v1(account, listingIndex, sowedPods, listingStart, listingPricePerPod, maxHarvestableIndex); + const createListingId = "podListingCreated-" + createEvent.transaction.hash.toHexString() + "-" + createEvent.logIndex.toString(); + assert.fieldEquals("PodListingCreated", createListingId, "placeInLine", placeInLine.toString()); + + // Line advances 1m before fill + let newHarvestable = currentHarvestable.plus(podlineMil_BI(1)); + setHarvestable(newHarvestable); + placeInLine = placeInLine.minus(podlineMil_BI(1)); + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = beans_BI(2000); + const fillEvent = fillListing_v1(account, account2, listingIndex, listingStart, filledPods, listingPricePerPod); + const fillListingId = "podListingFilled-" + fillEvent.transaction.hash.toHexString() + "-" + fillEvent.logIndex.toString(); + assert.fieldEquals("PodListingFilled", fillListingId, "placeInLine", placeInLine.toString()); + assert.fieldEquals("PodFill", getPodFillId(listingIndex, fillEvent), "placeInLine", placeInLine.toString()); + + placeInLine = placeInLine.plus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + const cancelListingEvent = cancelListing(account, newListingIndex); + const cancelListingId = + "podListingCancelled-" + cancelListingEvent.transaction.hash.toHexString() + "-" + cancelListingEvent.logIndex.toString(); + assert.fieldEquals("PodListingCancelled", cancelListingId, "placeInLine", placeInLine.toString()); + + // Test order fill + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + sow(account2, orderPlotIndex, sowedBeans, orderedPods); + placeInLine = orderPlotIndex.minus(newHarvestable); + + createOrder_v1(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); + const fillOrderEvent = fillOrder_v1(account2, account, orderId, orderPlotIndex, ZERO_BI, orderedPods, orderPricePerPod); + const fillOrderId = "podOrderFilled-" + fillOrderEvent.transaction.hash.toHexString() + "-" + fillOrderEvent.logIndex.toString(); + assert.fieldEquals("PodOrderFilled", fillOrderId, "placeInLine", placeInLine.toString()); + assert.fieldEquals("PodFill", getPodFillId(orderPlotIndex, fillOrderEvent), "placeInLine", placeInLine.toString()); + }); + describe("Tests requiring Listing", () => { beforeEach(() => { createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); }); test("Fill listing - full", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledBeans = listedPods.times(listingPricePerPod).div(BI_10.pow(6)); const event = fillListing_v1(account, account2, listingIndex, listingStart, listedPods, listingPricePerPod); @@ -143,7 +183,6 @@ describe("Marketplace", () => { }); test("Fill listing - partial, then full", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = filledPods.times(listingPricePerPod).div(BI_10.pow(6)); @@ -225,7 +264,6 @@ describe("Marketplace", () => { }); test("Cancel listing - partial", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = filledPods.times(listingPricePerPod).div(BI_10.pow(6)); @@ -254,7 +292,6 @@ describe("Marketplace", () => { }); test("Recreate listing", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); cancelListing(account, listingIndex); const listEvent = createListing_v1(account, listingIndex, sowedPods, listingStart, listingPricePerPod, maxHarvestableIndex); @@ -310,7 +347,6 @@ describe("Marketplace", () => { }); test("Listing expires due to moving podline", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const listingID = account + "-" + listingIndex.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -358,7 +394,6 @@ describe("Marketplace", () => { }); test("Listing expires due to plot harvesting", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const listingID = account + "-" + listingIndex.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -375,7 +410,6 @@ describe("Marketplace", () => { }); test("Cancel expired/nonexistent listing", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); setHarvestable(maxHarvestableIndex.plus(ONE_BI)); const listingID = account + "-" + listingIndex.toString(); diff --git a/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts b/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts index 6c06f2f6b3..9cf9dc8871 100644 --- a/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts +++ b/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts @@ -19,7 +19,9 @@ import { harvest, setHarvestable, sow } from "./utils/Field"; const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); -const listingIndex = podlineMil_BI(1); +const listingIndex = podlineMil_BI(10); +const listingStart = beans_BI(500); +const currentHarvestable = podlineMil_BI(4); const maxHarvestableIndex = podlineMil_BI(100); const sowedBeans = beans_BI(5000); const sowedPods = sowedBeans.times(BigInt.fromString("3")); @@ -30,6 +32,7 @@ const orderId = Bytes.fromHexString("0xabcd"); describe("Marketplace", () => { beforeEach(() => { + setHarvestable(currentHarvestable); sow(account, listingIndex, sowedBeans, sowedPods); }); @@ -103,13 +106,50 @@ describe("Marketplace", () => { ); }); - describe("Tests requiring Listing", () => { + test("Market events correctly track place in line", () => { + let placeInLine = listingIndex.plus(listingStart).minus(currentHarvestable); + const listedPods = sowedPods.minus(listingStart); + const createEvent = createListing_v2(account, listingIndex, sowedPods, listingStart, maxHarvestableIndex); + const createListingId = "podListingCreated-" + createEvent.transaction.hash.toHexString() + "-" + createEvent.logIndex.toString(); + assert.fieldEquals("PodListingCreated", createListingId, "placeInLine", placeInLine.toString()); + + // Line advances 1m before fill + let newHarvestable = currentHarvestable.plus(podlineMil_BI(1)); + setHarvestable(newHarvestable); + placeInLine = placeInLine.minus(podlineMil_BI(1)); + const filledPods = listedPods.div(BigInt.fromString("4")); + const filledBeans = beans_BI(2000); + const fillEvent = fillListing_v2(account, account2, listingIndex, listingStart, filledPods, filledBeans); + const fillListingId = "podListingFilled-" + fillEvent.transaction.hash.toHexString() + "-" + fillEvent.logIndex.toString(); + assert.fieldEquals("PodListingFilled", fillListingId, "placeInLine", placeInLine.toString()); + assert.fieldEquals("PodFill", getPodFillId(listingIndex, fillEvent), "placeInLine", placeInLine.toString()); + + placeInLine = placeInLine.plus(filledPods); + const newListingIndex = fillEvent.params.index.plus(listingStart).plus(filledPods); + const cancelListingEvent = cancelListing(account, newListingIndex); + const cancelListingId = + "podListingCancelled-" + cancelListingEvent.transaction.hash.toHexString() + "-" + cancelListingEvent.logIndex.toString(); + assert.fieldEquals("PodListingCancelled", cancelListingId, "placeInLine", placeInLine.toString()); + + // Test order fill + const orderPlotIndex = podlineMil_BI(15); + const orderedPods = orderBeans.times(BigInt.fromU32(1000000)).div(orderPricePerPod); + sow(account2, orderPlotIndex, sowedBeans, orderedPods); + placeInLine = orderPlotIndex.minus(newHarvestable); + + createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); + const fillOrderEvent = fillOrder_v2(account2, account, orderId, orderPlotIndex, ZERO_BI, orderedPods, orderBeans); + const fillOrderId = "podOrderFilled-" + fillOrderEvent.transaction.hash.toHexString() + "-" + fillOrderEvent.logIndex.toString(); + assert.fieldEquals("PodOrderFilled", fillOrderId, "placeInLine", placeInLine.toString()); + assert.fieldEquals("PodFill", getPodFillId(orderPlotIndex, fillOrderEvent), "placeInLine", placeInLine.toString()); + }); + + describe("Listing tests", () => { beforeEach(() => { createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); }); test("Fill listing - full", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledBeans = beans_BI(7000); const event = fillListing_v2(account, account2, listingIndex, listingStart, listedPods, filledBeans); @@ -125,7 +165,6 @@ describe("Marketplace", () => { }); test("Fill listing - partial, then full", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = beans_BI(2000); @@ -187,7 +226,6 @@ describe("Marketplace", () => { }); test("Cancel listing - partial", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = beans_BI(2000); @@ -216,7 +254,6 @@ describe("Marketplace", () => { }); test("Recreate listing", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); cancelListing(account, listingIndex); const listEvent = createListing_v2(account, listingIndex, sowedPods, listingStart, maxHarvestableIndex); @@ -272,7 +309,6 @@ describe("Marketplace", () => { }); test("Listing expires due to moving podline", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const listingID = account + "-" + listingIndex.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -320,7 +356,6 @@ describe("Marketplace", () => { }); test("Listing expires due to plot harvesting", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); const listingID = account + "-" + listingIndex.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -337,7 +372,6 @@ describe("Marketplace", () => { }); test("Cancel expired/nonexistent listing", () => { - const listingStart = beans_BI(500); const listedPods = sowedPods.minus(listingStart); setHarvestable(maxHarvestableIndex.plus(ONE_BI)); const listingID = account + "-" + listingIndex.toString(); @@ -351,7 +385,7 @@ describe("Marketplace", () => { }); }); - describe("Tests requiring Order", () => { + describe("Order tests", () => { beforeEach(() => { createOrder_v2(account, orderId, orderBeans, orderPricePerPod, maxHarvestableIndex); }); From dd471f5084be377b10c633d526f4d6cabc1410ed Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 15 May 2024 18:19:29 -0700 Subject: [PATCH 48/89] reorder transfer --- projects/subgraph-beanstalk/tests/utils/Marketplace.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index ee8c0b8369..10fd2285a1 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -61,12 +61,12 @@ export function fillListing_v1( podAmount: BigInt, pricePerPod: BigInt ): PodListingFilled_v1 { - const event = createPodListingFilledEvent(from, to, listingIndex, listingStart, podAmount); - handlePodListingFilled(event); - // Perform plot transfer transferPlot(from, to, listingIndex.plus(listingStart), podAmount); + const event = createPodListingFilledEvent(from, to, listingIndex, listingStart, podAmount); + handlePodListingFilled(event); + // Assert PodFill const podFillId = getPodFillId(event.params.index, event); assert.fieldEquals("PodFill", podFillId, "listing", event.params.from.toHexString() + "-" + event.params.index.toString()); From 90337aaed879fd6f67e5beb31b7cf126b6c75456 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Thu, 16 May 2024 12:51:32 -0700 Subject: [PATCH 49/89] plot source tests --- projects/subgraph-beanstalk/schema.graphql | 12 +++--- .../subgraph-beanstalk/src/FieldHandler.ts | 31 ++++++++------ .../src/MarketplaceHandler.ts | 1 - projects/subgraph-beanstalk/src/utils/Plot.ts | 8 ++-- .../tests/PlotTransfer.test.ts | 42 +++++++++++++------ 5 files changed, 59 insertions(+), 35 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 4131008c9d..206c14ce74 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -678,22 +678,22 @@ type Plot @entity { createdAt: BigInt! "Timestamp when updated" updatedAt: BigInt! + "Block when updated" + updatedAtBlock: BigInt! "Plot Index" index: BigInt! - "Beans used to sow, if any" - beans: BigInt! "Total pods in plot" pods: BigInt! - "Total pods that were sown, if any" - sownPods: BigInt! - "Temperature when the plot was sown" - temperature: Int! + "Number of beans spent for each pod, whether through sowing or on the marketplace" + beansPerPod: BigInt! "Number of pods harvestable" harvestablePods: BigInt! "Number of pods harvested" harvestedPods: BigInt! "Flag for if plot is fully harvested" fullyHarvested: Boolean! + "This field is required for correct indexing but has no meaning externally. Do not reference." + internalUseOnly: String! } type PodMarketplace @entity { diff --git a/projects/subgraph-beanstalk/src/FieldHandler.ts b/projects/subgraph-beanstalk/src/FieldHandler.ts index eb96592812..dee599388c 100644 --- a/projects/subgraph-beanstalk/src/FieldHandler.ts +++ b/projects/subgraph-beanstalk/src/FieldHandler.ts @@ -11,7 +11,7 @@ import { } from "../generated/Field/Beanstalk"; import { Harvest as HarvestEntity } from "../generated/schema"; import { BEANSTALK, BEANSTALK_FARMS } from "../../subgraph-core/utils/Constants"; -import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { BI_10, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { loadFarmer } from "./utils/Farmer"; import { handleRateChange, loadField, loadFieldDaily, loadFieldHourly } from "./utils/Field"; import { loadPlot } from "./utils/Plot"; @@ -77,10 +77,9 @@ export function handleSow(event: Sow): void { plot.creationHash = event.transaction.hash.toHexString(); plot.createdAt = event.block.timestamp; plot.updatedAt = event.block.timestamp; - plot.beans = event.params.beans; + plot.updatedAtBlock = event.block.number; plot.pods = event.params.pods; - plot.sownPods = event.params.pods; - plot.temperature = field.temperature; + plot.beansPerPod = event.params.beans.times(BI_10.pow(6)).div(plot.pods); plot.save(); // Increment protocol amounts @@ -176,10 +175,10 @@ export function handleHarvest(event: Harvest): void { remainingPlot.creationHash = event.transaction.hash.toHexString(); remainingPlot.createdAt = event.block.timestamp; remainingPlot.updatedAt = event.block.timestamp; + remainingPlot.updatedAtBlock = event.block.number; remainingPlot.index = remainingIndex; - remainingPlot.beans = ZERO_BI; remainingPlot.pods = remainingPods; - remainingPlot.temperature = plot.temperature; + remainingPlot.beansPerPod = plot.beansPerPod; remainingPlot.save(); plot.harvestedPods = harvestablePods; @@ -307,7 +306,9 @@ export function handlePlotTransfer(event: PlotTransfer): void { if (sourcePlot.pods == event.params.pods) { // Sending full plot sourcePlot.farmer = event.params.to.toHexString(); + sourcePlot.source = "TRANSFER"; sourcePlot.updatedAt = event.block.timestamp; + sourcePlot.updatedAtBlock = event.block.number; sourcePlot.save(); // log.debug("\nPodTransfer: Sending full plot\n", []); } else if (sourceIndex == event.params.id) { @@ -318,21 +319,26 @@ export function handlePlotTransfer(event: PlotTransfer): void { sortedPlots.push(remainderIndex); sourcePlot.farmer = event.params.to.toHexString(); + sourcePlot.source = "TRANSFER"; sourcePlot.updatedAt = event.block.timestamp; + sourcePlot.updatedAtBlock = event.block.number; sourcePlot.pods = event.params.pods; sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); remainderPlot.farmer = event.params.from.toHexString(); - remainderPlot.source = "TRANSFER"; remainderPlot.season = field.season; remainderPlot.creationHash = event.transaction.hash.toHexString(); remainderPlot.createdAt = event.block.timestamp; remainderPlot.updatedAt = event.block.timestamp; + remainderPlot.updatedAtBlock = event.block.number; remainderPlot.index = remainderIndex; remainderPlot.pods = sourceEndIndex.minus(transferEndIndex); remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, currentHarvestable); - remainderPlot.temperature = sourcePlot.temperature; + // FIXME: market needs to set these instead, but then its critical that we identify if its a market transfer.. + // if market doesnt set it for the remainder, then this would pull the one the market did update for source. + // in the case where its not a market transfer, then we do need to set it here + remainderPlot.beansPerPod = sourcePlot.beansPerPod; remainderPlot.save(); // log.debug("\nPodTransfer: sourceIndex == transferIndex\n", []); @@ -346,6 +352,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { sortedPlots.push(event.params.id); sourcePlot.updatedAt = event.block.timestamp; + sourcePlot.updatedAtBlock = event.block.number; sourcePlot.pods = sourcePlot.pods.minus(event.params.pods); sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); @@ -356,10 +363,10 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.creationHash = event.transaction.hash.toHexString(); toPlot.createdAt = event.block.timestamp; toPlot.updatedAt = event.block.timestamp; + toPlot.updatedAtBlock = event.block.number; toPlot.index = event.params.id; toPlot.pods = event.params.pods; toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); - toPlot.temperature = sourcePlot.temperature; toPlot.save(); // log.debug("\nPodTransfer: sourceEndIndex == transferEndIndex\n", []); @@ -374,6 +381,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { sortedPlots.push(remainderIndex); sourcePlot.updatedAt = event.block.timestamp; + sourcePlot.updatedAtBlock = event.block.number; sourcePlot.pods = event.params.id.minus(sourcePlot.index); sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); @@ -384,22 +392,21 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.creationHash = event.transaction.hash.toHexString(); toPlot.createdAt = event.block.timestamp; toPlot.updatedAt = event.block.timestamp; + toPlot.updatedAtBlock = event.block.number; toPlot.index = event.params.id; toPlot.pods = event.params.pods; toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); - toPlot.temperature = sourcePlot.temperature; toPlot.save(); remainderPlot.farmer = event.params.from.toHexString(); - remainderPlot.source = "TRANSFER"; remainderPlot.season = field.season; remainderPlot.creationHash = event.transaction.hash.toHexString(); remainderPlot.createdAt = event.block.timestamp; remainderPlot.updatedAt = event.block.timestamp; + remainderPlot.updatedAtBlock = event.block.number; remainderPlot.index = remainderIndex; remainderPlot.pods = sourceEndIndex.minus(transferEndIndex); remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, currentHarvestable); - remainderPlot.temperature = sourcePlot.temperature; remainderPlot.save(); // log.debug("\nPodTransfer: split source twice\n", []); diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 2f4a4bbda4..f80487d39a 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -28,7 +28,6 @@ import { } from "../generated/schema"; import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { loadFarmer } from "./utils/Farmer"; -import { loadPlot } from "./utils/Plot"; import { loadPodFill } from "./utils/PodFill"; import { createHistoricalPodListing, loadPodListing } from "./utils/PodListing"; import { diff --git a/projects/subgraph-beanstalk/src/utils/Plot.ts b/projects/subgraph-beanstalk/src/utils/Plot.ts index b6bcb2b4b1..919108562e 100644 --- a/projects/subgraph-beanstalk/src/utils/Plot.ts +++ b/projects/subgraph-beanstalk/src/utils/Plot.ts @@ -10,19 +10,19 @@ export function loadPlot(diamondAddress: Address, index: BigInt): Plot { plot = new Plot(index.toString()); plot.field = diamondAddress.toHexString(); plot.farmer = ADDRESS_ZERO.toHexString(); - plot.source = "SOW"; // Assume new plots come from sowing + plot.source = "SOW"; // Should be overwritten in case of a transfer creating a new plot plot.season = 0; plot.creationHash = ""; plot.createdAt = ZERO_BI; plot.updatedAt = ZERO_BI; + plot.updatedAtBlock = ZERO_BI; plot.index = index; - plot.beans = ZERO_BI; plot.pods = ZERO_BI; - plot.sownPods = ZERO_BI; - plot.temperature = 0; + plot.beansPerPod = ZERO_BI; plot.harvestablePods = ZERO_BI; plot.harvestedPods = ZERO_BI; plot.fullyHarvested = false; + plot.internalUseOnly = ""; plot.save(); let field = loadField(diamondAddress); diff --git a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts index 7d41cc044c..50cea49854 100644 --- a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts +++ b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts @@ -99,6 +99,11 @@ describe("Field: Plot Transfer", () => { assertFieldHas(ANVIL_ADDR_2, initialPlots[0].pods.minus(harvestableAmount), harvestableAmount); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.minus(harvestableAmount).plus(initialPlots[1].pods), harvestableAmount); }); + + test("F: Plot Source", () => { + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "TRANSFER"); + }); }); // Transfers the first third of the plot @@ -152,6 +157,14 @@ describe("Field: Plot Transfer", () => { assertFieldHas(ANVIL_ADDR_2, transferredUnharvestable, harvestableAmount); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.minus(harvestableAmount).plus(initialPlots[1].pods), harvestableAmount); }); + + test("S: Plot Source", () => { + const transferredIndex = initialPlots[0].plotStart; + const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "TRANSFER"); + assert.fieldEquals("Plot", transferredIndex.plus(transferredAmount).toString(), "source", "SOW"); + }); }); // Transfers the final third of the plot @@ -209,6 +222,14 @@ describe("Field: Plot Transfer", () => { assertFieldHas(ANVIL_ADDR_2, initialPlots[0].pods.minus(harvestableAmount), transferredHarvestable); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.minus(harvestableAmount).plus(initialPlots[1].pods), harvestableAmount); }); + + test("E: Plot Source", () => { + const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); + const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); + assert.fieldEquals("Plot", transferredIndex.toString(), "source", "TRANSFER"); + }); }); // Transfers the middle third of the plot @@ -263,17 +284,14 @@ describe("Field: Plot Transfer", () => { assertFieldHas(ANVIL_ADDR_2, transferredHarvestable, transferredHarvestable); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.plus(initialPlots[1].pods).minus(harvestableAmount), harvestableAmount); }); - }); - // Unclear whether tests like this are actually necessary - // describe("Invalid Transfers", () => { - // test("Too Many", () => { - // // Try to send 1/10^6 more pods. - // handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods.plus(BigInt.fromI32(1)))); - // }); - // test("Unowned Plot", () => { - // // Try to send someone else's plot - // handlePlotTransfer(createPlotTransferEvent(ANVIL_ADDR_2, ANVIL_ADDR_1, initialPlots[0].plotStart, initialPlots[0].pods)); - // }); - // }); + test("M: Plot Source", () => { + const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); + const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); + transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); + assert.fieldEquals("Plot", transferredIndex.toString(), "source", "TRANSFER"); + assert.fieldEquals("Plot", transferredIndex.plus(transferredAmount).toString(), "source", "SOW"); + }); + }); }); From 65c8d9ee8a181ee680380e221f7d7b87b4d6796e Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Thu, 16 May 2024 15:34:47 -0700 Subject: [PATCH 50/89] sow and plot source test --- projects/subgraph-beanstalk/schema.graphql | 8 +++-- .../subgraph-beanstalk/src/FieldHandler.ts | 21 +++++++++--- projects/subgraph-beanstalk/src/utils/Plot.ts | 1 + .../subgraph-beanstalk/tests/Field.test.ts | 33 +++++++++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 projects/subgraph-beanstalk/tests/Field.test.ts diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 206c14ce74..bc65df4dfe 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -11,8 +11,8 @@ enum MarketStatus { enum PlotSource { SOW - HARVEST TRANSFER + MARKET } enum EmaWindow { @@ -666,13 +666,15 @@ type Plot @entity { field: Field! "Farmer who owns this plot" farmer: Farmer! - "Transaction source for this plot" + "Transaction source for this plot. Not the same as creationHash which can include plots splitting from transfer or harvest without the owner changing" source: PlotSource! + "Transaction hash corresponding to source" + sourceHash: String! "Associated plot listing" listing: PodListing "Season when created" season: Int! - "Creation transaction hash" + "Transaction hash of when this plot entity was created" creationHash: String! "Timestamp of creation" createdAt: BigInt! diff --git a/projects/subgraph-beanstalk/src/FieldHandler.ts b/projects/subgraph-beanstalk/src/FieldHandler.ts index dee599388c..4c4c2546e0 100644 --- a/projects/subgraph-beanstalk/src/FieldHandler.ts +++ b/projects/subgraph-beanstalk/src/FieldHandler.ts @@ -73,6 +73,7 @@ export function handleSow(event: Sow): void { plot.farmer = event.params.account.toHexString(); plot.source = "SOW"; + plot.sourceHash = event.transaction.hash.toHexString(); plot.season = field.season; plot.creationHash = event.transaction.hash.toHexString(); plot.createdAt = event.block.timestamp; @@ -170,7 +171,8 @@ export function handleHarvest(event: Harvest): void { let remainingPlot = loadPlot(event.address, remainingIndex); remainingPlot.farmer = plot.farmer; - remainingPlot.source = "HARVEST"; + remainingPlot.source = plot.source; + remainingPlot.sourceHash = plot.sourceHash; remainingPlot.season = beanstalk.lastSeason; remainingPlot.creationHash = event.transaction.hash.toHexString(); remainingPlot.createdAt = event.block.timestamp; @@ -307,6 +309,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { // Sending full plot sourcePlot.farmer = event.params.to.toHexString(); sourcePlot.source = "TRANSFER"; + sourcePlot.sourceHash = event.transaction.hash.toHexString(); sourcePlot.updatedAt = event.block.timestamp; sourcePlot.updatedAtBlock = event.block.number; sourcePlot.save(); @@ -318,8 +321,12 @@ export function handlePlotTransfer(event: PlotTransfer): void { let remainderPlot = loadPlot(event.address, remainderIndex); sortedPlots.push(remainderIndex); + const originalSource = sourcePlot.source; + const originalSourceHash = sourcePlot.sourceHash; + sourcePlot.farmer = event.params.to.toHexString(); sourcePlot.source = "TRANSFER"; + sourcePlot.sourceHash = event.transaction.hash.toHexString(); sourcePlot.updatedAt = event.block.timestamp; sourcePlot.updatedAtBlock = event.block.number; sourcePlot.pods = event.params.pods; @@ -327,6 +334,8 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.save(); remainderPlot.farmer = event.params.from.toHexString(); + remainderPlot.source = originalSource; + remainderPlot.sourceHash = originalSourceHash; remainderPlot.season = field.season; remainderPlot.creationHash = event.transaction.hash.toHexString(); remainderPlot.createdAt = event.block.timestamp; @@ -335,9 +344,6 @@ export function handlePlotTransfer(event: PlotTransfer): void { remainderPlot.index = remainderIndex; remainderPlot.pods = sourceEndIndex.minus(transferEndIndex); remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, currentHarvestable); - // FIXME: market needs to set these instead, but then its critical that we identify if its a market transfer.. - // if market doesnt set it for the remainder, then this would pull the one the market did update for source. - // in the case where its not a market transfer, then we do need to set it here remainderPlot.beansPerPod = sourcePlot.beansPerPod; remainderPlot.save(); @@ -359,6 +365,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.farmer = event.params.to.toHexString(); toPlot.source = "TRANSFER"; + toPlot.sourceHash = event.transaction.hash.toHexString(); toPlot.season = field.season; toPlot.creationHash = event.transaction.hash.toHexString(); toPlot.createdAt = event.block.timestamp; @@ -367,6 +374,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.index = event.params.id; toPlot.pods = event.params.pods; toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); + toPlot.beansPerPod = sourcePlot.beansPerPod; toPlot.save(); // log.debug("\nPodTransfer: sourceEndIndex == transferEndIndex\n", []); @@ -388,6 +396,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.farmer = event.params.to.toHexString(); toPlot.source = "TRANSFER"; + toPlot.sourceHash = event.transaction.hash.toHexString(); toPlot.season = field.season; toPlot.creationHash = event.transaction.hash.toHexString(); toPlot.createdAt = event.block.timestamp; @@ -396,9 +405,12 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.index = event.params.id; toPlot.pods = event.params.pods; toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); + toPlot.beansPerPod = sourcePlot.beansPerPod; toPlot.save(); remainderPlot.farmer = event.params.from.toHexString(); + remainderPlot.source = sourcePlot.source; + remainderPlot.sourceHash = sourcePlot.sourceHash; remainderPlot.season = field.season; remainderPlot.creationHash = event.transaction.hash.toHexString(); remainderPlot.createdAt = event.block.timestamp; @@ -407,6 +419,7 @@ export function handlePlotTransfer(event: PlotTransfer): void { remainderPlot.index = remainderIndex; remainderPlot.pods = sourceEndIndex.minus(transferEndIndex); remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, currentHarvestable); + remainderPlot.beansPerPod = sourcePlot.beansPerPod; remainderPlot.save(); // log.debug("\nPodTransfer: split source twice\n", []); diff --git a/projects/subgraph-beanstalk/src/utils/Plot.ts b/projects/subgraph-beanstalk/src/utils/Plot.ts index 919108562e..100e063cd8 100644 --- a/projects/subgraph-beanstalk/src/utils/Plot.ts +++ b/projects/subgraph-beanstalk/src/utils/Plot.ts @@ -11,6 +11,7 @@ export function loadPlot(diamondAddress: Address, index: BigInt): Plot { plot.field = diamondAddress.toHexString(); plot.farmer = ADDRESS_ZERO.toHexString(); plot.source = "SOW"; // Should be overwritten in case of a transfer creating a new plot + plot.sourceHash = ""; plot.season = 0; plot.creationHash = ""; plot.createdAt = ZERO_BI; diff --git a/projects/subgraph-beanstalk/tests/Field.test.ts b/projects/subgraph-beanstalk/tests/Field.test.ts new file mode 100644 index 0000000000..9697462384 --- /dev/null +++ b/projects/subgraph-beanstalk/tests/Field.test.ts @@ -0,0 +1,33 @@ +/// + +import { afterEach, assert, clearStore, describe, test } from "matchstick-as/assembly/index"; +import { log } from "matchstick-as/assembly/log"; +import { BigInt } from "@graphprotocol/graph-ts"; + +import { BEANSTALK } from "../../subgraph-core/utils/Constants"; +import { BI_10, ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { beans_BI as beans, podlineMil_BI as mil } from "../../subgraph-core/tests/Values"; +import { assertFarmerHasPlot, assertFieldHas, sow } from "./utils/Field"; + +const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); + +const plotStart = mil(10); +const beansSown = beans(500); +const temperature = 15; +const pods = beansSown.times(BigInt.fromI32(temperature)); + +// Begin tests +describe("Field", () => { + afterEach(() => { + clearStore(); + }); + + test("Sow", () => { + sow(account, plotStart, beansSown, pods); + assertFarmerHasPlot(account, plotStart, pods); + assertFieldHas(BEANSTALK.toHexString(), pods, ZERO_BI); + + assert.fieldEquals("Plot", plotStart.toString(), "source", "SOW"); + assert.fieldEquals("Plot", plotStart.toString(), "beansPerPod", BI_10.pow(6).div(BigInt.fromU32(temperature)).toString()); + }); +}); From ae3af6e2246b4bc26ca9118d4db15ed1321f9e28 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Thu, 16 May 2024 16:38:59 -0700 Subject: [PATCH 51/89] set beans per pod after market fill --- projects/subgraph-beanstalk/schema.graphql | 2 - .../subgraph-beanstalk/src/FieldHandler.ts | 44 ++++++++++++------- .../src/MarketplaceHandler.ts | 29 +++++++++++- projects/subgraph-beanstalk/src/utils/Plot.ts | 1 - .../subgraph-beanstalk/tests/Field.test.ts | 3 -- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index bc65df4dfe..27c232b7f4 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -694,8 +694,6 @@ type Plot @entity { harvestedPods: BigInt! "Flag for if plot is fully harvested" fullyHarvested: Boolean! - "This field is required for correct indexing but has no meaning externally. Do not reference." - internalUseOnly: String! } type PodMarketplace @entity { diff --git a/projects/subgraph-beanstalk/src/FieldHandler.ts b/projects/subgraph-beanstalk/src/FieldHandler.ts index 4c4c2546e0..8cdcd270d7 100644 --- a/projects/subgraph-beanstalk/src/FieldHandler.ts +++ b/projects/subgraph-beanstalk/src/FieldHandler.ts @@ -307,9 +307,13 @@ export function handlePlotTransfer(event: PlotTransfer): void { // Actually transfer the plots if (sourcePlot.pods == event.params.pods) { // Sending full plot + const isMarket = sourcePlot.source == "MARKET" && sourcePlot.sourceHash == event.transaction.hash.toHexString(); + if (!isMarket) { + sourcePlot.source = "TRANSFER"; + sourcePlot.sourceHash = event.transaction.hash.toHexString(); + sourcePlot.beansPerPod = sourcePlot.beansPerPod; + } sourcePlot.farmer = event.params.to.toHexString(); - sourcePlot.source = "TRANSFER"; - sourcePlot.sourceHash = event.transaction.hash.toHexString(); sourcePlot.updatedAt = event.block.timestamp; sourcePlot.updatedAtBlock = event.block.number; sourcePlot.save(); @@ -321,12 +325,17 @@ export function handlePlotTransfer(event: PlotTransfer): void { let remainderPlot = loadPlot(event.address, remainderIndex); sortedPlots.push(remainderIndex); - const originalSource = sourcePlot.source; - const originalSourceHash = sourcePlot.sourceHash; - + const isMarket = sourcePlot.source == "MARKET" && sourcePlot.sourceHash == event.transaction.hash.toHexString(); + if (!isMarket) { + sourcePlot.source = "TRANSFER"; + sourcePlot.sourceHash = event.transaction.hash.toHexString(); + sourcePlot.beansPerPod = sourcePlot.beansPerPod; + // When sending the start of the plot via market, these cannot be derived from sourcePlot. + remainderPlot.source = sourcePlot.source; + remainderPlot.sourceHash = sourcePlot.sourceHash; + remainderPlot.beansPerPod = sourcePlot.beansPerPod; + } sourcePlot.farmer = event.params.to.toHexString(); - sourcePlot.source = "TRANSFER"; - sourcePlot.sourceHash = event.transaction.hash.toHexString(); sourcePlot.updatedAt = event.block.timestamp; sourcePlot.updatedAtBlock = event.block.number; sourcePlot.pods = event.params.pods; @@ -334,8 +343,6 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.save(); remainderPlot.farmer = event.params.from.toHexString(); - remainderPlot.source = originalSource; - remainderPlot.sourceHash = originalSourceHash; remainderPlot.season = field.season; remainderPlot.creationHash = event.transaction.hash.toHexString(); remainderPlot.createdAt = event.block.timestamp; @@ -344,7 +351,6 @@ export function handlePlotTransfer(event: PlotTransfer): void { remainderPlot.index = remainderIndex; remainderPlot.pods = sourceEndIndex.minus(transferEndIndex); remainderPlot.harvestablePods = calcHarvestable(remainderPlot.index, remainderPlot.pods, currentHarvestable); - remainderPlot.beansPerPod = sourcePlot.beansPerPod; remainderPlot.save(); // log.debug("\nPodTransfer: sourceIndex == transferIndex\n", []); @@ -363,9 +369,13 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); + const isMarket = toPlot.source == "MARKET" && toPlot.sourceHash == event.transaction.hash.toHexString(); + if (!isMarket) { + toPlot.source = "TRANSFER"; + toPlot.sourceHash = event.transaction.hash.toHexString(); + toPlot.beansPerPod = sourcePlot.beansPerPod; + } toPlot.farmer = event.params.to.toHexString(); - toPlot.source = "TRANSFER"; - toPlot.sourceHash = event.transaction.hash.toHexString(); toPlot.season = field.season; toPlot.creationHash = event.transaction.hash.toHexString(); toPlot.createdAt = event.block.timestamp; @@ -374,7 +384,6 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.index = event.params.id; toPlot.pods = event.params.pods; toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); - toPlot.beansPerPod = sourcePlot.beansPerPod; toPlot.save(); // log.debug("\nPodTransfer: sourceEndIndex == transferEndIndex\n", []); @@ -394,9 +403,13 @@ export function handlePlotTransfer(event: PlotTransfer): void { sourcePlot.harvestablePods = calcHarvestable(sourcePlot.index, sourcePlot.pods, currentHarvestable); sourcePlot.save(); + const isMarket = toPlot.source == "MARKET" && toPlot.sourceHash == event.transaction.hash.toHexString(); + if (!isMarket) { + toPlot.source = "TRANSFER"; + toPlot.sourceHash = event.transaction.hash.toHexString(); + toPlot.beansPerPod = sourcePlot.beansPerPod; + } toPlot.farmer = event.params.to.toHexString(); - toPlot.source = "TRANSFER"; - toPlot.sourceHash = event.transaction.hash.toHexString(); toPlot.season = field.season; toPlot.creationHash = event.transaction.hash.toHexString(); toPlot.createdAt = event.block.timestamp; @@ -405,7 +418,6 @@ export function handlePlotTransfer(event: PlotTransfer): void { toPlot.index = event.params.id; toPlot.pods = event.params.pods; toPlot.harvestablePods = calcHarvestable(toPlot.index, toPlot.pods, currentHarvestable); - toPlot.beansPerPod = sourcePlot.beansPerPod; toPlot.save(); remainderPlot.farmer = event.params.from.toHexString(); diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index f80487d39a..631b0272f5 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -26,7 +26,7 @@ import { PodOrder, PodListing } from "../generated/schema"; -import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { BI_10, ZERO_BI } from "../../subgraph-core/utils/Decimals"; import { loadFarmer } from "./utils/Farmer"; import { loadPodFill } from "./utils/PodFill"; import { createHistoricalPodListing, loadPodListing } from "./utils/PodListing"; @@ -39,6 +39,7 @@ import { } from "./utils/PodMarketplace"; import { createHistoricalPodOrder, loadPodOrder } from "./utils/PodOrder"; import { getHarvestableIndex } from "./utils/Season"; +import { loadPlot } from "./utils/Plot"; class PodListingCreatedParams { event: ethereum.Event; @@ -465,6 +466,8 @@ function podListingFilled(params: MarketFillParams): void { listing.fill = fill.id; listing.save(); + setBeansPerPodAfterFill(params.event, fill.index, fill.start, fill.amount, fill.costInBeans); + // Save the raw event data let id = "podListingFilled-" + params.event.transaction.hash.toHexString() + "-" + params.event.logIndex.toString(); let rawEvent = new PodListingFilledEvent(id); @@ -555,6 +558,8 @@ function podOrderFilled(params: MarketFillParams): void { fill.costInBeans = params.costInBeans; fill.save(); + setBeansPerPodAfterFill(params.event, fill.index, fill.start, fill.amount, fill.costInBeans); + if (order.status == "FILLED") { updateActiveOrders(params.event.address, MarketplaceAction.FILLED_FULL, order.id, order.maxPlaceInLine); } @@ -579,3 +584,25 @@ function podOrderFilled(params: MarketFillParams): void { rawEvent.createdAt = params.event.block.timestamp; rawEvent.save(); } + +function setBeansPerPodAfterFill(event: ethereum.Event, plotIndex: BigInt, start: BigInt, length: BigInt, costInBeans: BigInt): void { + // Load the plot that is being sent. It may or may not have been created already, depending + // on whether the PlotTransfer event has already been processed (sometims its emitted after the market transfer). + let fillPlot = loadPlot(event.address, plotIndex.plus(start)); + + if (start == ZERO_BI) { + // When sending the start of a plot via market, these cannot be set in any subsequent transfer, + // since the start plot has already been modified. + let remainderPlot = loadPlot(event.address, plotIndex.plus(length)); + remainderPlot.sourceHash = fillPlot.sourceHash; + remainderPlot.beansPerPod = fillPlot.beansPerPod; + remainderPlot.source = fillPlot.source; + remainderPlot.save(); + } + + // Update source/cost per pod of the sold plot + fillPlot.beansPerPod = costInBeans.times(BI_10.pow(6)).div(length); + fillPlot.source = "MARKET"; + fillPlot.sourceHash = event.transaction.hash.toHexString(); + fillPlot.save(); +} diff --git a/projects/subgraph-beanstalk/src/utils/Plot.ts b/projects/subgraph-beanstalk/src/utils/Plot.ts index 100e063cd8..8e97468e9c 100644 --- a/projects/subgraph-beanstalk/src/utils/Plot.ts +++ b/projects/subgraph-beanstalk/src/utils/Plot.ts @@ -23,7 +23,6 @@ export function loadPlot(diamondAddress: Address, index: BigInt): Plot { plot.harvestablePods = ZERO_BI; plot.harvestedPods = ZERO_BI; plot.fullyHarvested = false; - plot.internalUseOnly = ""; plot.save(); let field = loadField(diamondAddress); diff --git a/projects/subgraph-beanstalk/tests/Field.test.ts b/projects/subgraph-beanstalk/tests/Field.test.ts index 9697462384..a5b4687336 100644 --- a/projects/subgraph-beanstalk/tests/Field.test.ts +++ b/projects/subgraph-beanstalk/tests/Field.test.ts @@ -1,7 +1,4 @@ -/// - import { afterEach, assert, clearStore, describe, test } from "matchstick-as/assembly/index"; -import { log } from "matchstick-as/assembly/log"; import { BigInt } from "@graphprotocol/graph-ts"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; From cea6a46634b1968aec12eba9b1acf16073226ae1 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Thu, 16 May 2024 17:09:09 -0700 Subject: [PATCH 52/89] market transfer middle test --- projects/subgraph-beanstalk/schema.graphql | 2 +- .../subgraph-beanstalk/src/FieldHandler.ts | 7 +- .../subgraph-beanstalk/src/utils/PodFill.ts | 1 + .../tests/MarketplaceV1.test.ts | 20 +- .../tests/MarketplaceV2.test.ts | 15 +- .../tests/PlotTransfer.test.ts | 196 +++++++++++------- .../tests/utils/Marketplace.ts | 20 +- 7 files changed, 151 insertions(+), 110 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 27c232b7f4..fc5eb2a55b 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -1160,7 +1160,7 @@ type PodFill @entity { "Start of plot transferred" start: BigInt! "Total beans used to fill listing/order" - costInBeans: BigInt + costInBeans: BigInt! } ################################## diff --git a/projects/subgraph-beanstalk/src/FieldHandler.ts b/projects/subgraph-beanstalk/src/FieldHandler.ts index 8cdcd270d7..5c16d48342 100644 --- a/projects/subgraph-beanstalk/src/FieldHandler.ts +++ b/projects/subgraph-beanstalk/src/FieldHandler.ts @@ -327,13 +327,14 @@ export function handlePlotTransfer(event: PlotTransfer): void { const isMarket = sourcePlot.source == "MARKET" && sourcePlot.sourceHash == event.transaction.hash.toHexString(); if (!isMarket) { - sourcePlot.source = "TRANSFER"; - sourcePlot.sourceHash = event.transaction.hash.toHexString(); - sourcePlot.beansPerPod = sourcePlot.beansPerPod; // When sending the start of the plot via market, these cannot be derived from sourcePlot. remainderPlot.source = sourcePlot.source; remainderPlot.sourceHash = sourcePlot.sourceHash; remainderPlot.beansPerPod = sourcePlot.beansPerPod; + + sourcePlot.source = "TRANSFER"; + sourcePlot.sourceHash = event.transaction.hash.toHexString(); + sourcePlot.beansPerPod = sourcePlot.beansPerPod; } sourcePlot.farmer = event.params.to.toHexString(); sourcePlot.updatedAt = event.block.timestamp; diff --git a/projects/subgraph-beanstalk/src/utils/PodFill.ts b/projects/subgraph-beanstalk/src/utils/PodFill.ts index 08382de1f4..6f1f3bcad6 100644 --- a/projects/subgraph-beanstalk/src/utils/PodFill.ts +++ b/projects/subgraph-beanstalk/src/utils/PodFill.ts @@ -15,6 +15,7 @@ export function loadPodFill(diamondAddress: Address, index: BigInt, hash: String fill.amount = ZERO_BI; fill.index = ZERO_BI; fill.start = ZERO_BI; + fill.costInBeans = ZERO_BI; fill.save(); } return fill; diff --git a/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts b/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts index 037818ca74..d80d09f8c0 100644 --- a/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts +++ b/projects/subgraph-beanstalk/tests/MarketplaceV1.test.ts @@ -78,8 +78,8 @@ describe("Marketplace", () => { }); test("Create a pod listing - partial plot", () => { - const event = createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); - const listedPods = sowedPods.minus(beans_BI(500)); + const listedPods = sowedPods.minus(listingStart); + const event = createListing_v1(account, listingIndex, listedPods, listingStart, listingPricePerPod, maxHarvestableIndex); assertMarketListingsState( BEANSTALK.toHexString(), [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], @@ -94,8 +94,8 @@ describe("Marketplace", () => { }); test("Create a pod listing - partial plot", () => { - const event = createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); - const listedPods = sowedPods.minus(beans_BI(500)); + const listedPods = sowedPods.minus(listingStart); + const event = createListing_v1(account, listingIndex, listedPods, listingStart, listingPricePerPod, maxHarvestableIndex); assertMarketListingsState( BEANSTALK.toHexString(), [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], @@ -127,7 +127,7 @@ describe("Marketplace", () => { test("Market events correctly track place in line", () => { let placeInLine = listingIndex.plus(listingStart).minus(currentHarvestable); const listedPods = sowedPods.minus(listingStart); - const createEvent = createListing_v1(account, listingIndex, sowedPods, listingStart, listingPricePerPod, maxHarvestableIndex); + const createEvent = createListing_v1(account, listingIndex, listedPods, listingStart, listingPricePerPod, maxHarvestableIndex); const createListingId = "podListingCreated-" + createEvent.transaction.hash.toHexString() + "-" + createEvent.logIndex.toString(); assert.fieldEquals("PodListingCreated", createListingId, "placeInLine", placeInLine.toString()); @@ -164,7 +164,7 @@ describe("Marketplace", () => { describe("Tests requiring Listing", () => { beforeEach(() => { - createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); + createListing_v1(account, listingIndex, sowedPods.minus(beans_BI(500)), beans_BI(500), listingPricePerPod, maxHarvestableIndex); }); test("Fill listing - full", () => { @@ -294,7 +294,7 @@ describe("Marketplace", () => { test("Recreate listing", () => { const listedPods = sowedPods.minus(listingStart); cancelListing(account, listingIndex); - const listEvent = createListing_v1(account, listingIndex, sowedPods, listingStart, listingPricePerPod, maxHarvestableIndex); + const listEvent = createListing_v1(account, listingIndex, listedPods, listingStart, listingPricePerPod, maxHarvestableIndex); const listingID = listEvent.params.account.toHexString() + "-" + listEvent.params.index.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -363,7 +363,7 @@ describe("Marketplace", () => { // Test expiration after a partial sale setHarvestable(maxHarvestableIndex); - createListing_v1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); + createListing_v1(account, listingIndex, listedPods, listingStart, listingPricePerPod, maxHarvestableIndex); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = filledPods.times(listingPricePerPod).div(BI_10.pow(6)); @@ -649,8 +649,8 @@ describe("Marketplace", () => { }); test("Create a pod listing - partial plot", () => { - const event = createListing_v1_1(account, listingIndex, sowedPods, beans_BI(500), listingPricePerPod, maxHarvestableIndex); - const listedPods = sowedPods.minus(beans_BI(500)); + const listedPods = sowedPods.minus(listingStart); + const event = createListing_v1_1(account, listingIndex, listedPods, listingStart, listingPricePerPod, maxHarvestableIndex); assertMarketListingsState( BEANSTALK.toHexString(), [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], diff --git a/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts b/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts index 9cf9dc8871..80605ffd0f 100644 --- a/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts +++ b/projects/subgraph-beanstalk/tests/MarketplaceV2.test.ts @@ -24,7 +24,8 @@ const listingStart = beans_BI(500); const currentHarvestable = podlineMil_BI(4); const maxHarvestableIndex = podlineMil_BI(100); const sowedBeans = beans_BI(5000); -const sowedPods = sowedBeans.times(BigInt.fromString("3")); +const temperature = 37; +const sowedPods = sowedBeans.times(BigInt.fromU32(temperature)); const orderBeans = beans_BI(80000); const orderPricePerPod = BigInt.fromString("500000"); // 0.5 beans @@ -76,8 +77,8 @@ describe("Marketplace", () => { }); test("Create a pod listing - partial plot", () => { - const event = createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); - const listedPods = sowedPods.minus(beans_BI(500)); + const listedPods = sowedPods.minus(listingStart); + const event = createListing_v2(account, listingIndex, listedPods, listingStart, maxHarvestableIndex); assertMarketListingsState( BEANSTALK.toHexString(), [account + "-" + listingIndex.toString() + "-" + maxHarvestableIndex.toString()], @@ -109,7 +110,7 @@ describe("Marketplace", () => { test("Market events correctly track place in line", () => { let placeInLine = listingIndex.plus(listingStart).minus(currentHarvestable); const listedPods = sowedPods.minus(listingStart); - const createEvent = createListing_v2(account, listingIndex, sowedPods, listingStart, maxHarvestableIndex); + const createEvent = createListing_v2(account, listingIndex, listedPods, listingStart, maxHarvestableIndex); const createListingId = "podListingCreated-" + createEvent.transaction.hash.toHexString() + "-" + createEvent.logIndex.toString(); assert.fieldEquals("PodListingCreated", createListingId, "placeInLine", placeInLine.toString()); @@ -146,7 +147,7 @@ describe("Marketplace", () => { describe("Listing tests", () => { beforeEach(() => { - createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); + createListing_v2(account, listingIndex, sowedPods.minus(beans_BI(500)), beans_BI(500), maxHarvestableIndex); }); test("Fill listing - full", () => { @@ -256,7 +257,7 @@ describe("Marketplace", () => { test("Recreate listing", () => { const listedPods = sowedPods.minus(listingStart); cancelListing(account, listingIndex); - const listEvent = createListing_v2(account, listingIndex, sowedPods, listingStart, maxHarvestableIndex); + const listEvent = createListing_v2(account, listingIndex, listedPods, listingStart, maxHarvestableIndex); const listingID = listEvent.params.account.toHexString() + "-" + listEvent.params.index.toString(); assert.fieldEquals("PodListing", listingID, "status", "ACTIVE"); @@ -325,7 +326,7 @@ describe("Marketplace", () => { // Test expiration after a partial sale setHarvestable(maxHarvestableIndex); - createListing_v2(account, listingIndex, sowedPods, beans_BI(500), maxHarvestableIndex); + createListing_v2(account, listingIndex, listedPods, listingStart, maxHarvestableIndex); const filledPods = listedPods.div(BigInt.fromString("4")); const filledBeans = beans_BI(2000); diff --git a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts index 50cea49854..f632a290a3 100644 --- a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts +++ b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts @@ -2,23 +2,27 @@ import { beforeEach, afterEach, assert, clearStore, describe, test, createMockedFunction } from "matchstick-as/assembly/index"; import { log } from "matchstick-as/assembly/log"; -import { BigInt } from "@graphprotocol/graph-ts"; +import { BigInt, Bytes } from "@graphprotocol/graph-ts"; import { BEANSTALK } from "../../subgraph-core/utils/Constants"; -import { ZERO_BI } from "../../subgraph-core/utils/Decimals"; -import { beans_BI as beans, podlineMil_BI as mil } from "../../subgraph-core/tests/Values"; +import { BI_10, ZERO_BI } from "../../subgraph-core/utils/Decimals"; +import { beans_BI as beans, podlineMil_BI } from "../../subgraph-core/tests/Values"; import { assertFarmerHasPlot, assertFieldHas, setHarvestable, sow, transferPlot } from "./utils/Field"; +import { createListing_v2, createOrder_v2, fillListing_v2, fillOrder_v2 } from "./utils/Marketplace"; -const ANVIL_ADDR_1 = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); -const ANVIL_ADDR_2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); +const account = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266".toLowerCase(); +const account2 = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".toLowerCase(); // 2 plots: each sow 500 for 7500 at 10m and 15m in line. -const plot1Start = mil(10); -const plot2Start = mil(15); +const plot1Start = podlineMil_BI(10); +const plot2Start = podlineMil_BI(15); const beansSown = beans(500); const temperature = 15; const pods = beansSown.times(BigInt.fromI32(temperature)); +const maxHarvestableIndex = podlineMil_BI(100); +const orderId = Bytes.fromHexString("0xabcd"); + class Plot { plotStart: BigInt; beansSown: BigInt; @@ -49,12 +53,12 @@ describe("Field: Plot Transfer", () => { beforeEach(() => { // Create two equally sized plots next to each other for (let i = 0; i < initialPlots.length; ++i) { - sow(ANVIL_ADDR_1, initialPlots[i].plotStart, initialPlots[i].beansSown, initialPlots[i].pods); + sow(account, initialPlots[i].plotStart, initialPlots[i].beansSown, initialPlots[i].pods); } // Ensure setup was done correctly - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, initialPlots[0].pods); - assertFieldHas(ANVIL_ADDR_1, initialPlots[0].pods.plus(initialPlots[1].pods), ZERO_BI); - assert.notInStore("Field", ANVIL_ADDR_2); + assertFarmerHasPlot(account, initialPlots[0].plotStart, initialPlots[0].pods); + assertFieldHas(account, initialPlots[0].pods.plus(initialPlots[1].pods), ZERO_BI); + assert.notInStore("Field", account2); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.plus(initialPlots[1].pods), ZERO_BI); log.info("Initial data populated", []); @@ -67,11 +71,11 @@ describe("Field: Plot Transfer", () => { // Transfers entire first plot describe("Full Plot", () => { test("F: Unharvestable", () => { - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); + transferPlot(account, account2, initialPlots[0].plotStart, initialPlots[0].pods); - assertFarmerHasPlot(ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); - assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, ZERO_BI); - assertFieldHas(ANVIL_ADDR_2, initialPlots[0].pods, ZERO_BI); + assertFarmerHasPlot(account2, initialPlots[0].plotStart, initialPlots[0].pods); + assertFieldHas(account, initialPlots[1].pods, ZERO_BI); + assertFieldHas(account2, initialPlots[0].pods, ZERO_BI); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.plus(initialPlots[1].pods), ZERO_BI); }); @@ -79,11 +83,11 @@ describe("Field: Plot Transfer", () => { // Entire first plot is harvestable setHarvestable(initialPlots[0].plotStart.plus(initialPlots[0].pods)); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); + transferPlot(account, account2, initialPlots[0].plotStart, initialPlots[0].pods); - assertFarmerHasPlot(ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods, initialPlots[0].pods); - assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, ZERO_BI); - assertFieldHas(ANVIL_ADDR_2, ZERO_BI, initialPlots[0].pods); + assertFarmerHasPlot(account2, initialPlots[0].plotStart, initialPlots[0].pods, initialPlots[0].pods); + assertFieldHas(account, initialPlots[1].pods, ZERO_BI); + assertFieldHas(account2, ZERO_BI, initialPlots[0].pods); assertFieldHas(BEANSTALK.toHexString(), initialPlots[1].pods, initialPlots[0].pods); }); @@ -92,16 +96,16 @@ describe("Field: Plot Transfer", () => { const harvestableAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); setHarvestable(initialPlots[0].plotStart.plus(harvestableAmount)); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); + transferPlot(account, account2, initialPlots[0].plotStart, initialPlots[0].pods); - assertFarmerHasPlot(ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods, harvestableAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, ZERO_BI); - assertFieldHas(ANVIL_ADDR_2, initialPlots[0].pods.minus(harvestableAmount), harvestableAmount); + assertFarmerHasPlot(account2, initialPlots[0].plotStart, initialPlots[0].pods, harvestableAmount); + assertFieldHas(account, initialPlots[1].pods, ZERO_BI); + assertFieldHas(account2, initialPlots[0].pods.minus(harvestableAmount), harvestableAmount); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.minus(harvestableAmount).plus(initialPlots[1].pods), harvestableAmount); }); test("F: Plot Source", () => { - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, initialPlots[0].plotStart, initialPlots[0].pods); + transferPlot(account, account2, initialPlots[0].plotStart, initialPlots[0].pods); assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "TRANSFER"); }); }); @@ -111,12 +115,12 @@ describe("Field: Plot Transfer", () => { test("S: Unharvestable", () => { const transferredIndex = initialPlots[0].plotStart; const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, transferredIndex.plus(transferredAmount), initialPlots[0].pods.minus(transferredAmount)); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); - assertFieldHas(ANVIL_ADDR_2, transferredAmount, ZERO_BI); + assertFarmerHasPlot(account, transferredIndex.plus(transferredAmount), initialPlots[0].pods.minus(transferredAmount)); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount); + assertFieldHas(account, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); + assertFieldHas(account2, transferredAmount, ZERO_BI); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.plus(initialPlots[1].pods), ZERO_BI); }); @@ -126,17 +130,17 @@ describe("Field: Plot Transfer", () => { const transferredIndex = initialPlots[0].plotStart; const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); assertFarmerHasPlot( - ANVIL_ADDR_1, + account, transferredIndex.plus(transferredAmount), initialPlots[0].pods.minus(transferredAmount), initialPlots[0].pods.minus(transferredAmount) ); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount, transferredAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, initialPlots[0].pods.minus(transferredAmount)); - assertFieldHas(ANVIL_ADDR_2, ZERO_BI, transferredAmount); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount, transferredAmount); + assertFieldHas(account, initialPlots[1].pods, initialPlots[0].pods.minus(transferredAmount)); + assertFieldHas(account2, ZERO_BI, transferredAmount); assertFieldHas(BEANSTALK.toHexString(), initialPlots[1].pods, initialPlots[0].pods); }); @@ -148,20 +152,20 @@ describe("Field: Plot Transfer", () => { // Transfers first third of plot (only some of which is harvestable) const transferredIndex = initialPlots[0].plotStart; const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); const transferredUnharvestable = transferredAmount.minus(harvestableAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, transferredIndex.plus(transferredAmount), initialPlots[0].pods.minus(transferredAmount), ZERO_BI); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount, harvestableAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); - assertFieldHas(ANVIL_ADDR_2, transferredUnharvestable, harvestableAmount); + assertFarmerHasPlot(account, transferredIndex.plus(transferredAmount), initialPlots[0].pods.minus(transferredAmount), ZERO_BI); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount, harvestableAmount); + assertFieldHas(account, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); + assertFieldHas(account2, transferredUnharvestable, harvestableAmount); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.minus(harvestableAmount).plus(initialPlots[1].pods), harvestableAmount); }); test("S: Plot Source", () => { const transferredIndex = initialPlots[0].plotStart; const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "TRANSFER"); assert.fieldEquals("Plot", transferredIndex.plus(transferredAmount).toString(), "source", "SOW"); }); @@ -172,12 +176,12 @@ describe("Field: Plot Transfer", () => { test("E: Unharvestable", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, initialPlots[0].pods.minus(transferredAmount)); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); - assertFieldHas(ANVIL_ADDR_2, transferredAmount, ZERO_BI); + assertFarmerHasPlot(account, initialPlots[0].plotStart, initialPlots[0].pods.minus(transferredAmount)); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount); + assertFieldHas(account, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); + assertFieldHas(account2, transferredAmount, ZERO_BI); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.plus(initialPlots[1].pods), ZERO_BI); }); @@ -187,17 +191,17 @@ describe("Field: Plot Transfer", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); assertFarmerHasPlot( - ANVIL_ADDR_1, + account, initialPlots[0].plotStart, initialPlots[0].pods.minus(transferredAmount), initialPlots[0].pods.minus(transferredAmount) ); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount, transferredAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, initialPlots[0].pods.minus(transferredAmount)); - assertFieldHas(ANVIL_ADDR_2, ZERO_BI, transferredAmount); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount, transferredAmount); + assertFieldHas(account, initialPlots[1].pods, initialPlots[0].pods.minus(transferredAmount)); + assertFieldHas(account2, ZERO_BI, transferredAmount); assertFieldHas(BEANSTALK.toHexString(), initialPlots[1].pods, initialPlots[0].pods); }); @@ -208,25 +212,25 @@ describe("Field: Plot Transfer", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); const transferredHarvestable = harvestableIndex.minus(transferredIndex); assertFarmerHasPlot( - ANVIL_ADDR_1, + account, initialPlots[0].plotStart, initialPlots[0].pods.minus(transferredAmount), harvestableAmount.minus(transferredHarvestable) ); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount, transferredHarvestable); - assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, harvestableAmount.minus(transferredHarvestable)); - assertFieldHas(ANVIL_ADDR_2, initialPlots[0].pods.minus(harvestableAmount), transferredHarvestable); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount, transferredHarvestable); + assertFieldHas(account, initialPlots[1].pods, harvestableAmount.minus(transferredHarvestable)); + assertFieldHas(account2, initialPlots[0].pods.minus(harvestableAmount), transferredHarvestable); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.minus(harvestableAmount).plus(initialPlots[1].pods), harvestableAmount); }); test("E: Plot Source", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotEnd.minus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); assert.fieldEquals("Plot", transferredIndex.toString(), "source", "TRANSFER"); }); @@ -237,13 +241,13 @@ describe("Field: Plot Transfer", () => { test("M: Unharvestable", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); - assertFieldHas(ANVIL_ADDR_2, transferredAmount, ZERO_BI); + assertFarmerHasPlot(account, initialPlots[0].plotStart, transferredAmount); + assertFarmerHasPlot(account, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount); + assertFieldHas(account, initialPlots[0].pods.minus(transferredAmount).plus(initialPlots[1].pods), ZERO_BI); + assertFieldHas(account2, transferredAmount, ZERO_BI); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.plus(initialPlots[1].pods), ZERO_BI); }); @@ -253,13 +257,13 @@ describe("Field: Plot Transfer", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, transferredAmount, transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount, transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount, transferredAmount); - assertFieldHas(ANVIL_ADDR_1, initialPlots[1].pods, initialPlots[0].pods.minus(transferredAmount)); - assertFieldHas(ANVIL_ADDR_2, ZERO_BI, transferredAmount); + assertFarmerHasPlot(account, initialPlots[0].plotStart, transferredAmount, transferredAmount); + assertFarmerHasPlot(account, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount, transferredAmount); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount, transferredAmount); + assertFieldHas(account, initialPlots[1].pods, initialPlots[0].pods.minus(transferredAmount)); + assertFieldHas(account2, ZERO_BI, transferredAmount); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods, initialPlots[1].pods); }); @@ -270,28 +274,70 @@ describe("Field: Plot Transfer", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); const transferredHarvestable = harvestableAmount.minus(transferredAmount); - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotStart, transferredAmount, harvestableAmount.minus(transferredHarvestable)); - assertFarmerHasPlot(ANVIL_ADDR_1, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount, ZERO_BI); - assertFarmerHasPlot(ANVIL_ADDR_2, transferredIndex, transferredAmount, transferredHarvestable); + assertFarmerHasPlot(account, initialPlots[0].plotStart, transferredAmount, harvestableAmount.minus(transferredHarvestable)); + assertFarmerHasPlot(account, initialPlots[0].plotEnd.minus(transferredAmount), transferredAmount, ZERO_BI); + assertFarmerHasPlot(account2, transferredIndex, transferredAmount, transferredHarvestable); assertFieldHas( - ANVIL_ADDR_1, + account, initialPlots[0].pods.minus(harvestableAmount).minus(transferredHarvestable).plus(initialPlots[1].pods), harvestableAmount.minus(transferredHarvestable) ); - assertFieldHas(ANVIL_ADDR_2, transferredHarvestable, transferredHarvestable); + assertFieldHas(account2, transferredHarvestable, transferredHarvestable); assertFieldHas(BEANSTALK.toHexString(), initialPlots[0].pods.plus(initialPlots[1].pods).minus(harvestableAmount), harvestableAmount); }); test("M: Plot Source", () => { const transferredAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); const transferredIndex = initialPlots[0].plotStart.plus(transferredAmount); - transferPlot(ANVIL_ADDR_1, ANVIL_ADDR_2, transferredIndex, transferredAmount); + transferPlot(account, account2, transferredIndex, transferredAmount); assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); assert.fieldEquals("Plot", transferredIndex.toString(), "source", "TRANSFER"); assert.fieldEquals("Plot", transferredIndex.plus(transferredAmount).toString(), "source", "SOW"); }); + + test("M: Marketplace Listing", () => { + const listingStart = initialPlots[0].pods.div(BigInt.fromI32(3)); + const listingAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); + const fillBeans = beans(5500); + createListing_v2(account, initialPlots[0].plotStart, listingAmount, listingStart, maxHarvestableIndex); + fillListing_v2(account, account2, initialPlots[0].plotStart, listingStart, listingAmount, fillBeans); + + const initialBeansPerPod = BI_10.pow(6).div(BigInt.fromU32(temperature)).toString(); + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(listingAmount).toString(); + assert.entityCount("Plot", 4); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", initialBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(listingStart).toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(listingStart).toString(), "source", "MARKET"); + assert.fieldEquals( + "Plot", + initialPlots[0].plotStart.plus(listingStart).plus(listingAmount).toString(), + "beansPerPod", + initialBeansPerPod + ); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(listingStart).plus(listingAmount).toString(), "source", "SOW"); + }); + + test("M: Marketplace Order", () => { + const fillStart = initialPlots[0].pods.div(BigInt.fromI32(3)); + const fillAmount = initialPlots[0].pods.div(BigInt.fromI32(3)); + const fillBeans = beans(5500); + const orderPricePerPod = BigInt.fromString("1234"); + createOrder_v2(account, orderId, beans(10000), orderPricePerPod, maxHarvestableIndex); + fillOrder_v2(account2, account, orderId, initialPlots[0].plotStart, fillStart, fillAmount, fillBeans); + + const initialBeansPerPod = BI_10.pow(6).div(BigInt.fromU32(temperature)).toString(); + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(fillAmount).toString(); + assert.entityCount("Plot", 4); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", initialBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillStart).toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillStart).toString(), "source", "MARKET"); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillStart).plus(fillAmount).toString(), "beansPerPod", initialBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillStart).plus(fillAmount).toString(), "source", "SOW"); + }); }); }); diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index 10fd2285a1..d0d0f1e466 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -259,12 +259,12 @@ function assertOrderCreated_v2(account: string, event: PodOrderCreated_v2): void export function createListing_v1( account: string, index: BigInt, - plotTotalPods: BigInt, + listedPods: BigInt, start: BigInt, pricePerPod: BigInt, maxHarvestableIndex: BigInt ): PodListingCreated_v1 { - const event = createPodListingCreatedEvent(account, index, start, plotTotalPods.minus(start), pricePerPod, maxHarvestableIndex, true); + const event = createPodListingCreatedEvent(account, index, start, listedPods, pricePerPod, maxHarvestableIndex, true); handlePodListingCreated(event); assertListingCreated_v1(event); return event; @@ -273,20 +273,12 @@ export function createListing_v1( export function createListing_v1_1( account: string, index: BigInt, - plotTotalPods: BigInt, + listedPods: BigInt, start: BigInt, pricePerPod: BigInt, maxHarvestableIndex: BigInt ): PodListingCreated_v1_1 { - const event = createPodListingCreatedEvent_v1_1( - account, - index, - start, - plotTotalPods.minus(start), - pricePerPod, - maxHarvestableIndex, - ZERO_BI - ); + const event = createPodListingCreatedEvent_v1_1(account, index, start, listedPods, pricePerPod, maxHarvestableIndex, ZERO_BI); handlePodListingCreated_v1_1(event); assertListingCreated_v1_1(event); return event; @@ -295,7 +287,7 @@ export function createListing_v1_1( export function createListing_v2( account: string, index: BigInt, - plotTotalPods: BigInt, + listedPods: BigInt, start: BigInt, maxHarvestableIndex: BigInt ): PodListingCreated_v2 { @@ -303,7 +295,7 @@ export function createListing_v2( account, index, start, - plotTotalPods.minus(start), + listedPods, BigInt.fromString("250000"), maxHarvestableIndex, BigInt.fromString("10000000"), From 79bdb2f0c7c209b2f9fc4946e1750f9862b36ce0 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Thu, 16 May 2024 17:23:28 -0700 Subject: [PATCH 53/89] market transfer tests --- .../src/MarketplaceHandler.ts | 2 +- .../tests/PlotTransfer.test.ts | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 631b0272f5..b799237ca6 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -590,7 +590,7 @@ function setBeansPerPodAfterFill(event: ethereum.Event, plotIndex: BigInt, start // on whether the PlotTransfer event has already been processed (sometims its emitted after the market transfer). let fillPlot = loadPlot(event.address, plotIndex.plus(start)); - if (start == ZERO_BI) { + if (start == ZERO_BI && length < fillPlot.pods) { // When sending the start of a plot via market, these cannot be set in any subsequent transfer, // since the start plot has already been modified. let remainderPlot = loadPlot(event.address, plotIndex.plus(length)); diff --git a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts index f632a290a3..b87e47bcbb 100644 --- a/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts +++ b/projects/subgraph-beanstalk/tests/PlotTransfer.test.ts @@ -108,6 +108,29 @@ describe("Field: Plot Transfer", () => { transferPlot(account, account2, initialPlots[0].plotStart, initialPlots[0].pods); assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "TRANSFER"); }); + + test("F: Marketplace Listing", () => { + const fillBeans = beans(7500); + createListing_v2(account, initialPlots[0].plotStart, initialPlots[0].pods, ZERO_BI, maxHarvestableIndex); + fillListing_v2(account, account2, initialPlots[0].plotStart, ZERO_BI, initialPlots[0].pods, fillBeans); + + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(initialPlots[0].pods).toString(); + assert.entityCount("Plot", 2); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "MARKET"); + }); + + test("F: Marketplace Order", () => { + const fillBeans = beans(8500); + const orderPricePerPod = BigInt.fromString("1234"); + createOrder_v2(account, orderId, beans(10000), orderPricePerPod, maxHarvestableIndex); + fillOrder_v2(account2, account, orderId, initialPlots[0].plotStart, ZERO_BI, initialPlots[0].pods, fillBeans); + + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(initialPlots[0].pods).toString(); + assert.entityCount("Plot", 2); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "MARKET"); + }); }); // Transfers the first third of the plot @@ -169,6 +192,37 @@ describe("Field: Plot Transfer", () => { assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "TRANSFER"); assert.fieldEquals("Plot", transferredIndex.plus(transferredAmount).toString(), "source", "SOW"); }); + + test("S: Marketplace Listing", () => { + const listingAmount = initialPlots[0].pods.div(BigInt.fromI32(4)); + const fillBeans = beans(7500); + createListing_v2(account, initialPlots[0].plotStart, listingAmount, ZERO_BI, maxHarvestableIndex); + fillListing_v2(account, account2, initialPlots[0].plotStart, ZERO_BI, listingAmount, fillBeans); + + const initialBeansPerPod = BI_10.pow(6).div(BigInt.fromU32(temperature)).toString(); + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(listingAmount).toString(); + assert.entityCount("Plot", 3); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "MARKET"); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(listingAmount).toString(), "beansPerPod", initialBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(listingAmount).toString(), "source", "SOW"); + }); + + test("S: Marketplace Order", () => { + const fillAmount = initialPlots[0].pods.div(BigInt.fromI32(4)); + const fillBeans = beans(8500); + const orderPricePerPod = BigInt.fromString("1234"); + createOrder_v2(account, orderId, beans(10000), orderPricePerPod, maxHarvestableIndex); + fillOrder_v2(account2, account, orderId, initialPlots[0].plotStart, ZERO_BI, fillAmount, fillBeans); + + const initialBeansPerPod = BI_10.pow(6).div(BigInt.fromU32(temperature)).toString(); + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(fillAmount).toString(); + assert.entityCount("Plot", 3); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "MARKET"); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillAmount).toString(), "beansPerPod", initialBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillAmount).toString(), "source", "SOW"); + }); }); // Transfers the final third of the plot @@ -234,6 +288,39 @@ describe("Field: Plot Transfer", () => { assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); assert.fieldEquals("Plot", transferredIndex.toString(), "source", "TRANSFER"); }); + + test("E: Marketplace Listing", () => { + const listingStart = initialPlots[0].pods.div(BigInt.fromI32(3)); + const listingAmount = initialPlots[0].pods.minus(listingStart); + const fillBeans = beans(5500); + createListing_v2(account, initialPlots[0].plotStart, listingAmount, listingStart, maxHarvestableIndex); + fillListing_v2(account, account2, initialPlots[0].plotStart, listingStart, listingAmount, fillBeans); + + const initialBeansPerPod = BI_10.pow(6).div(BigInt.fromU32(temperature)).toString(); + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(listingAmount).toString(); + assert.entityCount("Plot", 3); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", initialBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(listingStart).toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(listingStart).toString(), "source", "MARKET"); + }); + + test("E: Marketplace Order", () => { + const fillStart = initialPlots[0].pods.div(BigInt.fromI32(3)); + const fillAmount = initialPlots[0].pods.minus(fillStart); + const fillBeans = beans(5500); + const orderPricePerPod = BigInt.fromString("1234"); + createOrder_v2(account, orderId, beans(10000), orderPricePerPod, maxHarvestableIndex); + fillOrder_v2(account2, account, orderId, initialPlots[0].plotStart, fillStart, fillAmount, fillBeans); + + const initialBeansPerPod = BI_10.pow(6).div(BigInt.fromU32(temperature)).toString(); + const filledBeansPerPod = fillBeans.times(BI_10.pow(6)).div(fillAmount).toString(); + assert.entityCount("Plot", 3); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "beansPerPod", initialBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.toString(), "source", "SOW"); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillStart).toString(), "beansPerPod", filledBeansPerPod); + assert.fieldEquals("Plot", initialPlots[0].plotStart.plus(fillStart).toString(), "source", "MARKET"); + }); }); // Transfers the middle third of the plot From 830a97209ce1b5b4f3053ec4976d1f97ae086a41 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 20 May 2024 18:38:49 -0700 Subject: [PATCH 54/89] minimal changes to accommodate new schema --- projects/ui/codegen-individual.yml | 10 +- .../Market/PodsV2/HistoricalPodOrders.graphql | 2 +- .../Market/PodsV2/PodOrder.fragment.graphql | 2 +- projects/ui/src/graph/endpoints.ts | 6 +- projects/ui/src/graph/graphql.schema.json | 3901 ++++++++++++----- .../ui/src/graph/schema-beanstalk.graphql | 623 ++- 6 files changed, 3304 insertions(+), 1240 deletions(-) diff --git a/projects/ui/codegen-individual.yml b/projects/ui/codegen-individual.yml index 2662ba6a14..3a312595aa 100644 --- a/projects/ui/codegen-individual.yml +++ b/projects/ui/codegen-individual.yml @@ -3,11 +3,11 @@ # A more optimal solution would involve generating a different schema for each entry in src/graph.endpoints.ts. overwrite: true generates: - ./src/graph/schema-beanstalk.graphql: - schema: - - https://graph.node.bean.money/subgraphs/name/beanstalk-testing - plugins: - - "schema-ast" + # ./src/graph/schema-beanstalk.graphql: + # schema: + # - https://api.studio.thegraph.com/query/69878/beanstalkdev/v2.2.1.1 + # plugins: + # - "schema-ast" ./src/graph/schema-bean.graphql: schema: - https://graph.node.bean.money/subgraphs/name/bean diff --git a/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql b/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql index 02c6bb55a0..25fe5b0490 100644 --- a/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql +++ b/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql @@ -15,7 +15,7 @@ query HistoricalPodOrders( maxPlaceInLine #// Amounts - podAmount + #podAmount # sk/fix/pod-market removed podAmount and added beanAmount podAmountFilled #// Metadata diff --git a/projects/ui/src/components/Market/PodsV2/PodOrder.fragment.graphql b/projects/ui/src/components/Market/PodsV2/PodOrder.fragment.graphql index a623b1c62d..2c8c4818cf 100644 --- a/projects/ui/src/components/Market/PodsV2/PodOrder.fragment.graphql +++ b/projects/ui/src/components/Market/PodsV2/PodOrder.fragment.graphql @@ -14,7 +14,7 @@ fragment PodOrder on PodOrder { minFillAmount #// Amounts - podAmount # Market V1: Original amount of the ordered pods + #podAmount # Market V1: Original amount of the ordered pods. sk/fix/pod-market removed podAmount beanAmount # Market V2: Original amount of beans used to ordered beans podAmountFilled # current filled amount beanAmountFilled # bean amount filled diff --git a/projects/ui/src/graph/endpoints.ts b/projects/ui/src/graph/endpoints.ts index 0dbbb7ff2d..edcd743460 100644 --- a/projects/ui/src/graph/endpoints.ts +++ b/projects/ui/src/graph/endpoints.ts @@ -35,7 +35,8 @@ export const SUBGRAPH_ENVIRONMENTS: Record = { [SGEnvironments.BF_TEST]: { name: 'Beanstalk Farms / Test', subgraphs: { - beanstalk: 'https://graph.node.bean.money/subgraphs/name/beanstalk', // fixme + beanstalk: + 'https://graph.node.bean.money/subgraphs/name/beanstalk-testing', // fixme bean: 'https://graph.node.bean.money/subgraphs/name/bean-testing', beanft: 'https://graph.node.bean.money/subgraphs/name/beanft-dev', }, @@ -43,7 +44,8 @@ export const SUBGRAPH_ENVIRONMENTS: Record = { [SGEnvironments.BF_2_0_3]: { name: 'Beanstalk Farms / v2.0.3', subgraphs: { - beanstalk: 'https://graph.node.bean.money/subgraphs/name/beanstalk-2-0-3', + beanstalk: + 'https://api.studio.thegraph.com/query/69878/beanstalkdev/v2.2.1.1', bean: 'https://graph.node.bean.money/subgraphs/name/bean', // fixme beanft: 'https://graph.node.bean.money/subgraphs/name/beanft-dev', }, diff --git a/projects/ui/src/graph/graphql.schema.json b/projects/ui/src/graph/graphql.schema.json index bfc723d3c5..c50d0c7891 100644 --- a/projects/ui/src/graph/graphql.schema.json +++ b/projects/ui/src/graph/graphql.schema.json @@ -46828,8 +46828,8 @@ "description": null, "fields": [ { - "name": "beans", - "description": "Beans used to sow, if any", + "name": "beansPerPod", + "description": "Number of beans spent for each pod, whether through sowing or on the marketplace", "args": [], "type": { "kind": "NON_NULL", @@ -46861,7 +46861,7 @@ }, { "name": "creationHash", - "description": "Creation transaction hash", + "description": "Transaction hash of when this plot entity was created", "args": [], "type": { "kind": "NON_NULL", @@ -47033,7 +47033,7 @@ }, { "name": "source", - "description": "Transaction source for this plot", + "description": "Transaction source for this plot. Not the same as creationHash which can include plots splitting from transfer or harvest without the owner changing", "args": [], "type": { "kind": "NON_NULL", @@ -47048,15 +47048,15 @@ "deprecationReason": null }, { - "name": "sownPods", - "description": "Total pods that were sown, if any", + "name": "sourceHash", + "description": "Transaction hash corresponding to source", "args": [], "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null } }, @@ -47064,15 +47064,15 @@ "deprecationReason": null }, { - "name": "temperature", - "description": "Temperature when the plot was sown", + "name": "updatedAt", + "description": "Timestamp when updated", "args": [], "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "SCALAR", - "name": "Int", + "name": "BigInt", "ofType": null } }, @@ -47080,8 +47080,8 @@ "deprecationReason": null }, { - "name": "updatedAt", - "description": "Timestamp when updated", + "name": "updatedAtBlock", + "description": "Block when updated", "args": [], "type": { "kind": "NON_NULL", @@ -47110,7 +47110,7 @@ "interfaces": null, "enumValues": [ { - "name": "HARVEST", + "name": "MARKET", "description": null, "isDeprecated": false, "deprecationReason": null @@ -47165,7 +47165,7 @@ "deprecationReason": null }, { - "name": "beans", + "name": "beansPerPod", "description": null, "type": { "kind": "SCALAR", @@ -47177,7 +47177,7 @@ "deprecationReason": null }, { - "name": "beans_gt", + "name": "beansPerPod_gt", "description": null, "type": { "kind": "SCALAR", @@ -47189,7 +47189,7 @@ "deprecationReason": null }, { - "name": "beans_gte", + "name": "beansPerPod_gte", "description": null, "type": { "kind": "SCALAR", @@ -47201,7 +47201,7 @@ "deprecationReason": null }, { - "name": "beans_in", + "name": "beansPerPod_in", "description": null, "type": { "kind": "LIST", @@ -47221,7 +47221,7 @@ "deprecationReason": null }, { - "name": "beans_lt", + "name": "beansPerPod_lt", "description": null, "type": { "kind": "SCALAR", @@ -47233,7 +47233,7 @@ "deprecationReason": null }, { - "name": "beans_lte", + "name": "beansPerPod_lte", "description": null, "type": { "kind": "SCALAR", @@ -47245,7 +47245,7 @@ "deprecationReason": null }, { - "name": "beans_not", + "name": "beansPerPod_not", "description": null, "type": { "kind": "SCALAR", @@ -47257,7 +47257,7 @@ "deprecationReason": null }, { - "name": "beans_not_in", + "name": "beansPerPod_not_in", "description": null, "type": { "kind": "LIST", @@ -49213,31 +49213,23 @@ "deprecationReason": null }, { - "name": "source_in", + "name": "sourceHash", "description": null, "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "PlotSource", - "ofType": null - } - } + "kind": "SCALAR", + "name": "String", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "source_not", + "name": "sourceHash_contains", "description": null, "type": { - "kind": "ENUM", - "name": "PlotSource", + "kind": "SCALAR", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49245,31 +49237,23 @@ "deprecationReason": null }, { - "name": "source_not_in", + "name": "sourceHash_contains_nocase", "description": null, "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "PlotSource", - "ofType": null - } - } + "kind": "SCALAR", + "name": "String", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "sownPods", + "name": "sourceHash_ends_with", "description": null, "type": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49277,11 +49261,11 @@ "deprecationReason": null }, { - "name": "sownPods_gt", + "name": "sourceHash_ends_with_nocase", "description": null, "type": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49289,11 +49273,11 @@ "deprecationReason": null }, { - "name": "sownPods_gte", + "name": "sourceHash_gt", "description": null, "type": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49301,7 +49285,19 @@ "deprecationReason": null }, { - "name": "sownPods_in", + "name": "sourceHash_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sourceHash_in", "description": null, "type": { "kind": "LIST", @@ -49311,7 +49307,7 @@ "name": null, "ofType": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null } } @@ -49321,11 +49317,11 @@ "deprecationReason": null }, { - "name": "sownPods_lt", + "name": "sourceHash_lt", "description": null, "type": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49333,11 +49329,11 @@ "deprecationReason": null }, { - "name": "sownPods_lte", + "name": "sourceHash_lte", "description": null, "type": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49345,11 +49341,59 @@ "deprecationReason": null }, { - "name": "sownPods_not", + "name": "sourceHash_not", "description": null, "type": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sourceHash_not_contains", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sourceHash_not_contains_nocase", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sourceHash_not_ends_with", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sourceHash_not_ends_with_nocase", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49357,7 +49401,7 @@ "deprecationReason": null }, { - "name": "sownPods_not_in", + "name": "sourceHash_not_in", "description": null, "type": { "kind": "LIST", @@ -49367,7 +49411,7 @@ "name": null, "ofType": { "kind": "SCALAR", - "name": "BigInt", + "name": "String", "ofType": null } } @@ -49377,11 +49421,11 @@ "deprecationReason": null }, { - "name": "temperature", + "name": "sourceHash_not_starts_with", "description": null, "type": { "kind": "SCALAR", - "name": "Int", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49389,11 +49433,11 @@ "deprecationReason": null }, { - "name": "temperature_gt", + "name": "sourceHash_not_starts_with_nocase", "description": null, "type": { "kind": "SCALAR", - "name": "Int", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49401,11 +49445,11 @@ "deprecationReason": null }, { - "name": "temperature_gte", + "name": "sourceHash_starts_with", "description": null, "type": { "kind": "SCALAR", - "name": "Int", + "name": "String", "ofType": null }, "defaultValue": null, @@ -49413,7 +49457,19 @@ "deprecationReason": null }, { - "name": "temperature_in", + "name": "sourceHash_starts_with_nocase", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "source_in", "description": null, "type": { "kind": "LIST", @@ -49422,8 +49478,8 @@ "kind": "NON_NULL", "name": null, "ofType": { - "kind": "SCALAR", - "name": "Int", + "kind": "ENUM", + "name": "PlotSource", "ofType": null } } @@ -49433,11 +49489,43 @@ "deprecationReason": null }, { - "name": "temperature_lt", + "name": "source_not", + "description": null, + "type": { + "kind": "ENUM", + "name": "PlotSource", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "source_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "PlotSource", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAt", "description": null, "type": { "kind": "SCALAR", - "name": "Int", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -49445,11 +49533,11 @@ "deprecationReason": null }, { - "name": "temperature_lte", + "name": "updatedAtBlock", "description": null, "type": { "kind": "SCALAR", - "name": "Int", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -49457,11 +49545,11 @@ "deprecationReason": null }, { - "name": "temperature_not", + "name": "updatedAtBlock_gt", "description": null, "type": { "kind": "SCALAR", - "name": "Int", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -49469,7 +49557,19 @@ "deprecationReason": null }, { - "name": "temperature_not_in", + "name": "updatedAtBlock_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAtBlock_in", "description": null, "type": { "kind": "LIST", @@ -49479,7 +49579,7 @@ "name": null, "ofType": { "kind": "SCALAR", - "name": "Int", + "name": "BigInt", "ofType": null } } @@ -49489,7 +49589,31 @@ "deprecationReason": null }, { - "name": "updatedAt", + "name": "updatedAtBlock_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAtBlock_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "updatedAtBlock_not", "description": null, "type": { "kind": "SCALAR", @@ -49500,6 +49624,26 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "updatedAtBlock_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "updatedAt_gt", "description": null, @@ -49614,7 +49758,7 @@ "interfaces": null, "enumValues": [ { - "name": "beans", + "name": "beansPerPod", "description": null, "isDeprecated": false, "deprecationReason": null @@ -49769,12 +49913,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "listing__cancelledAmount", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "listing__createdAt", "description": null, @@ -49908,19 +50046,19 @@ "deprecationReason": null }, { - "name": "sownPods", + "name": "sourceHash", "description": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "temperature", + "name": "updatedAt", "description": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "updatedAt", + "name": "updatedAtBlock", "description": null, "isDeprecated": false, "deprecationReason": null @@ -49954,9 +50092,13 @@ "description": "Total beans used to fill listing/order", "args": [], "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } }, "isDeprecated": false, "deprecationReason": null @@ -49979,7 +50121,7 @@ }, { "name": "from", - "description": "Account fulfilling the order", + "description": "Account that is sending pods", "args": [], "type": { "kind": "NON_NULL", @@ -50049,6 +50191,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": "Where these pods were in line when filled", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace", "description": "Marketplace associated with this fill", @@ -50083,7 +50241,7 @@ }, { "name": "to", - "description": "Account filling the order", + "description": "Account that is receiving pods", "args": [], "type": { "kind": "NON_NULL", @@ -51505,6 +51663,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace", "description": null, @@ -52214,12 +52484,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "listing__cancelledAmount", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "listing__createdAt", "description": null, @@ -52388,12 +52652,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "order__podAmount", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "order__podAmountFilled", "description": null, @@ -52430,6 +52688,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace", "description": null, @@ -52442,6 +52706,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__availableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__beanVolume", "description": null, @@ -52455,7 +52725,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__cancelledOrderedPods", + "name": "podMarketplace__cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -52472,6 +52742,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__filledOrderedPods", "description": null, @@ -52491,7 +52767,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__orderedPods", + "name": "podMarketplace__orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -52550,22 +52826,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "cancelledAmount", - "description": "The number of Pods that were remaining in *this* PodListing when it was Cancelled.\n", - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "createdAt", "description": "Timestamp of PodListing creation.", @@ -53061,6 +53321,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": "Where these pods were in line when cancelled", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": " The protocol this transaction belongs to ", @@ -54467,6 +54743,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": null, @@ -54796,6 +55184,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": null, @@ -55050,6 +55444,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": "Where these pods were in line when listed", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "pricePerPod", "description": "Price per pod", @@ -56960,6 +57370,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "pricePerPod", "description": null, @@ -57785,6 +58307,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "pricePerPod", "description": null, @@ -58027,6 +58555,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": "Where these pods were in line when filled", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": " The protocol this transaction belongs to ", @@ -59689,6 +60233,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": null, @@ -60398,6 +61054,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": null, @@ -60613,118 +61275,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "cancelledAmount", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "cancelledAmount_gt", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "cancelledAmount_gte", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "cancelledAmount_in", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "cancelledAmount_lt", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "cancelledAmount_lte", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "cancelledAmount_not", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "cancelledAmount_not_in", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "createdAt", "description": null, @@ -64224,12 +64774,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "cancelledAmount", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "createdAt", "description": null, @@ -64296,6 +64840,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "fill__placeInLine", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "fill__start", "description": null, @@ -64369,7 +64919,7 @@ "deprecationReason": null }, { - "name": "plot__beans", + "name": "plot__beansPerPod", "description": null, "isDeprecated": false, "deprecationReason": null @@ -64435,19 +64985,19 @@ "deprecationReason": null }, { - "name": "plot__sownPods", + "name": "plot__sourceHash", "description": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "plot__temperature", + "name": "plot__updatedAt", "description": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "plot__updatedAt", + "name": "plot__updatedAtBlock", "description": null, "isDeprecated": false, "deprecationReason": null @@ -64464,6 +65014,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__availableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__beanVolume", "description": null, @@ -64477,7 +65033,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__cancelledOrderedPods", + "name": "podMarketplace__cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -64494,6 +65050,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__filledOrderedPods", "description": null, @@ -64513,7 +65075,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__orderedPods", + "name": "podMarketplace__orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -64580,6 +65142,54 @@ "name": "PodMarketplace", "description": null, "fields": [ + { + "name": "activeListings", + "description": "Information about the active pod listings. Each entry of the form 'account-index-expiry'", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders", + "description": "Information about the active pod orders. Each entry of the form 'orderId-maxPlaceInLine'", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "allListings", "description": "All historical listings", @@ -64766,6 +65376,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": "Current amount of total beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": "Cumulative bean volume between listings and orders", @@ -64799,8 +65425,8 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", - "description": "Current cumulative pod orders cancelled", + "name": "cancelledOrderBeans", + "description": "Current cumulative beans in pod orders cancelled", "args": [], "type": { "kind": "NON_NULL", @@ -64931,6 +65557,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": "Current cumulative filled beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", "description": "Current cumulative pod orders filled", @@ -65150,32 +65792,8 @@ "deprecationReason": null }, { - "name": "listingIndexes", - "description": "Indexes of actively listed plots", - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orderedPods", - "description": "Current cumulative pod orders created", + "name": "orderBeans", + "description": "Current cumulative beans in pod orders created", "args": [], "type": { "kind": "NON_NULL", @@ -65189,91 +65807,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "orders", - "description": "Active pod order IDs", - "args": [ - { - "name": "first", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": "100", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orderBy", - "description": null, - "type": { - "kind": "ENUM", - "name": "PodOrder_orderBy", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orderDirection", - "description": null, - "type": { - "kind": "ENUM", - "name": "OrderDirection", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "skip", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": "0", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "where", - "description": null, - "type": { - "kind": "INPUT_OBJECT", - "name": "PodOrder_filter", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "PodOrder", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "podVolume", "description": "Cumulative pod volume between listings and orders", @@ -65333,6 +65866,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": "Current amount of total beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": "Point in time current cumulative bean volume between listings and orders", @@ -65366,8 +65915,8 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", - "description": "Point in time current cumulative pod orders cancelled", + "name": "cancelledOrderBeans", + "description": "Current cumulative beans in pod orders cancelled", "args": [], "type": { "kind": "NON_NULL", @@ -65413,6 +65962,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaAvailableOrderBeans", + "description": "Point in time current delta available ordered beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaBeanVolume", "description": "Point in time current delta bean volume between listings and orders", @@ -65446,8 +66011,8 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods", - "description": "Point in time current delta pod orders cancelled", + "name": "deltaCancelledOrderBeans", + "description": "Point in time current delta cancelled ordered beans in pod orders", "args": [], "type": { "kind": "NON_NULL", @@ -65493,6 +66058,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaFilledOrderBeans", + "description": "Point in time current delta filled ordered beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaFilledOrderedPods", "description": "Point in time current delta pod orders filled", @@ -65526,8 +66107,8 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods", - "description": "Point in time current delta pod orders created", + "name": "deltaOrderBeans", + "description": "Point in time current delta ordered beans in pod orders created", "args": [], "type": { "kind": "NON_NULL", @@ -65589,9 +66170,25 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": "Current cumulative filled beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", - "description": "Point in time current cumulative pod orders filled", + "description": "Current cumulative pod orders filled", "args": [], "type": { "kind": "NON_NULL", @@ -65638,8 +66235,8 @@ "deprecationReason": null }, { - "name": "orderedPods", - "description": "Point in time current cumulative pod orders created", + "name": "orderBeans", + "description": "Current cumulative beans in pod orders created", "args": [], "type": { "kind": "NON_NULL", @@ -65870,7 +66467,7 @@ "deprecationReason": null }, { - "name": "beanVolume", + "name": "availableOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -65882,7 +66479,7 @@ "deprecationReason": null }, { - "name": "beanVolume_gt", + "name": "availableOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -65894,7 +66491,7 @@ "deprecationReason": null }, { - "name": "beanVolume_gte", + "name": "availableOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -65906,7 +66503,7 @@ "deprecationReason": null }, { - "name": "beanVolume_in", + "name": "availableOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -65926,7 +66523,7 @@ "deprecationReason": null }, { - "name": "beanVolume_lt", + "name": "availableOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -65938,7 +66535,7 @@ "deprecationReason": null }, { - "name": "beanVolume_lte", + "name": "availableOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -65950,7 +66547,7 @@ "deprecationReason": null }, { - "name": "beanVolume_not", + "name": "availableOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -65962,7 +66559,7 @@ "deprecationReason": null }, { - "name": "beanVolume_not_in", + "name": "availableOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -65982,7 +66579,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods", + "name": "beanVolume", "description": null, "type": { "kind": "SCALAR", @@ -65994,7 +66591,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods_gt", + "name": "beanVolume_gt", "description": null, "type": { "kind": "SCALAR", @@ -66006,7 +66603,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods_gte", + "name": "beanVolume_gte", "description": null, "type": { "kind": "SCALAR", @@ -66018,7 +66615,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods_in", + "name": "beanVolume_in", "description": null, "type": { "kind": "LIST", @@ -66038,7 +66635,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods_lt", + "name": "beanVolume_lt", "description": null, "type": { "kind": "SCALAR", @@ -66050,7 +66647,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods_lte", + "name": "beanVolume_lte", "description": null, "type": { "kind": "SCALAR", @@ -66062,7 +66659,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods_not", + "name": "beanVolume_not", "description": null, "type": { "kind": "SCALAR", @@ -66074,7 +66671,7 @@ "deprecationReason": null }, { - "name": "cancelledListedPods_not_in", + "name": "beanVolume_not_in", "description": null, "type": { "kind": "LIST", @@ -66094,7 +66691,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", + "name": "cancelledListedPods", "description": null, "type": { "kind": "SCALAR", @@ -66106,7 +66703,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_gt", + "name": "cancelledListedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -66118,7 +66715,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_gte", + "name": "cancelledListedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -66130,7 +66727,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_in", + "name": "cancelledListedPods_in", "description": null, "type": { "kind": "LIST", @@ -66150,7 +66747,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_lt", + "name": "cancelledListedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -66162,7 +66759,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_lte", + "name": "cancelledListedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -66174,7 +66771,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_not", + "name": "cancelledListedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -66186,7 +66783,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_not_in", + "name": "cancelledListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -66206,7 +66803,7 @@ "deprecationReason": null }, { - "name": "createdAt", + "name": "cancelledOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -66218,7 +66815,7 @@ "deprecationReason": null }, { - "name": "createdAt_gt", + "name": "cancelledOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -66230,7 +66827,7 @@ "deprecationReason": null }, { - "name": "createdAt_gte", + "name": "cancelledOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -66242,7 +66839,7 @@ "deprecationReason": null }, { - "name": "createdAt_in", + "name": "cancelledOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -66262,7 +66859,7 @@ "deprecationReason": null }, { - "name": "createdAt_lt", + "name": "cancelledOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -66274,7 +66871,7 @@ "deprecationReason": null }, { - "name": "createdAt_lte", + "name": "cancelledOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -66286,7 +66883,7 @@ "deprecationReason": null }, { - "name": "createdAt_not", + "name": "cancelledOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -66298,7 +66895,7 @@ "deprecationReason": null }, { - "name": "createdAt_not_in", + "name": "cancelledOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -66318,7 +66915,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods", + "name": "createdAt", "description": null, "type": { "kind": "SCALAR", @@ -66330,7 +66927,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods_gt", + "name": "createdAt_gt", "description": null, "type": { "kind": "SCALAR", @@ -66342,7 +66939,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods_gte", + "name": "createdAt_gte", "description": null, "type": { "kind": "SCALAR", @@ -66354,7 +66951,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods_in", + "name": "createdAt_in", "description": null, "type": { "kind": "LIST", @@ -66374,7 +66971,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods_lt", + "name": "createdAt_lt", "description": null, "type": { "kind": "SCALAR", @@ -66386,7 +66983,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods_lte", + "name": "createdAt_lte", "description": null, "type": { "kind": "SCALAR", @@ -66398,7 +66995,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods_not", + "name": "createdAt_not", "description": null, "type": { "kind": "SCALAR", @@ -66410,7 +67007,7 @@ "deprecationReason": null }, { - "name": "deltaAvailableListedPods_not_in", + "name": "createdAt_not_in", "description": null, "type": { "kind": "LIST", @@ -66430,7 +67027,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume", + "name": "deltaAvailableListedPods", "description": null, "type": { "kind": "SCALAR", @@ -66442,7 +67039,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume_gt", + "name": "deltaAvailableListedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -66454,7 +67051,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume_gte", + "name": "deltaAvailableListedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -66466,7 +67063,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume_in", + "name": "deltaAvailableListedPods_in", "description": null, "type": { "kind": "LIST", @@ -66486,7 +67083,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume_lt", + "name": "deltaAvailableListedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -66498,7 +67095,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume_lte", + "name": "deltaAvailableListedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -66510,7 +67107,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume_not", + "name": "deltaAvailableListedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -66522,7 +67119,7 @@ "deprecationReason": null }, { - "name": "deltaBeanVolume_not_in", + "name": "deltaAvailableListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -66542,7 +67139,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods", + "name": "deltaAvailableOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -66554,7 +67151,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods_gt", + "name": "deltaAvailableOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -66566,7 +67163,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods_gte", + "name": "deltaAvailableOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -66578,7 +67175,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods_in", + "name": "deltaAvailableOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -66598,7 +67195,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods_lt", + "name": "deltaAvailableOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -66610,7 +67207,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods_lte", + "name": "deltaAvailableOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -66622,7 +67219,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods_not", + "name": "deltaAvailableOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -66634,7 +67231,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledListedPods_not_in", + "name": "deltaAvailableOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -66654,7 +67251,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods", + "name": "deltaBeanVolume", "description": null, "type": { "kind": "SCALAR", @@ -66666,7 +67263,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_gt", + "name": "deltaBeanVolume_gt", "description": null, "type": { "kind": "SCALAR", @@ -66678,7 +67275,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_gte", + "name": "deltaBeanVolume_gte", "description": null, "type": { "kind": "SCALAR", @@ -66690,7 +67287,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_in", + "name": "deltaBeanVolume_in", "description": null, "type": { "kind": "LIST", @@ -66710,7 +67307,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_lt", + "name": "deltaBeanVolume_lt", "description": null, "type": { "kind": "SCALAR", @@ -66722,7 +67319,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_lte", + "name": "deltaBeanVolume_lte", "description": null, "type": { "kind": "SCALAR", @@ -66734,7 +67331,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_not", + "name": "deltaBeanVolume_not", "description": null, "type": { "kind": "SCALAR", @@ -66746,7 +67343,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_not_in", + "name": "deltaBeanVolume_not_in", "description": null, "type": { "kind": "LIST", @@ -66766,7 +67363,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods", + "name": "deltaCancelledListedPods", "description": null, "type": { "kind": "SCALAR", @@ -66778,7 +67375,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods_gt", + "name": "deltaCancelledListedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -66790,7 +67387,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods_gte", + "name": "deltaCancelledListedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -66802,7 +67399,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods_in", + "name": "deltaCancelledListedPods_in", "description": null, "type": { "kind": "LIST", @@ -66822,7 +67419,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods_lt", + "name": "deltaCancelledListedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -66834,7 +67431,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods_lte", + "name": "deltaCancelledListedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -66846,7 +67443,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods_not", + "name": "deltaCancelledListedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -66858,7 +67455,7 @@ "deprecationReason": null }, { - "name": "deltaExpiredListedPods_not_in", + "name": "deltaCancelledListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -66878,7 +67475,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods", + "name": "deltaCancelledOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -66890,7 +67487,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods_gt", + "name": "deltaCancelledOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -66902,7 +67499,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods_gte", + "name": "deltaCancelledOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -66914,7 +67511,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods_in", + "name": "deltaCancelledOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -66934,7 +67531,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods_lt", + "name": "deltaCancelledOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -66946,7 +67543,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods_lte", + "name": "deltaCancelledOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -66958,7 +67555,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods_not", + "name": "deltaCancelledOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -66970,7 +67567,7 @@ "deprecationReason": null }, { - "name": "deltaFilledListedPods_not_in", + "name": "deltaCancelledOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -66990,7 +67587,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods", + "name": "deltaExpiredListedPods", "description": null, "type": { "kind": "SCALAR", @@ -67002,7 +67599,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods_gt", + "name": "deltaExpiredListedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -67014,7 +67611,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods_gte", + "name": "deltaExpiredListedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -67026,7 +67623,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods_in", + "name": "deltaExpiredListedPods_in", "description": null, "type": { "kind": "LIST", @@ -67046,7 +67643,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods_lt", + "name": "deltaExpiredListedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -67058,7 +67655,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods_lte", + "name": "deltaExpiredListedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -67070,7 +67667,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods_not", + "name": "deltaExpiredListedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -67082,7 +67679,7 @@ "deprecationReason": null }, { - "name": "deltaFilledOrderedPods_not_in", + "name": "deltaExpiredListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -67102,7 +67699,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods", + "name": "deltaFilledListedPods", "description": null, "type": { "kind": "SCALAR", @@ -67114,7 +67711,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods_gt", + "name": "deltaFilledListedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -67126,7 +67723,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods_gte", + "name": "deltaFilledListedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -67138,7 +67735,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods_in", + "name": "deltaFilledListedPods_in", "description": null, "type": { "kind": "LIST", @@ -67158,7 +67755,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods_lt", + "name": "deltaFilledListedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -67170,7 +67767,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods_lte", + "name": "deltaFilledListedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -67182,7 +67779,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods_not", + "name": "deltaFilledListedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -67194,7 +67791,7 @@ "deprecationReason": null }, { - "name": "deltaListedPods_not_in", + "name": "deltaFilledListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -67214,7 +67811,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods", + "name": "deltaFilledOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -67226,7 +67823,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_gt", + "name": "deltaFilledOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -67238,7 +67835,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_gte", + "name": "deltaFilledOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -67250,7 +67847,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_in", + "name": "deltaFilledOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -67270,7 +67867,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_lt", + "name": "deltaFilledOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -67282,7 +67879,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_lte", + "name": "deltaFilledOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -67294,7 +67891,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_not", + "name": "deltaFilledOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -67306,7 +67903,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_not_in", + "name": "deltaFilledOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -67326,7 +67923,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume", + "name": "deltaFilledOrderedPods", "description": null, "type": { "kind": "SCALAR", @@ -67338,7 +67935,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume_gt", + "name": "deltaFilledOrderedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -67350,7 +67947,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume_gte", + "name": "deltaFilledOrderedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -67362,7 +67959,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume_in", + "name": "deltaFilledOrderedPods_in", "description": null, "type": { "kind": "LIST", @@ -67382,7 +67979,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume_lt", + "name": "deltaFilledOrderedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -67394,7 +67991,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume_lte", + "name": "deltaFilledOrderedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -67406,7 +68003,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume_not", + "name": "deltaFilledOrderedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -67418,7 +68015,7 @@ "deprecationReason": null }, { - "name": "deltaPodVolume_not_in", + "name": "deltaFilledOrderedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -67438,7 +68035,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods", + "name": "deltaListedPods", "description": null, "type": { "kind": "SCALAR", @@ -67450,7 +68047,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods_gt", + "name": "deltaListedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -67462,7 +68059,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods_gte", + "name": "deltaListedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -67474,7 +68071,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods_in", + "name": "deltaListedPods_in", "description": null, "type": { "kind": "LIST", @@ -67494,7 +68091,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods_lt", + "name": "deltaListedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -67506,7 +68103,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods_lte", + "name": "deltaListedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -67518,7 +68115,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods_not", + "name": "deltaListedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -67530,7 +68127,7 @@ "deprecationReason": null }, { - "name": "expiredListedPods_not_in", + "name": "deltaListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -67550,7 +68147,7 @@ "deprecationReason": null }, { - "name": "filledListedPods", + "name": "deltaOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -67562,7 +68159,7 @@ "deprecationReason": null }, { - "name": "filledListedPods_gt", + "name": "deltaOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -67574,7 +68171,7 @@ "deprecationReason": null }, { - "name": "filledListedPods_gte", + "name": "deltaOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -67586,7 +68183,7 @@ "deprecationReason": null }, { - "name": "filledListedPods_in", + "name": "deltaOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -67606,7 +68203,7 @@ "deprecationReason": null }, { - "name": "filledListedPods_lt", + "name": "deltaOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -67618,7 +68215,7 @@ "deprecationReason": null }, { - "name": "filledListedPods_lte", + "name": "deltaOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -67630,7 +68227,7 @@ "deprecationReason": null }, { - "name": "filledListedPods_not", + "name": "deltaOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -67642,7 +68239,7 @@ "deprecationReason": null }, { - "name": "filledListedPods_not_in", + "name": "deltaOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -67662,7 +68259,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods", + "name": "deltaPodVolume", "description": null, "type": { "kind": "SCALAR", @@ -67674,7 +68271,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods_gt", + "name": "deltaPodVolume_gt", "description": null, "type": { "kind": "SCALAR", @@ -67686,7 +68283,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods_gte", + "name": "deltaPodVolume_gte", "description": null, "type": { "kind": "SCALAR", @@ -67698,7 +68295,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods_in", + "name": "deltaPodVolume_in", "description": null, "type": { "kind": "LIST", @@ -67718,7 +68315,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods_lt", + "name": "deltaPodVolume_lt", "description": null, "type": { "kind": "SCALAR", @@ -67730,7 +68327,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods_lte", + "name": "deltaPodVolume_lte", "description": null, "type": { "kind": "SCALAR", @@ -67742,7 +68339,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods_not", + "name": "deltaPodVolume_not", "description": null, "type": { "kind": "SCALAR", @@ -67754,7 +68351,7 @@ "deprecationReason": null }, { - "name": "filledOrderedPods_not_in", + "name": "deltaPodVolume_not_in", "description": null, "type": { "kind": "LIST", @@ -67774,11 +68371,11 @@ "deprecationReason": null }, { - "name": "id", + "name": "expiredListedPods", "description": null, "type": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -67786,11 +68383,11 @@ "deprecationReason": null }, { - "name": "id_gt", + "name": "expiredListedPods_gt", "description": null, "type": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -67798,11 +68395,11 @@ "deprecationReason": null }, { - "name": "id_gte", + "name": "expiredListedPods_gte", "description": null, "type": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -67810,7 +68407,7 @@ "deprecationReason": null }, { - "name": "id_in", + "name": "expiredListedPods_in", "description": null, "type": { "kind": "LIST", @@ -67820,7 +68417,7 @@ "name": null, "ofType": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null } } @@ -67830,11 +68427,11 @@ "deprecationReason": null }, { - "name": "id_lt", + "name": "expiredListedPods_lt", "description": null, "type": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -67842,11 +68439,11 @@ "deprecationReason": null }, { - "name": "id_lte", + "name": "expiredListedPods_lte", "description": null, "type": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -67854,11 +68451,11 @@ "deprecationReason": null }, { - "name": "id_not", + "name": "expiredListedPods_not", "description": null, "type": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null }, "defaultValue": null, @@ -67866,7 +68463,7 @@ "deprecationReason": null }, { - "name": "id_not_in", + "name": "expiredListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -67876,7 +68473,7 @@ "name": null, "ofType": { "kind": "SCALAR", - "name": "ID", + "name": "BigInt", "ofType": null } } @@ -67886,7 +68483,7 @@ "deprecationReason": null }, { - "name": "listedPods", + "name": "filledListedPods", "description": null, "type": { "kind": "SCALAR", @@ -67898,7 +68495,7 @@ "deprecationReason": null }, { - "name": "listedPods_gt", + "name": "filledListedPods_gt", "description": null, "type": { "kind": "SCALAR", @@ -67910,7 +68507,7 @@ "deprecationReason": null }, { - "name": "listedPods_gte", + "name": "filledListedPods_gte", "description": null, "type": { "kind": "SCALAR", @@ -67922,7 +68519,7 @@ "deprecationReason": null }, { - "name": "listedPods_in", + "name": "filledListedPods_in", "description": null, "type": { "kind": "LIST", @@ -67942,7 +68539,7 @@ "deprecationReason": null }, { - "name": "listedPods_lt", + "name": "filledListedPods_lt", "description": null, "type": { "kind": "SCALAR", @@ -67954,7 +68551,7 @@ "deprecationReason": null }, { - "name": "listedPods_lte", + "name": "filledListedPods_lte", "description": null, "type": { "kind": "SCALAR", @@ -67966,7 +68563,7 @@ "deprecationReason": null }, { - "name": "listedPods_not", + "name": "filledListedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -67978,7 +68575,7 @@ "deprecationReason": null }, { - "name": "listedPods_not_in", + "name": "filledListedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -67998,23 +68595,19 @@ "deprecationReason": null }, { - "name": "or", + "name": "filledOrderBeans", "description": null, "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "INPUT_OBJECT", - "name": "PodMarketplaceDailySnapshot_filter", - "ofType": null - } + "kind": "SCALAR", + "name": "BigInt", + "ofType": null }, "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "orderedPods", + "name": "filledOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -68026,7 +68619,7 @@ "deprecationReason": null }, { - "name": "orderedPods_gt", + "name": "filledOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -68038,7 +68631,387 @@ "deprecationReason": null }, { - "name": "orderedPods_gte", + "name": "filledOrderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderedPods_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "listedPods", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "listedPods_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "listedPods_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "listedPods_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "listedPods_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "listedPods_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "listedPods_not", "description": null, "type": { "kind": "SCALAR", @@ -68050,7 +69023,7 @@ "deprecationReason": null }, { - "name": "orderedPods_in", + "name": "listedPods_not_in", "description": null, "type": { "kind": "LIST", @@ -68070,7 +69043,23 @@ "deprecationReason": null }, { - "name": "orderedPods_lt", + "name": "or", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "PodMarketplaceDailySnapshot_filter", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "orderBeans", "description": null, "type": { "kind": "SCALAR", @@ -68082,7 +69071,7 @@ "deprecationReason": null }, { - "name": "orderedPods_lte", + "name": "orderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -68094,7 +69083,7 @@ "deprecationReason": null }, { - "name": "orderedPods_not", + "name": "orderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -68106,7 +69095,63 @@ "deprecationReason": null }, { - "name": "orderedPods_not_in", + "name": "orderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "orderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "orderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "orderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "orderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -68748,6 +69793,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": null, @@ -68761,7 +69812,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", + "name": "cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -68778,6 +69829,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaAvailableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaBeanVolume", "description": null, @@ -68791,7 +69848,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods", + "name": "deltaCancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -68808,6 +69865,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaFilledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaFilledOrderedPods", "description": null, @@ -68821,7 +69884,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods", + "name": "deltaOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -68844,6 +69907,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", "description": null, @@ -68863,7 +69932,7 @@ "deprecationReason": null }, { - "name": "orderedPods", + "name": "orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -68880,6 +69949,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__availableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__beanVolume", "description": null, @@ -68893,7 +69968,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__cancelledOrderedPods", + "name": "podMarketplace__cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -68910,6 +69985,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__filledOrderedPods", "description": null, @@ -68929,7 +70010,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__orderedPods", + "name": "podMarketplace__orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -68988,6 +70069,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": "Current amount of total beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": "Point in time current cumulative bean volume between listings and orders", @@ -69021,8 +70118,8 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", - "description": "Point in time current cumulative pod orders cancelled", + "name": "cancelledOrderBeans", + "description": "Current cumulative beans in pod orders cancelled", "args": [], "type": { "kind": "NON_NULL", @@ -69068,6 +70165,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaAvailableOrderBeans", + "description": "Point in time current delta available ordered beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaBeanVolume", "description": "Point in time current delta bean volume between listings and orders", @@ -69101,8 +70214,8 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods", - "description": "Point in time current delta pod orders cancelled", + "name": "deltaCancelledOrderBeans", + "description": "Point in time current delta cancelled ordered beans in pod orders", "args": [], "type": { "kind": "NON_NULL", @@ -69148,6 +70261,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaFilledOrderBeans", + "description": "Point in time current delta filled ordered beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaFilledOrderedPods", "description": "Point in time current delta pod orders filled", @@ -69181,8 +70310,8 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods", - "description": "Point in time current delta pod orders created", + "name": "deltaOrderBeans", + "description": "Point in time current delta ordered beans in pod orders created", "args": [], "type": { "kind": "NON_NULL", @@ -69244,9 +70373,25 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": "Current cumulative filled beans in pod orders", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", - "description": "Point in time current cumulative pod orders filled", + "description": "Current cumulative pod orders filled", "args": [], "type": { "kind": "NON_NULL", @@ -69293,8 +70438,8 @@ "deprecationReason": null }, { - "name": "orderedPods", - "description": "Point in time current cumulative pod orders created", + "name": "orderBeans", + "description": "Current cumulative beans in pod orders created", "args": [], "type": { "kind": "NON_NULL", @@ -69524,6 +70669,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": null, @@ -69749,7 +71006,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", + "name": "cancelledOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -69761,7 +71018,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_gt", + "name": "cancelledOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -69773,7 +71030,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_gte", + "name": "cancelledOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -69785,7 +71042,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_in", + "name": "cancelledOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -69805,7 +71062,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_lt", + "name": "cancelledOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -69817,7 +71074,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_lte", + "name": "cancelledOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -69829,7 +71086,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_not", + "name": "cancelledOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -69841,7 +71098,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_not_in", + "name": "cancelledOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -70084,6 +71341,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaAvailableOrderBeans", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaAvailableOrderBeans_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaAvailableOrderBeans_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaAvailableOrderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaAvailableOrderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaAvailableOrderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaAvailableOrderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaAvailableOrderBeans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaBeanVolume", "description": null, @@ -70309,7 +71678,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods", + "name": "deltaCancelledOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -70321,7 +71690,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_gt", + "name": "deltaCancelledOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -70333,7 +71702,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_gte", + "name": "deltaCancelledOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -70345,7 +71714,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_in", + "name": "deltaCancelledOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -70365,7 +71734,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_lt", + "name": "deltaCancelledOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -70377,7 +71746,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_lte", + "name": "deltaCancelledOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -70389,7 +71758,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_not", + "name": "deltaCancelledOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -70401,7 +71770,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods_not_in", + "name": "deltaCancelledOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -70644,6 +72013,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaFilledOrderBeans", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaFilledOrderBeans_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaFilledOrderBeans_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaFilledOrderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaFilledOrderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaFilledOrderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaFilledOrderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deltaFilledOrderBeans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaFilledOrderedPods", "description": null, @@ -70869,7 +72350,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods", + "name": "deltaOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -70881,7 +72362,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_gt", + "name": "deltaOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -70893,7 +72374,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_gte", + "name": "deltaOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -70905,7 +72386,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_in", + "name": "deltaOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -70925,7 +72406,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_lt", + "name": "deltaOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -70937,7 +72418,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_lte", + "name": "deltaOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -70949,7 +72430,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_not", + "name": "deltaOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -70961,7 +72442,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods_not_in", + "name": "deltaOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -71316,6 +72797,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", "description": null, @@ -71669,7 +73262,7 @@ "deprecationReason": null }, { - "name": "orderedPods", + "name": "orderBeans", "description": null, "type": { "kind": "SCALAR", @@ -71681,7 +73274,7 @@ "deprecationReason": null }, { - "name": "orderedPods_gt", + "name": "orderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -71693,7 +73286,7 @@ "deprecationReason": null }, { - "name": "orderedPods_gte", + "name": "orderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -71705,7 +73298,7 @@ "deprecationReason": null }, { - "name": "orderedPods_in", + "name": "orderBeans_in", "description": null, "type": { "kind": "LIST", @@ -71725,7 +73318,7 @@ "deprecationReason": null }, { - "name": "orderedPods_lt", + "name": "orderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -71737,7 +73330,7 @@ "deprecationReason": null }, { - "name": "orderedPods_lte", + "name": "orderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -71749,7 +73342,7 @@ "deprecationReason": null }, { - "name": "orderedPods_not", + "name": "orderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -71761,7 +73354,7 @@ "deprecationReason": null }, { - "name": "orderedPods_not_in", + "name": "orderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -72403,6 +73996,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": null, @@ -72416,7 +74015,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", + "name": "cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -72433,6 +74032,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaAvailableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaBeanVolume", "description": null, @@ -72446,7 +74051,7 @@ "deprecationReason": null }, { - "name": "deltaCancelledOrderedPods", + "name": "deltaCancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -72463,6 +74068,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "deltaFilledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "deltaFilledOrderedPods", "description": null, @@ -72476,7 +74087,7 @@ "deprecationReason": null }, { - "name": "deltaOrderedPods", + "name": "deltaOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -72499,6 +74110,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", "description": null, @@ -72518,7 +74135,7 @@ "deprecationReason": null }, { - "name": "orderedPods", + "name": "orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -72535,6 +74152,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__availableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__beanVolume", "description": null, @@ -72548,7 +74171,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__cancelledOrderedPods", + "name": "podMarketplace__cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -72565,6 +74188,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__filledOrderedPods", "description": null, @@ -72584,7 +74213,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__orderedPods", + "name": "podMarketplace__orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -72640,6 +74269,246 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "activeListings", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeListings_contains", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeListings_contains_nocase", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeListings_not", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeListings_not_contains", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeListings_not_contains_nocase", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders_contains", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders_contains_nocase", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders_not", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders_not_contains", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders_not_contains_nocase", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "allListings_", "description": null, @@ -72792,6 +74661,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "availableOrderBeans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": null, @@ -73017,7 +74998,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", + "name": "cancelledOrderBeans", "description": null, "type": { "kind": "SCALAR", @@ -73029,7 +75010,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_gt", + "name": "cancelledOrderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -73041,7 +75022,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_gte", + "name": "cancelledOrderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -73053,7 +75034,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_in", + "name": "cancelledOrderBeans_in", "description": null, "type": { "kind": "LIST", @@ -73073,7 +75054,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_lt", + "name": "cancelledOrderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -73085,7 +75066,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_lte", + "name": "cancelledOrderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -73097,7 +75078,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_not", + "name": "cancelledOrderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -73109,7 +75090,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods_not_in", + "name": "cancelledOrderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -73364,6 +75345,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "filledOrderBeans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", "description": null, @@ -73724,126 +75817,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "listingIndexes", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "listingIndexes_contains", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "listingIndexes_contains_nocase", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "listingIndexes_not", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "listingIndexes_not_contains", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "listingIndexes_not_contains_nocase", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "or", "description": null, @@ -73861,7 +75834,7 @@ "deprecationReason": null }, { - "name": "orderedPods", + "name": "orderBeans", "description": null, "type": { "kind": "SCALAR", @@ -73873,7 +75846,7 @@ "deprecationReason": null }, { - "name": "orderedPods_gt", + "name": "orderBeans_gt", "description": null, "type": { "kind": "SCALAR", @@ -73885,7 +75858,7 @@ "deprecationReason": null }, { - "name": "orderedPods_gte", + "name": "orderBeans_gte", "description": null, "type": { "kind": "SCALAR", @@ -73897,7 +75870,7 @@ "deprecationReason": null }, { - "name": "orderedPods_in", + "name": "orderBeans_in", "description": null, "type": { "kind": "LIST", @@ -73917,7 +75890,7 @@ "deprecationReason": null }, { - "name": "orderedPods_lt", + "name": "orderBeans_lt", "description": null, "type": { "kind": "SCALAR", @@ -73929,7 +75902,7 @@ "deprecationReason": null }, { - "name": "orderedPods_lte", + "name": "orderBeans_lte", "description": null, "type": { "kind": "SCALAR", @@ -73941,7 +75914,7 @@ "deprecationReason": null }, { - "name": "orderedPods_not", + "name": "orderBeans_not", "description": null, "type": { "kind": "SCALAR", @@ -73953,7 +75926,7 @@ "deprecationReason": null }, { - "name": "orderedPods_not_in", + "name": "orderBeans_not_in", "description": null, "type": { "kind": "LIST", @@ -73972,138 +75945,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "orders", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orders_", - "description": null, - "type": { - "kind": "INPUT_OBJECT", - "name": "PodOrder_filter", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orders_contains", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orders_contains_nocase", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orders_not", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orders_not_contains", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orders_not_contains_nocase", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "podVolume", "description": null, @@ -74341,6 +76182,18 @@ "inputFields": null, "interfaces": null, "enumValues": [ + { + "name": "activeListings", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "activeOrders", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "allListings", "description": null, @@ -74359,6 +76212,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "availableOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "beanVolume", "description": null, @@ -74372,7 +76231,7 @@ "deprecationReason": null }, { - "name": "cancelledOrderedPods", + "name": "cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -74395,6 +76254,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "filledOrderedPods", "description": null, @@ -74426,19 +76291,7 @@ "deprecationReason": null }, { - "name": "listingIndexes", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orderedPods", - "description": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "orders", + "name": "orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -74692,22 +76545,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "podAmount", - "description": "The original number of Pods requested by this PodOrder.\n\nDoes NOT change as Fills occur.\nNot deterministic for PodOrders with pricingType = DYNAMIC.\n\nIf pricingType = FIXED:\n Set to the number of Pods which can be purchased by the Order.\n If FIXED (V1): `amount` field emitted in PodOrderCreated.\n If FIXED (V2): `amount / pricePerPod` fields emitted in PodOrderCreated.\n\nIf pricingType = DYNAMIC:\n Set to `0`. The number of Pods that will be provided is unknown, since\n the price is calculated based on the place in line of supplied Pods.\n", - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "podAmountFilled", "description": "The current number of Pods that have been purchased by this PodOrder.\n\nIncreases during each subsequent Fill.\nIf pricingType = FIXED: `0 <= podAmountFilled <= podAmount`\nIf pricingType = DYNAMIC: No constraint, since `podAmount` is unknown.\n\nUpon PodOrder cancellation, this value is locked.\n", @@ -79803,6 +81640,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": "Where these pods were in line when filled", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": " The protocol this transaction belongs to ", @@ -81465,6 +83318,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "placeInLine_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": null, @@ -82174,6 +84139,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "placeInLine", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "protocol", "description": null, @@ -83877,18 +85848,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "podAmount", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "podAmountFilled", "description": null, @@ -84001,106 +85960,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "podAmount_gt", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "podAmount_gte", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "podAmount_in", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "podAmount_lt", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "podAmount_lte", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "podAmount_not", - "description": null, - "type": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "podAmount_not_in", - "description": null, - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "BigInt", - "ofType": null - } - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "podMarketplace", "description": null, @@ -84985,25 +86844,25 @@ "deprecationReason": null }, { - "name": "podAmount", + "name": "podAmountFilled", "description": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "podAmountFilled", + "name": "podMarketplace", "description": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "podMarketplace", + "name": "podMarketplace__availableListedPods", "description": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "podMarketplace__availableListedPods", + "name": "podMarketplace__availableOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -85021,7 +86880,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__cancelledOrderedPods", + "name": "podMarketplace__cancelledOrderBeans", "description": null, "isDeprecated": false, "deprecationReason": null @@ -85038,6 +86897,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "podMarketplace__filledOrderBeans", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "podMarketplace__filledOrderedPods", "description": null, @@ -85057,7 +86922,7 @@ "deprecationReason": null }, { - "name": "podMarketplace__orderedPods", + "name": "podMarketplace__orderBeans", "description": null, "isDeprecated": false, "deprecationReason": null diff --git a/projects/ui/src/graph/schema-beanstalk.graphql b/projects/ui/src/graph/schema-beanstalk.graphql index c7d7debf69..ccfee715e0 100644 --- a/projects/ui/src/graph/schema-beanstalk.graphql +++ b/projects/ui/src/graph/schema-beanstalk.graphql @@ -225,6 +225,11 @@ enum AddDeposit_orderBy { token } +enum Aggregation_interval { + day + hour +} + type Beanstalk { """ Array of the addresses for all active farmers in the silo """ activeFarmers: [String!]! @@ -2682,6 +2687,9 @@ enum Incentive_orderBy { protocol__subgraphVersion } +"8 bytes signed integer\n" +scalar Int8 + enum MarketStatus { ACTIVE CANCELLED @@ -2982,13 +2990,15 @@ enum OrderDirection { } type Plot { - """Beans used to sow, if any""" - beans: BigInt! + """ + Number of beans spent for each pod, whether through sowing or on the marketplace + """ + beansPerPod: BigInt! """Timestamp of creation""" createdAt: BigInt! - """Creation transaction hash""" + """Transaction hash of when this plot entity was created""" creationHash: String! """Farmer who owns this plot""" @@ -3021,21 +3031,23 @@ type Plot { """Season when created""" season: Int! - """Transaction source for this plot""" + """ + Transaction source for this plot. Not the same as creationHash which can include plots splitting from transfer or harvest without the owner changing + """ source: PlotSource! - """Total pods that were sown, if any""" - sownPods: BigInt! - - """Temperature when the plot was sown""" - temperature: Int! + """Transaction hash corresponding to source""" + sourceHash: String! """Timestamp when updated""" updatedAt: BigInt! + + """Block when updated""" + updatedAtBlock: BigInt! } enum PlotSource { - HARVEST + MARKET SOW TRANSFER } @@ -3044,14 +3056,14 @@ input Plot_filter { """Filter for the block changed event.""" _change_block: BlockChangedFilter and: [Plot_filter] - beans: BigInt - beans_gt: BigInt - beans_gte: BigInt - beans_in: [BigInt!] - beans_lt: BigInt - beans_lte: BigInt - beans_not: BigInt - beans_not_in: [BigInt!] + beansPerPod: BigInt + beansPerPod_gt: BigInt + beansPerPod_gte: BigInt + beansPerPod_in: [BigInt!] + beansPerPod_lt: BigInt + beansPerPod_lte: BigInt + beansPerPod_not: BigInt + beansPerPod_not_in: [BigInt!] createdAt: BigInt createdAt_gt: BigInt createdAt_gte: BigInt @@ -3197,26 +3209,38 @@ input Plot_filter { season_not: Int season_not_in: [Int!] source: PlotSource + sourceHash: String + sourceHash_contains: String + sourceHash_contains_nocase: String + sourceHash_ends_with: String + sourceHash_ends_with_nocase: String + sourceHash_gt: String + sourceHash_gte: String + sourceHash_in: [String!] + sourceHash_lt: String + sourceHash_lte: String + sourceHash_not: String + sourceHash_not_contains: String + sourceHash_not_contains_nocase: String + sourceHash_not_ends_with: String + sourceHash_not_ends_with_nocase: String + sourceHash_not_in: [String!] + sourceHash_not_starts_with: String + sourceHash_not_starts_with_nocase: String + sourceHash_starts_with: String + sourceHash_starts_with_nocase: String source_in: [PlotSource!] source_not: PlotSource source_not_in: [PlotSource!] - sownPods: BigInt - sownPods_gt: BigInt - sownPods_gte: BigInt - sownPods_in: [BigInt!] - sownPods_lt: BigInt - sownPods_lte: BigInt - sownPods_not: BigInt - sownPods_not_in: [BigInt!] - temperature: Int - temperature_gt: Int - temperature_gte: Int - temperature_in: [Int!] - temperature_lt: Int - temperature_lte: Int - temperature_not: Int - temperature_not_in: [Int!] updatedAt: BigInt + updatedAtBlock: BigInt + updatedAtBlock_gt: BigInt + updatedAtBlock_gte: BigInt + updatedAtBlock_in: [BigInt!] + updatedAtBlock_lt: BigInt + updatedAtBlock_lte: BigInt + updatedAtBlock_not: BigInt + updatedAtBlock_not_in: [BigInt!] updatedAt_gt: BigInt updatedAt_gte: BigInt updatedAt_in: [BigInt!] @@ -3227,7 +3251,7 @@ input Plot_filter { } enum Plot_orderBy { - beans + beansPerPod createdAt creationHash farmer @@ -3253,7 +3277,6 @@ enum Plot_orderBy { index listing listing__amount - listing__cancelledAmount listing__createdAt listing__creationHash listing__filled @@ -3276,9 +3299,9 @@ enum Plot_orderBy { pods season source - sownPods - temperature + sourceHash updatedAt + updatedAtBlock } type PodFill { @@ -3286,12 +3309,12 @@ type PodFill { amount: BigInt! """Total beans used to fill listing/order""" - costInBeans: BigInt + costInBeans: BigInt! """Creation timestamp""" createdAt: BigInt! - """Account fulfilling the order""" + """Account that is sending pods""" from: String! """Beanstalk address - Order/Listing index - transaction hash""" @@ -3306,13 +3329,16 @@ type PodFill { """Associated order, if any""" order: PodOrder + """Where these pods were in line when filled""" + placeInLine: BigInt! + """Marketplace associated with this fill""" podMarketplace: PodMarketplace! """Start of plot transferred""" start: BigInt! - """Account filling the order""" + """Account that is receiving pods""" to: Farmer! } @@ -3423,6 +3449,14 @@ input PodFill_filter { order_not_starts_with_nocase: String order_starts_with: String order_starts_with_nocase: String + placeInLine: BigInt + placeInLine_gt: BigInt + placeInLine_gte: BigInt + placeInLine_in: [BigInt!] + placeInLine_lt: BigInt + placeInLine_lte: BigInt + placeInLine_not: BigInt + placeInLine_not_in: [BigInt!] podMarketplace: String podMarketplace_: PodMarketplace_filter podMarketplace_contains: String @@ -3484,7 +3518,6 @@ enum PodFill_orderBy { index listing listing__amount - listing__cancelledAmount listing__createdAt listing__creationHash listing__filled @@ -3513,24 +3546,26 @@ enum PodFill_orderBy { order__id order__maxPlaceInLine order__minFillAmount - order__podAmount order__podAmountFilled order__pricePerPod order__pricingFunction order__pricingType order__status order__updatedAt + placeInLine podMarketplace podMarketplace__availableListedPods + podMarketplace__availableOrderBeans podMarketplace__beanVolume podMarketplace__cancelledListedPods - podMarketplace__cancelledOrderedPods + podMarketplace__cancelledOrderBeans podMarketplace__expiredListedPods podMarketplace__filledListedPods + podMarketplace__filledOrderBeans podMarketplace__filledOrderedPods podMarketplace__id podMarketplace__listedPods - podMarketplace__orderedPods + podMarketplace__orderBeans podMarketplace__podVolume podMarketplace__season start @@ -3542,9 +3577,6 @@ type PodListing { "The maximum amount of Pods remaining to be sold by *this* PodListing.\n\nWhen this PodListing is Filled or Cancelled, `amount` does NOT change.\n" amount: BigInt! - "The number of Pods that were remaining in *this* PodListing when it was Cancelled.\n" - cancelledAmount: BigInt! - """Timestamp of PodListing creation.""" createdAt: BigInt! @@ -3643,6 +3675,9 @@ type PodListingCancelled implements MarketplaceEvent { """ logIndex: Int! + """Where these pods were in line when cancelled""" + placeInLine: BigInt! + """ The protocol this transaction belongs to """ protocol: Beanstalk! } @@ -3752,6 +3787,14 @@ input PodListingCancelled_filter { logIndex_not: Int logIndex_not_in: [Int!] or: [PodListingCancelled_filter] + placeInLine: BigInt + placeInLine_gt: BigInt + placeInLine_gte: BigInt + placeInLine_in: [BigInt!] + placeInLine_lt: BigInt + placeInLine_lte: BigInt + placeInLine_not: BigInt + placeInLine_not_in: [BigInt!] protocol: String protocol_: Beanstalk_filter protocol_contains: String @@ -3784,6 +3827,7 @@ enum PodListingCancelled_orderBy { id index logIndex + placeInLine protocol protocol__id protocol__lastSeason @@ -3833,6 +3877,9 @@ type PodListingCreated implements MarketplaceEvent { """Claim to location""" mode: Int! + """Where these pods were in line when listed""" + placeInLine: BigInt! + """Price per pod""" pricePerPod: Int! @@ -3986,6 +4033,14 @@ input PodListingCreated_filter { mode_not: Int mode_not_in: [Int!] or: [PodListingCreated_filter] + placeInLine: BigInt + placeInLine_gt: BigInt + placeInLine_gte: BigInt + placeInLine_in: [BigInt!] + placeInLine_lt: BigInt + placeInLine_lte: BigInt + placeInLine_not: BigInt + placeInLine_not_in: [BigInt!] pricePerPod: Int pricePerPod_gt: Int pricePerPod_gte: Int @@ -4056,6 +4111,7 @@ enum PodListingCreated_orderBy { maxHarvestableIndex minFillAmount mode + placeInLine pricePerPod pricingFunction pricingType @@ -4103,6 +4159,9 @@ type PodListingFilled implements MarketplaceEvent { """ logIndex: Int! + """Where these pods were in line when filled""" + placeInLine: BigInt! + """ The protocol this transaction belongs to """ protocol: Beanstalk! @@ -4234,6 +4293,14 @@ input PodListingFilled_filter { logIndex_not: Int logIndex_not_in: [Int!] or: [PodListingFilled_filter] + placeInLine: BigInt + placeInLine_gt: BigInt + placeInLine_gte: BigInt + placeInLine_in: [BigInt!] + placeInLine_lt: BigInt + placeInLine_lte: BigInt + placeInLine_not: BigInt + placeInLine_not_in: [BigInt!] protocol: String protocol_: Beanstalk_filter protocol_contains: String @@ -4296,6 +4363,7 @@ enum PodListingFilled_orderBy { id index logIndex + placeInLine protocol protocol__id protocol__lastSeason @@ -4321,14 +4389,6 @@ input PodListing_filter { amount_not: BigInt amount_not_in: [BigInt!] and: [PodListing_filter] - cancelledAmount: BigInt - cancelledAmount_gt: BigInt - cancelledAmount_gte: BigInt - cancelledAmount_in: [BigInt!] - cancelledAmount_lt: BigInt - cancelledAmount_lte: BigInt - cancelledAmount_not: BigInt - cancelledAmount_not_in: [BigInt!] createdAt: BigInt createdAt_gt: BigInt createdAt_gte: BigInt @@ -4592,7 +4652,6 @@ input PodListing_filter { enum PodListing_orderBy { amount - cancelledAmount createdAt creationHash farmer @@ -4604,6 +4663,7 @@ enum PodListing_orderBy { fill__from fill__id fill__index + fill__placeInLine fill__start filled filledAmount @@ -4616,7 +4676,7 @@ enum PodListing_orderBy { originalAmount originalIndex plot - plot__beans + plot__beansPerPod plot__createdAt plot__creationHash plot__fullyHarvested @@ -4627,20 +4687,22 @@ enum PodListing_orderBy { plot__pods plot__season plot__source - plot__sownPods - plot__temperature + plot__sourceHash plot__updatedAt + plot__updatedAtBlock podMarketplace podMarketplace__availableListedPods + podMarketplace__availableOrderBeans podMarketplace__beanVolume podMarketplace__cancelledListedPods - podMarketplace__cancelledOrderedPods + podMarketplace__cancelledOrderBeans podMarketplace__expiredListedPods podMarketplace__filledListedPods + podMarketplace__filledOrderBeans podMarketplace__filledOrderedPods podMarketplace__id podMarketplace__listedPods - podMarketplace__orderedPods + podMarketplace__orderBeans podMarketplace__podVolume podMarketplace__season pricePerPod @@ -4653,6 +4715,16 @@ enum PodListing_orderBy { } type PodMarketplace { + """ + Information about the active pod listings. Each entry of the form 'account-index-expiry' + """ + activeListings: [String!]! + + """ + Information about the active pod orders. Each entry of the form 'orderId-maxPlaceInLine' + """ + activeOrders: [String!]! + """All historical listings""" allListings(first: Int = 100, orderBy: PodListing_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: PodListing_filter): [PodListing!]! @@ -4662,14 +4734,17 @@ type PodMarketplace { """Current amount of total pods listed""" availableListedPods: BigInt! + """Current amount of total beans in pod orders""" + availableOrderBeans: BigInt! + """Cumulative bean volume between listings and orders""" beanVolume: BigInt! """Current cumulative pod listings that were cancelled""" cancelledListedPods: BigInt! - """Current cumulative pod orders cancelled""" - cancelledOrderedPods: BigInt! + """Current cumulative beans in pod orders cancelled""" + cancelledOrderBeans: BigInt! """Link to daily snapshot data""" dailySnapshots(first: Int = 100, orderBy: PodMarketplaceDailySnapshot_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: PodMarketplaceDailySnapshot_filter): [PodMarketplaceDailySnapshot!]! @@ -4680,6 +4755,9 @@ type PodMarketplace { """Current cumulative pod listings filled""" filledListedPods: BigInt! + """Current cumulative filled beans in pod orders""" + filledOrderBeans: BigInt! + """Current cumulative pod orders filled""" filledOrderedPods: BigInt! @@ -4695,14 +4773,8 @@ type PodMarketplace { """Current cumulative pods listed for sale""" listedPods: BigInt! - """Indexes of actively listed plots""" - listingIndexes: [BigInt!]! - - """Current cumulative pod orders created""" - orderedPods: BigInt! - - """Active pod order IDs""" - orders(first: Int = 100, orderBy: PodOrder_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: PodOrder_filter): [PodOrder!]! + """Current cumulative beans in pod orders created""" + orderBeans: BigInt! """Cumulative pod volume between listings and orders""" podVolume: BigInt! @@ -4715,6 +4787,9 @@ type PodMarketplaceDailySnapshot { """Point in time current amount of total pods listed""" availableListedPods: BigInt! + """Current amount of total beans in pod orders""" + availableOrderBeans: BigInt! + """ Point in time current cumulative bean volume between listings and orders """ @@ -4723,8 +4798,8 @@ type PodMarketplaceDailySnapshot { """Point in time current cumulative pod listings that were cancelled""" cancelledListedPods: BigInt! - """Point in time current cumulative pod orders cancelled""" - cancelledOrderedPods: BigInt! + """Current cumulative beans in pod orders cancelled""" + cancelledOrderBeans: BigInt! """Timestamp of initial snapshot creation""" createdAt: BigInt! @@ -4732,14 +4807,17 @@ type PodMarketplaceDailySnapshot { """Point in time current delta of total pods listed""" deltaAvailableListedPods: BigInt! + """Point in time current delta available ordered beans in pod orders""" + deltaAvailableOrderBeans: BigInt! + """Point in time current delta bean volume between listings and orders""" deltaBeanVolume: BigInt! """Point in time current delta pod listings that were cancelled""" deltaCancelledListedPods: BigInt! - """Point in time current delta pod orders cancelled""" - deltaCancelledOrderedPods: BigInt! + """Point in time current delta cancelled ordered beans in pod orders""" + deltaCancelledOrderBeans: BigInt! """Point in time current delta pod listings that expired""" deltaExpiredListedPods: BigInt! @@ -4747,14 +4825,17 @@ type PodMarketplaceDailySnapshot { """Point in time current delta pod listings filled""" deltaFilledListedPods: BigInt! + """Point in time current delta filled ordered beans in pod orders""" + deltaFilledOrderBeans: BigInt! + """Point in time current delta pod orders filled""" deltaFilledOrderedPods: BigInt! """Point in time current delta pods listed for sale""" deltaListedPods: BigInt! - """Point in time current delta pod orders created""" - deltaOrderedPods: BigInt! + """Point in time current delta ordered beans in pod orders created""" + deltaOrderBeans: BigInt! """Point in time current delta pod volume between listings and orders""" deltaPodVolume: BigInt! @@ -4765,7 +4846,10 @@ type PodMarketplaceDailySnapshot { """Point in time current cumulative pod listings filled""" filledListedPods: BigInt! - """Point in time current cumulative pod orders filled""" + """Current cumulative filled beans in pod orders""" + filledOrderBeans: BigInt! + + """Current cumulative pod orders filled""" filledOrderedPods: BigInt! """Marketplace ID - Unix Timestamp""" @@ -4774,8 +4858,8 @@ type PodMarketplaceDailySnapshot { """Point in time current cumulative pods listed for sale""" listedPods: BigInt! - """Point in time current cumulative pod orders created""" - orderedPods: BigInt! + """Current cumulative beans in pod orders created""" + orderBeans: BigInt! """Marketplace associated with snapshot""" podMarketplace: PodMarketplace! @@ -4804,6 +4888,14 @@ input PodMarketplaceDailySnapshot_filter { availableListedPods_lte: BigInt availableListedPods_not: BigInt availableListedPods_not_in: [BigInt!] + availableOrderBeans: BigInt + availableOrderBeans_gt: BigInt + availableOrderBeans_gte: BigInt + availableOrderBeans_in: [BigInt!] + availableOrderBeans_lt: BigInt + availableOrderBeans_lte: BigInt + availableOrderBeans_not: BigInt + availableOrderBeans_not_in: [BigInt!] beanVolume: BigInt beanVolume_gt: BigInt beanVolume_gte: BigInt @@ -4820,14 +4912,14 @@ input PodMarketplaceDailySnapshot_filter { cancelledListedPods_lte: BigInt cancelledListedPods_not: BigInt cancelledListedPods_not_in: [BigInt!] - cancelledOrderedPods: BigInt - cancelledOrderedPods_gt: BigInt - cancelledOrderedPods_gte: BigInt - cancelledOrderedPods_in: [BigInt!] - cancelledOrderedPods_lt: BigInt - cancelledOrderedPods_lte: BigInt - cancelledOrderedPods_not: BigInt - cancelledOrderedPods_not_in: [BigInt!] + cancelledOrderBeans: BigInt + cancelledOrderBeans_gt: BigInt + cancelledOrderBeans_gte: BigInt + cancelledOrderBeans_in: [BigInt!] + cancelledOrderBeans_lt: BigInt + cancelledOrderBeans_lte: BigInt + cancelledOrderBeans_not: BigInt + cancelledOrderBeans_not_in: [BigInt!] createdAt: BigInt createdAt_gt: BigInt createdAt_gte: BigInt @@ -4844,6 +4936,14 @@ input PodMarketplaceDailySnapshot_filter { deltaAvailableListedPods_lte: BigInt deltaAvailableListedPods_not: BigInt deltaAvailableListedPods_not_in: [BigInt!] + deltaAvailableOrderBeans: BigInt + deltaAvailableOrderBeans_gt: BigInt + deltaAvailableOrderBeans_gte: BigInt + deltaAvailableOrderBeans_in: [BigInt!] + deltaAvailableOrderBeans_lt: BigInt + deltaAvailableOrderBeans_lte: BigInt + deltaAvailableOrderBeans_not: BigInt + deltaAvailableOrderBeans_not_in: [BigInt!] deltaBeanVolume: BigInt deltaBeanVolume_gt: BigInt deltaBeanVolume_gte: BigInt @@ -4860,14 +4960,14 @@ input PodMarketplaceDailySnapshot_filter { deltaCancelledListedPods_lte: BigInt deltaCancelledListedPods_not: BigInt deltaCancelledListedPods_not_in: [BigInt!] - deltaCancelledOrderedPods: BigInt - deltaCancelledOrderedPods_gt: BigInt - deltaCancelledOrderedPods_gte: BigInt - deltaCancelledOrderedPods_in: [BigInt!] - deltaCancelledOrderedPods_lt: BigInt - deltaCancelledOrderedPods_lte: BigInt - deltaCancelledOrderedPods_not: BigInt - deltaCancelledOrderedPods_not_in: [BigInt!] + deltaCancelledOrderBeans: BigInt + deltaCancelledOrderBeans_gt: BigInt + deltaCancelledOrderBeans_gte: BigInt + deltaCancelledOrderBeans_in: [BigInt!] + deltaCancelledOrderBeans_lt: BigInt + deltaCancelledOrderBeans_lte: BigInt + deltaCancelledOrderBeans_not: BigInt + deltaCancelledOrderBeans_not_in: [BigInt!] deltaExpiredListedPods: BigInt deltaExpiredListedPods_gt: BigInt deltaExpiredListedPods_gte: BigInt @@ -4884,6 +4984,14 @@ input PodMarketplaceDailySnapshot_filter { deltaFilledListedPods_lte: BigInt deltaFilledListedPods_not: BigInt deltaFilledListedPods_not_in: [BigInt!] + deltaFilledOrderBeans: BigInt + deltaFilledOrderBeans_gt: BigInt + deltaFilledOrderBeans_gte: BigInt + deltaFilledOrderBeans_in: [BigInt!] + deltaFilledOrderBeans_lt: BigInt + deltaFilledOrderBeans_lte: BigInt + deltaFilledOrderBeans_not: BigInt + deltaFilledOrderBeans_not_in: [BigInt!] deltaFilledOrderedPods: BigInt deltaFilledOrderedPods_gt: BigInt deltaFilledOrderedPods_gte: BigInt @@ -4900,14 +5008,14 @@ input PodMarketplaceDailySnapshot_filter { deltaListedPods_lte: BigInt deltaListedPods_not: BigInt deltaListedPods_not_in: [BigInt!] - deltaOrderedPods: BigInt - deltaOrderedPods_gt: BigInt - deltaOrderedPods_gte: BigInt - deltaOrderedPods_in: [BigInt!] - deltaOrderedPods_lt: BigInt - deltaOrderedPods_lte: BigInt - deltaOrderedPods_not: BigInt - deltaOrderedPods_not_in: [BigInt!] + deltaOrderBeans: BigInt + deltaOrderBeans_gt: BigInt + deltaOrderBeans_gte: BigInt + deltaOrderBeans_in: [BigInt!] + deltaOrderBeans_lt: BigInt + deltaOrderBeans_lte: BigInt + deltaOrderBeans_not: BigInt + deltaOrderBeans_not_in: [BigInt!] deltaPodVolume: BigInt deltaPodVolume_gt: BigInt deltaPodVolume_gte: BigInt @@ -4932,6 +5040,14 @@ input PodMarketplaceDailySnapshot_filter { filledListedPods_lte: BigInt filledListedPods_not: BigInt filledListedPods_not_in: [BigInt!] + filledOrderBeans: BigInt + filledOrderBeans_gt: BigInt + filledOrderBeans_gte: BigInt + filledOrderBeans_in: [BigInt!] + filledOrderBeans_lt: BigInt + filledOrderBeans_lte: BigInt + filledOrderBeans_not: BigInt + filledOrderBeans_not_in: [BigInt!] filledOrderedPods: BigInt filledOrderedPods_gt: BigInt filledOrderedPods_gte: BigInt @@ -4957,14 +5073,14 @@ input PodMarketplaceDailySnapshot_filter { listedPods_not: BigInt listedPods_not_in: [BigInt!] or: [PodMarketplaceDailySnapshot_filter] - orderedPods: BigInt - orderedPods_gt: BigInt - orderedPods_gte: BigInt - orderedPods_in: [BigInt!] - orderedPods_lt: BigInt - orderedPods_lte: BigInt - orderedPods_not: BigInt - orderedPods_not_in: [BigInt!] + orderBeans: BigInt + orderBeans_gt: BigInt + orderBeans_gte: BigInt + orderBeans_in: [BigInt!] + orderBeans_lt: BigInt + orderBeans_lte: BigInt + orderBeans_not: BigInt + orderBeans_not_in: [BigInt!] podMarketplace: String podMarketplace_: PodMarketplace_filter podMarketplace_contains: String @@ -5014,37 +5130,43 @@ input PodMarketplaceDailySnapshot_filter { enum PodMarketplaceDailySnapshot_orderBy { availableListedPods + availableOrderBeans beanVolume cancelledListedPods - cancelledOrderedPods + cancelledOrderBeans createdAt deltaAvailableListedPods + deltaAvailableOrderBeans deltaBeanVolume deltaCancelledListedPods - deltaCancelledOrderedPods + deltaCancelledOrderBeans deltaExpiredListedPods deltaFilledListedPods + deltaFilledOrderBeans deltaFilledOrderedPods deltaListedPods - deltaOrderedPods + deltaOrderBeans deltaPodVolume expiredListedPods filledListedPods + filledOrderBeans filledOrderedPods id listedPods - orderedPods + orderBeans podMarketplace podMarketplace__availableListedPods + podMarketplace__availableOrderBeans podMarketplace__beanVolume podMarketplace__cancelledListedPods - podMarketplace__cancelledOrderedPods + podMarketplace__cancelledOrderBeans podMarketplace__expiredListedPods podMarketplace__filledListedPods + podMarketplace__filledOrderBeans podMarketplace__filledOrderedPods podMarketplace__id podMarketplace__listedPods - podMarketplace__orderedPods + podMarketplace__orderBeans podMarketplace__podVolume podMarketplace__season podVolume @@ -5056,6 +5178,9 @@ type PodMarketplaceHourlySnapshot { """Point in time current amount of total pods listed""" availableListedPods: BigInt! + """Current amount of total beans in pod orders""" + availableOrderBeans: BigInt! + """ Point in time current cumulative bean volume between listings and orders """ @@ -5064,8 +5189,8 @@ type PodMarketplaceHourlySnapshot { """Point in time current cumulative pod listings that were cancelled""" cancelledListedPods: BigInt! - """Point in time current cumulative pod orders cancelled""" - cancelledOrderedPods: BigInt! + """Current cumulative beans in pod orders cancelled""" + cancelledOrderBeans: BigInt! """Timestamp of initial snapshot creation""" createdAt: BigInt! @@ -5073,14 +5198,17 @@ type PodMarketplaceHourlySnapshot { """Point in time current delta of total pods listed""" deltaAvailableListedPods: BigInt! + """Point in time current delta available ordered beans in pod orders""" + deltaAvailableOrderBeans: BigInt! + """Point in time current delta bean volume between listings and orders""" deltaBeanVolume: BigInt! """Point in time current delta pod listings that were cancelled""" deltaCancelledListedPods: BigInt! - """Point in time current delta pod orders cancelled""" - deltaCancelledOrderedPods: BigInt! + """Point in time current delta cancelled ordered beans in pod orders""" + deltaCancelledOrderBeans: BigInt! """Point in time current delta pod listings that expired""" deltaExpiredListedPods: BigInt! @@ -5088,14 +5216,17 @@ type PodMarketplaceHourlySnapshot { """Point in time current delta pod listings filled""" deltaFilledListedPods: BigInt! + """Point in time current delta filled ordered beans in pod orders""" + deltaFilledOrderBeans: BigInt! + """Point in time current delta pod orders filled""" deltaFilledOrderedPods: BigInt! """Point in time current delta pods listed for sale""" deltaListedPods: BigInt! - """Point in time current delta pod orders created""" - deltaOrderedPods: BigInt! + """Point in time current delta ordered beans in pod orders created""" + deltaOrderBeans: BigInt! """Point in time current delta pod volume between listings and orders""" deltaPodVolume: BigInt! @@ -5106,7 +5237,10 @@ type PodMarketplaceHourlySnapshot { """Point in time current cumulative pod listings filled""" filledListedPods: BigInt! - """Point in time current cumulative pod orders filled""" + """Current cumulative filled beans in pod orders""" + filledOrderBeans: BigInt! + + """Current cumulative pod orders filled""" filledOrderedPods: BigInt! """Marketplace ID - Unix Timestamp""" @@ -5115,8 +5249,8 @@ type PodMarketplaceHourlySnapshot { """Point in time current cumulative pods listed for sale""" listedPods: BigInt! - """Point in time current cumulative pod orders created""" - orderedPods: BigInt! + """Current cumulative beans in pod orders created""" + orderBeans: BigInt! """Marketplace associated with snapshot""" podMarketplace: PodMarketplace! @@ -5145,6 +5279,14 @@ input PodMarketplaceHourlySnapshot_filter { availableListedPods_lte: BigInt availableListedPods_not: BigInt availableListedPods_not_in: [BigInt!] + availableOrderBeans: BigInt + availableOrderBeans_gt: BigInt + availableOrderBeans_gte: BigInt + availableOrderBeans_in: [BigInt!] + availableOrderBeans_lt: BigInt + availableOrderBeans_lte: BigInt + availableOrderBeans_not: BigInt + availableOrderBeans_not_in: [BigInt!] beanVolume: BigInt beanVolume_gt: BigInt beanVolume_gte: BigInt @@ -5161,14 +5303,14 @@ input PodMarketplaceHourlySnapshot_filter { cancelledListedPods_lte: BigInt cancelledListedPods_not: BigInt cancelledListedPods_not_in: [BigInt!] - cancelledOrderedPods: BigInt - cancelledOrderedPods_gt: BigInt - cancelledOrderedPods_gte: BigInt - cancelledOrderedPods_in: [BigInt!] - cancelledOrderedPods_lt: BigInt - cancelledOrderedPods_lte: BigInt - cancelledOrderedPods_not: BigInt - cancelledOrderedPods_not_in: [BigInt!] + cancelledOrderBeans: BigInt + cancelledOrderBeans_gt: BigInt + cancelledOrderBeans_gte: BigInt + cancelledOrderBeans_in: [BigInt!] + cancelledOrderBeans_lt: BigInt + cancelledOrderBeans_lte: BigInt + cancelledOrderBeans_not: BigInt + cancelledOrderBeans_not_in: [BigInt!] createdAt: BigInt createdAt_gt: BigInt createdAt_gte: BigInt @@ -5185,6 +5327,14 @@ input PodMarketplaceHourlySnapshot_filter { deltaAvailableListedPods_lte: BigInt deltaAvailableListedPods_not: BigInt deltaAvailableListedPods_not_in: [BigInt!] + deltaAvailableOrderBeans: BigInt + deltaAvailableOrderBeans_gt: BigInt + deltaAvailableOrderBeans_gte: BigInt + deltaAvailableOrderBeans_in: [BigInt!] + deltaAvailableOrderBeans_lt: BigInt + deltaAvailableOrderBeans_lte: BigInt + deltaAvailableOrderBeans_not: BigInt + deltaAvailableOrderBeans_not_in: [BigInt!] deltaBeanVolume: BigInt deltaBeanVolume_gt: BigInt deltaBeanVolume_gte: BigInt @@ -5201,14 +5351,14 @@ input PodMarketplaceHourlySnapshot_filter { deltaCancelledListedPods_lte: BigInt deltaCancelledListedPods_not: BigInt deltaCancelledListedPods_not_in: [BigInt!] - deltaCancelledOrderedPods: BigInt - deltaCancelledOrderedPods_gt: BigInt - deltaCancelledOrderedPods_gte: BigInt - deltaCancelledOrderedPods_in: [BigInt!] - deltaCancelledOrderedPods_lt: BigInt - deltaCancelledOrderedPods_lte: BigInt - deltaCancelledOrderedPods_not: BigInt - deltaCancelledOrderedPods_not_in: [BigInt!] + deltaCancelledOrderBeans: BigInt + deltaCancelledOrderBeans_gt: BigInt + deltaCancelledOrderBeans_gte: BigInt + deltaCancelledOrderBeans_in: [BigInt!] + deltaCancelledOrderBeans_lt: BigInt + deltaCancelledOrderBeans_lte: BigInt + deltaCancelledOrderBeans_not: BigInt + deltaCancelledOrderBeans_not_in: [BigInt!] deltaExpiredListedPods: BigInt deltaExpiredListedPods_gt: BigInt deltaExpiredListedPods_gte: BigInt @@ -5225,6 +5375,14 @@ input PodMarketplaceHourlySnapshot_filter { deltaFilledListedPods_lte: BigInt deltaFilledListedPods_not: BigInt deltaFilledListedPods_not_in: [BigInt!] + deltaFilledOrderBeans: BigInt + deltaFilledOrderBeans_gt: BigInt + deltaFilledOrderBeans_gte: BigInt + deltaFilledOrderBeans_in: [BigInt!] + deltaFilledOrderBeans_lt: BigInt + deltaFilledOrderBeans_lte: BigInt + deltaFilledOrderBeans_not: BigInt + deltaFilledOrderBeans_not_in: [BigInt!] deltaFilledOrderedPods: BigInt deltaFilledOrderedPods_gt: BigInt deltaFilledOrderedPods_gte: BigInt @@ -5241,14 +5399,14 @@ input PodMarketplaceHourlySnapshot_filter { deltaListedPods_lte: BigInt deltaListedPods_not: BigInt deltaListedPods_not_in: [BigInt!] - deltaOrderedPods: BigInt - deltaOrderedPods_gt: BigInt - deltaOrderedPods_gte: BigInt - deltaOrderedPods_in: [BigInt!] - deltaOrderedPods_lt: BigInt - deltaOrderedPods_lte: BigInt - deltaOrderedPods_not: BigInt - deltaOrderedPods_not_in: [BigInt!] + deltaOrderBeans: BigInt + deltaOrderBeans_gt: BigInt + deltaOrderBeans_gte: BigInt + deltaOrderBeans_in: [BigInt!] + deltaOrderBeans_lt: BigInt + deltaOrderBeans_lte: BigInt + deltaOrderBeans_not: BigInt + deltaOrderBeans_not_in: [BigInt!] deltaPodVolume: BigInt deltaPodVolume_gt: BigInt deltaPodVolume_gte: BigInt @@ -5273,6 +5431,14 @@ input PodMarketplaceHourlySnapshot_filter { filledListedPods_lte: BigInt filledListedPods_not: BigInt filledListedPods_not_in: [BigInt!] + filledOrderBeans: BigInt + filledOrderBeans_gt: BigInt + filledOrderBeans_gte: BigInt + filledOrderBeans_in: [BigInt!] + filledOrderBeans_lt: BigInt + filledOrderBeans_lte: BigInt + filledOrderBeans_not: BigInt + filledOrderBeans_not_in: [BigInt!] filledOrderedPods: BigInt filledOrderedPods_gt: BigInt filledOrderedPods_gte: BigInt @@ -5298,14 +5464,14 @@ input PodMarketplaceHourlySnapshot_filter { listedPods_not: BigInt listedPods_not_in: [BigInt!] or: [PodMarketplaceHourlySnapshot_filter] - orderedPods: BigInt - orderedPods_gt: BigInt - orderedPods_gte: BigInt - orderedPods_in: [BigInt!] - orderedPods_lt: BigInt - orderedPods_lte: BigInt - orderedPods_not: BigInt - orderedPods_not_in: [BigInt!] + orderBeans: BigInt + orderBeans_gt: BigInt + orderBeans_gte: BigInt + orderBeans_in: [BigInt!] + orderBeans_lt: BigInt + orderBeans_lte: BigInt + orderBeans_not: BigInt + orderBeans_not_in: [BigInt!] podMarketplace: String podMarketplace_: PodMarketplace_filter podMarketplace_contains: String @@ -5355,37 +5521,43 @@ input PodMarketplaceHourlySnapshot_filter { enum PodMarketplaceHourlySnapshot_orderBy { availableListedPods + availableOrderBeans beanVolume cancelledListedPods - cancelledOrderedPods + cancelledOrderBeans createdAt deltaAvailableListedPods + deltaAvailableOrderBeans deltaBeanVolume deltaCancelledListedPods - deltaCancelledOrderedPods + deltaCancelledOrderBeans deltaExpiredListedPods deltaFilledListedPods + deltaFilledOrderBeans deltaFilledOrderedPods deltaListedPods - deltaOrderedPods + deltaOrderBeans deltaPodVolume expiredListedPods filledListedPods + filledOrderBeans filledOrderedPods id listedPods - orderedPods + orderBeans podMarketplace podMarketplace__availableListedPods + podMarketplace__availableOrderBeans podMarketplace__beanVolume podMarketplace__cancelledListedPods - podMarketplace__cancelledOrderedPods + podMarketplace__cancelledOrderBeans podMarketplace__expiredListedPods podMarketplace__filledListedPods + podMarketplace__filledOrderBeans podMarketplace__filledOrderedPods podMarketplace__id podMarketplace__listedPods - podMarketplace__orderedPods + podMarketplace__orderBeans podMarketplace__podVolume podMarketplace__season podVolume @@ -5396,6 +5568,18 @@ enum PodMarketplaceHourlySnapshot_orderBy { input PodMarketplace_filter { """Filter for the block changed event.""" _change_block: BlockChangedFilter + activeListings: [String!] + activeListings_contains: [String!] + activeListings_contains_nocase: [String!] + activeListings_not: [String!] + activeListings_not_contains: [String!] + activeListings_not_contains_nocase: [String!] + activeOrders: [String!] + activeOrders_contains: [String!] + activeOrders_contains_nocase: [String!] + activeOrders_not: [String!] + activeOrders_not_contains: [String!] + activeOrders_not_contains_nocase: [String!] allListings_: PodListing_filter allOrders_: PodOrder_filter and: [PodMarketplace_filter] @@ -5407,6 +5591,14 @@ input PodMarketplace_filter { availableListedPods_lte: BigInt availableListedPods_not: BigInt availableListedPods_not_in: [BigInt!] + availableOrderBeans: BigInt + availableOrderBeans_gt: BigInt + availableOrderBeans_gte: BigInt + availableOrderBeans_in: [BigInt!] + availableOrderBeans_lt: BigInt + availableOrderBeans_lte: BigInt + availableOrderBeans_not: BigInt + availableOrderBeans_not_in: [BigInt!] beanVolume: BigInt beanVolume_gt: BigInt beanVolume_gte: BigInt @@ -5423,14 +5615,14 @@ input PodMarketplace_filter { cancelledListedPods_lte: BigInt cancelledListedPods_not: BigInt cancelledListedPods_not_in: [BigInt!] - cancelledOrderedPods: BigInt - cancelledOrderedPods_gt: BigInt - cancelledOrderedPods_gte: BigInt - cancelledOrderedPods_in: [BigInt!] - cancelledOrderedPods_lt: BigInt - cancelledOrderedPods_lte: BigInt - cancelledOrderedPods_not: BigInt - cancelledOrderedPods_not_in: [BigInt!] + cancelledOrderBeans: BigInt + cancelledOrderBeans_gt: BigInt + cancelledOrderBeans_gte: BigInt + cancelledOrderBeans_in: [BigInt!] + cancelledOrderBeans_lt: BigInt + cancelledOrderBeans_lte: BigInt + cancelledOrderBeans_not: BigInt + cancelledOrderBeans_not_in: [BigInt!] dailySnapshots_: PodMarketplaceDailySnapshot_filter expiredListedPods: BigInt expiredListedPods_gt: BigInt @@ -5448,6 +5640,14 @@ input PodMarketplace_filter { filledListedPods_lte: BigInt filledListedPods_not: BigInt filledListedPods_not_in: [BigInt!] + filledOrderBeans: BigInt + filledOrderBeans_gt: BigInt + filledOrderBeans_gte: BigInt + filledOrderBeans_in: [BigInt!] + filledOrderBeans_lt: BigInt + filledOrderBeans_lte: BigInt + filledOrderBeans_not: BigInt + filledOrderBeans_not_in: [BigInt!] filledOrderedPods: BigInt filledOrderedPods_gt: BigInt filledOrderedPods_gte: BigInt @@ -5474,28 +5674,15 @@ input PodMarketplace_filter { listedPods_lte: BigInt listedPods_not: BigInt listedPods_not_in: [BigInt!] - listingIndexes: [BigInt!] - listingIndexes_contains: [BigInt!] - listingIndexes_contains_nocase: [BigInt!] - listingIndexes_not: [BigInt!] - listingIndexes_not_contains: [BigInt!] - listingIndexes_not_contains_nocase: [BigInt!] or: [PodMarketplace_filter] - orderedPods: BigInt - orderedPods_gt: BigInt - orderedPods_gte: BigInt - orderedPods_in: [BigInt!] - orderedPods_lt: BigInt - orderedPods_lte: BigInt - orderedPods_not: BigInt - orderedPods_not_in: [BigInt!] - orders: [String!] - orders_: PodOrder_filter - orders_contains: [String!] - orders_contains_nocase: [String!] - orders_not: [String!] - orders_not_contains: [String!] - orders_not_contains_nocase: [String!] + orderBeans: BigInt + orderBeans_gt: BigInt + orderBeans_gte: BigInt + orderBeans_in: [BigInt!] + orderBeans_lt: BigInt + orderBeans_lte: BigInt + orderBeans_not: BigInt + orderBeans_not_in: [BigInt!] podVolume: BigInt podVolume_gt: BigInt podVolume_gte: BigInt @@ -5515,23 +5702,25 @@ input PodMarketplace_filter { } enum PodMarketplace_orderBy { + activeListings + activeOrders allListings allOrders availableListedPods + availableOrderBeans beanVolume cancelledListedPods - cancelledOrderedPods + cancelledOrderBeans dailySnapshots expiredListedPods filledListedPods + filledOrderBeans filledOrderedPods fills hourlySnapshots id listedPods - listingIndexes - orderedPods - orders + orderBeans podVolume season } @@ -5567,9 +5756,6 @@ type PodOrder { """Minimum number of Pods required to perform a Fill.""" minFillAmount: BigInt! - "The original number of Pods requested by this PodOrder.\n\nDoes NOT change as Fills occur.\nNot deterministic for PodOrders with pricingType = DYNAMIC.\n\nIf pricingType = FIXED:\n Set to the number of Pods which can be purchased by the Order.\n If FIXED (V1): `amount` field emitted in PodOrderCreated.\n If FIXED (V2): `amount / pricePerPod` fields emitted in PodOrderCreated.\n\nIf pricingType = DYNAMIC:\n Set to `0`. The number of Pods that will be provided is unknown, since\n the price is calculated based on the place in line of supplied Pods.\n" - podAmount: BigInt! - "The current number of Pods that have been purchased by this PodOrder.\n\nIncreases during each subsequent Fill.\nIf pricingType = FIXED: `0 <= podAmountFilled <= podAmount`\nIf pricingType = DYNAMIC: No constraint, since `podAmount` is unknown.\n\nUpon PodOrder cancellation, this value is locked.\n" podAmountFilled: BigInt! @@ -6068,6 +6254,9 @@ type PodOrderFilled implements MarketplaceEvent { """ logIndex: Int! + """Where these pods were in line when filled""" + placeInLine: BigInt! + """ The protocol this transaction belongs to """ protocol: Beanstalk! @@ -6199,6 +6388,14 @@ input PodOrderFilled_filter { logIndex_not: Int logIndex_not_in: [Int!] or: [PodOrderFilled_filter] + placeInLine: BigInt + placeInLine_gt: BigInt + placeInLine_gte: BigInt + placeInLine_in: [BigInt!] + placeInLine_lt: BigInt + placeInLine_lte: BigInt + placeInLine_not: BigInt + placeInLine_not_in: [BigInt!] protocol: String protocol_: Beanstalk_filter protocol_contains: String @@ -6261,6 +6458,7 @@ enum PodOrderFilled_orderBy { id index logIndex + placeInLine protocol protocol__id protocol__lastSeason @@ -6395,7 +6593,6 @@ input PodOrder_filter { minFillAmount_not: BigInt minFillAmount_not_in: [BigInt!] or: [PodOrder_filter] - podAmount: BigInt podAmountFilled: BigInt podAmountFilled_gt: BigInt podAmountFilled_gte: BigInt @@ -6404,13 +6601,6 @@ input PodOrder_filter { podAmountFilled_lte: BigInt podAmountFilled_not: BigInt podAmountFilled_not_in: [BigInt!] - podAmount_gt: BigInt - podAmount_gte: BigInt - podAmount_in: [BigInt!] - podAmount_lt: BigInt - podAmount_lte: BigInt - podAmount_not: BigInt - podAmount_not_in: [BigInt!] podMarketplace: String podMarketplace_: PodMarketplace_filter podMarketplace_contains: String @@ -6484,19 +6674,20 @@ enum PodOrder_orderBy { id maxPlaceInLine minFillAmount - podAmount podAmountFilled podMarketplace podMarketplace__availableListedPods + podMarketplace__availableOrderBeans podMarketplace__beanVolume podMarketplace__cancelledListedPods - podMarketplace__cancelledOrderedPods + podMarketplace__cancelledOrderBeans podMarketplace__expiredListedPods podMarketplace__filledListedPods + podMarketplace__filledOrderBeans podMarketplace__filledOrderedPods podMarketplace__id podMarketplace__listedPods - podMarketplace__orderedPods + podMarketplace__orderBeans podMarketplace__podVolume podMarketplace__season pricePerPod @@ -12533,6 +12724,9 @@ type Subscription { ): [WhitelistToken!]! } +"A string representation of microseconds UNIX timestamp (16 digits)\n" +scalar Timestamp + type TokenYield { """Bean APY for season""" beanAPY: BigDecimal! @@ -13574,6 +13768,9 @@ type _Block_ { """The block number""" number: Int! + """The hash of the parent block""" + parentHash: Bytes + """Integer representation of the timestamp stored in blocks for the chain""" timestamp: Int } From 3d15a59b1f7c391f12a1fd8aaac767c8e8ec989d Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 21 May 2024 12:10:33 -0700 Subject: [PATCH 55/89] Update listing/order fetch size --- .../ui/src/components/Market/PodsV2/FarmerPodListings.graphql | 2 +- .../ui/src/components/Market/PodsV2/FarmerPodOrders.graphql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/FarmerPodListings.graphql b/projects/ui/src/components/Market/PodsV2/FarmerPodListings.graphql index 5ebfb97931..ade30dbe3b 100644 --- a/projects/ui/src/components/Market/PodsV2/FarmerPodListings.graphql +++ b/projects/ui/src/components/Market/PodsV2/FarmerPodListings.graphql @@ -1,7 +1,7 @@ #import "../../PodListing.fragment.graphql" query FarmerPodListings( - $first: Int = 100, + $first: Int = 1000, $createdAt_gt: BigInt, $account: String! ) { diff --git a/projects/ui/src/components/Market/PodsV2/FarmerPodOrders.graphql b/projects/ui/src/components/Market/PodsV2/FarmerPodOrders.graphql index 54d5c561c3..46041843a4 100644 --- a/projects/ui/src/components/Market/PodsV2/FarmerPodOrders.graphql +++ b/projects/ui/src/components/Market/PodsV2/FarmerPodOrders.graphql @@ -1,7 +1,7 @@ #import "../../PodOrder.fragment.graphql" query FarmerPodOrders( - $first: Int = 100, + $first: Int = 1000, $createdAt_gt: BigInt, $account: String! ) { From 176e2053500493e7e3c31695e0a6e630805a71d6 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 21 May 2024 12:14:20 -0700 Subject: [PATCH 56/89] increase pod price precision --- .../ui/src/hooks/farmer/market/useFarmerMarketItemStats.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ui/src/hooks/farmer/market/useFarmerMarketItemStats.tsx b/projects/ui/src/hooks/farmer/market/useFarmerMarketItemStats.tsx index 5b2872d54a..4a93bb6b67 100644 --- a/projects/ui/src/hooks/farmer/market/useFarmerMarketItemStats.tsx +++ b/projects/ui/src/hooks/farmer/market/useFarmerMarketItemStats.tsx @@ -40,7 +40,7 @@ export default function useFarmerMarketItemStats( }); items.push({ label: 'PRICE', - info: displayFullBN(item.pricePerPod, 2, 2), + info: displayFullBN(item.pricePerPod, 4, 2), }); if (isListing(item)) { items.push({ From c44423f760c6796d15b2e7c06b21a5f1d9ea6a4a Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 21 May 2024 15:07:22 -0700 Subject: [PATCH 57/89] use verbose id --- projects/subgraph-beanstalk/src/MarketplaceHandler.ts | 2 +- projects/ui/src/state/farmer/market/index.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index b799237ca6..76fd69ca00 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -350,7 +350,7 @@ function podListingCreated(params: PodListingCreatedParams): void { listing.remainingAmount = listing.originalAmount; listing.status = "ACTIVE"; - listing.createdAt = listing.createdAt == ZERO_BI ? params.event.block.timestamp : listing.createdAt; + listing.createdAt = params.event.block.timestamp; listing.updatedAt = params.event.block.timestamp; listing.creationHash = params.event.transaction.hash.toHexString(); diff --git a/projects/ui/src/state/farmer/market/index.ts b/projects/ui/src/state/farmer/market/index.ts index dcbaed06bb..cf83e950ad 100644 --- a/projects/ui/src/state/farmer/market/index.ts +++ b/projects/ui/src/state/farmer/market/index.ts @@ -26,8 +26,9 @@ export const castPodListing = ( listing: PodListingFragment, harvestableIndex: BigNumber ): PodListing => { - const [account, id] = listing.id.split('-'); // Subgraph returns a conjoined ID - const index = toTokenUnitsBN(id, BEAN[1].decimals); + // Subgraph returns id of the form account-index(-relistCount if it got relisted). + const [account, listingIndex] = listing.id.split('-'); + const index = toTokenUnitsBN(listingIndex, BEAN[1].decimals); const maxHarvestableIndex = toTokenUnitsBN( listing.maxHarvestableIndex, BEAN[1].decimals @@ -35,7 +36,7 @@ export const castPodListing = ( return { // Identifiers - id: id, + id: listing.id, account: listing.farmer.id || account, // Configuration From 0e0f0d3b98b9cd6ea69a40b02a8df3daf10e4195 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 21 May 2024 15:12:15 -0700 Subject: [PATCH 58/89] bump subgraph version --- projects/subgraph-beanstalk/src/utils/Beanstalk.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/subgraph-beanstalk/src/utils/Beanstalk.ts b/projects/subgraph-beanstalk/src/utils/Beanstalk.ts index ad75e4e9c2..639b9e26eb 100644 --- a/projects/subgraph-beanstalk/src/utils/Beanstalk.ts +++ b/projects/subgraph-beanstalk/src/utils/Beanstalk.ts @@ -8,9 +8,9 @@ export function loadBeanstalk(protocol: Address): Beanstalk { beanstalk = new Beanstalk(protocol.toHexString()); beanstalk.name = "Beanstalk"; beanstalk.slug = "beanstalk"; - beanstalk.schemaVersion = "2.2.0"; - beanstalk.subgraphVersion = "2.2.0"; - beanstalk.methodologyVersion = "2.2.0"; + beanstalk.schemaVersion = "2.2.1"; + beanstalk.subgraphVersion = "2.2.1"; + beanstalk.methodologyVersion = "2.2.1"; beanstalk.lastUpgrade = ZERO_BI; beanstalk.lastSeason = 1; beanstalk.activeFarmers = []; From e2db68c4d94f5bc8ec8ab268eb5241a1d8173d31 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 21 May 2024 16:15:03 -0700 Subject: [PATCH 59/89] add log index into history id --- projects/subgraph-beanstalk/src/MarketplaceHandler.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts index 76fd69ca00..f6f0d11348 100644 --- a/projects/subgraph-beanstalk/src/MarketplaceHandler.ts +++ b/projects/subgraph-beanstalk/src/MarketplaceHandler.ts @@ -330,7 +330,7 @@ function podListingCreated(params: PodListingCreatedParams): void { listing.filledAmount = ZERO_BI; } - listing.historyID = listing.id + "-" + params.event.block.timestamp.toString(); + listing.historyID = listing.id + "-" + params.event.block.timestamp.toString() + "-" + params.event.logIndex.toString(); listing.plot = plot.id; listing.start = params.start; @@ -417,7 +417,8 @@ function podListingFilled(params: MarketFillParams): void { listing.status = "FILLED_PARTIAL"; let remainingListing = loadPodListing(Address.fromString(listing.farmer), listing.index.plus(params.amount).plus(listing.start)); - remainingListing.historyID = remainingListing.id + "-" + params.event.block.timestamp.toString(); + remainingListing.historyID = + remainingListing.id + "-" + params.event.block.timestamp.toString() + "-" + params.event.logIndex.toString(); remainingListing.plot = listing.index.plus(params.amount).plus(listing.start).toString(); remainingListing.createdAt = listing.createdAt; remainingListing.updatedAt = params.event.block.timestamp; @@ -495,7 +496,7 @@ function podOrderCreated(params: PodOrderCreatedParams): void { createHistoricalPodOrder(order); } - order.historyID = order.id + "-" + params.event.block.timestamp.toString(); + order.historyID = order.id + "-" + params.event.block.timestamp.toString() + "-" + params.event.logIndex.toString(); order.farmer = params.account.toHexString(); order.createdAt = params.event.block.timestamp; order.updatedAt = params.event.block.timestamp; From f6ef05b6dad6f11e199f3692a58b830182a307e9 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 21 May 2024 16:18:16 -0700 Subject: [PATCH 60/89] update test --- projects/subgraph-beanstalk/tests/utils/Marketplace.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts index d0d0f1e466..d6bfb69abe 100644 --- a/projects/subgraph-beanstalk/tests/utils/Marketplace.ts +++ b/projects/subgraph-beanstalk/tests/utils/Marketplace.ts @@ -228,7 +228,7 @@ function assertListingCreated_v2(event: PodListingCreated_v2): void { function assertOrderCreated_v1(account: string, event: PodOrderCreated_v1): void { let orderID = event.params.id.toHexString(); - assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); + assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString() + "-" + event.logIndex.toString()); assert.fieldEquals("PodOrder", orderID, "farmer", account); assert.fieldEquals("PodOrder", orderID, "status", "ACTIVE"); assert.fieldEquals( @@ -244,7 +244,7 @@ function assertOrderCreated_v1(account: string, event: PodOrderCreated_v1): void function assertOrderCreated_v2(account: string, event: PodOrderCreated_v2): void { let orderID = event.params.id.toHexString(); - assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString()); + assert.fieldEquals("PodOrder", orderID, "historyID", orderID + "-" + event.block.timestamp.toString() + "-" + event.logIndex.toString()); assert.fieldEquals("PodOrder", orderID, "farmer", account); assert.fieldEquals("PodOrder", orderID, "status", "ACTIVE"); assert.fieldEquals("PodOrder", orderID, "beanAmount", event.params.amount.toString()); From d394f3f8704454c079d25018e728043ba40ddf2d Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Tue, 21 May 2024 16:33:40 -0700 Subject: [PATCH 61/89] fix basin test --- projects/subgraph-basin/package.json | 2 +- projects/subgraph-basin/tests/Well.test.ts | 10 +++++----- projects/subgraph-beanft/package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/projects/subgraph-basin/package.json b/projects/subgraph-basin/package.json index 5f7ddc7da8..93a659bed9 100644 --- a/projects/subgraph-basin/package.json +++ b/projects/subgraph-basin/package.json @@ -11,7 +11,7 @@ "codegen": "rm -rf ./generated && graph codegen", "build": "yarn codegen && graph build", "test": "graph test", - "testd": "docker run -it --rm --mount type=bind,source=\"$(pwd)\"/matchstick.yaml.docker,target=/matchstick/matchstick.yaml --mount type=bind,source=\"$(pwd)\"/../../,target=/matchstick/repo-mounted/ matchstick", + "testd": "docker run -it --rm --mount type=bind,source=\"$(pwd)\"/matchstick-docker.yaml,target=/matchstick/matchstick.yaml --mount type=bind,source=\"$(pwd)\"/../../,target=/matchstick/repo-mounted/ matchstick", "testd-named": "../subgraph-core/tests/scripts/docker-run-named.sh", "create-local": "graph create --node http://127.0.0.1:8020/ basin", "remove-local": "graph remove --node http://127.0.0.1:8020/ basin", diff --git a/projects/subgraph-basin/tests/Well.test.ts b/projects/subgraph-basin/tests/Well.test.ts index 85ef7ab48b..937d65f618 100644 --- a/projects/subgraph-basin/tests/Well.test.ts +++ b/projects/subgraph-basin/tests/Well.test.ts @@ -72,7 +72,7 @@ describe("Well Entity: Single Event Tests", () => { test("Previous day snapshot entity created", () => { createDefaultAddLiquidity(); - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; + let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; let daySnapshotID = WELL.concatI32(dayID); let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; @@ -104,7 +104,7 @@ describe("Well Entity: Single Event Tests", () => { test("Previous day snapshot entity created", () => { createDefaultAddLiquidity(); - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; + let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; let daySnapshotID = WELL.concatI32(dayID); let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; @@ -142,7 +142,7 @@ describe("Well Entity: Single Event Tests", () => { test("Previous day snapshot entity created", () => { createDefaultAddLiquidity(); - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; + let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; let daySnapshotID = WELL.concatI32(dayID); let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; @@ -174,7 +174,7 @@ describe("Well Entity: Single Event Tests", () => { test("Previous day snapshot entity created", () => { createDefaultAddLiquidity(); - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; + let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; let daySnapshotID = WELL.concatI32(dayID); let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; @@ -227,7 +227,7 @@ describe("Well Entity: Single Event Tests", () => { test("Previous day snapshot entity created", () => { createDefaultAddLiquidity(); - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; + let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; let daySnapshotID = WELL.concatI32(dayID); let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; diff --git a/projects/subgraph-beanft/package.json b/projects/subgraph-beanft/package.json index 6a7f6291dc..9b5e1b4f9f 100644 --- a/projects/subgraph-beanft/package.json +++ b/projects/subgraph-beanft/package.json @@ -5,7 +5,7 @@ "codegen": "rm -rf ./generated && graph codegen", "build": "yarn codegen && graph build", "test": "graph test", - "testd": "docker run -it --rm --mount type=bind,source=\"$(pwd)\"/matchstick.yaml.docker,target=/matchstick/matchstick.yaml --mount type=bind,source=\"$(pwd)\"/../../,target=/matchstick/repo-mounted/ matchstick", + "testd": "docker run -it --rm --mount type=bind,source=\"$(pwd)\"/matchstick-docker.yaml,target=/matchstick/matchstick.yaml --mount type=bind,source=\"$(pwd)\"/../../,target=/matchstick/repo-mounted/ matchstick", "testd-named": "../subgraph-core/tests/scripts/docker-run-named.sh", "create-local": "graph create --node http://localhost:8020/ beanft", "remove-local": "graph remove --node http://localhost:8020/ beanft", From e49b45e48d42bbef46d8d3d438644daa4e5b4dec Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:31:08 -0700 Subject: [PATCH 62/89] Remove deprecated test and bump version --- projects/subgraph-basin/tests/Well.test.ts | 426 ------------------ .../subgraph-beanstalk/src/utils/Beanstalk.ts | 6 +- 2 files changed, 3 insertions(+), 429 deletions(-) delete mode 100644 projects/subgraph-basin/tests/Well.test.ts diff --git a/projects/subgraph-basin/tests/Well.test.ts b/projects/subgraph-basin/tests/Well.test.ts deleted file mode 100644 index 937d65f618..0000000000 --- a/projects/subgraph-basin/tests/Well.test.ts +++ /dev/null @@ -1,426 +0,0 @@ -import { afterEach, assert, beforeEach, clearStore, describe, logStore, test } from "matchstick-as/assembly/index"; -import { BEAN_ERC20, WETH } from "../../subgraph-core/utils/Constants"; -import { ZERO_BD, ZERO_BI } from "../../subgraph-core/utils/Decimals"; -import { loadWell } from "../src/utils/Well"; -import { - ACCOUNT_ENTITY_TYPE, - BEAN_SWAP_AMOUNT, - BEAN_USD_AMOUNT, - CURRENT_BLOCK_TIMESTAMP, - DEPOSIT_ENTITY_TYPE, - SWAP_ACCOUNT, - SWAP_ENTITY_TYPE, - WELL, - WELL_DAILY_ENTITY_TYPE, - WELL_ENTITY_TYPE, - WELL_HOURLY_ENTITY_TYPE, - WELL_LP_AMOUNT, - WETH_SWAP_AMOUNT, - WETH_USD_AMOUNT, - WITHDRAW_ENTITY_TYPE -} from "./helpers/Constants"; -import { boreDefaultWell } from "./helpers/Aquifer"; -import { createDefaultSwap } from "./helpers/Swap"; -import { - createDefaultAddLiquidity, - createDefaultRemoveLiquidity, - createRemoveLiquidityOneBean, - createRemoveLiquidityOneWeth, - loadWithdraw -} from "./helpers/Liquidity"; -import { loadDeposit } from "./helpers/Liquidity"; -import { dayFromTimestamp, hourFromTimestamp } from "../../subgraph-core/utils/Dates"; -import { BigDecimal, BigInt } from "@graphprotocol/graph-ts"; - -describe("Well Entity: Single Event Tests", () => { - beforeEach(() => { - boreDefaultWell(); - }); - - afterEach(() => { - clearStore(); - }); - - describe("Add Liquidity", () => { - test("Deposit counter incremented", () => { - createDefaultAddLiquidity(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "cumulativeDepositCount", "1"); - }); - test("Token Balances updated", () => { - createDefaultAddLiquidity(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.reserves; - - assert.bigIntEquals(BEAN_SWAP_AMOUNT, endingBalances[0]); - assert.bigIntEquals(WETH_SWAP_AMOUNT, endingBalances[1]); - }); - test("Token Balances USD updated", () => { - createDefaultAddLiquidity(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.reservesUSD; - - assert.stringEquals(BEAN_USD_AMOUNT.toString(), endingBalances[0].toString()); - assert.stringEquals(WETH_USD_AMOUNT.toString(), endingBalances[1].toString()); - assert.stringEquals(WETH_USD_AMOUNT.times(BigDecimal.fromString("2")).toString(), updatedStore.totalLiquidityUSD.toString()); - }); - test("Liquidity Token balance", () => { - createDefaultAddLiquidity(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "lpTokenSupply", WELL_LP_AMOUNT.toString()); - }); - test("Previous day snapshot entity created", () => { - createDefaultAddLiquidity(); - - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; - let daySnapshotID = WELL.concatI32(dayID); - - let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; - let hourSnapshotID = WELL.concatI32(hourID); - - assert.fieldEquals(WELL_DAILY_ENTITY_TYPE, daySnapshotID.toHexString(), "id", daySnapshotID.toHexString()); - assert.fieldEquals(WELL_HOURLY_ENTITY_TYPE, hourSnapshotID.toHexString(), "id", hourSnapshotID.toHexString()); - }); - }); - - describe("Remove Liquidity", () => { - test("Withdraw counter incremented", () => { - createDefaultRemoveLiquidity(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "cumulativeWithdrawCount", "1"); - }); - test("Token Balances updated", () => { - createDefaultRemoveLiquidity(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.reserves; - - assert.bigIntEquals(ZERO_BI.minus(BEAN_SWAP_AMOUNT), endingBalances[0]); - assert.bigIntEquals(ZERO_BI.minus(WETH_SWAP_AMOUNT), endingBalances[1]); - }); - test("Liquidity Token balance", () => { - createDefaultRemoveLiquidity(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "lpTokenSupply", ZERO_BI.minus(WELL_LP_AMOUNT).toString()); - }); - test("Previous day snapshot entity created", () => { - createDefaultAddLiquidity(); - - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; - let daySnapshotID = WELL.concatI32(dayID); - - let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; - let hourSnapshotID = WELL.concatI32(hourID); - - assert.fieldEquals(WELL_DAILY_ENTITY_TYPE, daySnapshotID.toHexString(), "id", daySnapshotID.toHexString()); - assert.fieldEquals(WELL_HOURLY_ENTITY_TYPE, hourSnapshotID.toHexString(), "id", hourSnapshotID.toHexString()); - }); - }); - - describe("Remove Liquidity One - Bean", () => { - test("Withdraw counter incremented", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - createRemoveLiquidityOneBean(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "cumulativeWithdrawCount", "1"); - }); - test("Token Balances updated", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - createRemoveLiquidityOneBean(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.reserves; - - assert.bigIntEquals(BEAN_SWAP_AMOUNT, endingBalances[0]); - assert.bigIntEquals(WETH_SWAP_AMOUNT.times(BigInt.fromI32(2)), endingBalances[1]); - }); - test("Liquidity Token balance", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - createRemoveLiquidityOneBean(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "lpTokenSupply", WELL_LP_AMOUNT.toString()); - }); - test("Previous day snapshot entity created", () => { - createDefaultAddLiquidity(); - - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; - let daySnapshotID = WELL.concatI32(dayID); - - let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; - let hourSnapshotID = WELL.concatI32(hourID); - - assert.fieldEquals(WELL_DAILY_ENTITY_TYPE, daySnapshotID.toHexString(), "id", daySnapshotID.toHexString()); - assert.fieldEquals(WELL_HOURLY_ENTITY_TYPE, hourSnapshotID.toHexString(), "id", hourSnapshotID.toHexString()); - }); - }); - - describe("Remove Liquidity One - WETH", () => { - test("Withdraw counter incremented", () => { - createRemoveLiquidityOneWeth(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "cumulativeWithdrawCount", "1"); - }); - test("Token Balances updated", () => { - createRemoveLiquidityOneWeth(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.reserves; - - assert.bigIntEquals(ZERO_BI, endingBalances[0]); - assert.bigIntEquals(ZERO_BI.minus(WETH_SWAP_AMOUNT), endingBalances[1]); - }); - test("Liquidity Token balance", () => { - createRemoveLiquidityOneWeth(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "lpTokenSupply", ZERO_BI.minus(WELL_LP_AMOUNT).toString()); - }); - test("Previous day snapshot entity created", () => { - createDefaultAddLiquidity(); - - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; - let daySnapshotID = WELL.concatI32(dayID); - - let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; - let hourSnapshotID = WELL.concatI32(hourID); - - assert.fieldEquals(WELL_DAILY_ENTITY_TYPE, daySnapshotID.toHexString(), "id", daySnapshotID.toHexString()); - assert.fieldEquals(WELL_HOURLY_ENTITY_TYPE, hourSnapshotID.toHexString(), "id", hourSnapshotID.toHexString()); - }); - }); - - describe("Swap", () => { - test("Swap counter incremented", () => { - createDefaultSwap(); - assert.fieldEquals(WELL_ENTITY_TYPE, WELL.toHexString(), "cumulativeSwapCount", "1"); - }); - - test("Token Balances updated", () => { - createDefaultSwap(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.reserves; - - assert.bigIntEquals(BEAN_SWAP_AMOUNT, endingBalances[0]); - assert.bigIntEquals(ZERO_BI.minus(WETH_SWAP_AMOUNT), endingBalances[1]); - }); - - test("Token Volumes updated", () => { - createDefaultSwap(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.cumulativeVolumeReserves; - - assert.bigIntEquals(BEAN_SWAP_AMOUNT, endingBalances[0]); - assert.bigIntEquals(ZERO_BI, endingBalances[1]); - }); - - test("Token Volumes USD updated", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - createDefaultSwap(); - - let updatedStore = loadWell(WELL); - let endingBalances = updatedStore.cumulativeVolumeReservesUSD; - - assert.stringEquals(BEAN_USD_AMOUNT.toString(), endingBalances[0].toString()); - assert.stringEquals(ZERO_BD.toString(), endingBalances[1].toString()); - assert.stringEquals(BEAN_USD_AMOUNT.toString(), updatedStore.cumulativeVolumeUSD.toString()); - }); - - test("Previous day snapshot entity created", () => { - createDefaultAddLiquidity(); - - let dayID = dayFromTimestamp(CURRENT_BLOCK_TIMESTAMP, 8 * 60 * 60) - 1; - let daySnapshotID = WELL.concatI32(dayID); - - let hourID = hourFromTimestamp(CURRENT_BLOCK_TIMESTAMP) - 1; - let hourSnapshotID = WELL.concatI32(hourID); - - assert.fieldEquals(WELL_DAILY_ENTITY_TYPE, daySnapshotID.toHexString(), "id", daySnapshotID.toHexString()); - assert.fieldEquals(WELL_HOURLY_ENTITY_TYPE, hourSnapshotID.toHexString(), "id", hourSnapshotID.toHexString()); - }); - }); -}); - -describe("Swap Entity", () => { - beforeEach(() => { - boreDefaultWell(); - }); - - afterEach(() => { - clearStore(); - }); - - test("Swap entity exists", () => { - let id = createDefaultSwap(); - assert.fieldEquals(SWAP_ENTITY_TYPE, id, "id", id); - }); - test("Account entity exists", () => { - let id = createDefaultSwap(); - assert.fieldEquals(ACCOUNT_ENTITY_TYPE, SWAP_ACCOUNT.toHexString(), "id", SWAP_ACCOUNT.toHexString()); - }); - test("Well value", () => { - let id = createDefaultSwap(); - assert.fieldEquals(SWAP_ENTITY_TYPE, id, "well", WELL.toHexString()); - }); - test("fromToken value", () => { - let id = createDefaultSwap(); - assert.fieldEquals(SWAP_ENTITY_TYPE, id, "fromToken", BEAN_ERC20.toHexString()); - }); - test("amountIn value", () => { - let id = createDefaultSwap(); - assert.fieldEquals(SWAP_ENTITY_TYPE, id, "amountIn", BEAN_SWAP_AMOUNT.toString()); - }); - test("toToken value", () => { - let id = createDefaultSwap(); - assert.fieldEquals(SWAP_ENTITY_TYPE, id, "toToken", WETH.toHexString()); - }); - test("amountOut value", () => { - let id = createDefaultSwap(); - assert.fieldEquals(SWAP_ENTITY_TYPE, id, "amountOut", WETH_SWAP_AMOUNT.toString()); - }); -}); - -describe("AddLiquidity => Deposit Entity", () => { - beforeEach(() => { - boreDefaultWell(); - }); - - afterEach(() => { - clearStore(); - }); - - test("Deposit entity exists", () => { - let id = createDefaultAddLiquidity(); - assert.fieldEquals(DEPOSIT_ENTITY_TYPE, id, "id", id); - }); - test("Account entity exists", () => { - let id = createDefaultAddLiquidity(); - assert.fieldEquals(ACCOUNT_ENTITY_TYPE, SWAP_ACCOUNT.toHexString(), "id", SWAP_ACCOUNT.toHexString()); - }); - test("Well value", () => { - let id = createDefaultAddLiquidity(); - assert.fieldEquals(DEPOSIT_ENTITY_TYPE, id, "well", WELL.toHexString()); - }); - test("lpAmountOut => liquidity value", () => { - let id = createDefaultAddLiquidity(); - assert.fieldEquals(DEPOSIT_ENTITY_TYPE, id, "liquidity", WELL_LP_AMOUNT.toString()); - }); - test("inputTokens value", () => { - let id = createDefaultAddLiquidity(); - - let updatedStore = loadDeposit(id); - let tokens = updatedStore.tokens; - - assert.bytesEquals(BEAN_ERC20, tokens[0]); - assert.bytesEquals(WETH, tokens[1]); - }); - test("inputTokenAmounts value", () => { - let id = createDefaultAddLiquidity(); - - let updatedStore = loadDeposit(id); - let reserves = updatedStore.reserves; - - assert.bigIntEquals(BEAN_SWAP_AMOUNT, reserves[0]); - assert.bigIntEquals(WETH_SWAP_AMOUNT, reserves[1]); - }); -}); - -describe("RemoveLiquidity => Withdraw Entity", () => { - beforeEach(() => { - boreDefaultWell(); - }); - - afterEach(() => { - clearStore(); - }); - - test("Withdraw entity exists", () => { - let id = createDefaultRemoveLiquidity(); - assert.fieldEquals(WITHDRAW_ENTITY_TYPE, id, "id", id); - }); - test("Account entity exists", () => { - let id = createDefaultRemoveLiquidity(); - assert.fieldEquals(ACCOUNT_ENTITY_TYPE, SWAP_ACCOUNT.toHexString(), "id", SWAP_ACCOUNT.toHexString()); - }); - test("Well value", () => { - let id = createDefaultRemoveLiquidity(); - assert.fieldEquals(WITHDRAW_ENTITY_TYPE, id, "well", WELL.toHexString()); - }); - test("lpAmountIn => liquidity value", () => { - let id = createDefaultRemoveLiquidity(); - assert.fieldEquals(WITHDRAW_ENTITY_TYPE, id, "liquidity", WELL_LP_AMOUNT.toString()); - }); - test("inputTokens value", () => { - let id = createDefaultRemoveLiquidity(); - - let updatedStore = loadWithdraw(id); - let tokens = updatedStore.tokens; - - assert.bytesEquals(BEAN_ERC20, tokens[0]); - assert.bytesEquals(WETH, tokens[1]); - }); - test("inputTokenAmounts value", () => { - let id = createDefaultRemoveLiquidity(); - - let updatedStore = loadWithdraw(id); - let reserves = updatedStore.reserves; - - assert.bigIntEquals(BEAN_SWAP_AMOUNT, reserves[0]); - assert.bigIntEquals(WETH_SWAP_AMOUNT, reserves[1]); - }); -}); - -describe("RemoveLiquidityOneToken => Withdraw Entity", () => { - beforeEach(() => { - boreDefaultWell(); - }); - - afterEach(() => { - clearStore(); - }); - - test("Withdraw entity exists", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - let id = createRemoveLiquidityOneBean(); - assert.fieldEquals(WITHDRAW_ENTITY_TYPE, id, "id", id); - }); - test("Account entity exists", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - let id = createRemoveLiquidityOneBean(); - assert.fieldEquals(ACCOUNT_ENTITY_TYPE, SWAP_ACCOUNT.toHexString(), "id", SWAP_ACCOUNT.toHexString()); - }); - test("Well value", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - let id = createRemoveLiquidityOneBean(); - assert.fieldEquals(WITHDRAW_ENTITY_TYPE, id, "well", WELL.toHexString()); - }); - test("lpAmountIn => liquidity value", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - let id = createRemoveLiquidityOneBean(); - assert.fieldEquals(WITHDRAW_ENTITY_TYPE, id, "liquidity", WELL_LP_AMOUNT.toString()); - }); - test("inputTokens value", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - let id = createRemoveLiquidityOneBean(); - - let updatedStore = loadWithdraw(id); - let tokens = updatedStore.tokens; - - assert.bytesEquals(BEAN_ERC20, tokens[0]); - assert.bytesEquals(WETH, tokens[1]); - }); - test("inputTokenAmounts value", () => { - createDefaultAddLiquidity(); - createDefaultAddLiquidity(); - let id = createRemoveLiquidityOneBean(); - - let updatedStore = loadWithdraw(id); - let reserves = updatedStore.reserves; - - assert.bigIntEquals(BEAN_SWAP_AMOUNT, reserves[0]); - assert.bigIntEquals(ZERO_BI, reserves[1]); - }); -}); diff --git a/projects/subgraph-beanstalk/src/utils/Beanstalk.ts b/projects/subgraph-beanstalk/src/utils/Beanstalk.ts index 670f388e9e..f291ba5861 100644 --- a/projects/subgraph-beanstalk/src/utils/Beanstalk.ts +++ b/projects/subgraph-beanstalk/src/utils/Beanstalk.ts @@ -8,9 +8,9 @@ export function loadBeanstalk(protocol: Address): Beanstalk { beanstalk = new Beanstalk(protocol.toHexString()); beanstalk.name = "Beanstalk"; beanstalk.slug = "beanstalk"; - beanstalk.schemaVersion = "2.2.2"; - beanstalk.subgraphVersion = "2.2.2"; - beanstalk.methodologyVersion = "2.2.2"; + beanstalk.schemaVersion = "2.3.0"; + beanstalk.subgraphVersion = "2.3.0"; + beanstalk.methodologyVersion = "2.3.0"; beanstalk.lastUpgrade = ZERO_BI; beanstalk.lastSeason = 1; beanstalk.activeFarmers = []; From c78c801198dc70ef039c8be4b54350283d7335a7 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:54:39 -0700 Subject: [PATCH 63/89] update codegen --- projects/ui/codegen-individual.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/projects/ui/codegen-individual.yml b/projects/ui/codegen-individual.yml index cae7276cba..3901a79bbc 100644 --- a/projects/ui/codegen-individual.yml +++ b/projects/ui/codegen-individual.yml @@ -3,11 +3,11 @@ # A more optimal solution would involve generating a different schema for each entry in src/graph.endpoints.ts. overwrite: true generates: - ./src/graph/schema-beanstalk.graphql: - schema: - - https://graph.node.bean.money/subgraphs/name/beanstalk - plugins: - - "schema-ast" + # ./src/graph/schema-beanstalk.graphql: + # schema: + # - https://graph.node.bean.money/subgraphs/name/beanstalk-testing + # plugins: + # - "schema-ast" ./src/graph/schema-bean.graphql: schema: - https://graph.node.bean.money/subgraphs/name/bean From 0e5446e73b85d2dd98a9a490b6d0db15c2769a22 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Wed, 3 Jul 2024 18:40:09 +0200 Subject: [PATCH 64/89] use placeInLine --- .../hooks/beanstalk/useMarketActivityData.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts index 0435d17718..0784b825ac 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts @@ -174,7 +174,7 @@ const useMarketActivityData = () => { if (!e.historyID || !podOrder) return null; const podAmount = toTokenUnitsBN( - podOrder.podAmount || 0, + podOrder.podAmountFilled || 0, BEAN[1].decimals ); const pricePerPod = toTokenUnitsBN( @@ -192,7 +192,7 @@ const useMarketActivityData = () => { hash: e.hash, type: 'order' as const, action: 'cancel' as const, - amountPods: toTokenUnitsBN(podOrder?.podAmount, BEAN[1].decimals), + amountPods: toTokenUnitsBN(podOrder?.podAmountFilled, BEAN[1].decimals), placeInLine: toTokenUnitsBN( podOrder?.maxPlaceInLine, BEAN[1].decimals @@ -231,9 +231,9 @@ const useMarketActivityData = () => { action: 'fill' as const, amountPods: podAmountFilled, placeInLine: toTokenUnitsBN( - new BigNumber(e.index), + new BigNumber(e.placeInLine), BEAN[1].decimals - ).minus(harvestableIndex), + ), pricePerPod: pricePerPod, amountBeans: totalBeans, amountUSD: getUSD(BEAN[1], totalBeans), @@ -251,8 +251,9 @@ const useMarketActivityData = () => { type: 'listing' as const, action: 'create' as const, amountPods: numPods, - placeInLine: toTokenUnitsBN(e.index, BEAN[1].decimals).minus( - harvestableIndex + placeInLine: toTokenUnitsBN( + new BigNumber(e.placeInLine), + BEAN[1].decimals ), pricePerPod: pricePerPod, amountBeans: totalBeans, @@ -279,9 +280,9 @@ const useMarketActivityData = () => { action: 'cancel' as const, amountPods: numPods, placeInLine: toTokenUnitsBN( - podListing?.index, + new BigNumber(e.placeInLine), BEAN[1].decimals - ).minus(harvestableIndex), + ), pricePerPod: pricePerPod, amountBeans: totalBeans, amountUSD: getUSD(BEAN[1], totalBeans), @@ -309,9 +310,9 @@ const useMarketActivityData = () => { action: 'fill' as const, amountPods: numPodsFilled, placeInLine: toTokenUnitsBN( - podListing?.index, + new BigNumber(e.placeInLine), BEAN[1].decimals - ).minus(harvestableIndex), + ), pricePerPod: pricePerPod, amountBeans: totalBeans, amountUSD: getUSD(BEAN[1], totalBeans), From e6fadb7599d36380609b892b922b45cd763e4f38 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:12:51 +0200 Subject: [PATCH 65/89] update pod listings/orders queries --- .../components/Market/PodsV2/HistoricalPodListings.graphql | 2 +- .../src/components/Market/PodsV2/HistoricalPodOrders.graphql | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/HistoricalPodListings.graphql b/projects/ui/src/components/Market/PodsV2/HistoricalPodListings.graphql index a51c0eec1a..26e2dbb251 100644 --- a/projects/ui/src/components/Market/PodsV2/HistoricalPodListings.graphql +++ b/projects/ui/src/components/Market/PodsV2/HistoricalPodListings.graphql @@ -3,7 +3,7 @@ query HistoricalPodListings( ) { podListings(where: { historyID_in: $historyIDs - }, orderBy: updatedAt, orderDirection: desc) { + }, orderBy: updatedAt, orderDirection: desc, first: 1000) { #// Identifiers id status diff --git a/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql b/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql index 25fe5b0490..6444c06811 100644 --- a/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql +++ b/projects/ui/src/components/Market/PodsV2/HistoricalPodOrders.graphql @@ -3,7 +3,7 @@ query HistoricalPodOrders( ) { podOrders(where: { historyID_in: $historyIDs - }, orderBy: updatedAt, orderDirection: desc) { + }, orderBy: updatedAt, orderDirection: desc, first: 1000) { #// Identifiers id historyID @@ -16,6 +16,8 @@ query HistoricalPodOrders( #// Amounts #podAmount # sk/fix/pod-market removed podAmount and added beanAmount + beanAmount + beanAmountFilled podAmountFilled #// Metadata From ec8f59cbb60dca4c49ad355a59c87b73efcefb66 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:43:43 +0200 Subject: [PATCH 66/89] remove fetchMoreData --- .../ui/src/components/Market/PodsV2/Modules/MarketTables.tsx | 1 - .../ui/src/components/Market/PodsV2/Tables/MarketActivity.tsx | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx b/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx index 23f1b4bab1..017dc2929b 100644 --- a/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx +++ b/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx @@ -127,7 +127,6 @@ const MarketTables: React.FC<{}> = () => { {openState !== 0 && tab === 3 && ( )} diff --git a/projects/ui/src/components/Market/PodsV2/Tables/MarketActivity.tsx b/projects/ui/src/components/Market/PodsV2/Tables/MarketActivity.tsx index fb6fc338c1..a4b2d4a0ad 100644 --- a/projects/ui/src/components/Market/PodsV2/Tables/MarketActivity.tsx +++ b/projects/ui/src/components/Market/PodsV2/Tables/MarketActivity.tsx @@ -22,8 +22,7 @@ const columns = [ const MarketActivity: React.FC<{ data: MarketEvent[] | undefined; initializing: boolean; - fetchMoreData: () => Promise; -}> = ({ data, initializing, fetchMoreData }) => { +}> = ({ data, initializing }) => { const rows = useMemo(() => (!data || !data.length ? [] : data), [data]); return ( @@ -31,7 +30,6 @@ const MarketActivity: React.FC<{ rows={rows} columns={columns} loading={initializing} - fetchMore={fetchMoreData} getRowId={(row: MarketEvent) => row.eventId} /> ); From 53cc61201a5d9f736dfe323fe7472d7b48487c8d Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:43:53 +0200 Subject: [PATCH 67/89] update marketevents query --- projects/ui/src/components/Market/PodsV2/MarketEvents.graphql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projects/ui/src/components/Market/PodsV2/MarketEvents.graphql b/projects/ui/src/components/Market/PodsV2/MarketEvents.graphql index a86e0b24e3..9740e60f30 100644 --- a/projects/ui/src/components/Market/PodsV2/MarketEvents.graphql +++ b/projects/ui/src/components/Market/PodsV2/MarketEvents.graphql @@ -20,6 +20,7 @@ query MarketEvents( index # of the Listing that was cancelled account historyID + placeInLine # => amount # => pricePerPod } @@ -30,6 +31,7 @@ query MarketEvents( maxHarvestableIndex pricePerPod historyID + placeInLine } ... on PodListingFilled { id @@ -37,6 +39,7 @@ query MarketEvents( to amount index # of Listing that sold + placeInLine start historyID # => pricePerPod @@ -66,6 +69,7 @@ query MarketEvents( to historyID amount + placeInLine index # index of plot was sold to the Order start # # => maxPlaceInLine From c56097b9514c7f4eaf0774bacfb5cfaf3b128b17 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:44:28 +0200 Subject: [PATCH 68/89] updateActivityData now fetches all market events --- .../hooks/beanstalk/useMarketActivityData.ts | 163 ++++++++++++------ 1 file changed, 109 insertions(+), 54 deletions(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts index 0784b825ac..22ddeb87d5 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts @@ -2,6 +2,12 @@ import BigNumber from 'bignumber.js'; import { useCallback, useState, useEffect } from 'react'; import keyBy from 'lodash/keyBy'; import { + HistoricalPodListingsQuery, + HistoricalPodListingsQueryResult, + HistoricalPodOrdersQuery, + HistoricalPodOrdersQueryResult, + MarketEventsQuery, + MarketEventsQueryResult, useHistoricalPodListingsLazyQuery, useHistoricalPodOrdersLazyQuery, useMarketEventsLazyQuery, @@ -27,7 +33,6 @@ export type MarketEvent = { hash: string; }; -export const QUERY_AMOUNT = 500; export const MAX_TIMESTAMP = '9999999999999'; // 166 455 351 3803 /** @@ -43,42 +48,65 @@ const useMarketActivityData = () => { const [page, setPage] = useState(0); const [data, setData] = useState([]); const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + + const [podOrders, setPodOrders] = useState([]); + const [podListings, setPodListings] = useState([]); + const [markEvents, setMarketEvents] = useState([]); /// Queries - const [getMarketEvents, marketEventsQuery] = useMarketEventsLazyQuery({ + const [getMarketEvents] = useMarketEventsLazyQuery({ fetchPolicy: 'network-only', notifyOnNetworkStatusChange: true, variables: { - events_first: QUERY_AMOUNT, + events_first: 1000, events_timestamp_lt: MAX_TIMESTAMP, }, }); - const [getPodOrders, podOrdersQuery] = useHistoricalPodOrdersLazyQuery({ + + const [getPodOrders] = useHistoricalPodOrdersLazyQuery({ fetchPolicy: 'network-only', }); - const [getPodListings, podListingsQuery] = useHistoricalPodListingsLazyQuery({ + + const [getPodListings] = useHistoricalPodListingsLazyQuery({ fetchPolicy: 'network-only', }); - const error = - marketEventsQuery.error || podOrdersQuery.error || podListingsQuery.error; - // fetch const _fetch = useCallback( - async (first: number, after: string) => { + async () => { setLoading(true); setPage((p) => p + 1); - const result = await getMarketEvents({ - variables: { events_first: first, events_timestamp_lt: after }, - }); - // run join query if we loaded more market events - if (result.data?.marketEvents.length) { + let lastOutputLength = 0; + let lastTimestamp = MAX_TIMESTAMP; + + const podMarketEvents: MarketEventsQuery["marketEvents"] = []; + const podOrdersHistoryIDs: HistoricalPodOrdersQuery["podOrders"] = []; + const podListingsHistoryIDs: HistoricalPodListingsQuery["podListings"] = []; + + try { + do { + const events = await getMarketEvents({ + variables: { events_first: 1000, events_timestamp_lt: lastTimestamp }, + }); + if (events.data?.marketEvents.length) { + podMarketEvents.push(...events.data.marketEvents); + lastOutputLength = events.data.marketEvents.length; + lastTimestamp = events.data.marketEvents[events.data.marketEvents.length - 1].createdAt; + }; + } while ( lastOutputLength === 1000 ); + setError(false); + } catch (e) { + setError(true); + } + + // run join query if we loaded market events + if (podMarketEvents.length > 0) { + setMarketEvents(podMarketEvents); // find IDs to join against - const [orderIDs, listingIDs] = result.data.marketEvents.reduce< - [string[], string[]] - >( - (prev, curr) => { + const [orderIDs, listingIDs] = podMarketEvents.reduce( + (prev: any, curr: any) => { if ( curr.__typename === 'PodOrderFilled' || curr.__typename === 'PodOrderCancelled' @@ -96,18 +124,60 @@ const useMarketActivityData = () => { ); // lookup all of the orders and listings needed to join to the above query - await Promise.all([ - getPodOrders({ - variables: { - historyIDs: orderIDs, - }, - }), - getPodListings({ - variables: { - historyIDs: listingIDs, - }, - }), - ]); + + const promises: Promise[] = []; + + const podOrdersRequests = Math.ceil(orderIDs.length / 1000); + const podListingsRequests = Math.ceil(listingIDs.length / 1000); + + try { + for (let i = 0; i < podOrdersRequests; i += 1) { + const startPosition = i * 1000; + const amountToSplice = i !== podOrdersRequests - 1 ? 1000 : orderIDs.length % 1000; + const selectedPodOrders = orderIDs.slice(startPosition, startPosition + amountToSplice); + promises.push( + getPodOrders({ + variables: { + historyIDs: selectedPodOrders + } + }).then( + (r) => { + if (r.data && r.data.podOrders.length) { + podOrdersHistoryIDs.push(...r.data.podOrders); + }; + } + ) + ); + }; + + for (let i = 0; i < podListingsRequests; i += 1) { + const startPosition = i * 1000; + const amountToSplice = i !== podListingsRequests - 1 ? 1000 : listingIDs.length % 1000; + const selectedPodListings = listingIDs.slice(startPosition, startPosition + amountToSplice); + promises.push( + getPodListings({ + variables: { + historyIDs: selectedPodListings + } + }) + .then( + (r) => { + if (r.data && r.data.podListings.length) { + podListingsHistoryIDs.push(...r.data.podListings) + }; + } + ) + ); + }; + setError(false); + } catch (e) { + setError(true); + }; + + + await Promise.all(promises); + setPodOrders(podOrdersHistoryIDs); + setPodListings(podListingsHistoryIDs); } setLoading(false); @@ -115,27 +185,14 @@ const useMarketActivityData = () => { [getMarketEvents, getPodListings, getPodOrders] ); - // look up the next set of marketplaceEvents using the last known timestamp - const fetchMoreData = useCallback(async () => { - const first = QUERY_AMOUNT; - const after = marketEventsQuery.data?.marketEvents?.length - ? marketEventsQuery.data?.marketEvents[ - marketEventsQuery.data?.marketEvents.length - 1 - ].createdAt - : MAX_TIMESTAMP; - console.debug('Fetch more: ', first, after); - await _fetch(first, after); - }, [_fetch, marketEventsQuery.data?.marketEvents]); // when all queries finish, process data + useEffect(() => { - const events = marketEventsQuery.data?.marketEvents; + const events = markEvents; if (!loading && events?.length) { - const podOrdersById = keyBy(podOrdersQuery.data?.podOrders, 'historyID'); - const podListingsById = keyBy( - podListingsQuery.data?.podListings, - 'historyID' - ); + const podOrdersById = keyBy(podOrders, 'historyID'); + const podListingsById = keyBy(podListings, 'historyID'); // FIXME: // This duplicates logic from `castPodListing` and `castPodOrder`. @@ -326,8 +383,7 @@ const useMarketActivityData = () => { }; const _data: MarketEvent[] = []; - const _max = Math.min(events.length, QUERY_AMOUNT * page); - for (let i = 0; i < _max; i += 1) { + for (let i = 0; i < events.length; i += 1) { const parsed = parseEvent(events[i]); if (parsed) _data.push(parsed); } @@ -338,15 +394,15 @@ const useMarketActivityData = () => { getUSD, harvestableIndex, loading, - marketEventsQuery.data, - podListingsQuery.data, - podOrdersQuery.data, + podOrders, + podListings, + markEvents, page, ]); // kick things off useEffect(() => { - _fetch(QUERY_AMOUNT, MAX_TIMESTAMP); + _fetch(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -355,7 +411,6 @@ const useMarketActivityData = () => { harvestableIndex, loading, error, - fetchMoreData, page, }; }; From 257a0c14926b332d50c1f927736e1b1a26d11743 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:21:43 +0200 Subject: [PATCH 69/89] update table spacings --- .../ui/src/components/Market/PodsV2/Tables/FarmerOrders.tsx | 6 +++--- projects/ui/src/hooks/beanstalk/useMarketActivityData.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/Tables/FarmerOrders.tsx b/projects/ui/src/components/Market/PodsV2/Tables/FarmerOrders.tsx index 03f89a4aa4..02c6ed6ed6 100644 --- a/projects/ui/src/components/Market/PodsV2/Tables/FarmerOrders.tsx +++ b/projects/ui/src/components/Market/PodsV2/Tables/FarmerOrders.tsx @@ -10,10 +10,10 @@ const columns = [ MarketColumns.HistoryItem.amountPods(1, 'left'), MarketColumns.Shared.placeInLine(undefined, 1, 'left'), MarketColumns.Shared.pricePerPod(0.8), - MarketColumns.HistoryItem.amountBeans(1.3), + MarketColumns.HistoryItem.amountBeans(1), MarketColumns.HistoryItem.fillPct(0.6), - MarketColumns.Shared.expiry(0.5), - MarketColumns.HistoryItem.status(0.6, 'right'), + MarketColumns.Shared.expiry(0.7), + MarketColumns.HistoryItem.status(0.9, 'right'), ]; /** * Displays a table of a Farmer's outstanding Listings and Orders. diff --git a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts index 22ddeb87d5..5dc4ec9e37 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts @@ -101,7 +101,7 @@ const useMarketActivityData = () => { setError(true); } - // run join query if we loaded market events + // run join query if we loaded any market events if (podMarketEvents.length > 0) { setMarketEvents(podMarketEvents); // find IDs to join against From 26b13248dd8ea24287fa01e0430838ebfd5f25b8 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:08:01 +0200 Subject: [PATCH 70/89] fix broken forms --- .../ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx | 5 +++-- .../components/Market/PodsV2/Tables/AllActiveListings.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx b/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx index 8805900f7c..7db6df9a5f 100644 --- a/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx +++ b/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx @@ -565,7 +565,8 @@ const Graph: FC = ({ setSelectedPoint(hoveredPoint); if (hoveredPoint.type === 'listing') { // handleClickFill(PodOrderAction.BUY, PodOrderType.FILL); - navigate(`/market/buy/${listings[hoveredPoint.index].id}`); + const idNumber = listings[hoveredPoint.index].id.slice(43); + navigate(`/market/buy/${idNumber}`); } else if (hoveredPoint.type === 'order') { // handleClickFill(PodOrderAction.SELL, PodOrderType.FILL); navigate(`/market/sell/${orders[hoveredPoint.index].id}`); @@ -581,7 +582,7 @@ const Graph: FC = ({ hideTooltip(); } } else if (params.listingID) { - const index = listings.findIndex((l) => l.id === params.listingID); + const index = listings.findIndex((l) => l.id.slice(43) === params.listingID); if (index === -1) { if (selectedPoint) { setSelectedPoint(undefined); diff --git a/projects/ui/src/components/Market/PodsV2/Tables/AllActiveListings.tsx b/projects/ui/src/components/Market/PodsV2/Tables/AllActiveListings.tsx index 1435ef1c56..489e789074 100644 --- a/projects/ui/src/components/Market/PodsV2/Tables/AllActiveListings.tsx +++ b/projects/ui/src/components/Market/PodsV2/Tables/AllActiveListings.tsx @@ -38,7 +38,7 @@ const AllActiveListings: React.FC<{ loading={data.loading} getRowId={(row: PodListing) => `${row.account}-${row.id}`} onRowClick={({ row }) => { - navigate(`/market/buy/${row.id.toString()}`); + navigate(`/market/buy/${row.id.toString().slice(43)}`); }} /> ); From f08a363e57d81111cf54f5e5316db075a18ae9bf Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:10:30 +0200 Subject: [PATCH 71/89] update chart tooltip --- .../ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx b/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx index 7db6df9a5f..0c7df4c5f9 100644 --- a/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx +++ b/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx @@ -851,7 +851,7 @@ const Graph: FC = ({ > Viewing: {selectedPoint.type}{' '} {selectedPoint.type === 'listing' - ? selectedPoint.coordinate.id + ? selectedPoint.coordinate.id.slice(43) : selectedPoint.coordinate.id.substring(0, 8)} Date: Thu, 4 Jul 2024 18:33:07 +0200 Subject: [PATCH 72/89] fix pod amount on orders --- projects/ui/src/state/farmer/market/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ui/src/state/farmer/market/index.ts b/projects/ui/src/state/farmer/market/index.ts index cf83e950ad..f40da4a437 100644 --- a/projects/ui/src/state/farmer/market/index.ts +++ b/projects/ui/src/state/farmer/market/index.ts @@ -83,8 +83,8 @@ export const castPodListing = ( * @returns Redux form of PodOrder. */ export const castPodOrder = (order: PodOrderFragment): PodOrder => { - const podAmount = toTokenUnitsBN(order.podAmount, BEAN[1].decimals); const beanAmount = toTokenUnitsBN(order.beanAmount, BEAN[1].decimals); + const podAmount = beanAmount.div(toTokenUnitsBN(order.pricePerPod, BEAN[1].decimals)); const podAmountFilled = toTokenUnitsBN( order.podAmountFilled, BEAN[1].decimals From 9878b798308ea162ec89d79e409dfa5f781f0755 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:58:00 +0200 Subject: [PATCH 73/89] rename cancelled_partial column --- .../components/Market/PodsV2/Tables/columns/market-columns.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx b/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx index 84e1156d99..2f509c63bf 100644 --- a/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx +++ b/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx @@ -461,7 +461,7 @@ export const MarketColumns = { return ( - {params.value.toString().toUpperCase()} + {key === 'cancelled_partial' ? `CANCELLED (PARTIAL)` : params.value.toString().toUpperCase()} ); }, From 4835ad9712818d2d96666b06b1a002228dca8a8c Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:15:11 +0200 Subject: [PATCH 74/89] mark orders >99.99% filled as filled --- .../Market/PodsV2/Modules/MarketTables.tsx | 3 --- .../hooks/farmer/market/useFarmerMarket2.ts | 21 ++++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx b/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx index 017dc2929b..5ff4181cc8 100644 --- a/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx +++ b/projects/ui/src/components/Market/PodsV2/Modules/MarketTables.tsx @@ -3,9 +3,7 @@ import { Stack, Tab, Tabs } from '@mui/material'; import FullscreenIcon from '@mui/icons-material/Fullscreen'; import FullscreenExitIcon from '@mui/icons-material/FullscreenExit'; import { useAtom, useAtomValue } from 'jotai'; - import useTabs from '~/hooks/display/useTabs'; - import { FontSize, FontWeight } from '~/components/App/muiTheme'; import Row from '~/components/Common/Row'; import { @@ -53,7 +51,6 @@ const MarketTables: React.FC<{}> = () => { const { data: eventsData, harvestableIndex, - fetchMoreData, } = useMarketActivityData(); // "MARKET ACTIVITY" // FUNCTIONS diff --git a/projects/ui/src/hooks/farmer/market/useFarmerMarket2.ts b/projects/ui/src/hooks/farmer/market/useFarmerMarket2.ts index 98f953328d..c5e1f6ee16 100644 --- a/projects/ui/src/hooks/farmer/market/useFarmerMarket2.ts +++ b/projects/ui/src/hooks/farmer/market/useFarmerMarket2.ts @@ -195,15 +195,30 @@ export default function useFarmerMarket() { // Cast query data to history item form const data = useMemo( - () => + () => { + const filteredOrderItems: FarmerMarketOrder[] = []; + if (orderItems) { + orderItems.forEach((order) => { + if (order.amountBeans.minus(order.amountBeansFilled).lt(new BigNumber(0.00001))) { + const newOrder = { + ...order, + status: MarketStatus.Filled + }; + filteredOrderItems.push(newOrder); + } else { + filteredOrderItems.push(order); + }; + }); + }; // shortcut to check if listings / orders are still loading - [...(listingItems || []), ...(orderItems || [])].sort((a, b) => { + return [...(listingItems || []), ...(filteredOrderItems || [])].sort((a, b) => { // Sort by MARKET_STATUS_TO_ORDER, then by creation date const x = MARKET_STATUS_TO_ORDER[a.status] - MARKET_STATUS_TO_ORDER[b.status]; if (x !== 0) return x; return parseInt(b.createdAt, 10) - parseInt(a.createdAt, 10); - }), + }); + }, [listingItems, orderItems] ); From 7583ce84d744b212e67c4f0fa546e7042b15b1c7 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Sat, 6 Jul 2024 22:14:49 +0200 Subject: [PATCH 75/89] update allPodListings/allPodOrders queries --- .../ui/src/components/Market/PodsV2/AllPodListings.graphql | 4 +++- projects/ui/src/components/Market/PodsV2/AllPodOrders.graphql | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/AllPodListings.graphql b/projects/ui/src/components/Market/PodsV2/AllPodListings.graphql index 0c09d770dc..5f5b0662cb 100644 --- a/projects/ui/src/components/Market/PodsV2/AllPodListings.graphql +++ b/projects/ui/src/components/Market/PodsV2/AllPodListings.graphql @@ -2,10 +2,12 @@ query AllPodListings( $first: Int = 1000, $status: MarketStatus = ACTIVE, - $maxHarvestableIndex: BigInt! + $maxHarvestableIndex: BigInt!, + $skip: Int = 0, ) { podListings( first: $first, + skip: $skip, where: { status: $status, maxHarvestableIndex_gt: $maxHarvestableIndex, diff --git a/projects/ui/src/components/Market/PodsV2/AllPodOrders.graphql b/projects/ui/src/components/Market/PodsV2/AllPodOrders.graphql index f101f43383..afc287e71e 100644 --- a/projects/ui/src/components/Market/PodsV2/AllPodOrders.graphql +++ b/projects/ui/src/components/Market/PodsV2/AllPodOrders.graphql @@ -1,10 +1,12 @@ #import "./PodOrder.fragment.graphql" query AllPodOrders( $first: Int = 1000, - $status: MarketStatus = ACTIVE + $status: MarketStatus = ACTIVE, + $skip: Int = 0, ) { podOrders( first: $first, + skip: $skip, orderBy: createdAt, orderDirection: desc, where: { status: $status } From bb6de5504f4051525a5e34f9ecee213509965282 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Sat, 6 Jul 2024 22:15:23 +0200 Subject: [PATCH 76/89] add support for more than 1000 listings/orders --- .../ui/src/hooks/beanstalk/useMarketData.ts | 154 ++++++++++++------ 1 file changed, 100 insertions(+), 54 deletions(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketData.ts b/projects/ui/src/hooks/beanstalk/useMarketData.ts index 1622f81b7e..921d671d35 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketData.ts @@ -1,81 +1,127 @@ import BigNumber from 'bignumber.js'; -import { useCallback, useMemo } from 'react'; -import { MarketStatus, useAllPodOrdersQuery } from '~/generated/graphql'; -import useCastApolloQuery from '~/hooks/app/useCastApolloQuery'; +import { useCallback, useEffect, useState } from 'react'; +import { AllPodListingsQuery, AllPodOrdersQuery, MarketStatus, useAllPodListingsLazyQuery, useAllPodOrdersLazyQuery } from '~/generated/graphql'; import useHarvestableIndex from '~/hooks/beanstalk/useHarvestableIndex'; -import usePodListings from '~/hooks/beanstalk/usePodListings'; import { castPodListing, castPodOrder, PodListing, PodOrder, } from '~/state/farmer/market'; +import useSdk from '../sdk'; const MIN_POD_AMOUNT = 1; const useMarketData = () => { - /// Beanstalk data + const harvestableIndex = useHarvestableIndex(); + const sdk = useSdk(); + + /// status + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + + const [listings, setListings] = useState(); + const [orders, setOrders] = useState(); + + const [maxPlaceInLine, setMaxPlaceInLine] = useState(); + const [maxPlotSize, setMaxPlotSize] = useState(); + + const harvestableIndexFormatted = + harvestableIndex.multipliedBy(new BigNumber(10).pow(sdk.tokens.BEAN.decimals)).toString() /// Queries - const listingsQuery = usePodListings({ - variables: { status: MarketStatus.Active }, - fetchPolicy: 'cache-and-network', - nextFetchPolicy: 'cache-first', - notifyOnNetworkStatusChange: true, - }); - const ordersQuery = useAllPodOrdersQuery({ - variables: { status: MarketStatus.Active }, - fetchPolicy: 'cache-and-network', - nextFetchPolicy: 'cache-first', - notifyOnNetworkStatusChange: true, - }); + const [getListings] = useAllPodListingsLazyQuery(); + const [getOrders] = useAllPodOrdersLazyQuery(); - /// Query status - const loading = listingsQuery.loading || ordersQuery.loading; - const error = listingsQuery.error || ordersQuery.error; + const _fetch = useCallback( + async() => { + const _listings: AllPodListingsQuery["podListings"] = []; + const _orders: AllPodOrdersQuery["podOrders"] = []; - /// Cast query data to BigNumber, etc. - const listings = useCastApolloQuery( - listingsQuery, - 'podListings', - useCallback( - (_listing) => castPodListing(_listing, harvestableIndex), - [harvestableIndex] - ), - loading - ); - let orders = useCastApolloQuery( - ordersQuery, - 'podOrders', - castPodOrder, - loading - ); - orders = orders?.filter((order) => - order.beanAmountRemaining.gt(MIN_POD_AMOUNT) - ); + let listingsOutputLength = 0; + let listingsQueryLoops = 1; + let ordersOutputLength = 0; + let ordersQueryLoops = 1; + try { + setLoading(true); + setError(false); + do { + if (harvestableIndex?.gt(0)) { + const listings = await getListings({ + variables: { + first: 1000, + skip: (listingsQueryLoops * 1000) - 1000, + status: MarketStatus.Active, + maxHarvestableIndex: harvestableIndexFormatted, + }, + fetchPolicy: 'cache-and-network', + nextFetchPolicy: 'cache-first', + notifyOnNetworkStatusChange: true, + }); + if (listings.data) { + _listings.push(...listings.data.podListings); + listingsOutputLength = listings.data.podListings.length; + listingsQueryLoops += 1; + }; + }; + } while ( listingsOutputLength === 1000 ); + do { + const orders = await getOrders({ + variables: { + first: 1000, + skip: (ordersQueryLoops * 1000) - 1000, + status: MarketStatus.Active + }, + fetchPolicy: 'cache-and-network', + nextFetchPolicy: 'cache-first', + notifyOnNetworkStatusChange: true, + }); + if (orders.data) { + _orders.push(...orders.data.podOrders); + ordersOutputLength = orders.data.podOrders.length; + ordersQueryLoops += 1; + }; + } while ( ordersOutputLength === 1000 ); + const _listingsOutput = _listings.map((listing: any) => castPodListing(listing, harvestableIndex)); + setListings(_listingsOutput); + const _ordersOutput = _orders.map(castPodOrder).filter((order: any) => + order.beanAmountRemaining.gt(MIN_POD_AMOUNT) + ); + setOrders(_ordersOutput); + setLoading(false); + } catch (e) { + setError(true); + }; + }, + []) + + useEffect(() => { + _fetch(); + }, []); /// Calculations - const maxPlaceInLine = useMemo( - () => - listings + useEffect(() => { + if (harvestableIndex) { + const _maxPlaceInLine = listings ? Math.max( ...listings.map((l) => new BigNumber(l.index).minus(harvestableIndex).toNumber() ) ) - : 0, - [harvestableIndex, listings] - ); - const maxPlotSize = useMemo( - () => - listings - ? Math.max( - ...listings.map((l) => new BigNumber(l.remainingAmount).toNumber()) - ) - : 0, - [listings] - ); + : 0; + setMaxPlaceInLine(_maxPlaceInLine); + }; + }, [harvestableIndex, listings]); + + useEffect(() => { + const _maxPlotSize = listings + ? Math.max( + ...listings.map((l) => new BigNumber(l.remainingAmount).toNumber()) + ) + : 0; + setMaxPlotSize(_maxPlotSize); + }, [listings]); return { listings, From a4466748229bb838c7bf0781c00f4a7151540939 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Sat, 6 Jul 2024 23:31:38 +0200 Subject: [PATCH 77/89] fix issue on first load --- projects/ui/src/hooks/beanstalk/useMarketData.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketData.ts b/projects/ui/src/hooks/beanstalk/useMarketData.ts index 921d671d35..0e534c4932 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketData.ts @@ -27,9 +27,6 @@ const useMarketData = () => { const [maxPlaceInLine, setMaxPlaceInLine] = useState(); const [maxPlotSize, setMaxPlotSize] = useState(); - const harvestableIndexFormatted = - harvestableIndex.multipliedBy(new BigNumber(10).pow(sdk.tokens.BEAN.decimals)).toString() - /// Queries const [getListings] = useAllPodListingsLazyQuery(); const [getOrders] = useAllPodOrdersLazyQuery(); @@ -43,6 +40,10 @@ const useMarketData = () => { let listingsQueryLoops = 1; let ordersOutputLength = 0; let ordersQueryLoops = 1; + + const harvestableIndexFormatted = + harvestableIndex.multipliedBy(new BigNumber(10).pow(sdk.tokens.BEAN.decimals)).toString(); + try { setLoading(true); setError(false); @@ -94,11 +95,11 @@ const useMarketData = () => { setError(true); }; }, - []) + [harvestableIndex]); useEffect(() => { _fetch(); - }, []); + }, [harvestableIndex]); /// Calculations useEffect(() => { From 680b6fe9029df069b78043f4ad8e398f6046de4d Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Mon, 8 Jul 2024 01:40:57 +0200 Subject: [PATCH 78/89] fix error on successfull pod order fill --- projects/ui/src/components/Common/Form/PlotInputField.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/ui/src/components/Common/Form/PlotInputField.tsx b/projects/ui/src/components/Common/Form/PlotInputField.tsx index 7d508e8288..293c0945b0 100644 --- a/projects/ui/src/components/Common/Form/PlotInputField.tsx +++ b/projects/ui/src/components/Common/Form/PlotInputField.tsx @@ -72,6 +72,7 @@ const PlotInputField: FC< const [numPods, numPodsFloat] = useMemo(() => { if (!plot.index) return [ZERO_BN, 0]; const _pods = plots[plot.index]; + if (!_pods) return [ZERO_BN, 0]; return [_pods, _pods.toNumber()]; }, [plots, plot.index]); From e1bc8f085d9824fbac8f16f334d62ace4f668600 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Mon, 8 Jul 2024 01:41:38 +0200 Subject: [PATCH 79/89] fix dust pods on pod order fill --- projects/ui/src/state/farmer/market/index.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/projects/ui/src/state/farmer/market/index.ts b/projects/ui/src/state/farmer/market/index.ts index f40da4a437..72b0fc7ed1 100644 --- a/projects/ui/src/state/farmer/market/index.ts +++ b/projects/ui/src/state/farmer/market/index.ts @@ -83,8 +83,9 @@ export const castPodListing = ( * @returns Redux form of PodOrder. */ export const castPodOrder = (order: PodOrderFragment): PodOrder => { + const pricePerPod = toTokenUnitsBN(order.pricePerPod, BEAN[1].decimals); + const beanAmount = toTokenUnitsBN(order.beanAmount, BEAN[1].decimals); - const podAmount = beanAmount.div(toTokenUnitsBN(order.pricePerPod, BEAN[1].decimals)); const podAmountFilled = toTokenUnitsBN( order.podAmountFilled, BEAN[1].decimals @@ -94,6 +95,10 @@ export const castPodOrder = (order: PodOrderFragment): PodOrder => { BEAN[1].decimals ); + const beanAmountRemaining = toTokenUnitsBN(beanAmount.minus(beanAmountFilled).toFixed(6, BigNumber.ROUND_UP), 0); + const podAmountRemaining = toTokenUnitsBN(beanAmountRemaining.div(pricePerPod).toFixed(6, BigNumber.ROUND_UP), 0); + const podAmount = podAmountFilled.plus(podAmountRemaining); + return { // Identifiers id: order.id, @@ -118,8 +123,8 @@ export const castPodOrder = (order: PodOrderFragment): PodOrder => { beanAmountFilled: beanAmountFilled, // Computed - podAmountRemaining: podAmount.minus(podAmountFilled), - beanAmountRemaining: beanAmount.minus(beanAmountFilled), + podAmountRemaining: podAmountRemaining, + beanAmountRemaining: beanAmountRemaining, // Metadata status: order.status as MarketStatus, From 64e80cc2a99e849ba78cf168beb41695a1df8353 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:26:27 +0200 Subject: [PATCH 80/89] fix dust pods on pod listing fill --- .../PodsV2/Actions/Buy/FillListingForm.tsx | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/Actions/Buy/FillListingForm.tsx b/projects/ui/src/components/Market/PodsV2/Actions/Buy/FillListingForm.tsx index f52bfa4ecc..3907fee100 100644 --- a/projects/ui/src/components/Market/PodsV2/Actions/Buy/FillListingForm.tsx +++ b/projects/ui/src/components/Market/PodsV2/Actions/Buy/FillListingForm.tsx @@ -139,11 +139,32 @@ const FillListingV2Form: FC< (async () => { if (!account) return; + const _pricePerPod = toTokenUnitsBN(podListing.pricePerPod, 0); + const _remaining = toTokenUnitsBN(podListing.remainingAmount, 0); // Maximum BEAN precision is 6 decimals. remainingAmount * pricePerPod may // have more decimals, so we truncate at 6. - const maxBeans = podListing.remainingAmount - .times(podListing.pricePerPod) - .dp(BEAN[1].decimals, BigNumber.ROUND_DOWN); + + let maxBeans = _remaining.times(_pricePerPod).dp(6, BigNumber.ROUND_UP); + const diff = (maxBeans.div(podListing.pricePerPod)).dp(6, BigNumber.ROUND_DOWN).minus(podListing.remainingAmount); + + let loop = 0; + let found = false; + + do { + let adjustedMaxBeans + if (diff.isPositive()) { + adjustedMaxBeans = maxBeans.minus(new BigNumber(loop * 0.0000001)); + } else { + adjustedMaxBeans = maxBeans.plus(new BigNumber(loop * 0.0000001)); + }; + const adjustedPodAmount = adjustedMaxBeans.div(podListing.pricePerPod).dp(6, BigNumber.ROUND_DOWN); + if (adjustedPodAmount.eq(podListing.remainingAmount)) { + maxBeans = adjustedMaxBeans; + found = true; + } else { + loop += 1; + }; + } while (found === false && loop < 50); if (maxBeans.gt(0)) { if (tokenIn === Bean) { From 8a11c142c7a87894cdd67cb3f3cb4a441932f945 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:00:10 +0200 Subject: [PATCH 81/89] fix css errors --- .../ui/src/components/Common/ScrollPaginationControl.tsx | 6 +++--- .../ui/src/components/Market/PodsV2/Tables/BaseTable.tsx | 6 +++--- .../Market/PodsV2/Tables/columns/market-columns.tsx | 9 ++++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/projects/ui/src/components/Common/ScrollPaginationControl.tsx b/projects/ui/src/components/Common/ScrollPaginationControl.tsx index db4f8b68da..a216abd98a 100644 --- a/projects/ui/src/components/Common/ScrollPaginationControl.tsx +++ b/projects/ui/src/components/Common/ScrollPaginationControl.tsx @@ -12,7 +12,7 @@ type IScrollPaginationControl = { /** * ref of the data grid container element */ - scrollRef: React.MutableRefObject; + scrollref: React.MutableRefObject; /** * async function to fetch more data when scrolled to the bottom of the table */ @@ -33,7 +33,7 @@ type ControllerCache = { const CONTROL_HEIGHT = 52; const ScrollPaginationControl: React.FC = ({ - scrollRef, + scrollref, handleFetchMore, }) => { const apiRef = useGridApiContext(); @@ -56,7 +56,7 @@ const ScrollPaginationControl: React.FC = ({ }, []); // get the Mui Data-Grid-scroll container element in which the scrollbar is rendered - const el = scrollRef?.current?.querySelector('.MuiDataGrid-virtualScroller'); + const el = scrollref?.current?.querySelector('.MuiDataGrid-virtualScroller'); const hasNextPage = useMemo( () => !(page === pageCount - 1 || pageCount === 0), diff --git a/projects/ui/src/components/Market/PodsV2/Tables/BaseTable.tsx b/projects/ui/src/components/Market/PodsV2/Tables/BaseTable.tsx index 533b8a3f20..df18b21486 100644 --- a/projects/ui/src/components/Market/PodsV2/Tables/BaseTable.tsx +++ b/projects/ui/src/components/Market/PodsV2/Tables/BaseTable.tsx @@ -57,10 +57,10 @@ const BaseTable: FC = ({ sortModel, ...props }) => { - const scrollRef = useRef(null); + const scrollref = useRef(null); return ( = ({ }} componentsProps={{ footer: { - scrollRef, + scrollref, // handleFetchMore: fetchMore, }, noRowsOverlay: { diff --git a/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx b/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx index 2f509c63bf..9fb0d4d45c 100644 --- a/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx +++ b/projects/ui/src/components/Market/PodsV2/Tables/columns/market-columns.tsx @@ -140,7 +140,7 @@ export const MarketColumns = { valueFormatter: (params: GridValueFormatterParams) => formatDate(params.value), renderCell: (params: GridRenderCellParams) => ( - + <> {params.row[hashKey] ? ( @@ -160,9 +161,11 @@ export const MarketColumns = { ) : ( - params.formattedValue + + {params.formattedValue} + )} - + ), } as GridColumns[number]), /** */ From 5cc483f76b16335042c4f82e5d46b2762a661c1f Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:08:54 +0200 Subject: [PATCH 82/89] fix css warning message --- projects/ui/src/components/Common/TxnToast.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/ui/src/components/Common/TxnToast.tsx b/projects/ui/src/components/Common/TxnToast.tsx index 3f4869415d..742f702e91 100644 --- a/projects/ui/src/components/Common/TxnToast.tsx +++ b/projects/ui/src/components/Common/TxnToast.tsx @@ -41,9 +41,11 @@ export function ToastAlert({ display: 'flex', alignItems: 'center', flexDirection: 'row', + maxHeight: 250, + overflow: 'hidden', }} > - + {desc} {hash && ( @@ -70,7 +72,7 @@ export function ToastAlert({
{msg}
)} -
+
{rawError && ( Date: Tue, 9 Jul 2024 15:09:14 +0200 Subject: [PATCH 83/89] update error message parsing --- projects/ui/src/util/Ledger.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/projects/ui/src/util/Ledger.ts b/projects/ui/src/util/Ledger.ts index 50eda11303..37de6512f9 100644 --- a/projects/ui/src/util/Ledger.ts +++ b/projects/ui/src/util/Ledger.ts @@ -63,8 +63,14 @@ export const parseError = (error: any) => { case 'UNSUPPORTED_OPERATION': case 'CALL_EXCEPTION': if (error.reason) { - errorMessage.message = error.reason.replace('execution reverted: ', ''); - return errorMessage; + if (error.reason.includes('viem')) { + const _message = error.reason.substring(error.reason.indexOf('execution reverted: ')); + errorMessage.message = _message.replace('execution reverted: ', ''); + return errorMessage; + } else { + errorMessage.message = error.reason.replace('execution reverted: ', ''); + return errorMessage; + } } if (error.data && error.data.message) { From 06e5aee6ad704dc508ff2cf1b280a1e10b60ae11 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Tue, 9 Jul 2024 16:45:45 +0200 Subject: [PATCH 84/89] simplify --- projects/ui/src/state/farmer/market/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/ui/src/state/farmer/market/index.ts b/projects/ui/src/state/farmer/market/index.ts index 72b0fc7ed1..22793a4dfe 100644 --- a/projects/ui/src/state/farmer/market/index.ts +++ b/projects/ui/src/state/farmer/market/index.ts @@ -95,8 +95,8 @@ export const castPodOrder = (order: PodOrderFragment): PodOrder => { BEAN[1].decimals ); - const beanAmountRemaining = toTokenUnitsBN(beanAmount.minus(beanAmountFilled).toFixed(6, BigNumber.ROUND_UP), 0); - const podAmountRemaining = toTokenUnitsBN(beanAmountRemaining.div(pricePerPod).toFixed(6, BigNumber.ROUND_UP), 0); + const beanAmountRemaining = beanAmount.minus(beanAmountFilled).dp(6, BigNumber.ROUND_UP); + const podAmountRemaining = beanAmountRemaining.div(pricePerPod).dp(6, BigNumber.ROUND_UP); const podAmount = podAmountFilled.plus(podAmountRemaining); return { From 73648658ef67e6e9eecb1422ca86d2193f8ff95b Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:39:03 +0200 Subject: [PATCH 85/89] fix build --- projects/ui/src/hooks/beanstalk/useMarketData.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketData.ts b/projects/ui/src/hooks/beanstalk/useMarketData.ts index 0e534c4932..19fa03c972 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketData.ts @@ -24,8 +24,8 @@ const useMarketData = () => { const [listings, setListings] = useState(); const [orders, setOrders] = useState(); - const [maxPlaceInLine, setMaxPlaceInLine] = useState(); - const [maxPlotSize, setMaxPlotSize] = useState(); + const [maxPlaceInLine, setMaxPlaceInLine] = useState(0); + const [maxPlotSize, setMaxPlotSize] = useState(0); /// Queries const [getListings] = useAllPodListingsLazyQuery(); From f4f1a6cfc57747b2a76accfc6ae1c22290fd8fb2 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:20:01 +0200 Subject: [PATCH 86/89] fix market activity table values --- .../hooks/beanstalk/useMarketActivityData.ts | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts index 5dc4ec9e37..19c4e2c0d4 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts @@ -228,19 +228,19 @@ const useMarketActivityData = () => { case 'PodOrderCancelled': { // HOTFIX: Fixes edge case where PodOrderCancelled is emitted for an order that doesn't actually exist. const podOrder = podOrdersById[e.historyID]; - if (!e.historyID || !podOrder) return null; - const podAmount = toTokenUnitsBN( - podOrder.podAmountFilled || 0, + if (!e.historyID || !podOrder) return null; + const beanAmount = toTokenUnitsBN( + podOrder.beanAmount || 0, BEAN[1].decimals ); const pricePerPod = toTokenUnitsBN( new BigNumber(podOrder.pricePerPod || 0), BEAN[1].decimals ); - const totalBeans = - podAmount && pricePerPod - ? podAmount.multipliedBy(pricePerPod) + const podAmount = + beanAmount && pricePerPod + ? beanAmount.multipliedBy(pricePerPod) : undefined; return { @@ -249,17 +249,14 @@ const useMarketActivityData = () => { hash: e.hash, type: 'order' as const, action: 'cancel' as const, - amountPods: toTokenUnitsBN(podOrder?.podAmountFilled, BEAN[1].decimals), + amountPods: podAmount, placeInLine: toTokenUnitsBN( podOrder?.maxPlaceInLine, BEAN[1].decimals ), - pricePerPod: toTokenUnitsBN( - new BigNumber(podOrder?.pricePerPod || 0), - BEAN[1].decimals - ), - amountBeans: totalBeans, - amountUSD: totalBeans ? getUSD(BEAN[1], totalBeans) : undefined, + pricePerPod: pricePerPod, + amountBeans: beanAmount, + amountUSD: beanAmount ? getUSD(BEAN[1], beanAmount) : undefined, createdAt: e.createdAt, }; } @@ -273,13 +270,10 @@ const useMarketActivityData = () => { BEAN[1].decimals ); const podAmountFilled = toTokenUnitsBN( - podOrder.podAmountFilled, + e.amount, BEAN[1].decimals ); - const totalBeans = getUSD( - BEAN[1], - podAmountFilled.multipliedBy(pricePerPod) - ); + const totalBeans = podAmountFilled.multipliedBy(pricePerPod).dp(6); return { id: podOrder.id, eventId: e.id, @@ -327,8 +321,7 @@ const useMarketActivityData = () => { new BigNumber(podListing.pricePerPod || 0), BEAN[1].decimals ); - const totalBeans = numPods.multipliedBy(pricePerPod); - + const totalBeans = numPods.multipliedBy(pricePerPod).dp(6); return { id: e.historyID.split('-')[1], eventId: e.id, From 422b04dab5762ec759e507ecb68f11da2b4f8de7 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:51:03 +0200 Subject: [PATCH 87/89] fix values of pod order creation events --- projects/ui/src/hooks/beanstalk/useMarketActivityData.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts index 19c4e2c0d4..6b85894ac8 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts @@ -208,9 +208,8 @@ const useMarketActivityData = () => { e.maxPlaceInLine, BEAN[1].decimals ); - // HOTFIX: amountPods is using the legacy bean amount format for these events - const amountPods = amount; - const amountBeans = amount.multipliedBy(pricePerPod); + const amountPods = amount.div(pricePerPod).dp(6); + const amountBeans = amount; return { id: 'unknown', eventId: e.id, From 06aa6237f92a2105690f9d6cada224cd93c31af3 Mon Sep 17 00:00:00 2001 From: uncoolzero <107518216+uncoolzero@users.noreply.github.com> Date: Wed, 10 Jul 2024 22:11:08 +0200 Subject: [PATCH 88/89] fix pod amount on pod order cancellations --- projects/ui/src/hooks/beanstalk/useMarketActivityData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts index 6b85894ac8..027baf0a9a 100644 --- a/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts +++ b/projects/ui/src/hooks/beanstalk/useMarketActivityData.ts @@ -239,7 +239,7 @@ const useMarketActivityData = () => { ); const podAmount = beanAmount && pricePerPod - ? beanAmount.multipliedBy(pricePerPod) + ? beanAmount.dividedBy(pricePerPod).dp(6) : undefined; return { From 2330778835c1bb1c2ee32bcddd6e8ae5b9630d6e Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Mon, 15 Jul 2024 11:28:17 -0700 Subject: [PATCH 89/89] comment on 43 --- .../Market/PodsV2/Modules/MarketGraph.tsx | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx b/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx index 0c7df4c5f9..98d1e54367 100644 --- a/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx +++ b/projects/ui/src/components/Market/PodsV2/Modules/MarketGraph.tsx @@ -366,10 +366,10 @@ const Graph: FC = ({ !cursorPoint?.type ? 1 : cursorPoint.type === _type - ? cursorPoint.index === _i - ? 1 - : HOVER_PEER_OPACITY - : HOVER_PEER_OPACITY, + ? cursorPoint.index === _i + ? 1 + : HOVER_PEER_OPACITY + : HOVER_PEER_OPACITY, [cursorPoint] ); @@ -582,14 +582,17 @@ const Graph: FC = ({ hideTooltip(); } } else if (params.listingID) { - const index = listings.findIndex((l) => l.id.slice(43) === params.listingID); + // Extract index from listing id "0xaddr-index" + const index = listings.findIndex( + (l) => l.id.slice(43) === params.listingID + ); if (index === -1) { if (selectedPoint) { setSelectedPoint(undefined); hideTooltip(); } - return - }; + return; + } const newSelectdPoint: SelectedPoint = { type: 'listing', index, @@ -609,8 +612,8 @@ const Graph: FC = ({ setSelectedPoint(undefined); hideTooltip(); } - return - }; + return; + } if (!selectedPoint || selectedPoint.index !== index) { setSelectedPoint({ type: 'order', @@ -776,10 +779,10 @@ const Graph: FC = ({ cursor: selectedPoint ? 'default' // when selected, freeze cursor : hoveredPoint // hovering over a point but haven't clicked it yet - ? 'pointer' - : zoom.isDragging - ? 'grabbing' // if dragging, show grab - : 'default', + ? 'pointer' + : zoom.isDragging + ? 'grabbing' // if dragging, show grab + : 'default', touchAction: 'none', }} />