Skip to content

Commit

Permalink
Merge pull request #926 from rainlanguage/2024-10-10-clear-event
Browse files Browse the repository at this point in the history
Adding clear event to subgraph
  • Loading branch information
thedavidmeister authored Oct 11, 2024
2 parents f34da12 + cfd5706 commit b498680
Show file tree
Hide file tree
Showing 6 changed files with 572 additions and 6 deletions.
20 changes: 19 additions & 1 deletion subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,22 @@ type ERC20 @entity(immutable: true) {
symbol: String
"The number of decimals of the ERC20 token"
decimals: BigInt
}
}

type ClearTemporaryData @entity(immutable: true) {
id: Bytes!
aliceOrderHash: Bytes!
aliceAddress: Bytes!
aliceInputVaultId: BigInt!
aliceInputToken: Bytes!
aliceOutputVaultId: BigInt!
aliceOutputToken: Bytes!
aliceBounty: BigInt!
bobOrderHash: Bytes!
bobAddress: Bytes!
bobInputVaultId: BigInt!
bobInputToken: Bytes!
bobOutputVaultId: BigInt!
bobOutputToken: Bytes!
bobBounty: BigInt!
}
185 changes: 185 additions & 0 deletions subgraph/src/clear.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { AfterClear, ClearV2 } from "../generated/OrderBook/OrderBook";
import { ClearTemporaryData } from "../generated/schema";
import { createTradeEntity } from "./trade";
import { createTradeVaultBalanceChangeEntity } from "./tradevaultbalancechange";
import { handleVaultBalanceChange, vaultEntityId } from "./vault";
import { log } from "@graphprotocol/graph-ts";
import {
BigInt,
Bytes,
crypto,
ethereum,
store,
} from "@graphprotocol/graph-ts";

export function orderHashFromClearEvent(
event: ClearV2,
isAlice: boolean
): Bytes {
let orderHash = crypto.keccak256(
ethereum.encode(event.parameters[isAlice ? 1 : 2].value.toTuple()[0])!
);
return Bytes.fromByteArray(orderHash);
}

export function clearTemporaryDataEntityId(event: ethereum.Event): Bytes {
return Bytes.fromByteArray(
crypto.keccak256(event.transaction.hash.concat(event.address))
);
}

export function handleClear(event: ClearV2): void {
let clearTemporaryData = new ClearTemporaryData(
clearTemporaryDataEntityId(event)
);

let aliceOrderHash = orderHashFromClearEvent(event, true);
let bobOrderHash = orderHashFromClearEvent(event, false);

let aliceInput =
event.params.alice.validInputs[
event.params.clearConfig.aliceInputIOIndex.toU32()
];
let aliceOutput =
event.params.alice.validOutputs[
event.params.clearConfig.aliceOutputIOIndex.toU32()
];
let bobInput =
event.params.bob.validInputs[
event.params.clearConfig.bobInputIOIndex.toU32()
];
let bobOutput =
event.params.bob.validOutputs[
event.params.clearConfig.bobOutputIOIndex.toU32()
];

clearTemporaryData.aliceOrderHash = aliceOrderHash;
clearTemporaryData.bobOrderHash = bobOrderHash;

clearTemporaryData.aliceAddress = event.params.alice.owner;
clearTemporaryData.bobAddress = event.params.bob.owner;

clearTemporaryData.aliceInputVaultId = aliceInput.vaultId;
clearTemporaryData.aliceOutputVaultId = aliceOutput.vaultId;
clearTemporaryData.bobInputVaultId = bobInput.vaultId;
clearTemporaryData.bobOutputVaultId = bobOutput.vaultId;

clearTemporaryData.aliceInputToken = aliceInput.token;
clearTemporaryData.aliceOutputToken = aliceOutput.token;
clearTemporaryData.bobInputToken = bobInput.token;
clearTemporaryData.bobOutputToken = bobOutput.token;

clearTemporaryData.aliceBounty = event.params.clearConfig.aliceBountyVaultId;
clearTemporaryData.bobBounty = event.params.clearConfig.bobBountyVaultId;

clearTemporaryData.save();
}

function createTrade(
event: AfterClear,
clearData: ClearTemporaryData,
isAlice: boolean
): void {
let owner = isAlice ? clearData.aliceAddress : clearData.bobAddress;

let orderHash = isAlice ? clearData.aliceOrderHash : clearData.bobOrderHash;

let input = isAlice
? event.params.clearStateChange.aliceInput
: event.params.clearStateChange.bobInput;
let output = isAlice
? event.params.clearStateChange.aliceOutput
: event.params.clearStateChange.bobOutput;

let inputVaultId = isAlice
? clearData.aliceInputVaultId
: clearData.bobInputVaultId;
let inputToken = isAlice
? clearData.aliceInputToken
: clearData.bobInputToken;

let outputVaultId = isAlice
? clearData.aliceOutputVaultId
: clearData.bobOutputVaultId;
let outputToken = isAlice
? clearData.aliceOutputToken
: clearData.bobOutputToken;

let oldInputVaultBalance = handleVaultBalanceChange(
event.address,
inputVaultId,
inputToken,
input.neg(),
owner
);
let oldOutputVaultBalance = handleVaultBalanceChange(
event.address,
outputVaultId,
outputToken,
output,
owner
);

let inputVaultBalanceChange = createTradeVaultBalanceChangeEntity(
event,
orderHash,
vaultEntityId(event.address, owner, inputVaultId, inputToken),
oldInputVaultBalance,
input.neg()
);
let outputVaultBalanceChange = createTradeVaultBalanceChangeEntity(
event,
orderHash,
vaultEntityId(event.address, owner, outputVaultId, outputToken),
oldOutputVaultBalance,
output
);

createTradeEntity(
event,
orderHash,
inputVaultBalanceChange,
outputVaultBalanceChange
);
}

export function handleAfterClear(event: AfterClear): void {
let clearTemporaryData = ClearTemporaryData.load(
clearTemporaryDataEntityId(event)
);
if (clearTemporaryData) {
createTrade(event, clearTemporaryData, true);
createTrade(event, clearTemporaryData, false);

// handle bounty vault changes
const aliceBountyAmount = event.params.clearStateChange.aliceOutput.minus(
event.params.clearStateChange.bobInput
);
const bobBountyAmount = event.params.clearStateChange.bobOutput.minus(
event.params.clearStateChange.aliceInput
);
if (aliceBountyAmount.gt(BigInt.fromU32(0))) {
handleVaultBalanceChange(
event.address,
clearTemporaryData.aliceBounty,
clearTemporaryData.aliceOutputToken,
aliceBountyAmount,
event.params.sender
);
}
if (bobBountyAmount.gt(BigInt.fromU32(0))) {
handleVaultBalanceChange(
event.address,
clearTemporaryData.bobBounty,
clearTemporaryData.bobOutputToken,
bobBountyAmount,
event.params.sender
);
}
store.remove("ClearTemporaryData", clearTemporaryData.id.toHexString());
} else {
log.error("ClearTemporaryData not found for event {}", [
event.transaction.hash.toHexString(),
]);
}
}
14 changes: 14 additions & 0 deletions subgraph/src/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
AddOrderV2,
AfterClear,
ClearV2,
Deposit,
MetaV1_2,
RemoveOrderV2,
Expand All @@ -14,6 +16,10 @@ import {
} from "./order";
import { handleMeta as _handleMeta } from "./meta";
import { handleTakeOrder as _handleTakeOrder } from "./takeorder";
import {
handleClear as _handleClear,
handleAfterClear as _handleAfterClear,
} from "./clear";

export function handleDeposit(event: Deposit): void {
_handleDeposit(event);
Expand All @@ -38,3 +44,11 @@ export function handleTakeOrder(event: TakeOrderV2): void {
export function handleMeta(event: MetaV1_2): void {
_handleMeta(event);
}

export function handleClear(event: ClearV2): void {
_handleClear(event);
}

export function handleAfterClear(event: AfterClear): void {
_handleAfterClear(event);
}
4 changes: 4 additions & 0 deletions subgraph/subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ dataSources:
handler: handleTakeOrder
- event: MetaV1_2(address,bytes32,bytes)
handler: handleMeta
- event: ClearV2(address,(address,(address,address,bytes),(address,uint8,uint256)[],(address,uint8,uint256)[],bytes32),(address,(address,address,bytes),(address,uint8,uint256)[],(address,uint8,uint256)[],bytes32),(uint256,uint256,uint256,uint256,uint256,uint256))
handler: handleClear
- event: AfterClear(address,(uint256,uint256,uint256,uint256))
handler: handleAfterClear
file: "./src/handlers.ts"
Loading

0 comments on commit b498680

Please sign in to comment.