base-sepolia
This commit is contained in:
parent
6ee65f4834
commit
1ea5bc0403
18 changed files with 6637 additions and 0 deletions
4
subgraph/base_sepolia/.gitignore
vendored
Normal file
4
subgraph/base_sepolia/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
build/
|
||||
node_modules/
|
||||
generated/
|
||||
yarn.lock
|
||||
9
subgraph/base_sepolia/README.md
Normal file
9
subgraph/base_sepolia/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
|
||||
## deployment
|
||||
|
||||
```
|
||||
yarn codegen
|
||||
yarn build
|
||||
yarn deploy
|
||||
```
|
||||
1
subgraph/base_sepolia/abis/BaseLineLP.json
Normal file
1
subgraph/base_sepolia/abis/BaseLineLP.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH9","type":"address"},{"internalType":"address","name":"_harb","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"liquidity","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"IncreaseLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"liquidity","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"}],"name":"PositionLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount0Owed","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amount1Owed","type":"uint256"}],"name":"UniCallback","type":"event"},{"inputs":[],"name":"liquidityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"outstanding","outputs":[{"internalType":"uint256","name":"_outstanding","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum BaseLineLP.Stage","name":"","type":"uint8"}],"name":"positions","outputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"feeDestination_","type":"address"}],"name":"setFeeDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slide","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spendingLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum BaseLineLP.Stage","name":"s","type":"uint8"}],"name":"tokensIn","outputs":[{"internalType":"uint256","name":"_ethInPosition","type":"uint256"},{"internalType":"uint256","name":"_harbInPosition","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Owed","type":"uint256"},{"internalType":"uint256","name":"amount1Owed","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"uniswapV3MintCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
|
||||
1
subgraph/base_sepolia/abis/Harb.json
Normal file
1
subgraph/base_sepolia/abis/Harb.json
Normal file
File diff suppressed because one or more lines are too long
1
subgraph/base_sepolia/abis/Stake.json
Normal file
1
subgraph/base_sepolia/abis/Stake.json
Normal file
File diff suppressed because one or more lines are too long
12
subgraph/base_sepolia/networks.json
Normal file
12
subgraph/base_sepolia/networks.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"sepolia": {
|
||||
"Harb": {
|
||||
"address": "0x00d5690044cf91fb3fc674c780697d511702f729",
|
||||
"startBlock": 13984247
|
||||
},
|
||||
"Stake": {
|
||||
"address": "0x275403401f9c6f4659b6ffb6ab01798e1de9a912",
|
||||
"startBlock": 13984247
|
||||
}
|
||||
}
|
||||
}
|
||||
5904
subgraph/base_sepolia/package-lock.json
generated
Normal file
5904
subgraph/base_sepolia/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
23
subgraph/base_sepolia/package.json
Normal file
23
subgraph/base_sepolia/package.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "harb",
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
"codegen": "graph codegen",
|
||||
"build": "graph build",
|
||||
"deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ harb-base-sepolia",
|
||||
"create-local": "graph create --node http://localhost:8020/ harb",
|
||||
"remove-local": "graph remove --node http://localhost:8020/ harb",
|
||||
"deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 harb",
|
||||
"test": "graph test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphprotocol/graph-cli": "0.69.0",
|
||||
"@graphprotocol/graph-ts": "0.34.0",
|
||||
"assemblyscript": "0.27.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.30",
|
||||
"matchstick-as": "0.5.0",
|
||||
"typescript": "^5.4.3"
|
||||
}
|
||||
}
|
||||
59
subgraph/base_sepolia/schema.graphql
Normal file
59
subgraph/base_sepolia/schema.graphql
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# scalar Bytes
|
||||
# scalar BigInt
|
||||
# scalar BigDecimal
|
||||
|
||||
type Stats @entity {
|
||||
id: Bytes!
|
||||
outstandingSupply: BigInt! # uint256
|
||||
activeSupply: BigInt! # uint256
|
||||
ringBuffer: [BigInt!]! # Ring buffer to store daily totals
|
||||
ringBufferPointer: Int! # Pointer to the current day in the ring buffer
|
||||
lastUpdatedHour: Int! # The last updated day boundary (timestamp in days)
|
||||
totalMinted: BigInt!
|
||||
mintedLastWeek: BigInt!
|
||||
mintedLastDay: BigInt!
|
||||
mintNextHourProjected: BigInt!
|
||||
|
||||
totalBurned: BigInt!
|
||||
burnedLastWeek: BigInt!
|
||||
burnedLastDay: BigInt!
|
||||
burnNextHourProjected: BigInt!
|
||||
|
||||
totalTaxPaid: BigInt!
|
||||
taxPaidLastWeek: BigInt!
|
||||
taxPaidLastDay: BigInt!
|
||||
taxNextHourProjected: BigInt!
|
||||
|
||||
totalUbiClaimed: BigInt!
|
||||
ubiClaimedLastWeek: BigInt!
|
||||
ubiClaimedLastDay: BigInt!
|
||||
ubiNextHourProjected: BigInt!
|
||||
}
|
||||
|
||||
enum PositionStatus {
|
||||
Active
|
||||
Closed
|
||||
}
|
||||
|
||||
type Position @entity {
|
||||
id: Bytes!
|
||||
owner: Bytes! # address
|
||||
share: BigDecimal!
|
||||
# harb at start
|
||||
# current harb value
|
||||
creationTime: Int!
|
||||
lastTaxTime: Int
|
||||
taxRate: BigDecimal!
|
||||
taxPaid: BigInt!
|
||||
harbDeposit: BigInt!
|
||||
snatched: Int!
|
||||
totalSupplyInit: BigInt!
|
||||
totalSupplyEnd: BigInt
|
||||
status: PositionStatus!
|
||||
payout: BigInt!
|
||||
}
|
||||
|
||||
# type Query {
|
||||
# stats: [Stats!]
|
||||
# positions: [Position!]
|
||||
#}
|
||||
222
subgraph/base_sepolia/src/harb.ts
Normal file
222
subgraph/base_sepolia/src/harb.ts
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
import {
|
||||
Approval as ApprovalEvent,
|
||||
EIP712DomainChanged as EIP712DomainChangedEvent,
|
||||
Transfer as TransferEvent,
|
||||
UbiClaimed as UbiClaimedEvent
|
||||
} from "../generated/Harb/Harb";
|
||||
import { BigInt, Bytes, ethereum, Address, log } from "@graphprotocol/graph-ts";
|
||||
import { Stats } from "../generated/schema"
|
||||
|
||||
|
||||
// Helper function to get or create Stats entity
|
||||
function getOrCreateStats(): Stats {
|
||||
let stats = Stats.load(Bytes.fromHexString("0x01") as Bytes);
|
||||
if (stats == null) {
|
||||
stats = new Stats(Bytes.fromHexString("0x01") as Bytes);
|
||||
stats.outstandingSupply = BigInt.zero();
|
||||
stats.activeSupply = BigInt.zero();
|
||||
|
||||
// Minted
|
||||
stats.totalMinted = BigInt.zero();
|
||||
stats.mintedLastWeek = BigInt.zero();
|
||||
stats.mintedLastDay = BigInt.zero();
|
||||
stats.mintNextHourProjected = BigInt.zero();
|
||||
|
||||
// Burned
|
||||
stats.totalBurned = BigInt.zero();
|
||||
stats.burnedLastWeek = BigInt.zero();
|
||||
stats.burnedLastDay = BigInt.zero();
|
||||
stats.burnNextHourProjected = BigInt.zero();
|
||||
|
||||
// Tax paid
|
||||
stats.totalTaxPaid = BigInt.zero();
|
||||
stats.taxPaidLastWeek = BigInt.zero();
|
||||
stats.taxPaidLastDay = BigInt.zero();
|
||||
stats.taxNextHourProjected = BigInt.zero();
|
||||
|
||||
// UBI claimed
|
||||
stats.totalUbiClaimed = BigInt.zero();
|
||||
stats.ubiClaimedLastWeek = BigInt.zero();
|
||||
stats.ubiClaimedLastDay = BigInt.zero();
|
||||
stats.ubiNextHourProjected = BigInt.zero();
|
||||
|
||||
stats.ringBuffer = new Array<BigInt>(168 * 4).fill(BigInt.zero());
|
||||
stats.ringBufferPointer = 0;
|
||||
stats.lastUpdatedHour = 0;
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
|
||||
export function handleUbiClaimed(event: UbiClaimedEvent): void {
|
||||
|
||||
let stats = getOrCreateStats();
|
||||
|
||||
// Get a copy of the ring buffer
|
||||
let ringBuffer = stats.ringBuffer;
|
||||
|
||||
// Update total UBI claimed
|
||||
stats.totalUbiClaimed = stats.totalUbiClaimed.plus(event.params.ubiAmount);
|
||||
|
||||
// Add the UBI amount to the current hour's total in the ring buffer
|
||||
let ubiBufferIndex = (stats.ringBufferPointer * 4) + 0; // UBI is at index 0
|
||||
ringBuffer[ubiBufferIndex] = ringBuffer[ubiBufferIndex].plus(event.params.ubiAmount);
|
||||
|
||||
// Update the ring buffer in the stats entity
|
||||
stats.ringBuffer = ringBuffer;
|
||||
|
||||
// Save the updated Stats entity
|
||||
stats.save();
|
||||
}
|
||||
|
||||
export function handleTransfer(event: TransferEvent): void {
|
||||
let ZERO_ADDRESS = Address.fromString("0x0000000000000000000000000000000000000000");
|
||||
let TAX_POOL_ADDR = Address.fromString("0x0000000000000000000000000000000000000002");
|
||||
|
||||
let stats = getOrCreateStats();
|
||||
|
||||
// Get a copy of the ring buffer
|
||||
let ringBuffer = stats.ringBuffer;
|
||||
|
||||
// Determine if it's a mint or burn event
|
||||
if (event.params.from == ZERO_ADDRESS) {
|
||||
// Mint event
|
||||
stats.totalMinted = stats.totalMinted.plus(event.params.value);
|
||||
|
||||
// Add the minted amount to the current hour's total in the ring buffer
|
||||
let mintBufferIndex = (stats.ringBufferPointer * 4) + 1; // Minted tokens are at index 1
|
||||
ringBuffer[mintBufferIndex] = ringBuffer[mintBufferIndex].plus(event.params.value);
|
||||
|
||||
} else if (event.params.to == ZERO_ADDRESS) {
|
||||
// Burn event
|
||||
stats.totalBurned = stats.totalBurned.plus(event.params.value);
|
||||
|
||||
// Add the burned amount to the current hour's total in the ring buffer
|
||||
let burnBufferIndex = (stats.ringBufferPointer * 4) + 2; // Burned tokens are at index 2
|
||||
ringBuffer[burnBufferIndex] = ringBuffer[burnBufferIndex].plus(event.params.value);
|
||||
|
||||
} else if (event.params.to == TAX_POOL_ADDR) {
|
||||
// Tax paid event
|
||||
stats.totalTaxPaid = stats.totalTaxPaid.plus(event.params.value);
|
||||
|
||||
// Add the burned amount to the current hour's total in the ring buffer
|
||||
let taxBufferIndex = (stats.ringBufferPointer * 4) + 3; // tax paid is at index 3
|
||||
ringBuffer[taxBufferIndex] = ringBuffer[taxBufferIndex].plus(event.params.value);
|
||||
|
||||
}
|
||||
|
||||
// Update the ring buffer in the stats entity
|
||||
stats.ringBuffer = ringBuffer;
|
||||
|
||||
// Save the updated Stats entity
|
||||
stats.save();
|
||||
}
|
||||
|
||||
// Block handler to aggregate stats
|
||||
export function handleBlock(block: ethereum.Block): void {
|
||||
// Update Stats entity
|
||||
let stats = getOrCreateStats();
|
||||
|
||||
// Get a copy of the ring buffer
|
||||
let ringBuffer = stats.ringBuffer;
|
||||
|
||||
// Calculate the current hour
|
||||
let currentHour = block.timestamp.toI32() / 3600;
|
||||
|
||||
// Check if we've moved to a new hour
|
||||
if (currentHour > stats.lastUpdatedHour) {
|
||||
// Move the ring buffer pointer forward
|
||||
stats.ringBufferPointer = (stats.ringBufferPointer + 1) % 168;
|
||||
|
||||
// Reset the new current hour in the ring buffer
|
||||
let baseIndex = stats.ringBufferPointer * 4;
|
||||
ringBuffer[baseIndex] = BigInt.zero(); // UBI claimed
|
||||
ringBuffer[baseIndex + 1] = BigInt.zero(); // Minted tokens
|
||||
ringBuffer[baseIndex + 2] = BigInt.zero(); // Burned tokens
|
||||
|
||||
// Update the last updated hour
|
||||
stats.lastUpdatedHour = currentHour;
|
||||
|
||||
// Recalculate the sum of the last 7 days and 24 hours
|
||||
|
||||
let mintedLastWeek = BigInt.zero();
|
||||
let burnedLastWeek = BigInt.zero();
|
||||
let taxPaidLastWeek = BigInt.zero();
|
||||
let ubiClaimedLastWeek = BigInt.zero();
|
||||
|
||||
let mintedLastDay = BigInt.zero();
|
||||
let burnedLastDay = BigInt.zero();
|
||||
let taxPaidLastDay = BigInt.zero();
|
||||
let ubiClaimedLastDay = BigInt.zero();
|
||||
|
||||
|
||||
for (let i = 0; i < 168; i++) {
|
||||
let index = ((stats.ringBufferPointer - i + 168) % 168) * 4;
|
||||
ubiClaimedLastWeek = ubiClaimedLastWeek.plus(ringBuffer[index]);
|
||||
mintedLastWeek = mintedLastWeek.plus(ringBuffer[index + 1]);
|
||||
burnedLastWeek = burnedLastWeek.plus(ringBuffer[index + 2]);
|
||||
taxPaidLastWeek = taxPaidLastWeek.plus(ringBuffer[index + 3]);
|
||||
|
||||
if (i < 24) {
|
||||
ubiClaimedLastDay = ubiClaimedLastDay.plus(ringBuffer[index]);
|
||||
mintedLastDay = mintedLastDay.plus(ringBuffer[index + 1]);
|
||||
burnedLastDay = burnedLastDay.plus(ringBuffer[index + 2]);
|
||||
taxPaidLastDay = taxPaidLastDay.plus(ringBuffer[index + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stats.mintedLastWeek = mintedLastWeek;
|
||||
stats.burnedLastWeek = burnedLastWeek;
|
||||
stats.taxPaidLastWeek = taxPaidLastWeek;
|
||||
stats.ubiClaimedLastWeek = ubiClaimedLastWeek;
|
||||
|
||||
|
||||
stats.mintedLastDay = mintedLastDay;
|
||||
stats.burnedLastDay = burnedLastDay;
|
||||
stats.taxPaidLastDay = taxPaidLastDay;
|
||||
stats.ubiClaimedLastDay = ubiClaimedLastDay;
|
||||
|
||||
// Update the ring buffer in the stats entity
|
||||
stats.ringBuffer = ringBuffer;
|
||||
|
||||
} else {
|
||||
// update projected stats with every block
|
||||
|
||||
// Calculate the elapsed time in the current hour
|
||||
let currentTimestamp = block.timestamp.toI32();
|
||||
let startOfHour = (currentTimestamp / 3600) * 3600;
|
||||
let elapsedSeconds = currentTimestamp - startOfHour;
|
||||
|
||||
for (var i = 0; i <= 3; i++) {
|
||||
let bufferIndex = (stats.ringBufferPointer * 4) + i;
|
||||
// Project the current hour's total based on the average rate of burned tokens in the current hour
|
||||
let projectedTotal = ringBuffer[bufferIndex].times(BigInt.fromI32(3600)).div(BigInt.fromI32(elapsedSeconds));
|
||||
|
||||
// Calculate the medium between the previous hour and the projection
|
||||
let previousHourTotal = ringBuffer[((stats.ringBufferPointer - 1 + 168) % 168) * 4 + i];
|
||||
|
||||
log.info("projecting stats : {} projected total: {}. previous hour Total: {}. medium: {}", [
|
||||
i.toString(),
|
||||
projectedTotal.toString(),
|
||||
previousHourTotal.toString(),
|
||||
previousHourTotal.plus(projectedTotal).div(BigInt.fromI32(2)).toString(),
|
||||
]);
|
||||
|
||||
let medium = previousHourTotal.plus(projectedTotal).div(BigInt.fromI32(2));
|
||||
|
||||
if (i == 0) {
|
||||
stats.ubiNextHourProjected = (medium > BigInt.zero()) ? medium : stats.ubiClaimedLastWeek.div(BigInt.fromI32(7));
|
||||
} else if (i == 1) {
|
||||
stats.mintNextHourProjected = (medium > BigInt.zero()) ? medium : stats.mintedLastWeek.div(BigInt.fromI32(7));
|
||||
} else if (i == 2) {
|
||||
stats.burnNextHourProjected = (medium > BigInt.zero()) ? medium : stats.burnedLastWeek.div(BigInt.fromI32(7));
|
||||
} else if (i == 3) {
|
||||
stats.taxNextHourProjected = (medium > BigInt.zero()) ? medium : stats.taxPaidLastWeek.div(BigInt.fromI32(7));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Save the updated Stats entity
|
||||
stats.save();
|
||||
}
|
||||
11
subgraph/base_sepolia/src/queries/getPositions.graphql
Normal file
11
subgraph/base_sepolia/src/queries/getPositions.graphql
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
query GetPositions {
|
||||
positions {
|
||||
id
|
||||
owner
|
||||
share
|
||||
creationTime
|
||||
lastTaxTime
|
||||
taxRate
|
||||
status
|
||||
}
|
||||
}
|
||||
60
subgraph/base_sepolia/src/stake.ts
Normal file
60
subgraph/base_sepolia/src/stake.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import {
|
||||
PositionCreated as PositionCreatedEvent,
|
||||
PositionRemoved as PositionRemovedEvent,
|
||||
PositionTaxPaid as PositionTaxPaidEvent,
|
||||
PositionShrunk as PositionShrunkEvent,
|
||||
} from "../generated/Stake/Stake";
|
||||
import { Harb } from "../generated/Harb/Harb";
|
||||
import { BigDecimal, BigInt, Bytes } from "@graphprotocol/graph-ts";
|
||||
import { Position } from "../generated/schema";
|
||||
|
||||
let decimals: BigDecimal = BigDecimal.fromString("1000000000000000000");
|
||||
let totalSupply: BigDecimal = BigDecimal.fromString("10000000000000000000000000");
|
||||
|
||||
export function handlePositionCreated(event: PositionCreatedEvent): void {
|
||||
let position = new Position(Bytes.fromI32(event.params.positionId.toI32()));
|
||||
position.owner = event.params.owner;
|
||||
position.share = event.params.share.toBigDecimal().div(totalSupply);
|
||||
position.creationTime = event.block.timestamp.toI32();
|
||||
position.taxRate = event.params.taxRate.toBigDecimal().div(BigDecimal.fromString("100"));
|
||||
position.harbDeposit = event.params.harbDeposit;
|
||||
position.status = "Active";
|
||||
position.snatched = 0;
|
||||
position.payout = BigInt.fromString("0");
|
||||
position.taxPaid = BigInt.fromString("0");
|
||||
let harb = Harb.bind(event.address);
|
||||
position.totalSupplyInit = harb.totalSupply();
|
||||
position.save();
|
||||
}
|
||||
|
||||
export function handlePositionRemoved(event: PositionRemovedEvent): void {
|
||||
let position = Position.load(Bytes.fromI32(event.params.positionId.toI32()));
|
||||
if (position != null) {
|
||||
position.status = "Closed";
|
||||
let harb = Harb.bind(event.address);
|
||||
position.totalSupplyEnd = harb.totalSupply();
|
||||
position.payout = position.payout.plus(event.params.harbPayout);
|
||||
position.save();
|
||||
}
|
||||
}
|
||||
|
||||
export function handlePositionShrunk(event: PositionShrunkEvent): void {
|
||||
let position = Position.load(Bytes.fromI32(event.params.positionId.toI32()));
|
||||
if (position != null) {
|
||||
position.share = event.params.newShares.toBigDecimal().div(totalSupply);
|
||||
position.harbDeposit = position.harbDeposit.minus(event.params.harbPayout);
|
||||
position.snatched = position.snatched++;
|
||||
|
||||
position.payout = position.payout.plus(event.params.harbPayout);
|
||||
position.save();
|
||||
}
|
||||
}
|
||||
|
||||
export function handleTaxPaid(event: PositionTaxPaidEvent): void {
|
||||
let position = Position.load(Bytes.fromI32(event.params.positionId.toI32()));
|
||||
if (position != null) {
|
||||
position.taxPaid = position.taxPaid.plus(event.params.taxPaid);
|
||||
position.taxRate = event.params.taxRate.toBigDecimal().div(BigDecimal.fromString("100"));
|
||||
position.save();
|
||||
}
|
||||
}
|
||||
59
subgraph/base_sepolia/subgraph.yaml
Normal file
59
subgraph/base_sepolia/subgraph.yaml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
specVersion: 0.0.4
|
||||
repository: http://gitea.loseyourip.com:4000/dark-meme-society/harb.git
|
||||
description: Harberger Tax Token
|
||||
schema:
|
||||
file: ./schema.graphql
|
||||
dataSources:
|
||||
- kind: ethereum
|
||||
name: Harb
|
||||
network: base-sepolia
|
||||
source:
|
||||
address: "0x00d5690044cf91fb3fc674c780697d511702f729"
|
||||
abi: Harb
|
||||
startBlock: 13984247
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
entities:
|
||||
- Stats
|
||||
- UbiClaim
|
||||
abis:
|
||||
- name: Harb
|
||||
file: ./abis/Harb.json
|
||||
eventHandlers:
|
||||
- event: Transfer(indexed address,indexed address,uint256)
|
||||
handler: handleTransfer
|
||||
- event: UbiClaimed(indexed address,uint256)
|
||||
handler: handleUbiClaimed
|
||||
blockHandlers:
|
||||
- handler: handleBlock
|
||||
file: ./src/harb.ts
|
||||
- kind: ethereum
|
||||
name: Stake
|
||||
network: base-sepolia
|
||||
source:
|
||||
address: "0x275403401f9c6f4659b6ffb6ab01798e1de9a912"
|
||||
abi: Stake
|
||||
startBlock: 13984247
|
||||
mapping:
|
||||
kind: ethereum/events
|
||||
apiVersion: 0.0.7
|
||||
language: wasm/assemblyscript
|
||||
entities:
|
||||
- Position
|
||||
abis:
|
||||
- name: Stake
|
||||
file: ./abis/Stake.json
|
||||
- name: Harb
|
||||
file: ./abis/Harb.json
|
||||
eventHandlers:
|
||||
- event: PositionCreated(indexed uint256,indexed address,uint256,uint256,uint32)
|
||||
handler: handlePositionCreated
|
||||
- event: PositionRemoved(indexed uint256,indexed address,uint256)
|
||||
handler: handlePositionRemoved
|
||||
- event: PositionShrunk(indexed uint256,indexed address,uint256,uint256)
|
||||
handler: handlePositionShrunk
|
||||
- event: PositionTaxPaid(indexed uint256,indexed address,uint256,uint256,uint256)
|
||||
handler: handleTaxPaid
|
||||
file: ./src/stake.ts
|
||||
55
subgraph/base_sepolia/tests/harb-utils.ts
Normal file
55
subgraph/base_sepolia/tests/harb-utils.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { newMockEvent } from "matchstick-as"
|
||||
import { ethereum, Address, BigInt } from "@graphprotocol/graph-ts"
|
||||
import { Approval, EIP712DomainChanged, Transfer } from "../generated/Harb/Harb"
|
||||
|
||||
export function createApprovalEvent(
|
||||
owner: Address,
|
||||
spender: Address,
|
||||
value: BigInt
|
||||
): Approval {
|
||||
let approvalEvent = changetype<Approval>(newMockEvent())
|
||||
|
||||
approvalEvent.parameters = new Array()
|
||||
|
||||
approvalEvent.parameters.push(
|
||||
new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner))
|
||||
)
|
||||
approvalEvent.parameters.push(
|
||||
new ethereum.EventParam("spender", ethereum.Value.fromAddress(spender))
|
||||
)
|
||||
approvalEvent.parameters.push(
|
||||
new ethereum.EventParam("value", ethereum.Value.fromUnsignedBigInt(value))
|
||||
)
|
||||
|
||||
return approvalEvent
|
||||
}
|
||||
|
||||
export function createEIP712DomainChangedEvent(): EIP712DomainChanged {
|
||||
let eip712DomainChangedEvent = changetype<EIP712DomainChanged>(newMockEvent())
|
||||
|
||||
eip712DomainChangedEvent.parameters = new Array()
|
||||
|
||||
return eip712DomainChangedEvent
|
||||
}
|
||||
|
||||
export function createTransferEvent(
|
||||
from: Address,
|
||||
to: Address,
|
||||
value: BigInt
|
||||
): Transfer {
|
||||
let transferEvent = changetype<Transfer>(newMockEvent())
|
||||
|
||||
transferEvent.parameters = new Array()
|
||||
|
||||
transferEvent.parameters.push(
|
||||
new ethereum.EventParam("from", ethereum.Value.fromAddress(from))
|
||||
)
|
||||
transferEvent.parameters.push(
|
||||
new ethereum.EventParam("to", ethereum.Value.fromAddress(to))
|
||||
)
|
||||
transferEvent.parameters.push(
|
||||
new ethereum.EventParam("value", ethereum.Value.fromUnsignedBigInt(value))
|
||||
)
|
||||
|
||||
return transferEvent
|
||||
}
|
||||
62
subgraph/base_sepolia/tests/harb.test.ts
Normal file
62
subgraph/base_sepolia/tests/harb.test.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import {
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll
|
||||
} from "matchstick-as/assembly/index"
|
||||
import { Address, BigInt } from "@graphprotocol/graph-ts"
|
||||
import { Approval } from "../generated/schema"
|
||||
import { Approval as ApprovalEvent } from "../generated/Harb/Harb"
|
||||
import { handleApproval } from "../src/harb"
|
||||
import { createApprovalEvent } from "./harb-utils"
|
||||
|
||||
// Tests structure (matchstick-as >=0.5.0)
|
||||
// https://thegraph.com/docs/en/developer/matchstick/#tests-structure-0-5-0
|
||||
|
||||
describe("Describe entity assertions", () => {
|
||||
beforeAll(() => {
|
||||
let owner = Address.fromString("0x0000000000000000000000000000000000000001")
|
||||
let spender = Address.fromString(
|
||||
"0x0000000000000000000000000000000000000001"
|
||||
)
|
||||
let value = BigInt.fromI32(234)
|
||||
let newApprovalEvent = createApprovalEvent(owner, spender, value)
|
||||
handleApproval(newApprovalEvent)
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
clearStore()
|
||||
})
|
||||
|
||||
// For more test scenarios, see:
|
||||
// https://thegraph.com/docs/en/developer/matchstick/#write-a-unit-test
|
||||
|
||||
test("Approval created and stored", () => {
|
||||
assert.entityCount("Approval", 1)
|
||||
|
||||
// 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function
|
||||
assert.fieldEquals(
|
||||
"Approval",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"owner",
|
||||
"0x0000000000000000000000000000000000000001"
|
||||
)
|
||||
assert.fieldEquals(
|
||||
"Approval",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"spender",
|
||||
"0x0000000000000000000000000000000000000001"
|
||||
)
|
||||
assert.fieldEquals(
|
||||
"Approval",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"value",
|
||||
"234"
|
||||
)
|
||||
|
||||
// More assert options:
|
||||
// https://thegraph.com/docs/en/developer/matchstick/#asserts
|
||||
})
|
||||
})
|
||||
70
subgraph/base_sepolia/tests/stake-utils.ts
Normal file
70
subgraph/base_sepolia/tests/stake-utils.ts
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import { newMockEvent } from "matchstick-as"
|
||||
import { ethereum, BigInt, Address } from "@graphprotocol/graph-ts"
|
||||
import { PositionCreated, PositionRemoved } from "../generated/Stake/Stake"
|
||||
|
||||
export function createPositionCreatedEvent(
|
||||
positionId: BigInt,
|
||||
owner: Address,
|
||||
share: BigInt,
|
||||
creationTime: BigInt,
|
||||
taxRate: BigInt
|
||||
): PositionCreated {
|
||||
let positionCreatedEvent = changetype<PositionCreated>(newMockEvent())
|
||||
|
||||
positionCreatedEvent.parameters = new Array()
|
||||
|
||||
positionCreatedEvent.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
"positionId",
|
||||
ethereum.Value.fromUnsignedBigInt(positionId)
|
||||
)
|
||||
)
|
||||
positionCreatedEvent.parameters.push(
|
||||
new ethereum.EventParam("owner", ethereum.Value.fromAddress(owner))
|
||||
)
|
||||
positionCreatedEvent.parameters.push(
|
||||
new ethereum.EventParam("share", ethereum.Value.fromUnsignedBigInt(share))
|
||||
)
|
||||
positionCreatedEvent.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
"creationTime",
|
||||
ethereum.Value.fromUnsignedBigInt(creationTime)
|
||||
)
|
||||
)
|
||||
positionCreatedEvent.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
"taxRate",
|
||||
ethereum.Value.fromUnsignedBigInt(taxRate)
|
||||
)
|
||||
)
|
||||
|
||||
return positionCreatedEvent
|
||||
}
|
||||
|
||||
export function createPositionRemovedEvent(
|
||||
positionId: BigInt,
|
||||
share: BigInt,
|
||||
lastTaxTime: BigInt
|
||||
): PositionRemoved {
|
||||
let positionRemovedEvent = changetype<PositionRemoved>(newMockEvent())
|
||||
|
||||
positionRemovedEvent.parameters = new Array()
|
||||
|
||||
positionRemovedEvent.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
"positionId",
|
||||
ethereum.Value.fromUnsignedBigInt(positionId)
|
||||
)
|
||||
)
|
||||
positionRemovedEvent.parameters.push(
|
||||
new ethereum.EventParam("share", ethereum.Value.fromUnsignedBigInt(share))
|
||||
)
|
||||
positionRemovedEvent.parameters.push(
|
||||
new ethereum.EventParam(
|
||||
"lastTaxTime",
|
||||
ethereum.Value.fromUnsignedBigInt(lastTaxTime)
|
||||
)
|
||||
)
|
||||
|
||||
return positionRemovedEvent
|
||||
}
|
||||
80
subgraph/base_sepolia/tests/stake.test.ts
Normal file
80
subgraph/base_sepolia/tests/stake.test.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import {
|
||||
assert,
|
||||
describe,
|
||||
test,
|
||||
clearStore,
|
||||
beforeAll,
|
||||
afterAll
|
||||
} from "matchstick-as/assembly/index"
|
||||
import { BigInt, Address } from "@graphprotocol/graph-ts"
|
||||
import { PositionCreated } from "../generated/schema"
|
||||
import { PositionCreated as PositionCreatedEvent } from "../generated/Stake/Stake"
|
||||
import { handlePositionCreated } from "../src/stake"
|
||||
import { createPositionCreatedEvent } from "./stake-utils"
|
||||
|
||||
// Tests structure (matchstick-as >=0.5.0)
|
||||
// https://thegraph.com/docs/en/developer/matchstick/#tests-structure-0-5-0
|
||||
|
||||
describe("Describe entity assertions", () => {
|
||||
beforeAll(() => {
|
||||
let positionId = BigInt.fromI32(234)
|
||||
let owner = Address.fromString("0x0000000000000000000000000000000000000001")
|
||||
let share = BigInt.fromI32(234)
|
||||
let creationTime = BigInt.fromI32(234)
|
||||
let taxRate = BigInt.fromI32(234)
|
||||
let newPositionCreatedEvent = createPositionCreatedEvent(
|
||||
positionId,
|
||||
owner,
|
||||
share,
|
||||
creationTime,
|
||||
taxRate
|
||||
)
|
||||
handlePositionCreated(newPositionCreatedEvent)
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
clearStore()
|
||||
})
|
||||
|
||||
// For more test scenarios, see:
|
||||
// https://thegraph.com/docs/en/developer/matchstick/#write-a-unit-test
|
||||
|
||||
test("PositionCreated created and stored", () => {
|
||||
assert.entityCount("PositionCreated", 1)
|
||||
|
||||
// 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function
|
||||
assert.fieldEquals(
|
||||
"PositionCreated",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"positionId",
|
||||
"234"
|
||||
)
|
||||
assert.fieldEquals(
|
||||
"PositionCreated",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"owner",
|
||||
"0x0000000000000000000000000000000000000001"
|
||||
)
|
||||
assert.fieldEquals(
|
||||
"PositionCreated",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"share",
|
||||
"234"
|
||||
)
|
||||
assert.fieldEquals(
|
||||
"PositionCreated",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"creationTime",
|
||||
"234"
|
||||
)
|
||||
assert.fieldEquals(
|
||||
"PositionCreated",
|
||||
"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1",
|
||||
"taxRate",
|
||||
"234"
|
||||
)
|
||||
|
||||
// More assert options:
|
||||
// https://thegraph.com/docs/en/developer/matchstick/#asserts
|
||||
})
|
||||
})
|
||||
4
subgraph/base_sepolia/tsconfig.json
Normal file
4
subgraph/base_sepolia/tsconfig.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "@graphprotocol/graph-ts/types/tsconfig.base.json",
|
||||
"include": ["src", "tests"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue