Skip to content

Commit

Permalink
feat: Add price ref for stableswap arb
Browse files Browse the repository at this point in the history
  • Loading branch information
0xjojoex committed Feb 7, 2024
1 parent ea7d6a5 commit 36cd61a
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 205 deletions.
121 changes: 121 additions & 0 deletions subgraphs/exchange-stableswap/arb/abis/PriceLens0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
[
{
"type": "constructor",
"inputs": [
{ "name": "nativePriceAggregator", "type": "address", "internalType": "address" },
{ "name": "wnative", "type": "address", "internalType": "address" }
],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "DECIMALS",
"inputs": [],
"outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }],
"stateMutability": "view"
},
{
"type": "function",
"name": "_nativePriceAggregator",
"inputs": [],
"outputs": [{ "name": "", "type": "address", "internalType": "address" }],
"stateMutability": "view"
},
{
"type": "function",
"name": "_wnative",
"inputs": [],
"outputs": [{ "name": "", "type": "address", "internalType": "address" }],
"stateMutability": "view"
},
{
"type": "function",
"name": "getNativePrice",
"inputs": [{ "name": "token", "type": "address", "internalType": "address" }],
"outputs": [{ "name": "nativePrice", "type": "uint256", "internalType": "uint256" }],
"stateMutability": "view"
},
{
"type": "function",
"name": "getUsd",
"inputs": [{ "name": "token", "type": "address", "internalType": "address" }],
"outputs": [{ "name": "price", "type": "uint256", "internalType": "uint256" }],
"stateMutability": "view"
},
{
"type": "function",
"name": "owner",
"inputs": [],
"outputs": [{ "name": "", "type": "address", "internalType": "address" }],
"stateMutability": "view"
},
{
"type": "function",
"name": "setNativePriceAggregator",
"inputs": [{ "name": "nativePriceAggregator", "type": "address", "internalType": "address" }],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "setSource",
"inputs": [
{ "name": "token", "type": "address", "internalType": "address" },
{ "name": "sourceType", "type": "uint8", "internalType": "enum PriceLens0.SourceType" },
{ "name": "sourceAddress", "type": "address", "internalType": "address" },
{ "name": "baseAddress", "type": "address", "internalType": "address" }
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "setSourceList",
"inputs": [
{
"name": "sourceList",
"type": "tuple[]",
"internalType": "struct PriceLens0.SourceList[]",
"components": [
{ "name": "token", "type": "address", "internalType": "address" },
{ "name": "sourceType", "type": "uint8", "internalType": "enum PriceLens0.SourceType" },
{ "name": "sourceAddress", "type": "address", "internalType": "address" },
{ "name": "baseAddress", "type": "address", "internalType": "address" }
]
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "sources",
"inputs": [{ "name": "", "type": "address", "internalType": "address" }],
"outputs": [
{ "name": "sourceType", "type": "uint8", "internalType": "enum PriceLens0.SourceType" },
{ "name": "sourceAddress", "type": "address", "internalType": "address" },
{ "name": "baseAddress", "type": "address", "internalType": "address" }
],
"stateMutability": "view"
},
{
"type": "function",
"name": "transferOwnership",
"inputs": [{ "name": "newOwner", "type": "address", "internalType": "address" }],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "event",
"name": "OwnershipTransferred",
"inputs": [
{ "name": "user", "type": "address", "indexed": true, "internalType": "address" },
{ "name": "newOwner", "type": "address", "indexed": true, "internalType": "address" }
],
"anonymous": false
},
{ "type": "error", "name": "IncorrectBaseAddress", "inputs": [] },
{ "type": "error", "name": "IncorrectChainlinkPrice", "inputs": [] },
{ "type": "error", "name": "IncorrectSourceAddress", "inputs": [] },
{ "type": "error", "name": "UnknowPrice", "inputs": [] }
]
46 changes: 11 additions & 35 deletions subgraphs/exchange-stableswap/arb/mappings/services/swap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { BigDecimal, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts";
import { Bundle, Pair, Swap, Token, Transaction } from "../../generated/schema";
import { BIG_DECIMAL_ZERO, BIG_INT_ONE, convertTokenToDecimal } from "../utils";
import { getTrackedFeeVolumeUSD, getTrackedVolumeUSD } from "../utils/pricing";
import { getOrCreateFactory } from "../utils/data";
import { updatePairDayData, updatePairHourData, updatePancakeDayData, updateTokenDayData } from "./dayUpdates";

Expand Down Expand Up @@ -52,48 +51,25 @@ export function swap(event: ethereum.Event, params: SwapParams): void {
}
let derivedFeeAmountUSD = derivedFeeAmountBNB.times(bundle.ethPrice);

// only accounts for volume through white listed tokens
let trackedAmountUSD = getTrackedVolumeUSD(
bundle as Bundle,
amount0Total,
token0 as Token,
amount1Total,
token1 as Token
);
let trackedFeeAmountUSD = getTrackedFeeVolumeUSD(
bundle as Bundle,
amount0Total,
token0 as Token,
amount1Total,
token1 as Token
);

let price0 = token0.derivedETH.times(bundle.ethPrice);
let price1 = token1.derivedETH.times(bundle.ethPrice);

let trackedAmountBNB: BigDecimal;
if (bundle.ethPrice.equals(BIG_DECIMAL_ZERO)) {
trackedAmountBNB = BIG_DECIMAL_ZERO;
} else {
trackedAmountBNB = trackedAmountUSD.div(bundle.ethPrice);
}

// update token0 global volume and token liquidity stats
token0.tradeVolume = token0.tradeVolume.plus(amount0In.plus(amount0Out));
token0.tradeVolumeUSD = token0.tradeVolumeUSD.plus(trackedAmountUSD);
token0.tradeVolumeUSD = token0.tradeVolumeUSD.plus(derivedAmountUSD);
token0.untrackedVolumeUSD = token0.untrackedVolumeUSD.plus(derivedAmountUSD);

// update token1 global volume and token liquidity stats
token1.tradeVolume = token1.tradeVolume.plus(amount1In.plus(amount1Out));
token1.tradeVolumeUSD = token1.tradeVolumeUSD.plus(trackedAmountUSD);
token1.tradeVolumeUSD = token1.tradeVolumeUSD.plus(derivedAmountUSD);
token1.untrackedVolumeUSD = token1.untrackedVolumeUSD.plus(derivedAmountUSD);

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

// update pair volume data, use tracked amount if we have it as its probably more accurate
pair.volumeUSD = pair.volumeUSD.plus(trackedAmountUSD);
pair.volumeUSD = pair.volumeUSD.plus(derivedAmountUSD);
pair.volumeOutUSD = pair.volumeOutUSD.plus(amount0Out.times(price0)).plus(amount1Out.times(price1));
pair.volumeToken0 = pair.volumeToken0.plus(amount0Total);
pair.volumeToken1 = pair.volumeToken1.plus(amount1Total);
Expand All @@ -103,8 +79,8 @@ export function swap(event: ethereum.Event, params: SwapParams): void {

// update global values, only used tracked amounts for volume
let factory = getOrCreateFactory(pair.factory);
factory.totalVolumeUSD = factory.totalVolumeUSD.plus(trackedAmountUSD);
factory.totalVolumeETH = factory.totalVolumeETH.plus(trackedAmountBNB);
factory.totalVolumeUSD = factory.totalVolumeUSD.plus(derivedAmountUSD);
factory.totalVolumeETH = factory.totalVolumeETH.plus(derivedAmountBNB);
factory.untrackedVolumeUSD = factory.untrackedVolumeUSD.plus(derivedAmountUSD);
factory.totalTransactions = factory.totalTransactions.plus(BIG_INT_ONE);

Expand Down Expand Up @@ -140,8 +116,8 @@ export function swap(event: ethereum.Event, params: SwapParams): void {
swap.from = event.transaction.from;
swap.logIndex = event.logIndex;
// use the tracked amount if we have it
swap.amountUSD = trackedAmountUSD === BIG_DECIMAL_ZERO ? derivedAmountUSD : trackedAmountUSD;
swap.amountFeeUSD = trackedFeeAmountUSD === BIG_DECIMAL_ZERO ? derivedFeeAmountUSD : trackedFeeAmountUSD;
swap.amountUSD = derivedAmountUSD;
swap.amountFeeUSD = derivedFeeAmountUSD;
swap.save();

// update the transaction
Expand All @@ -160,21 +136,21 @@ export function swap(event: ethereum.Event, params: SwapParams): void {
let token1DayData = updateTokenDayData(token1 as Token, event);

// swap specific updating
pancakeDayData.dailyVolumeUSD = pancakeDayData.dailyVolumeUSD.plus(trackedAmountUSD);
pancakeDayData.dailyVolumeETH = pancakeDayData.dailyVolumeETH.plus(trackedAmountBNB);
pancakeDayData.dailyVolumeUSD = pancakeDayData.dailyVolumeUSD.plus(derivedAmountUSD);
pancakeDayData.dailyVolumeETH = pancakeDayData.dailyVolumeETH.plus(derivedAmountBNB);
pancakeDayData.dailyVolumeUntracked = pancakeDayData.dailyVolumeUntracked.plus(derivedAmountUSD);
pancakeDayData.save();

// swap specific updating for pair
pairDayData.dailyVolumeToken0 = pairDayData.dailyVolumeToken0.plus(amount0Total);
pairDayData.dailyVolumeToken1 = pairDayData.dailyVolumeToken1.plus(amount1Total);
pairDayData.dailyVolumeUSD = pairDayData.dailyVolumeUSD.plus(trackedAmountUSD);
pairDayData.dailyVolumeUSD = pairDayData.dailyVolumeUSD.plus(derivedAmountUSD);
pairDayData.save();

// update hourly pair data
pairHourData.hourlyVolumeToken0 = pairHourData.hourlyVolumeToken0.plus(amount0Total);
pairHourData.hourlyVolumeToken1 = pairHourData.hourlyVolumeToken1.plus(amount1Total);
pairHourData.hourlyVolumeUSD = pairHourData.hourlyVolumeUSD.plus(trackedAmountUSD);
pairHourData.hourlyVolumeUSD = pairHourData.hourlyVolumeUSD.plus(derivedAmountUSD);
pairHourData.save();

// swap specific updating for token0
Expand Down
13 changes: 12 additions & 1 deletion subgraphs/exchange-stableswap/arb/mappings/services/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,22 @@ export function sync(pairAddress: Address): void {
bundle.save();

let t0derivedETH = findBnbPerToken(token0 as Token);
let t1derivedETH = findBnbPerToken(token1 as Token);

// if t0 bnb is not found
if (t0derivedETH.equals(BIG_DECIMAL_ZERO) && t1derivedETH.gt(BIG_DECIMAL_ZERO)) {
t0derivedETH = t1derivedETH.times(pair.token1Price);
}

// if t1 bnb is not found
if (t1derivedETH.equals(BIG_DECIMAL_ZERO) && t0derivedETH.gt(BIG_DECIMAL_ZERO)) {
t1derivedETH = t0derivedETH.times(pair.token0Price);
}

token0.derivedETH = t0derivedETH;
token0.derivedUSD = t0derivedETH.times(bundle.ethPrice);
token0.save();

let t1derivedETH = findBnbPerToken(token1 as Token);
token1.derivedETH = t1derivedETH;
token1.derivedUSD = t1derivedETH.times(bundle.ethPrice);
token1.save();
Expand Down
4 changes: 4 additions & 0 deletions subgraphs/exchange-stableswap/arb/mappings/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Address, BigDecimal, BigInt } from "@graphprotocol/graph-ts";
// import { ERC20 } from "../../../exchange/generated/Factory/ERC20";
// import { ERC20NameBytes } from "../../../exchange/generated/Factory/ERC20NameBytes";
// import { ERC20SymbolBytes } from "../../../exchange/generated/Factory/ERC20SymbolBytes";
import { PriceLens0 } from "../../generated/StableSwapFactory/PriceLens0";
import { StableSwapFactory } from "../../generated/StableSwapFactory/StableSwapFactory";
import { ERC20 } from "../../generated/StableSwapFactory/ERC20";
import { ERC20SymbolBytes } from "../../generated/StableSwapFactory/ERC20SymbolBytes";
Expand All @@ -18,6 +19,8 @@ export let PENDLE_ADDRESS = "0x0c880f6761F1af8d9Aa9C466984b80DAb9a8c9e8";
//When new factory was deployed, and SC address into list
export let FACTORIES: string[] = [STABLESWAP_FACTORY_ADDRESS];

export let priceLensContract = PriceLens0.bind(Address.fromString("0x6234d989583520565d00131948c1fb7c4ebb691d"));

export let USDT_ADDR = Address.fromString(USDT_ADDRESS);
export let USDC_ADDR = Address.fromString(USDC_ADDRESS);
export let WETH_ADDR = Address.fromString(WETH_ADDRESS);
Expand All @@ -29,6 +32,7 @@ export let BIG_DECIMAL_ZERO = BigDecimal.fromString("0");
export let BIG_DECIMAL_ONE = BigDecimal.fromString("1");
export let BIG_DECIMAL_TEN = BigDecimal.fromString("10");
export let BIG_INT_18 = BigInt.fromI32(18);
export let BIG_INT_6 = BigInt.fromI32(6);

export let stableSwapFactoryContract = StableSwapFactory.bind(Address.fromString(STABLESWAP_FACTORY_ADDRESS));
export function exponentToBigDecimal(decimals: BigInt): BigDecimal {
Expand Down
79 changes: 8 additions & 71 deletions subgraphs/exchange-stableswap/arb/mappings/utils/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import {
PENDLE_ADDR,
USDC_ADDR,
PENDLE_ADDRESS,
priceLensContract,
convertTokenToDecimal,
BIG_INT_6,
} from "./index";
import { PairV3 as PairV3Contract } from "../../generated/StableSwapFactory/PairV3";
import { StableSwapPair as StableSwapPairContract } from "../../generated/StableSwapFactory/StableSwapPair";
Expand Down Expand Up @@ -128,72 +131,12 @@ export function findBnbPerToken(token: Token): BigDecimal {
}
}
}
return BIG_DECIMAL_ZERO; // nothing was found return 0
}

/**
* Accepts tokens and amounts, return tracked amount based on token whitelist
* If one token on whitelist, return amount in that token converted to USD.
* If both are, return average of two amounts
* If neither is, return 0
*/
export function getTrackedVolumeUSD(
bundle: Bundle,
tokenAmount0: BigDecimal,
token0: Token,
tokenAmount1: BigDecimal,
token1: Token
): BigDecimal {
let price0 = token0.derivedETH.times(bundle.ethPrice);
let price1 = token1.derivedETH.times(bundle.ethPrice);

// both are whitelist tokens, take average of both amounts
if (WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
return tokenAmount0.times(price0).plus(tokenAmount1.times(price1)).div(BigDecimal.fromString("2"));
}

// take full value of the whitelisted token amount
if (WHITELIST.includes(token0.id) && !WHITELIST.includes(token1.id)) {
return tokenAmount0.times(price0);
}

// take full value of the whitelisted token amount
if (!WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
return tokenAmount1.times(price1);
let tokenBNBPrice = priceLensContract.try_getNativePrice(Address.fromString(token.id));
if (!tokenBNBPrice.reverted) {
return convertTokenToDecimal(tokenBNBPrice.value, BIG_INT_6);
}

// neither token is on white list, tracked volume is 0
return BIG_DECIMAL_ZERO;
}

/**
* Accepts tokens and amounts, return tracked fee amount based on token whitelist
* If both are, return the difference between the token amounts
* If not, return 0
*/
export function getTrackedFeeVolumeUSD(
bundle: Bundle,
tokenAmount0: BigDecimal,
token0: Token,
tokenAmount1: BigDecimal,
token1: Token
): BigDecimal {
let price0 = token0.derivedETH.times(bundle.ethPrice);
let price1 = token1.derivedETH.times(bundle.ethPrice);

// both are whitelist tokens, take average of both amounts
if (WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
let tokenAmount0USD = tokenAmount0.times(price0);
let tokenAmount1USD = tokenAmount1.times(price1);
if (tokenAmount0USD.ge(tokenAmount1USD)) {
return tokenAmount0USD.minus(tokenAmount1USD);
} else {
return tokenAmount1USD.minus(tokenAmount0USD);
}
}

// neither token is on white list, tracked volume is 0
return BIG_DECIMAL_ZERO;
return BIG_DECIMAL_ZERO; // nothing was found return 0
}

/**
Expand All @@ -212,11 +155,6 @@ export function getTrackedLiquidityUSD(
let price0 = token0.derivedETH.times(bundle.ethPrice);
let price1 = token1.derivedETH.times(bundle.ethPrice);

// both are whitelist tokens, take average of both amounts
if (WHITELIST.includes(token0.id) && WHITELIST.includes(token1.id)) {
return tokenAmount0.times(price0).plus(tokenAmount1.times(price1));
}

// take double value of the whitelisted token amount
if (WHITELIST.includes(token0.id) && !WHITELIST.includes(token1.id)) {
return tokenAmount0.times(price0).times(BigDecimal.fromString("2"));
Expand All @@ -227,6 +165,5 @@ export function getTrackedLiquidityUSD(
return tokenAmount1.times(price1).times(BigDecimal.fromString("2"));
}

// neither token is on white list, tracked volume is 0
return BIG_DECIMAL_ZERO;
return tokenAmount0.times(price0).plus(tokenAmount1.times(price1));
}
Loading

0 comments on commit 36cd61a

Please sign in to comment.