Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multichain stable swap #251

Merged
merged 2 commits into from
Jan 26, 2024
Merged
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
67 changes: 67 additions & 0 deletions subgraphs/exchange-stableswap/arb/mappings/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* eslint-disable prefer-const */
import { DataSourceContext, log } from "@graphprotocol/graph-ts";
import { StableSwapPair as StableSwapPairContract } from "../generated/templates/StableSwapPair/StableSwapPair";
import { StableSwap3PairV2 as StableSwap3PairV2Contract } from "../generated/templates/StableSwap3PairV2/StableSwap3PairV2";
import { BIG_DECIMAL_ZERO, BIG_INT_ONE, BIG_INT_ZERO, ADDRESS_ZERO } from "./utils";
import { getOrCreateFactory, getOrCreateToken } from "./utils/data";
import { NewStableSwapPair } from "../generated/StableSwapFactory/StableSwapFactory";
import { ERC20, StableSwapPair } from "../generated/templates";
import { Pair } from "../generated/schema";

export function handlePairCreated(event: NewStableSwapPair): void {
log.info("handlePairCreated. address: {}", [event.address.toHex()]);
let pair = Pair.load(event.params.swapContract.toHex());
let factory = getOrCreateFactory(event.address.toHex());
if (pair === null) {
let token0 = getOrCreateToken(event.params.tokenA);
let token1 = getOrCreateToken(event.params.tokenB);

pair = new Pair(event.params.swapContract.toHex());

if (event.params.tokenC.toHex() != ADDRESS_ZERO) {
let token2 = getOrCreateToken(event.params.tokenC);
pair.token2 = token2.id;
pair.token2Price = BIG_DECIMAL_ZERO;
pair.reserve2 = BIG_DECIMAL_ZERO;
}
pair.token0 = token0.id;
pair.token1 = token1.id;
pair.name = token0.symbol.concat("-").concat(token1.symbol);

pair.token0Price = BIG_DECIMAL_ZERO;
pair.token1Price = BIG_DECIMAL_ZERO;
pair.volumeToken0 = BIG_DECIMAL_ZERO;
pair.volumeToken1 = BIG_DECIMAL_ZERO;
pair.volumeUSD = BIG_DECIMAL_ZERO;
pair.volumeOutUSD = BIG_DECIMAL_ZERO;
pair.totalTransactions = BIG_INT_ZERO;
pair.reserve0 = BIG_DECIMAL_ZERO;
pair.reserve1 = BIG_DECIMAL_ZERO;
pair.trackedReserveETH = BIG_DECIMAL_ZERO;
pair.reserveETH = BIG_DECIMAL_ZERO;
pair.reserveUSD = BIG_DECIMAL_ZERO;
pair.untrackedVolumeUSD = BIG_DECIMAL_ZERO;
pair.totalSupply = BIG_DECIMAL_ZERO;

pair.virtualPrice = BIG_DECIMAL_ZERO;
pair.block = event.block.number;
pair.timestamp = event.block.timestamp;
pair.factory = factory.id;

pair.save();
}

factory.pairs = factory.pairs.concat([pair.id]);
factory.totalPairs = factory.totalPairs.plus(BIG_INT_ONE);
factory.save();

StableSwapPair.create(event.params.swapContract);

let context = new DataSourceContext();
context.setString("pairAddress", event.params.swapContract.toHex());
if (event.params.tokenC.toHex() != ADDRESS_ZERO) {
ERC20.createWithContext(StableSwap3PairV2Contract.bind(event.params.swapContract).token(), context);
} else {
ERC20.createWithContext(StableSwapPairContract.bind(event.params.swapContract).token(), context);
}
}
61 changes: 61 additions & 0 deletions subgraphs/exchange-stableswap/arb/mappings/services/burn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* eslint-disable prefer-const */
import { BigDecimal, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts";
import { updatePairDayData, updatePairHourData, updatePancakeDayData, updateTokenDayData } from "./dayUpdates";
import { Bundle, Burn, Pair, Token, Transaction } from "../../generated/schema";
import { getOrCreateFactory } from "../utils/data";
import { BIG_INT_ONE, convertTokenToDecimal } from "../utils";

export function burn(event: ethereum.Event, tokenAmount0: BigInt, tokenAmount1: BigInt, to: Bytes | null): void {
let transaction = Transaction.load(event.transaction.hash.toHex());
if (transaction === null) {
return;
}

let burns = transaction.burns;
let burn = Burn.load(burns[burns.length - 1]);

let pair = Pair.load(event.address.toHex());
let factory = getOrCreateFactory(pair.factory);

//update token info
let token0 = Token.load(pair.token0);
let token1 = Token.load(pair.token1);
let token0Amount = convertTokenToDecimal(tokenAmount0, token0.decimals);
let token1Amount = convertTokenToDecimal(tokenAmount1, token1.decimals);

// update txn counts
token0.totalTransactions = token0.totalTransactions.plus(BIG_INT_ONE);
token1.totalTransactions = token1.totalTransactions.plus(BIG_INT_ONE);

// get new amounts of USD and BNB for tracking
let bundle = Bundle.load("1");
let amountTotalUSD = token1.derivedETH
.times(token1Amount)
.plus(token0.derivedETH.times(token0Amount))
.times(bundle.ethPrice);

// update txn counts
// factory. = factory.totalTransactions.plus(BIG_INT_ONE);
pair.totalTransactions = pair.totalTransactions.plus(BIG_INT_ONE);

// update global counter and save
token0.save();
token1.save();
pair.save();
factory.save();

// update burn
burn.sender = event.transaction.from;
burn.amount0 = token0Amount as BigDecimal;
burn.amount1 = token1Amount as BigDecimal;
burn.to = to;
burn.logIndex = event.logIndex;
burn.amountUSD = amountTotalUSD as BigDecimal;
burn.save();

updatePairDayData(event);
updatePairHourData(event);
updatePancakeDayData(event);
updateTokenDayData(token0 as Token, event);
updateTokenDayData(token1 as Token, event);
}
129 changes: 129 additions & 0 deletions subgraphs/exchange-stableswap/arb/mappings/services/dayUpdates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/* eslint-disable prefer-const */
import { Bundle, Pair, PairDayData, PairHourData, PancakeDayData, Token, TokenDayData } from "../../generated/schema";
import { BigDecimal, BigInt, ethereum } from "@graphprotocol/graph-ts";
import { BIG_DECIMAL_ZERO, BIG_INT_ONE, BIG_INT_ZERO, FACTORIES } from "../utils";
import { getOrCreateFactory } from "../utils/data";

export function updatePancakeDayData(event: ethereum.Event): PancakeDayData {
let timestamp = event.block.timestamp.toI32();
let dayID = timestamp / 86400;
let dayStartTimestamp = dayID * 86400;

let pancakeDayData = PancakeDayData.load(dayID.toString());
if (pancakeDayData === null) {
pancakeDayData = new PancakeDayData(dayID.toString());
pancakeDayData.date = dayStartTimestamp;
pancakeDayData.dailyVolumeUSD = BIG_DECIMAL_ZERO;
pancakeDayData.dailyVolumeETH = BIG_DECIMAL_ZERO;
pancakeDayData.totalVolumeUSD = BIG_DECIMAL_ZERO;
pancakeDayData.totalVolumeETH = BIG_DECIMAL_ZERO;
pancakeDayData.dailyVolumeUntracked = BIG_DECIMAL_ZERO;
}

let totalLiquidityETH = BIG_DECIMAL_ZERO;
let totalLiquidityUSD = BIG_DECIMAL_ZERO;
let totalTransactions = BIG_INT_ZERO;
for (let i = 0; i < FACTORIES.length; i++) {
let factory = getOrCreateFactory(FACTORIES[i]);
totalLiquidityETH = totalLiquidityETH.plus(factory.totalLiquidityETH);
totalLiquidityUSD = totalLiquidityUSD.plus(factory.totalLiquidityUSD);
totalTransactions = totalTransactions.plus(factory.totalTransactions);
}

pancakeDayData.totalLiquidityUSD = totalLiquidityUSD;
pancakeDayData.totalLiquidityETH = totalLiquidityETH;
pancakeDayData.totalTransactions = totalTransactions;
pancakeDayData.save();

return pancakeDayData as PancakeDayData;
}

export function updatePairDayData(event: ethereum.Event): PairDayData {
let timestamp = event.block.timestamp.toI32();
let dayID = timestamp / 86400;
let dayStartTimestamp = dayID * 86400;
let dayPairID = event.address.toHex().concat("-").concat(BigInt.fromI32(dayID).toString());
let pair = Pair.load(event.address.toHex());
let pairDayData = PairDayData.load(dayPairID);
if (pairDayData === null) {
pairDayData = new PairDayData(dayPairID);
pairDayData.date = dayStartTimestamp;
pairDayData.token0 = pair.token0;
pairDayData.token1 = pair.token1;
pairDayData.pairAddress = event.address;
pairDayData.dailyVolumeToken0 = BIG_DECIMAL_ZERO;
pairDayData.dailyVolumeToken1 = BIG_DECIMAL_ZERO;
pairDayData.dailyVolumeUSD = BIG_DECIMAL_ZERO;
pairDayData.dailyTxns = BIG_INT_ZERO;
}
pairDayData.totalSupply = pair.totalSupply;
pairDayData.virtualPrice = pair.virtualPrice;
pairDayData.reserve0 = pair.reserve0;
pairDayData.reserve1 = pair.reserve1;
pairDayData.reserveUSD = pair.reserveUSD;
pairDayData.dailyTxns = pairDayData.dailyTxns.plus(BIG_INT_ONE);
pairDayData.token0Price = pair.token0Price;
pairDayData.token1Price = pair.token1Price;
pairDayData.token2Price = pair.token2Price;
pairDayData.save();

return pairDayData as PairDayData;
}

export function updatePairHourData(event: ethereum.Event): PairHourData {
let timestamp = event.block.timestamp.toI32();
let hourIndex = timestamp / 3600;
let hourStartUnix = hourIndex * 3600;
let hourPairID = event.address.toHex().concat("-").concat(BigInt.fromI32(hourIndex).toString());
let pair = Pair.load(event.address.toHex());
let pairHourData = PairHourData.load(hourPairID);
if (pairHourData === null) {
pairHourData = new PairHourData(hourPairID);
pairHourData.hourStartUnix = hourStartUnix;
pairHourData.pair = event.address.toHex();
pairHourData.hourlyVolumeToken0 = BIG_DECIMAL_ZERO;
pairHourData.hourlyVolumeToken1 = BIG_DECIMAL_ZERO;
pairHourData.hourlyVolumeUSD = BIG_DECIMAL_ZERO;
pairHourData.hourlyTxns = BIG_INT_ZERO;
}
pairHourData.totalSupply = pair.totalSupply;
pairHourData.reserve0 = pair.reserve0;
pairHourData.reserve1 = pair.reserve1;
pairHourData.reserveUSD = pair.reserveUSD;
pairHourData.token0Price = pair.token0Price;
pairHourData.token1Price = pair.token1Price;
pairHourData.token2Price = pair.token2Price;
pairHourData.hourlyTxns = pairHourData.hourlyTxns.plus(BIG_INT_ONE);
pairHourData.save();

return pairHourData as PairHourData;
}

export function updateTokenDayData(token: Token, event: ethereum.Event): TokenDayData {
let bundle = Bundle.load("1");
let timestamp = event.block.timestamp.toI32();
let dayID = timestamp / 86400;
let dayStartTimestamp = dayID * 86400;
let tokenDayID = token.id.toString().concat("-").concat(BigInt.fromI32(dayID).toString());

let tokenDayData = TokenDayData.load(tokenDayID);
if (tokenDayData === null) {
tokenDayData = new TokenDayData(tokenDayID);
tokenDayData.date = dayStartTimestamp;
tokenDayData.token = token.id;
tokenDayData.priceUSD = token.derivedETH.times(bundle.ethPrice);
tokenDayData.dailyVolumeToken = BIG_DECIMAL_ZERO;
tokenDayData.dailyVolumeETH = BIG_DECIMAL_ZERO;
tokenDayData.dailyVolumeUSD = BIG_DECIMAL_ZERO;
tokenDayData.dailyTxns = BIG_INT_ZERO;
tokenDayData.totalLiquidityUSD = BIG_DECIMAL_ZERO;
}
tokenDayData.priceUSD = token.derivedETH.times(bundle.ethPrice);
tokenDayData.totalLiquidityToken = token.totalLiquidity;
tokenDayData.totalLiquidityETH = token.totalLiquidity.times(token.derivedETH as BigDecimal);
tokenDayData.totalLiquidityUSD = tokenDayData.totalLiquidityETH.times(bundle.ethPrice);
tokenDayData.dailyTxns = tokenDayData.dailyTxns.plus(BIG_INT_ONE);
tokenDayData.save();

return tokenDayData as TokenDayData;
}
56 changes: 56 additions & 0 deletions subgraphs/exchange-stableswap/arb/mappings/services/mint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* eslint-disable prefer-const */
import { BigDecimal, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts";
import { updatePairDayData, updatePairHourData, updatePancakeDayData, updateTokenDayData } from "./dayUpdates";
import { Bundle, Mint, Pair, Token, Transaction } from "../../generated/schema";
import { BIG_INT_ONE, convertTokenToDecimal } from "../utils";
import { getOrCreateFactory } from "../utils/data";

export function mint(event: ethereum.Event, tokenAmount0: BigInt, tokenAmount1: BigInt, sender?: Bytes): void {
let transaction = Transaction.load(event.transaction.hash.toHex());
let mints = transaction.mints;
let mint = Mint.load(mints[mints.length - 1]);

let pair = Pair.load(event.address.toHex());
let factory = getOrCreateFactory(pair.factory);

let token0 = Token.load(pair.token0);
let token1 = Token.load(pair.token1);

// update exchange info (except balances, sync will cover that)
let token0Amount = convertTokenToDecimal(tokenAmount0, token0.decimals);
let token1Amount = convertTokenToDecimal(tokenAmount1, token1.decimals);

// update txn counts
token0.totalTransactions = token0.totalTransactions.plus(BIG_INT_ONE);
token1.totalTransactions = token1.totalTransactions.plus(BIG_INT_ONE);

// get new amounts of USD and BNB for tracking
let bundle = Bundle.load("1");
let amountTotalUSD = token1.derivedETH
.times(token1Amount)
.plus(token0.derivedETH.times(token0Amount))
.times(bundle.ethPrice);

// update txn counts
pair.totalTransactions = pair.totalTransactions.plus(BIG_INT_ONE);
factory.totalTransactions = factory.totalTransactions.plus(BIG_INT_ONE);

// save entities
token0.save();
token1.save();
pair.save();
factory.save();

mint.sender = sender;
mint.amount0 = token0Amount as BigDecimal;
mint.amount1 = token1Amount as BigDecimal;
mint.logIndex = event.logIndex;
mint.amountUSD = amountTotalUSD as BigDecimal;
mint.save();

updatePairDayData(event);
updatePairHourData(event);
updatePancakeDayData(event);
updateTokenDayData(token0 as Token, event);
updateTokenDayData(token1 as Token, event);
}
Loading
Loading