222 lines
7.9 KiB
TypeScript
222 lines
7.9 KiB
TypeScript
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();
|
|
}
|