From 545aacc1935230282fc4d017a1cc8d0da6f79e41 Mon Sep 17 00:00:00 2001 From: Jean Chambras Date: Thu, 2 May 2024 10:32:37 +0200 Subject: [PATCH] Fix TokenAmoun id clash (#145) * Add logIndex in AssetAmount ids * Fix LPToken out zero for the first add liquidity --- src/entities/AssetAmount.ts | 2 ++ src/entities/Pool.ts | 9 +++--- src/mappings/amm.ts | 13 ++++++-- src/mappings/futures.ts | 5 +++ src/mappings/transfers.ts | 1 + src/tests/amm.test.ts | 56 +++++++++++++++++++++++++-------- src/tests/events/FutureVault.ts | 3 +- src/tests/futures.test.ts | 5 +++ src/utils/idGenerators.ts | 3 +- 9 files changed, 75 insertions(+), 22 deletions(-) diff --git a/src/entities/AssetAmount.ts b/src/entities/AssetAmount.ts index 3b20832..bf2a7e2 100644 --- a/src/entities/AssetAmount.ts +++ b/src/entities/AssetAmount.ts @@ -10,11 +10,13 @@ export function getAssetAmount( assetAddress: Address, amount: BigInt, type: string, + logIndex: string, timestamp: BigInt ): AssetAmount { let id = generateAssetAmountId( transactionAddress.toHex(), assetAddress.toHex(), + logIndex, type ) diff --git a/src/entities/Pool.ts b/src/entities/Pool.ts index 8bc29e4..7f93b88 100644 --- a/src/entities/Pool.ts +++ b/src/entities/Pool.ts @@ -22,6 +22,7 @@ class PoolDetails { ptAddress: Address factoryAddress: Address timestamp: BigInt + logIndex: BigInt transactionHash: Bytes } @@ -33,6 +34,7 @@ export function createPool(params: PoolDetails): Pool { params.ibtAddress, ZERO_BI, AssetType.IBT, + params.logIndex.toString(), params.timestamp ) @@ -44,6 +46,7 @@ export function createPool(params: PoolDetails): Pool { params.ptAddress, ZERO_BI, AssetType.PT, + params.logIndex.toString(), params.timestamp ) @@ -79,11 +82,7 @@ export function createPool(params: PoolDetails): Pool { pool.liquidityToken = lpToken.id - const lpTotalSupply = getERC20TotalSupply( - Address.fromBytes(lpToken.address) - ) - - pool.lpTotalSupply = lpTotalSupply + pool.lpTotalSupply = ZERO_BI let factory = Factory.load(params.factoryAddress.toHex()) if (factory) { diff --git a/src/mappings/amm.ts b/src/mappings/amm.ts index 571bab3..751133b 100644 --- a/src/mappings/amm.ts +++ b/src/mappings/amm.ts @@ -47,6 +47,7 @@ export function handleAddLiquidity(event: AddLiquidity): void { Address.fromString(ibtAddress), event.params.token_amounts[0], AssetType.IBT, + event.logIndex.toString(), eventTimestamp ) @@ -62,6 +63,7 @@ export function handleAddLiquidity(event: AddLiquidity): void { Address.fromString(ptAddress), event.params.token_amounts[1], AssetType.PT, + event.logIndex.toString(), eventTimestamp ) @@ -75,15 +77,15 @@ export function handleAddLiquidity(event: AddLiquidity): void { let lpTokenAddress = getPoolLPToken(event.address) const lpTotalSupply = getERC20TotalSupply(lpTokenAddress) - pool.lpTotalSupply = lpTotalSupply - let lpTokenDiff = lpTotalSupply.minus(pool.lpTotalSupply) + pool.lpTotalSupply = lpTotalSupply let lpAmountOut = getAssetAmount( event.transaction.hash, lpTokenAddress, lpTokenDiff, AssetType.LP, + event.logIndex.toString(), eventTimestamp ) @@ -185,6 +187,7 @@ export function handleRemoveLiquidity(event: RemoveLiquidity): void { lpTokenAddress, lpTokenDiff, AssetType.LP, + event.logIndex.toString(), eventTimestamp ) @@ -214,6 +217,7 @@ export function handleRemoveLiquidity(event: RemoveLiquidity): void { Address.fromString(ibtAddress), event.params.token_amounts[0], AssetType.IBT, + event.logIndex.toString(), eventTimestamp ) @@ -229,6 +233,7 @@ export function handleRemoveLiquidity(event: RemoveLiquidity): void { Address.fromString(ptAddress), event.params.token_amounts[1], AssetType.PT, + event.logIndex.toString(), eventTimestamp ) @@ -317,6 +322,7 @@ export function handleTokenExchange(event: TokenExchange): void { Address.fromString(poolAssetInAmount.asset), event.params.tokens_sold, event.params.sold_id.equals(ZERO_BI) ? AssetType.IBT : AssetType.PT, + event.logIndex.toString(), eventTimestamp ) @@ -334,6 +340,7 @@ export function handleTokenExchange(event: TokenExchange): void { event.params.bought_id.equals(ZERO_BI) ? AssetType.IBT : AssetType.PT, + event.logIndex.toString(), eventTimestamp ) @@ -466,6 +473,7 @@ export function handleRemoveLiquidityOne(event: RemoveLiquidityOne): void { lpTokenAddress, event.params.token_amount, AssetType.LP, + event.logIndex.toString(), eventTimestamp ) @@ -496,6 +504,7 @@ export function handleRemoveLiquidityOne(event: RemoveLiquidityOne): void { Address.fromString(withdrawnTokenAddress), event.params.coin_amount, withdrawnAssetType, + event.logIndex.toString(), eventTimestamp ) diff --git a/src/mappings/futures.ts b/src/mappings/futures.ts index 02fe9ef..f8b0ec4 100644 --- a/src/mappings/futures.ts +++ b/src/mappings/futures.ts @@ -219,6 +219,7 @@ export function handleMint(event: Mint): void { ptAddress, event.params.amount, AssetType.PT, + event.logIndex.toString(), event.block.timestamp ) @@ -234,6 +235,7 @@ export function handleMint(event: Mint): void { ytAddress, event.params.amount, AssetType.YT, + event.logIndex.toString(), event.block.timestamp ) @@ -301,6 +303,7 @@ export function handleRedeem(event: Redeem): void { ptAddress, event.params.amount, AssetType.PT, + event.logIndex.toString(), event.block.timestamp ) @@ -316,6 +319,7 @@ export function handleRedeem(event: Redeem): void { ytAddress, event.params.amount, AssetType.YT, + event.logIndex.toString(), event.block.timestamp ) @@ -403,6 +407,7 @@ export function handleCurvePoolDeployed(event: CurvePoolDeployed): void { factoryAddress: event.address, ptAddress: event.params.pt, timestamp: event.block.timestamp, + logIndex: event.logIndex, transactionHash: event.transaction.hash, }) } diff --git a/src/mappings/transfers.ts b/src/mappings/transfers.ts index 16f154e..5c3c369 100644 --- a/src/mappings/transfers.ts +++ b/src/mappings/transfers.ts @@ -42,6 +42,7 @@ export function handleTransfer(event: TransferEvent): void { event.address, event.params.value, asset.type, + event.logIndex.toString(), eventTimestamp ) diff --git a/src/tests/amm.test.ts b/src/tests/amm.test.ts index f22f9ad..711e976 100644 --- a/src/tests/amm.test.ts +++ b/src/tests/amm.test.ts @@ -207,6 +207,7 @@ describe("handleAddLiquidity()", () => { generateAssetAmountId( POOL_DEPLOY_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.IBT ), "amount", @@ -218,6 +219,7 @@ describe("handleAddLiquidity()", () => { generateAssetAmountId( POOL_DEPLOY_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT ), "amount", @@ -233,10 +235,12 @@ describe("handleAddLiquidity()", () => { `[${generateAssetAmountId( POOL_ADD_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.IBT )}, ${generateAssetAmountId( POOL_ADD_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT )}]` ) @@ -247,6 +251,7 @@ describe("handleAddLiquidity()", () => { `[${generateAssetAmountId( POOL_ADD_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_LP_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.LP )}]` ) @@ -258,6 +263,7 @@ describe("handleAddLiquidity()", () => { generateAssetAmountId( POOL_ADD_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.IBT ), "amount", @@ -268,6 +274,7 @@ describe("handleAddLiquidity()", () => { generateAssetAmountId( POOL_ADD_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT ), "amount", @@ -278,11 +285,11 @@ describe("handleAddLiquidity()", () => { generateAssetAmountId( POOL_ADD_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_LP_ADDRESS_MOCK.toHex(), + ADD_LIQUIDITY_LOG_INDEX.toString(), AssetType.LP ), "amount", - // as mock is the same for the supply before and after liquidity transaction so difference is 0 - "0" + LP_TOTAL_SUPPLY.toString() ) }) @@ -452,13 +459,14 @@ describe("handleRemoveLiquidity()", () => { assert.fieldEquals( ASSET_AMOUNT_ENTITY, generateAssetAmountId( - POOL_DEPLOY_TRANSACTION_HASH.toHex(), + POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.IBT ), "amount", toPrecision( - BigInt.fromI32(100), + BigInt.fromI32(50), 1, STANDARD_DECIMALS_MOCK ).toString() @@ -467,13 +475,14 @@ describe("handleRemoveLiquidity()", () => { assert.fieldEquals( ASSET_AMOUNT_ENTITY, generateAssetAmountId( - POOL_DEPLOY_TRANSACTION_HASH.toHex(), + POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT ), "amount", toPrecision( - BigInt.fromI32(50), + BigInt.fromI32(100), 1, STANDARD_DECIMALS_MOCK ).toString() @@ -488,6 +497,7 @@ describe("handleRemoveLiquidity()", () => { `[${generateAssetAmountId( POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_LP_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.LP )}]` ) @@ -498,10 +508,12 @@ describe("handleRemoveLiquidity()", () => { `[${generateAssetAmountId( POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.IBT )}, ${generateAssetAmountId( POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT )}]` ) @@ -513,6 +525,7 @@ describe("handleRemoveLiquidity()", () => { generateAssetAmountId( POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.IBT ), "amount", @@ -527,6 +540,7 @@ describe("handleRemoveLiquidity()", () => { generateAssetAmountId( POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT ), "amount", @@ -541,6 +555,7 @@ describe("handleRemoveLiquidity()", () => { generateAssetAmountId( POOL_REMOVE_LIQUIDITY_TRANSACTION_HASH.toHex(), POOL_LP_ADDRESS_MOCK.toHex(), + REMOVE_LIQUIDITY_LOG_INDEX.toString(), AssetType.LP ), "amount", @@ -707,25 +722,31 @@ describe("handleTokenExchange()", () => { assert.fieldEquals( ASSET_AMOUNT_ENTITY, generateAssetAmountId( - POOL_DEPLOY_TRANSACTION_HASH.toHex(), + POOL_EXCHANGE_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + EXCHANGE_LOG_INDEX.toString(), AssetType.IBT ), "amount", - "0" + toPrecision( + BigInt.fromI32(100), + 1, + STANDARD_DECIMALS_MOCK + ).toString() ) assert.fieldEquals( ASSET_AMOUNT_ENTITY, generateAssetAmountId( - POOL_DEPLOY_TRANSACTION_HASH.toHex(), + POOL_EXCHANGE_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + EXCHANGE_LOG_INDEX.toString(), AssetType.PT ), "amount", toPrecision( - BigInt.fromI32(10), - 0, + BigInt.fromI32(50), + 1, STANDARD_DECIMALS_MOCK ).toString() ) @@ -737,6 +758,7 @@ describe("handleTokenExchange()", () => { generateAssetAmountId( POOL_EXCHANGE_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + EXCHANGE_LOG_INDEX.toString(), AssetType.IBT ), "amount", @@ -751,6 +773,7 @@ describe("handleTokenExchange()", () => { generateAssetAmountId( POOL_EXCHANGE_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + EXCHANGE_LOG_INDEX.toString(), AssetType.PT ), "amount", @@ -766,6 +789,7 @@ describe("handleTokenExchange()", () => { `[${generateAssetAmountId( POOL_EXCHANGE_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + EXCHANGE_LOG_INDEX.toString(), AssetType.PT )}]` ) @@ -776,6 +800,7 @@ describe("handleTokenExchange()", () => { `[${generateAssetAmountId( POOL_EXCHANGE_TRANSACTION_HASH.toHex(), POOL_IBT_ADDRESS_MOCK.toHex(), + EXCHANGE_LOG_INDEX.toString(), AssetType.IBT )}]` ) @@ -1026,13 +1051,14 @@ describe("handleRemoveLiquidityOne()", () => { assert.fieldEquals( ASSET_AMOUNT_ENTITY, generateAssetAmountId( - POOL_DEPLOY_TRANSACTION_HASH.toHex(), + POOL_REMOVE_LIQUIDITY_ONE_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + REMOVE_ONE_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT ), "amount", toPrecision( - BigInt.fromI32(35).neg(), + BigInt.fromI32(50), 0, STANDARD_DECIMALS_MOCK ).toString() @@ -1047,6 +1073,7 @@ describe("handleRemoveLiquidityOne()", () => { `[${generateAssetAmountId( POOL_REMOVE_LIQUIDITY_ONE_TRANSACTION_HASH.toHex(), POOL_LP_ADDRESS_MOCK.toHex(), + REMOVE_ONE_LIQUIDITY_LOG_INDEX.toString(), AssetType.LP )}]` ) @@ -1057,6 +1084,7 @@ describe("handleRemoveLiquidityOne()", () => { `[${generateAssetAmountId( POOL_REMOVE_LIQUIDITY_ONE_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + REMOVE_ONE_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT )}]` ) @@ -1068,6 +1096,7 @@ describe("handleRemoveLiquidityOne()", () => { generateAssetAmountId( POOL_REMOVE_LIQUIDITY_ONE_TRANSACTION_HASH.toHex(), POOL_PT_ADDRESS_MOCK.toHex(), + REMOVE_ONE_LIQUIDITY_LOG_INDEX.toString(), AssetType.PT ), "amount", @@ -1082,6 +1111,7 @@ describe("handleRemoveLiquidityOne()", () => { generateAssetAmountId( POOL_REMOVE_LIQUIDITY_ONE_TRANSACTION_HASH.toHex(), POOL_LP_ADDRESS_MOCK.toHex(), + REMOVE_ONE_LIQUIDITY_LOG_INDEX.toString(), AssetType.LP ), "amount", diff --git a/src/tests/events/FutureVault.ts b/src/tests/events/FutureVault.ts index d40cadf..4cd0e70 100644 --- a/src/tests/events/FutureVault.ts +++ b/src/tests/events/FutureVault.ts @@ -29,6 +29,7 @@ import { } from "../mocks/FutureVault" export const SHARES_RETURN = 51 +export const DEFAULT_EMIT_LOG_INDEX = BigInt.fromI32(1) export const emitFutureVaultDeployed = (futureVaultAddress: Address): void => { let futureVaultDeployedEvent = changetype(newMockEvent()) @@ -49,7 +50,7 @@ export const emitMint = ( let mintEvent = changetype(newMockEvent()) mintEvent.address = FIRST_FUTURE_VAULT_ADDRESS_MOCK mintEvent.transaction.hash = DEPOSIT_TRANSACTION_HASH - mintEvent.logIndex = BigInt.fromI32(1) + mintEvent.logIndex = DEFAULT_EMIT_LOG_INDEX if (timestamp) { mintEvent.block.timestamp = BigInt.fromI32(timestamp as i32) diff --git a/src/tests/futures.test.ts b/src/tests/futures.test.ts index 0d51e2d..b11fba0 100644 --- a/src/tests/futures.test.ts +++ b/src/tests/futures.test.ts @@ -41,6 +41,7 @@ import { emitMint, emitFutureVaultDeployed, SHARES_RETURN, + DEFAULT_EMIT_LOG_INDEX, } from "./events/FutureVault" import { mockCurvePoolFunctions, @@ -475,10 +476,12 @@ describe("handleMint()", () => { `[${generateAssetAmountId( DEPOSIT_TRANSACTION_HASH.toHex(), FIRST_FUTURE_VAULT_ADDRESS_MOCK.toHex(), + DEFAULT_EMIT_LOG_INDEX.toString(), AssetType.PT )}, ${generateAssetAmountId( DEPOSIT_TRANSACTION_HASH.toHex(), YT_ADDRESS_MOCK.toHex(), + DEFAULT_EMIT_LOG_INDEX.toString(), AssetType.YT )}]` ) @@ -619,10 +622,12 @@ describe("handleRedeem()", () => { `[${generateAssetAmountId( WITHDRAW_TRANSACTION_HASH.toHex(), FIRST_FUTURE_VAULT_ADDRESS_MOCK.toHex(), + WITHDRAW_LOG_INDEX.toString(), AssetType.PT )}, ${generateAssetAmountId( WITHDRAW_TRANSACTION_HASH.toHex(), YT_ADDRESS_MOCK.toHex(), + WITHDRAW_LOG_INDEX.toString(), AssetType.YT )}]` ) diff --git a/src/utils/idGenerators.ts b/src/utils/idGenerators.ts index 6391c21..3b221da 100644 --- a/src/utils/idGenerators.ts +++ b/src/utils/idGenerators.ts @@ -12,8 +12,9 @@ export const generateLPInfoId = (tokenAddress: string): string => export const generateAssetAmountId = ( transactionHash: string, assetAddress: string, + logIndex: string, type: string -): string => `${transactionHash}-${assetAddress}-${type}` +): string => `${transactionHash}-${assetAddress}-${type}-${logIndex}` // AssetPrice export const generateAssetPriceId = (