Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/subgraph/src/mappings/gdav1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,28 @@ export function handleBufferAdjusted(event: BufferAdjusted): void {
event.params.token,
event.block
);
tokenStatistic.totalDeposit = tokenStatistic.totalDeposit.plus(
event.params.bufferDelta
);
tokenStatistic.totalGDADeposit = tokenStatistic.totalGDADeposit.plus(
event.params.bufferDelta
);
tokenStatistic.save();

// Update AccountTokenSnapshot for the pool distributor (fixes #2155)
const accountTokenSnapshot = getOrInitAccountTokenSnapshot(
event.params.from,
event.params.token,
event.block
);
accountTokenSnapshot.totalGDADeposit = accountTokenSnapshot.totalGDADeposit.plus(
event.params.bufferDelta
);
accountTokenSnapshot.totalDeposit = accountTokenSnapshot.totalDeposit.plus(
event.params.bufferDelta
);
accountTokenSnapshot.save();

// Create Event Entity
_createBufferAdjustedEntity(event, poolDistributor.id);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* Issue: https://github.com/superfluid-org/protocol-monorepo/issues/2155
*
* AccountTokenSnapshot.totalGDADeposit (and totalDeposit) can be 0 in the subgraph
* when the account actually has nonzero GDA buffer on-chain.
*
* Root cause: handleBufferAdjusted updates TokenStatistic.totalGDADeposit but does
* NOT update AccountTokenSnapshot.totalGDADeposit for the pool distributor (from).
*/
import { BigInt } from "@graphprotocol/graph-ts";
import { assert, beforeEach, clearStore, describe, test } from "matchstick-as/assembly/index";
import { handleBufferAdjusted } from "../../src/mappings/gdav1";
import { createBufferAdjustedEvent, createPoolAndReturnPoolCreatedEvent } from "../gdav1/gdav1.helper";
import { alice, maticXAddress, superfluidPool } from "../constants";
import { BIG_INT_ZERO } from "../../src/utils";

describe("Issue 2155: AccountTokenSnapshot totalGDADeposit on BufferAdjusted", () => {
beforeEach(() => {
clearStore();
});

test("handleBufferAdjusted() should update account and token deposits for the pool distributor", () => {
// Create pool with alice as admin so AccountTokenSnapshot exists for alice
createPoolAndReturnPoolCreatedEvent(alice, maticXAddress, superfluidPool, BIG_INT_ZERO);

const bufferDelta = BigInt.fromI32(526847904); // e.g. 526e9 wei
const newBufferAmount = bufferDelta;
const totalBufferAmount = bufferDelta;
const poolDistributor = alice;

const bufferAdjustedEvent = createBufferAdjustedEvent(
maticXAddress,
superfluidPool,
poolDistributor,
bufferDelta,
newBufferAmount,
totalBufferAmount
);

handleBufferAdjusted(bufferAdjustedEvent);

const accountTokenSnapshotId = poolDistributor + "-" + maticXAddress;
assert.fieldEquals(
"TokenStatistic",
maticXAddress,
"totalGDADeposit",
bufferDelta.toString()
);
assert.fieldEquals(
"TokenStatistic",
maticXAddress,
"totalDeposit",
bufferDelta.toString()
);
assert.fieldEquals(
"AccountTokenSnapshot",
accountTokenSnapshotId,
"totalGDADeposit",
bufferDelta.toString()
);
assert.fieldEquals(
"AccountTokenSnapshot",
accountTokenSnapshotId,
"totalDeposit",
bufferDelta.toString()
);
});

test("handleBufferAdjusted() should decrement account and token deposits when buffer shrinks", () => {
createPoolAndReturnPoolCreatedEvent(alice, maticXAddress, superfluidPool, BIG_INT_ZERO);

const poolDistributor = alice;
const depositAmount = BigInt.fromI32(526847904);
const withdrawAmount = BigInt.fromI32(-526847904);

handleBufferAdjusted(
createBufferAdjustedEvent(
maticXAddress,
superfluidPool,
poolDistributor,
depositAmount,
depositAmount,
depositAmount
)
);
handleBufferAdjusted(
createBufferAdjustedEvent(
maticXAddress,
superfluidPool,
poolDistributor,
withdrawAmount,
BIG_INT_ZERO,
BIG_INT_ZERO
)
);

const accountTokenSnapshotId = poolDistributor + "-" + maticXAddress;
assert.fieldEquals("TokenStatistic", maticXAddress, "totalGDADeposit", "0");
assert.fieldEquals("TokenStatistic", maticXAddress, "totalDeposit", "0");
assert.fieldEquals(
"AccountTokenSnapshot",
accountTokenSnapshotId,
"totalGDADeposit",
"0"
);
assert.fieldEquals(
"AccountTokenSnapshot",
accountTokenSnapshotId,
"totalDeposit",
"0"
);
});
});
16 changes: 16 additions & 0 deletions packages/subgraph/tests/converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,22 @@ export function getBigIntEventParam(
);
}

/**
* Takes a signed BigInt value and returns a BigInt ethereum.EventParam object
* @param name the name of the parameter (must match actual value from contracts)
* @param value BigInt parameter value
* @returns ethereum.EventParam
*/
export function getSignedBigIntEventParam(
name: string,
value: BigInt
): ethereum.EventParam {
return new ethereum.EventParam(
name,
ethereum.Value.fromSignedBigInt(value)
);
}

/**
* Takes an i32 value and returns an i32 ethereum.EventParam object
* @param name the name of the parameter (must match actual value from contracts)
Expand Down
10 changes: 8 additions & 2 deletions packages/subgraph/tests/gdav1/gdav1.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import {
DistributionClaimed,
MemberUnitsUpdated,
} from "../../generated/GeneralDistributionAgreementV1/ISuperfluidPool";
import { getAddressEventParam, getBigIntEventParam, getBooleanEventParam, getBytesEventParam } from "../converters";
import {
getAddressEventParam,
getBigIntEventParam,
getBooleanEventParam,
getBytesEventParam,
getSignedBigIntEventParam,
} from "../converters";
import { BigInt, Bytes } from "@graphprotocol/graph-ts";
import { handlePoolConnectionUpdated, handlePoolCreated } from "../../src/mappings/gdav1";
import { BIG_INT_ZERO } from "../../src/utils";
Expand Down Expand Up @@ -131,7 +137,7 @@ export function createBufferAdjustedEvent(
newBufferAdjustedEvent.parameters.push(getAddressEventParam("token", token));
newBufferAdjustedEvent.parameters.push(getAddressEventParam("pool", pool));
newBufferAdjustedEvent.parameters.push(getAddressEventParam("poolDistributor", poolDistributor));
newBufferAdjustedEvent.parameters.push(getBigIntEventParam("bufferDelta", bufferDelta));
newBufferAdjustedEvent.parameters.push(getSignedBigIntEventParam("bufferDelta", bufferDelta));
newBufferAdjustedEvent.parameters.push(getBigIntEventParam("newBufferAmount", newBufferAmount));
newBufferAdjustedEvent.parameters.push(getBigIntEventParam("totalBufferAmount", totalBufferAmount));

Expand Down
Loading