diff --git a/projects/subgraph-basin/src/utils/VolumeCP.ts b/projects/subgraph-basin/src/utils/VolumeCP.ts index fff86f439a..337a4647c2 100644 --- a/projects/subgraph-basin/src/utils/VolumeCP.ts +++ b/projects/subgraph-basin/src/utils/VolumeCP.ts @@ -46,11 +46,11 @@ export function updateWellVolumesAfterLiquidity( let well = loadWell(wellAddress); const wellTokens = well.tokens.map
((t) => Address.fromBytes(t)); - // Determines which token is bought and how much was bought - const boughtTokens = calcLiquidityVolume(well.reserves, padTokenAmounts(wellTokens, tokens, amounts)); + // Determines which tokens were bough/sold and how much + const tradeAmount = calcLiquidityVolume(well.reserves, padTokenAmounts(wellTokens, tokens, amounts)); const deltaTransferVolumeReserves = padTokenAmounts(wellTokens, tokens, amounts); - updateVolumeStats(well, boughtTokens, deltaTransferVolumeReserves); + updateVolumeStats(well, tradeAmount, deltaTransferVolumeReserves); well.lastUpdateTimestamp = timestamp; well.lastUpdateBlockNumber = blockNumber; @@ -76,7 +76,7 @@ export function updateWellVolumesAfterLiquidity( * * @param currentReserves - the current reserves, after the liquidity event * @param addedReserves - the net change in reserves after the liquidity event - * @returns a list of tokens and the amount bought of each. in practice only one will be nonzero, and always postive. + * @returns a list of tokens and the amount bought of each. the purchased token is positive, the sold token negative. */ export function calcLiquidityVolume(currentReserves: BigInt[], addedReserves: BigInt[]): BigInt[] { // Reserves prior to adding liquidity @@ -106,11 +106,10 @@ export function calcLiquidityVolume(currentReserves: BigInt[], addedReserves: Bi // log.debug("scaleSqrt {}", [scaleSqrt.toString()]); // log.debug("reservesBeforeBalancedAdd [{}, {}]", [reservesBeforeBalancedAdd[0].toString(), reservesBeforeBalancedAdd[1].toString()]); - // The negative value is the token which got bought (removed from the pool). - // Returns the positive value for the token which was bought and zero for the other token. + // Returns the positive value for the token which was bought and negative for the sold token. const tokenAmountBought = [ - reservesBeforeBalancedAdd[0].minus(initialReserves[0]) < ZERO_BI ? initialReserves[0].minus(reservesBeforeBalancedAdd[0]) : ZERO_BI, - reservesBeforeBalancedAdd[1].minus(initialReserves[1]) < ZERO_BI ? initialReserves[1].minus(reservesBeforeBalancedAdd[1]) : ZERO_BI + initialReserves[0].minus(reservesBeforeBalancedAdd[0]), + initialReserves[1].minus(reservesBeforeBalancedAdd[1]) ]; return tokenAmountBought; } @@ -134,16 +133,18 @@ function updateVolumeStats(well: Well, deltaTradeVolumeReserves: BigInt[], delta let totalTradeUSD = ZERO_BD; let totalTransferUSD = ZERO_BD; for (let i = 0; i < deltaTradeVolumeReserves.length; ++i) { - tradeVolumeReserves[i] = tradeVolumeReserves[i].plus(deltaTradeVolumeReserves[i]); - rollingDailyTradeVolumeReserves[i] = rollingDailyTradeVolumeReserves[i].plus(deltaTradeVolumeReserves[i]); - rollingWeeklyTradeVolumeReserves[i] = rollingWeeklyTradeVolumeReserves[i].plus(deltaTradeVolumeReserves[i]); + const tokenInfo = loadToken(Address.fromBytes(well.tokens[i])); + let usdTradeAmount = ZERO_BD; + if (deltaTradeVolumeReserves[i] > ZERO_BI) { + tradeVolumeReserves[i] = tradeVolumeReserves[i].plus(deltaTradeVolumeReserves[i]); + rollingDailyTradeVolumeReserves[i] = rollingDailyTradeVolumeReserves[i].plus(deltaTradeVolumeReserves[i]); + rollingWeeklyTradeVolumeReserves[i] = rollingWeeklyTradeVolumeReserves[i].plus(deltaTradeVolumeReserves[i]); + usdTradeAmount = toDecimal(deltaTradeVolumeReserves[i], tokenInfo.decimals).times(tokenInfo.lastPriceUSD); + } transferVolumeReserves[i] = transferVolumeReserves[i].plus(deltaTransferVolumeReserves[i].abs()); rollingDailyTransferVolumeReserves[i] = rollingDailyTransferVolumeReserves[i].plus(deltaTransferVolumeReserves[i].abs()); rollingWeeklyTransferVolumeReserves[i] = rollingWeeklyTransferVolumeReserves[i].plus(deltaTransferVolumeReserves[i].abs()); - - const tokenInfo = loadToken(Address.fromBytes(well.tokens[i])); - let usdTradeAmount = toDecimal(deltaTradeVolumeReserves[i].abs(), tokenInfo.decimals).times(tokenInfo.lastPriceUSD); let usdTransferAmount = toDecimal(deltaTransferVolumeReserves[i].abs(), tokenInfo.decimals).times(tokenInfo.lastPriceUSD); tradeVolumeReservesUSD[i] = tradeVolumeReservesUSD[i].plus(usdTradeAmount); diff --git a/projects/subgraph-basin/tests/Liquidity.test.ts b/projects/subgraph-basin/tests/Liquidity.test.ts index d0886e2579..ec903af16b 100644 --- a/projects/subgraph-basin/tests/Liquidity.test.ts +++ b/projects/subgraph-basin/tests/Liquidity.test.ts @@ -31,6 +31,10 @@ const BD_2 = BigDecimal.fromString("2"); const BD_3 = BigDecimal.fromString("3"); const BD_4 = BigDecimal.fromString("4"); +function zeroNegative(tokenAmounts: BigInt[]): BigInt[] { + return [tokenAmounts[0] < ZERO_BI ? ZERO_BI : tokenAmounts[0], tokenAmounts[1] < ZERO_BI ? ZERO_BI : tokenAmounts[1]]; +} + function assignUSD(tokenAmounts: BigInt[]): BigDecimal[] { const bean = loadToken(BEAN_ERC20); const weth = loadToken(WETH); @@ -81,7 +85,9 @@ describe("Well Entity: Liquidity Event Tests", () => { const tradeReservesUSD = updatedStore.cumulativeTradeVolumeReservesUSD; const transferReservesUSD = updatedStore.cumulativeTransferVolumeReservesUSD; - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.bigIntEquals(expectedTradeVolume[0], tradeReserves[0]); @@ -95,7 +101,9 @@ describe("Well Entity: Liquidity Event Tests", () => { }); test("Cumulative volume updated (CP)", () => { let updatedStore = loadWell(WELL); - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.stringEquals(BigDecimal_max(expectedTradeVolumeUSD).toString(), updatedStore.cumulativeTradeVolumeUSD.toString()); assert.stringEquals(BEAN_USD_AMOUNT.plus(WETH_USD_AMOUNT).toString(), updatedStore.cumulativeTransferVolumeUSD.toString()); @@ -136,7 +144,9 @@ describe("Well Entity: Liquidity Event Tests", () => { const tradeReservesUSD = updatedStore.cumulativeTradeVolumeReservesUSD; const transferReservesUSD = updatedStore.cumulativeTransferVolumeReservesUSD; - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, ZERO_BI]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, ZERO_BI]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.bigIntEquals(expectedTradeVolume[0], tradeReserves[0]); @@ -150,7 +160,9 @@ describe("Well Entity: Liquidity Event Tests", () => { }); test("Cumulative volume updated (CP)", () => { let updatedStore = loadWell(WELL); - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, ZERO_BI]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT, ZERO_BI]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.stringEquals(BigDecimal_max(expectedTradeVolumeUSD).toString(), updatedStore.cumulativeTradeVolumeUSD.toString()); assert.stringEquals( @@ -193,9 +205,8 @@ describe("Well Entity: Liquidity Event Tests", () => { const tradeReservesUSD = updatedStore.cumulativeTradeVolumeReservesUSD; const transferReservesUSD = updatedStore.cumulativeTransferVolumeReservesUSD; - const expectedTradeVolume = calcLiquidityVolume( - [BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], - [BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT.div(BI_2)] + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT.div(BI_2)]) ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); @@ -210,9 +221,8 @@ describe("Well Entity: Liquidity Event Tests", () => { }); test("Cumulative volume updated (CP)", () => { let updatedStore = loadWell(WELL); - const expectedTradeVolume = calcLiquidityVolume( - [BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], - [BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT.div(BI_2)] + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT], [BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT.div(BI_2)]) ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.stringEquals(BigDecimal_max(expectedTradeVolumeUSD).toString(), updatedStore.cumulativeTradeVolumeUSD.toString()); @@ -255,9 +265,8 @@ describe("Well Entity: Liquidity Event Tests", () => { const tradeReservesUSD = updatedStore.cumulativeTradeVolumeReservesUSD; const transferReservesUSD = updatedStore.cumulativeTransferVolumeReservesUSD; - const expectedTradeVolume = calcLiquidityVolume( - [BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT], - [ZERO_BI, WETH_SWAP_AMOUNT.div(BI_2)] + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT], [ZERO_BI, WETH_SWAP_AMOUNT.div(BI_2)]) ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); @@ -272,9 +281,8 @@ describe("Well Entity: Liquidity Event Tests", () => { }); test("Cumulative volume updated (CP)", () => { let updatedStore = loadWell(WELL); - const expectedTradeVolume = calcLiquidityVolume( - [BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT], - [ZERO_BI, WETH_SWAP_AMOUNT.div(BI_2)] + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT.div(BI_2), WETH_SWAP_AMOUNT], [ZERO_BI, WETH_SWAP_AMOUNT.div(BI_2)]) ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.stringEquals(BigDecimal_max(expectedTradeVolumeUSD).toString(), updatedStore.cumulativeTradeVolumeUSD.toString()); @@ -307,7 +315,7 @@ describe("Well Entity: Liquidity Event Tests", () => { const tradeReservesUSD = updatedStore.cumulativeTradeVolumeReservesUSD; const transferReservesUSD = updatedStore.cumulativeTransferVolumeReservesUSD; - const expectedTradeVolume = calcLiquidityVolume([ZERO_BI, ZERO_BI], [BEAN_SWAP_AMOUNT.neg(), WETH_SWAP_AMOUNT.neg()]); + const expectedTradeVolume = zeroNegative(calcLiquidityVolume([ZERO_BI, ZERO_BI], [BEAN_SWAP_AMOUNT.neg(), WETH_SWAP_AMOUNT.neg()])); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.bigIntEquals(expectedTradeVolume[0], tradeReserves[0]); @@ -321,7 +329,7 @@ describe("Well Entity: Liquidity Event Tests", () => { }); test("Cumulative volume updated (CP)", () => { let updatedStore = loadWell(WELL); - const expectedTradeVolume = calcLiquidityVolume([ZERO_BI, ZERO_BI], [BEAN_SWAP_AMOUNT.neg(), WETH_SWAP_AMOUNT.neg()]); + const expectedTradeVolume = zeroNegative(calcLiquidityVolume([ZERO_BI, ZERO_BI], [BEAN_SWAP_AMOUNT.neg(), WETH_SWAP_AMOUNT.neg()])); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.stringEquals(BigDecimal_max(expectedTradeVolumeUSD).toString(), updatedStore.cumulativeTradeVolumeUSD.toString()); assert.stringEquals( @@ -357,7 +365,9 @@ describe("Well Entity: Liquidity Event Tests", () => { const tradeReservesUSD = updatedStore.cumulativeTradeVolumeReservesUSD; const transferReservesUSD = updatedStore.cumulativeTransferVolumeReservesUSD; - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT.times(BI_2)], [BEAN_SWAP_AMOUNT.neg(), ZERO_BI]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT.times(BI_2)], [BEAN_SWAP_AMOUNT.neg(), ZERO_BI]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.bigIntEquals(expectedTradeVolume[0], tradeReserves[0]); @@ -371,7 +381,9 @@ describe("Well Entity: Liquidity Event Tests", () => { }); test("Cumulative volume updated (CP)", () => { let updatedStore = loadWell(WELL); - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT.times(BI_2)], [BEAN_SWAP_AMOUNT.neg(), ZERO_BI]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT, WETH_SWAP_AMOUNT.times(BI_2)], [BEAN_SWAP_AMOUNT.neg(), ZERO_BI]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.stringEquals(BigDecimal_max(expectedTradeVolumeUSD).toString(), updatedStore.cumulativeTradeVolumeUSD.toString()); assert.stringEquals( @@ -407,7 +419,9 @@ describe("Well Entity: Liquidity Event Tests", () => { const tradeReservesUSD = updatedStore.cumulativeTradeVolumeReservesUSD; const transferReservesUSD = updatedStore.cumulativeTransferVolumeReservesUSD; - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [ZERO_BI, WETH_SWAP_AMOUNT.neg()]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [ZERO_BI, WETH_SWAP_AMOUNT.neg()]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.bigIntEquals(expectedTradeVolume[0], tradeReserves[0]); @@ -421,7 +435,9 @@ describe("Well Entity: Liquidity Event Tests", () => { }); test("Cumulative volume updated (CP)", () => { let updatedStore = loadWell(WELL); - const expectedTradeVolume = calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [ZERO_BI, WETH_SWAP_AMOUNT.neg()]); + const expectedTradeVolume = zeroNegative( + calcLiquidityVolume([BEAN_SWAP_AMOUNT.times(BI_2), WETH_SWAP_AMOUNT], [ZERO_BI, WETH_SWAP_AMOUNT.neg()]) + ); const expectedTradeVolumeUSD = assignUSD(expectedTradeVolume); assert.stringEquals(BigDecimal_max(expectedTradeVolumeUSD).toString(), updatedStore.cumulativeTradeVolumeUSD.toString()); assert.stringEquals(