diff --git a/packages/solidity-mapper/src/storage.test.ts b/packages/solidity-mapper/src/storage.test.ts index e48b24e6..5ed640ea 100644 --- a/packages/solidity-mapper/src/storage.test.ts +++ b/packages/solidity-mapper/src/storage.test.ts @@ -178,7 +178,7 @@ describe('Get value from storage', () => { const { storageLayout } = contracts.TestAddress; const { value, proof: { data: proofData } } = await getStorageValue(storageLayout, getStorageAt, blockHash, testAddress.address, 'address1'); expect(value).to.be.a('string'); - expect(String(value).toLowerCase()).to.equal(address1Value); + expect(value).to.equal(address1Value); if (isIpldGql) { assertProofData(blockHash, testAddress.address, JSON.parse(proofData)); diff --git a/packages/solidity-mapper/src/storage.ts b/packages/solidity-mapper/src/storage.ts index 7355ff30..8fc49040 100644 --- a/packages/solidity-mapper/src/storage.ts +++ b/packages/solidity-mapper/src/storage.ts @@ -97,6 +97,10 @@ export const getValueByType = (storageValue: string, typeLabel: string): bigint return utils.toUtf8String(storageValue); } + if (typeLabel.startsWith('address')) { + return utils.getAddress(storageValue); + } + return storageValue; }; diff --git a/packages/solidity-mapper/test/utils.ts b/packages/solidity-mapper/test/utils.ts index c1c7bd01..579210ff 100644 --- a/packages/solidity-mapper/test/utils.ts +++ b/packages/solidity-mapper/test/utils.ts @@ -91,7 +91,7 @@ export const getStorageAt: GetStorageAt = async ({ blockHash, contract, slot }) */ export const generateDummyAddresses = (length: number): Array => { return Array.from({ length }, () => { - return ethers.utils.hexlify(ethers.utils.randomBytes(20)); + return ethers.utils.getAddress(ethers.utils.hexlify(ethers.utils.randomBytes(20))); }); }; diff --git a/packages/uni-info-watcher/src/database.ts b/packages/uni-info-watcher/src/database.ts index ecd8aa83..fa6517c3 100644 --- a/packages/uni-info-watcher/src/database.ts +++ b/packages/uni-info-watcher/src/database.ts @@ -18,6 +18,8 @@ import { TokenDayData } from './entity/TokenDayData'; import { TokenHourData } from './entity/TokenHourData'; import { Burn } from './entity/Burn'; import { Swap } from './entity/Swap'; +import { Position } from './entity/Position'; +import { PositionSnapshot } from './entity/PositionSnapshot'; export class Database { _config: ConnectionOptions @@ -80,6 +82,44 @@ export class Database { return repo.findOne(findOptions); } + async getPosition ({ id, blockNumber }: DeepPartial): Promise { + const repo = this._conn.getRepository(Position); + const whereOptions: FindConditions = { id }; + + if (blockNumber) { + whereOptions.blockNumber = LessThanOrEqual(blockNumber); + } + + const findOptions: FindOneOptions = { + where: whereOptions, + relations: ['pool', 'token0', 'token1', 'tickLower', 'tickUpper', 'transaction'], + order: { + blockNumber: 'DESC' + } + }; + + return repo.findOne(findOptions); + } + + async getTick ({ id, blockNumber }: DeepPartial): Promise { + const repo = this._conn.getRepository(Tick); + const whereOptions: FindConditions = { id }; + + if (blockNumber) { + whereOptions.blockNumber = LessThanOrEqual(blockNumber); + } + + const findOptions: FindOneOptions = { + where: whereOptions, + relations: ['pool'], + order: { + blockNumber: 'DESC' + } + }; + + return repo.findOne(findOptions); + } + async getFactories ({ blockNumber }: DeepPartial, queryOptions: { [key: string]: any }): Promise> { const repo = this._conn.getRepository(Factory); @@ -438,6 +478,52 @@ export class Database { }); } + async loadPosition ({ id, blockNumber, ...values }: DeepPartial): Promise { + return this._conn.transaction(async (tx) => { + const repo = tx.getRepository(Position); + + let selectQueryBuilder = repo.createQueryBuilder('position') + .where('id = :id', { id }); + + if (blockNumber) { + selectQueryBuilder = selectQueryBuilder.andWhere('block_number <= :blockNumber', { blockNumber }); + } + + let entity = await selectQueryBuilder.orderBy('block_number', 'DESC') + .getOne(); + + if (!entity) { + entity = repo.create({ blockNumber, id, ...values }); + entity = await repo.save(entity); + } + + return entity; + }); + } + + async loadPositionSnapshot ({ id, blockNumber, ...values }: DeepPartial): Promise { + return this._conn.transaction(async (tx) => { + const repo = tx.getRepository(PositionSnapshot); + + let selectQueryBuilder = repo.createQueryBuilder('positionSnapshot') + .where('id = :id', { id }); + + if (blockNumber) { + selectQueryBuilder = selectQueryBuilder.andWhere('block_number <= :blockNumber', { blockNumber }); + } + + let entity = await selectQueryBuilder.orderBy('block_number', 'DESC') + .getOne(); + + if (!entity) { + entity = repo.create({ blockNumber, id, ...values }); + entity = await repo.save(entity); + } + + return entity; + }); + } + async saveFactory (factory: Factory, blockNumber: number): Promise { return this._conn.transaction(async (tx) => { const repo = tx.getRepository(Factory); @@ -526,6 +612,14 @@ export class Database { }); } + async savePosition (position: Position, blockNumber: number): Promise { + return this._conn.transaction(async (tx) => { + const repo = tx.getRepository(Position); + position.blockNumber = blockNumber; + return repo.save(position); + }); + } + // Returns true if events have already been synced for the (block, token) combination. async didSyncEvents ({ blockHash, token }: { blockHash: string, token: string }): Promise { const numRows = await this._conn.getRepository(EventSyncProgress) diff --git a/packages/uni-info-watcher/src/entity/Position.ts b/packages/uni-info-watcher/src/entity/Position.ts new file mode 100644 index 00000000..a7f13f12 --- /dev/null +++ b/packages/uni-info-watcher/src/entity/Position.ts @@ -0,0 +1,66 @@ +import { Entity, PrimaryColumn, Column, ManyToOne } from 'typeorm'; +import Decimal from 'decimal.js'; +import { decimalTransformer } from '@vulcanize/util'; + +import { Pool } from './Pool'; +import { Token } from './Token'; +import { Tick } from './Tick'; +import { Transaction } from './Transaction'; +import { ADDRESS_ZERO } from '../utils/constants'; + +@Entity() +export class Position { + @PrimaryColumn('varchar') + id!: string; + + @PrimaryColumn('integer') + blockNumber!: number; + + @Column('bigint') + feeGrowthInside0LastX128!: bigint + + @Column('bigint') + feeGrowthInside1LastX128!: bigint + + @Column('bigint', { default: BigInt(0) }) + liquidity!: bigint + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + depositedToken0!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + depositedToken1!: Decimal + + @Column('varchar', { length: 42, default: ADDRESS_ZERO }) + owner!: string + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + withdrawnToken0!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + withdrawnToken1!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + collectedFeesToken0!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + collectedFeesToken1!: Decimal + + @ManyToOne(() => Pool) + pool!: Pool + + @ManyToOne(() => Token) + token0!: Token + + @ManyToOne(() => Token) + token1!: Token + + @ManyToOne(() => Tick) + tickLower!: Tick + + @ManyToOne(() => Tick) + tickUpper!: Tick + + @ManyToOne(() => Transaction) + transaction!: Transaction +} diff --git a/packages/uni-info-watcher/src/entity/PositionSnapshot.ts b/packages/uni-info-watcher/src/entity/PositionSnapshot.ts new file mode 100644 index 00000000..0f387a3b --- /dev/null +++ b/packages/uni-info-watcher/src/entity/PositionSnapshot.ts @@ -0,0 +1,59 @@ +import { Entity, PrimaryColumn, Column, ManyToOne } from 'typeorm'; +import Decimal from 'decimal.js'; +import { decimalTransformer } from '@vulcanize/util'; + +import { Pool } from './Pool'; +import { Transaction } from './Transaction'; +import { ADDRESS_ZERO } from '../utils/constants'; +import { Position } from './Position'; + +@Entity() +export class PositionSnapshot { + @PrimaryColumn('varchar') + id!: string; + + @PrimaryColumn('integer') + blockNumber!: number; + + @Column('bigint') + timestamp!: BigInt; + + @Column('bigint') + feeGrowthInside0LastX128!: bigint + + @Column('bigint') + feeGrowthInside1LastX128!: bigint + + @Column('bigint', { default: BigInt(0) }) + liquidity!: bigint + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + depositedToken0!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + depositedToken1!: Decimal + + @Column('varchar', { length: 42, default: ADDRESS_ZERO }) + owner!: string + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + withdrawnToken0!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + withdrawnToken1!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + collectedFeesToken0!: Decimal + + @Column('numeric', { default: 0, transformer: decimalTransformer }) + collectedFeesToken1!: Decimal + + @ManyToOne(() => Pool) + pool!: Pool + + @ManyToOne(() => Position) + position!: Position + + @ManyToOne(() => Transaction) + transaction!: Transaction +} diff --git a/packages/uni-info-watcher/src/events.ts b/packages/uni-info-watcher/src/events.ts index 943a66d5..9cb7cfb7 100644 --- a/packages/uni-info-watcher/src/events.ts +++ b/packages/uni-info-watcher/src/events.ts @@ -2,7 +2,7 @@ import assert from 'assert'; import debug from 'debug'; import { Client as UniClient } from '@vulcanize/uni-watcher'; import { Client as ERC20Client } from '@vulcanize/erc20-watcher'; -import { BigNumber } from 'ethers'; +import { BigNumber, utils } from 'ethers'; import { Database } from './database'; import { findEthPerToken, getEthPriceInUSD, getTrackedAmountUSD, sqrtPriceX96ToTokenPrices, WHITELIST_TOKENS } from './utils/pricing'; @@ -11,6 +11,7 @@ import { Token } from './entity/Token'; import { convertTokenToDecimal, loadTransaction, safeDiv } from './utils'; import { loadTick } from './utils/tick'; import Decimal from 'decimal.js'; +import { Position } from './entity/Position'; const log = debug('vulcanize:events'); @@ -61,6 +62,14 @@ interface SwapEvent { tick: bigint; } +interface IncreaseLiquidityEvent { + __typename: 'IncreaseLiquidityEvent'; + tokenId: bigint; + liquidity: bigint; + amount0: bigint; + amount1: bigint; +} + interface Block { number: number; hash: string; @@ -76,7 +85,7 @@ interface ResultEvent { block: Block; tx: Transaction; contract: string; - event: PoolCreatedEvent | InitializeEvent | MintEvent | BurnEvent | SwapEvent; + event: PoolCreatedEvent | InitializeEvent | MintEvent | BurnEvent | SwapEvent | IncreaseLiquidityEvent; proof: { data: string; } @@ -139,6 +148,11 @@ export class EventWatcher { this._handleSwap(block, contract, tx, event as SwapEvent); break; + case 'IncreaseLiquidityEvent': + log('NFPM IncreaseLiquidity event', contract); + this._handleIncreaseLiquidity(block, contract, tx, event as IncreaseLiquidityEvent); + break; + default: break; } @@ -299,7 +313,7 @@ export class EventWatcher { BigInt(mintEvent.tickLower) <= BigInt(pool.tick) && BigInt(mintEvent.tickUpper) > BigInt(pool.tick) ) { - pool.liquidity = BigInt(pool.liquidity) + mintEvent.amount; + pool.liquidity = BigInt(pool.liquidity) + BigInt(mintEvent.amount); } } @@ -346,14 +360,14 @@ export class EventWatcher { const lowerTickId = poolAddress + '#' + mintEvent.tickLower.toString(); const upperTickId = poolAddress + '#' + mintEvent.tickUpper.toString(); - const lowerTick = await loadTick(this._db, lowerTickId, lowerTickIdx, pool, blockNumber); - const upperTick = await loadTick(this._db, upperTickId, upperTickIdx, pool, blockNumber); + const lowerTick = await loadTick(this._db, lowerTickId, BigInt(lowerTickIdx), pool, blockNumber); + const upperTick = await loadTick(this._db, upperTickId, BigInt(upperTickIdx), pool, blockNumber); - const amount = mintEvent.amount; - lowerTick.liquidityGross = lowerTick.liquidityGross + amount; - lowerTick.liquidityNet = lowerTick.liquidityNet + amount; - upperTick.liquidityGross = upperTick.liquidityGross + amount; - upperTick.liquidityNet = upperTick.liquidityNet + amount; + const amount = BigInt(mintEvent.amount); + lowerTick.liquidityGross = BigInt(lowerTick.liquidityGross) + amount; + lowerTick.liquidityNet = BigInt(lowerTick.liquidityNet) + amount; + upperTick.liquidityGross = BigInt(upperTick.liquidityGross) + amount; + upperTick.liquidityNet = BigInt(upperTick.liquidityNet) + amount; // TODO: Update Tick's volume, fees, and liquidity provider count. // Computing these on the tick level requires reimplementing some of the swapping code from v3-core. @@ -395,8 +409,8 @@ export class EventWatcher { const token0 = pool.token0; const token1 = pool.token1; - const amount0 = convertTokenToDecimal(burnEvent.amount0, token0.decimals); - const amount1 = convertTokenToDecimal(burnEvent.amount1, token1.decimals); + const amount0 = convertTokenToDecimal(burnEvent.amount0, BigInt(token0.decimals)); + const amount1 = convertTokenToDecimal(burnEvent.amount1, BigInt(token1.decimals)); const amountUSD = amount0 .times(token0.derivedETH.times(bundle.ethPriceUSD)) @@ -406,20 +420,20 @@ export class EventWatcher { factory.totalValueLockedETH = factory.totalValueLockedETH.minus(pool.totalValueLockedETH); // Update globals. - factory.txCount = factory.txCount + BigInt(1); + factory.txCount = BigInt(factory.txCount) + BigInt(1); // Update token0 data. - token0.txCount = token0.txCount + BigInt(1); + token0.txCount = BigInt(token0.txCount) + BigInt(1); token0.totalValueLocked = token0.totalValueLocked.minus(amount0); token0.totalValueLockedUSD = token0.totalValueLocked.times(token0.derivedETH.times(bundle.ethPriceUSD)); // Update token1 data. - token1.txCount = token1.txCount + BigInt(1); + token1.txCount = BigInt(token1.txCount) + BigInt(1); token1.totalValueLocked = token1.totalValueLocked.minus(amount1); token1.totalValueLockedUSD = token1.totalValueLocked.times(token1.derivedETH.times(bundle.ethPriceUSD)); // Pool data. - pool.txCount = pool.txCount + BigInt(1); + pool.txCount = BigInt(pool.txCount) + BigInt(1); // Pools liquidity tracks the currently active liquidity given pools current tick. // We only want to update it on burn if the position being burnt includes the current tick. @@ -473,11 +487,11 @@ export class EventWatcher { const upperTickId = poolAddress + '#' + (burnEvent.tickUpper).toString(); const lowerTick = await this._db.loadTick({ id: lowerTickId, blockNumber }); const upperTick = await this._db.loadTick({ id: upperTickId, blockNumber }); - const amount = burnEvent.amount; - lowerTick.liquidityGross = lowerTick.liquidityGross - amount; - lowerTick.liquidityNet = lowerTick.liquidityNet - amount; - upperTick.liquidityGross = upperTick.liquidityGross - amount; - upperTick.liquidityNet = upperTick.liquidityNet + amount; + const amount = BigInt(burnEvent.amount); + lowerTick.liquidityGross = BigInt(lowerTick.liquidityGross) - amount; + lowerTick.liquidityNet = BigInt(lowerTick.liquidityNet) - amount; + upperTick.liquidityGross = BigInt(upperTick.liquidityGross) - amount; + upperTick.liquidityNet = BigInt(upperTick.liquidityNet) + amount; await updateUniswapDayData(this._db, { blockNumber, contractAddress, blockTimestamp }); await updatePoolDayData(this._db, { blockNumber, contractAddress, blockTimestamp }); @@ -527,8 +541,8 @@ export class EventWatcher { assert(token0 && token1, 'Pool tokens not found.'); // Amounts - 0/1 are token deltas. Can be positive or negative. - const amount0 = convertTokenToDecimal(swapEvent.amount0, token0.decimals); - const amount1 = convertTokenToDecimal(swapEvent.amount1, token1.decimals); + const amount0 = convertTokenToDecimal(swapEvent.amount0, BigInt(token0.decimals)); + const amount1 = convertTokenToDecimal(swapEvent.amount1, BigInt(token1.decimals)); // Need absolute amounts for volume. let amount0Abs = amount0; @@ -557,7 +571,7 @@ export class EventWatcher { const feesUSD = amountTotalUSDTracked.times(pool.feeTier.toString()).div(new Decimal('1000000')); // Global updates. - factory.txCount = factory.txCount + BigInt(1); + factory.txCount = BigInt(factory.txCount) + BigInt(1); factory.totalVolumeETH = factory.totalVolumeETH.plus(amountTotalETHTracked); factory.totalVolumeUSD = factory.totalVolumeUSD.plus(amountTotalUSDTracked); factory.untrackedVolumeUSD = factory.untrackedVolumeUSD.plus(amountTotalUSDUntracked); @@ -574,7 +588,7 @@ export class EventWatcher { pool.volumeUSD = pool.volumeUSD.plus(amountTotalUSDTracked); pool.untrackedVolumeUSD = pool.untrackedVolumeUSD.plus(amountTotalUSDUntracked); pool.feesUSD = pool.feesUSD.plus(feesUSD); - pool.txCount = pool.txCount + BigInt(1); + pool.txCount = BigInt(pool.txCount) + BigInt(1); // Update the pool with the new active liquidity, price, and tick. pool.liquidity = swapEvent.liquidity; @@ -589,7 +603,7 @@ export class EventWatcher { token0.volumeUSD = token0.volumeUSD.plus(amountTotalUSDTracked); token0.untrackedVolumeUSD = token0.untrackedVolumeUSD.plus(amountTotalUSDUntracked); token0.feesUSD = token0.feesUSD.plus(feesUSD); - token0.txCount = token0.txCount + BigInt(1); + token0.txCount = BigInt(token0.txCount) + BigInt(1); // Update token1 data. token1.volume = token1.volume.plus(amount1Abs); @@ -597,7 +611,7 @@ export class EventWatcher { token1.volumeUSD = token1.volumeUSD.plus(amountTotalUSDTracked); token1.untrackedVolumeUSD = token1.untrackedVolumeUSD.plus(amountTotalUSDUntracked); token1.feesUSD = token1.feesUSD.plus(feesUSD); - token1.txCount = token1.txCount + BigInt(1); + token1.txCount = BigInt(token1.txCount) + BigInt(1); // Updated pool rates. const prices = sqrtPriceX96ToTokenPrices(pool.sqrtPrice, token0 as Token, token1 as Token); @@ -707,4 +721,117 @@ export class EventWatcher { // Skipping update of inner vars of current or crossed ticks as they are not queried. } + + async _handleIncreaseLiquidity (block: Block, contractAddress: string, tx: Transaction, event: IncreaseLiquidityEvent): Promise { + const { number: blockNumber } = block; + const position = await this._getPosition(block, contractAddress, tx, BigInt(event.tokenId)); + + // position was not able to be fetched. + if (position === null) { + return; + } + + // Temp fix. + if (utils.getAddress(position.pool.id) === utils.getAddress('0x8fe8d9bb8eeba3ed688069c3d6b556c9ca258248')) { + return; + } + + const token0 = position.token0; + const token1 = position.token1; + + const amount0 = convertTokenToDecimal(BigInt(event.amount0), BigInt(token0.decimals)); + const amount1 = convertTokenToDecimal(BigInt(event.amount1), BigInt(token1.decimals)); + + position.liquidity = BigInt(position.liquidity) + BigInt(event.liquidity); + position.depositedToken0 = position.depositedToken0.plus(amount0); + position.depositedToken1 = position.depositedToken1.plus(amount1); + + await this._updateFeeVars(position, block, contractAddress, BigInt(event.tokenId)); + + await this._db.savePosition(position, blockNumber); + + await this._savePositionSnapshot(position, block, tx); + } + + async _getPosition (block: Block, contractAddress: string, tx: Transaction, tokenId: bigint): Promise { + const { number: blockNumber, hash: blockHash, timestamp: blockTimestamp } = block; + const { hash: txHash } = tx; + let position = await this._db.getPosition({ id: tokenId.toString(), blockNumber }); + + if (!position) { + const nfpmPosition = await this._uniClient.getPosition(blockHash, tokenId); + + // The contract call reverts in situations where the position is minted and deleted in the same block. + // From my investigation this happens in calls from BancorSwap. + // (e.g. 0xf7867fa19aa65298fadb8d4f72d0daed5e836f3ba01f0b9b9631cdc6c36bed40) + + if (nfpmPosition) { + const { token0: token0Address, token1: token1Address, fee } = await this._uniClient.poolIdToPoolKey(blockHash, nfpmPosition.poolId); + + const { pool: poolAddress } = await this._uniClient.getPool(blockHash, token0Address, token1Address, fee); + + const transaction = await loadTransaction(this._db, { txHash, blockNumber, blockTimestamp }); + const pool = await this._db.getPool({ id: poolAddress, blockNumber }); + + const [token0, token1] = await Promise.all([ + this._db.getToken({ id: token0Address, blockNumber }), + this._db.getToken({ id: token0Address, blockNumber }) + ]); + + const [tickLower, tickUpper] = await Promise.all([ + this._db.getTick({ id: poolAddress.concat('#').concat(nfpmPosition.tickLower.toString()), blockNumber }), + this._db.getTick({ id: poolAddress.concat('#').concat(nfpmPosition.tickUpper.toString()), blockNumber }) + ]); + + position = await this._db.loadPosition({ + id: tokenId.toString(), + blockNumber, + pool, + token0, + token1, + tickLower, + tickUpper, + transaction, + feeGrowthInside0LastX128: BigInt(nfpmPosition.feeGrowthInside0LastX128.toString()), + feeGrowthInside1LastX128: BigInt(nfpmPosition.feeGrowthInside1LastX128.toString()) + }); + } + } + + return position || null; + } + + async _updateFeeVars (position: Position, block: Block, contractAddress: string, tokenId: bigint): Promise { + const nfpmPosition = await this._uniClient.getPosition(block.hash, tokenId); + + if (nfpmPosition) { + position.feeGrowthInside0LastX128 = BigInt(nfpmPosition.feeGrowthInside0LastX128.toString()); + position.feeGrowthInside1LastX128 = BigInt(nfpmPosition.feeGrowthInside1LastX128.toString()); + } + + return position; + } + + async _savePositionSnapshot (position: Position, block: Block, tx: Transaction): Promise { + const transaction = await loadTransaction(this._db, { txHash: tx.hash, blockNumber: block.number, blockTimestamp: block.timestamp }); + + await this._db.loadPositionSnapshot({ + id: position.id.concat('#').concat(block.number.toString()), + blockNumber: block.number, + owner: position.owner, + pool: position.pool, + position: position, + timestamp: block.timestamp, + liquidity: position.liquidity, + depositedToken0: position.depositedToken0, + depositedToken1: position.depositedToken1, + withdrawnToken0: position.withdrawnToken0, + withdrawnToken1: position.withdrawnToken1, + collectedFeesToken0: position.collectedFeesToken0, + collectedFeesToken1: position.collectedFeesToken1, + transaction, + feeGrowthInside0LastX128: position.feeGrowthInside0LastX128, + feeGrowthInside1LastX128: position.feeGrowthInside1LastX128 + }); + } } diff --git a/packages/uni-info-watcher/src/utils/constants.ts b/packages/uni-info-watcher/src/utils/constants.ts new file mode 100644 index 00000000..573ab1f4 --- /dev/null +++ b/packages/uni-info-watcher/src/utils/constants.ts @@ -0,0 +1,3 @@ +import { utils } from 'ethers'; + +export const ADDRESS_ZERO = utils.getAddress('0x0000000000000000000000000000000000000000'); diff --git a/packages/uni-watcher/src/artifacts/NonfungiblePositionManager.json b/packages/uni-watcher/src/artifacts/NonfungiblePositionManager.json index 29cef050..9f8fabfe 100644 --- a/packages/uni-watcher/src/artifacts/NonfungiblePositionManager.json +++ b/packages/uni-watcher/src/artifacts/NonfungiblePositionManager.json @@ -1,1193 +1,1700 @@ -[ - { - "inputs": [ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "address", + "name": "_WETH9", + "type": "address" + }, + { + "internalType": "address", + "name": "_tokenDescriptor_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "DecreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "IncreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH9", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "baseURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Max", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Max", + "type": "uint128" + } + ], + "internalType": "struct INonfungiblePositionManager.CollectParams", + "name": "params", + "type": "tuple" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "createAndInitializePoolIfNecessary", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct INonfungiblePositionManager.DecreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "decreaseLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct INonfungiblePositionManager.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "amount0Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Desired", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "internalType": "struct INonfungiblePositionManager.MintParams", + "name": "params", + "type": "tuple" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint96", + "name": "nonce", + "type": "uint96" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "refundETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount0Owed", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Owed", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "uniswapV3MintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "storageLayout": { + "storage": [ { - "internalType": "address", - "name": "_factory", - "type": "address" + "astId": 460, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_supportedInterfaces", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes4,t_bool)" }, { - "internalType": "address", - "name": "_WETH9", - "type": "address" + "astId": 1676, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_holderTokens", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_struct(UintSet)4092_storage)" }, { - "internalType": "address", - "name": "_tokenDescriptor_", - "type": "address" + "astId": 1678, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_tokenOwners", + "offset": 0, + "slot": "2", + "type": "t_struct(UintToAddressMap)3469_storage" + }, + { + "astId": 1682, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_tokenApprovals", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 1688, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_operatorApprovals", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + }, + { + "astId": 1690, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_name", + "offset": 0, + "slot": "6", + "type": "t_string_storage" + }, + { + "astId": 1692, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_symbol", + "offset": 0, + "slot": "7", + "type": "t_string_storage" + }, + { + "astId": 1696, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_tokenURIs", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_uint256,t_string_storage)" + }, + { + "astId": 1698, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_baseURI", + "offset": 0, + "slot": "9", + "type": "t_string_storage" + }, + { + "astId": 7097, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_poolIds", + "offset": 0, + "slot": "10", + "type": "t_mapping(t_address,t_uint80)" + }, + { + "astId": 7102, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_poolIdToPoolKey", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_uint80,t_struct(PoolKey)16521_storage)" + }, + { + "astId": 7107, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_positions", + "offset": 0, + "slot": "12", + "type": "t_mapping(t_uint256,t_struct(Position)7092_storage)" + }, + { + "astId": 7111, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_nextId", + "offset": 0, + "slot": "13", + "type": "t_uint176" + }, + { + "astId": 7115, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_nextPoolId", + "offset": 22, + "slot": "13", + "type": "t_uint80" } ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" + "t_array(t_struct(MapEntry)3143_storage)dyn_storage": { + "base": "t_struct(MapEntry)3143_storage", + "encoding": "dynamic_array", + "label": "struct EnumerableMap.MapEntry[]", + "numberOfBytes": "32" }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" }, - { - "indexed": false, - "internalType": "address", - "name": "recipient", - "type": "address" + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" + "t_int24": { + "encoding": "inplace", + "label": "int24", + "numberOfBytes": "3" }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "Collect", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" }, - { - "indexed": false, - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" + "t_mapping(t_address,t_struct(UintSet)4092_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.UintSet)", + "numberOfBytes": "32", + "value": "t_struct(UintSet)4092_storage" }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "DecreaseLiquidity", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + "t_mapping(t_address,t_uint80)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint80)", + "numberOfBytes": "32", + "value": "t_uint80" }, - { - "indexed": false, - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount0", - "type": "uint256" + "t_mapping(t_bytes4,t_bool)": { + "encoding": "mapping", + "key": "t_bytes4", + "label": "mapping(bytes4 => bool)", + "numberOfBytes": "32", + "value": "t_bool" }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "name": "IncreaseLiquidity", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" + "t_mapping(t_uint256,t_address)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address)", + "numberOfBytes": "32", + "value": "t_address" }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" + "t_mapping(t_uint256,t_string_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => string)", + "numberOfBytes": "32", + "value": "t_string_storage" }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PERMIT_TYPEHASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "WETH9", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" + "t_mapping(t_uint256,t_struct(Position)7092_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct NonfungiblePositionManager.Position)", + "numberOfBytes": "32", + "value": "t_struct(Position)7092_storage" }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "burn", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + "t_mapping(t_uint80,t_struct(PoolKey)16521_storage)": { + "encoding": "mapping", + "key": "t_uint80", + "label": "mapping(uint80 => struct PoolAddress.PoolKey)", + "numberOfBytes": "32", + "value": "t_struct(PoolKey)16521_storage" }, - { - "internalType": "address", - "name": "recipient", - "type": "address" + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" }, - { - "internalType": "uint128", - "name": "amount0Max", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "amount1Max", - "type": "uint128" - } - ], - "name": "collect", - "outputs": [ - { - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" - }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint24", - "name": "fee", - "type": "uint24" - }, - { - "internalType": "uint160", - "name": "sqrtPriceX96", - "type": "uint160" - } - ], - "name": "createAndInitializePoolIfNecessary", - "outputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "decreaseLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount0Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - } - ], - "name": "increaseLiquidity", - "outputs": [ - { - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ + "t_struct(Map)3151_storage": { + "encoding": "inplace", + "label": "struct EnumerableMap.Map", + "members": [ { - "internalType": "address", - "name": "token0", - "type": "address" + "astId": 3146, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_entries", + "offset": 0, + "slot": "0", + "type": "t_array(t_struct(MapEntry)3143_storage)dyn_storage" }, { - "internalType": "address", - "name": "token1", - "type": "address" - }, - { - "internalType": "uint24", - "name": "fee", - "type": "uint24" - }, - { - "internalType": "int24", - "name": "tickLower", - "type": "int24" - }, - { - "internalType": "int24", - "name": "tickUpper", - "type": "int24" - }, - { - "internalType": "uint256", - "name": "amount0Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Desired", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount0Min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Min", - "type": "uint256" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" + "astId": 3150, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" } ], - "internalType": "struct INonfungiblePositionManager.MintParams", - "name": "params", - "type": "tuple" + "numberOfBytes": "64" + }, + "t_struct(MapEntry)3143_storage": { + "encoding": "inplace", + "label": "struct EnumerableMap.MapEntry", + "members": [ + { + "astId": 3140, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_key", + "offset": 0, + "slot": "0", + "type": "t_bytes32" + }, + { + "astId": 3142, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_value", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_struct(PoolKey)16521_storage": { + "encoding": "inplace", + "label": "struct PoolAddress.PoolKey", + "members": [ + { + "astId": 16516, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "token0", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 16518, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "token1", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 16520, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "fee", + "offset": 20, + "slot": "1", + "type": "t_uint24" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Position)7092_storage": { + "encoding": "inplace", + "label": "struct NonfungiblePositionManager.Position", + "members": [ + { + "astId": 7073, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "nonce", + "offset": 0, + "slot": "0", + "type": "t_uint96" + }, + { + "astId": 7075, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "operator", + "offset": 12, + "slot": "0", + "type": "t_address" + }, + { + "astId": 7077, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "poolId", + "offset": 0, + "slot": "1", + "type": "t_uint80" + }, + { + "astId": 7079, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "tickLower", + "offset": 10, + "slot": "1", + "type": "t_int24" + }, + { + "astId": 7081, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "tickUpper", + "offset": 13, + "slot": "1", + "type": "t_int24" + }, + { + "astId": 7083, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "liquidity", + "offset": 16, + "slot": "1", + "type": "t_uint128" + }, + { + "astId": 7085, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "feeGrowthInside0LastX128", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 7087, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "feeGrowthInside1LastX128", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 7089, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "tokensOwed0", + "offset": 0, + "slot": "4", + "type": "t_uint128" + }, + { + "astId": 7091, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "tokensOwed1", + "offset": 16, + "slot": "4", + "type": "t_uint128" + } + ], + "numberOfBytes": "160" + }, + "t_struct(Set)3706_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 3701, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 3705, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(UintSet)4092_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.UintSet", + "members": [ + { + "astId": 4091, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)3706_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(UintToAddressMap)3469_storage": { + "encoding": "inplace", + "label": "struct EnumerableMap.UintToAddressMap", + "members": [ + { + "astId": 3468, + "contract": "contracts/NonfungiblePositionManager.sol:NonfungiblePositionManager", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Map)3151_storage" + } + ], + "numberOfBytes": "64" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + }, + "t_uint176": { + "encoding": "inplace", + "label": "uint176", + "numberOfBytes": "22" + }, + "t_uint24": { + "encoding": "inplace", + "label": "uint24", + "numberOfBytes": "3" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint80": { + "encoding": "inplace", + "label": "uint80", + "numberOfBytes": "10" + }, + "t_uint96": { + "encoding": "inplace", + "label": "uint96", + "numberOfBytes": "12" } - ], - "name": "mint", - "outputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "amount0", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes[]", - "name": "data", - "type": "bytes[]" - } - ], - "name": "multicall", - "outputs": [ - { - "internalType": "bytes[]", - "name": "results", - "type": "bytes[]" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "permit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "positions", - "outputs": [ - { - "internalType": "uint96", - "name": "nonce", - "type": "uint96" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "address", - "name": "token0", - "type": "address" - }, - { - "internalType": "address", - "name": "token1", - "type": "address" - }, - { - "internalType": "uint24", - "name": "fee", - "type": "uint24" - }, - { - "internalType": "int24", - "name": "tickLower", - "type": "int24" - }, - { - "internalType": "int24", - "name": "tickUpper", - "type": "int24" - }, - { - "internalType": "uint128", - "name": "liquidity", - "type": "uint128" - }, - { - "internalType": "uint256", - "name": "feeGrowthInside0LastX128", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "feeGrowthInside1LastX128", - "type": "uint256" - }, - { - "internalType": "uint128", - "name": "tokensOwed0", - "type": "uint128" - }, - { - "internalType": "uint128", - "name": "tokensOwed1", - "type": "uint128" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "selfPermit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expiry", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "selfPermitAllowed", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expiry", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "selfPermitAllowedIfNecessary", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "selfPermitIfNecessary", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountMinimum", - "type": "uint256" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "name": "sweepToken", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "tokenOfOwnerByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount0Owed", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount1Owed", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "uniswapV3MintCallback", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amountMinimum", - "type": "uint256" - }, - { - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "name": "unwrapWETH9", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" + } } -] \ No newline at end of file +} diff --git a/packages/uni-watcher/src/artifacts/factory.json b/packages/uni-watcher/src/artifacts/factory.json index 25032129..0735d329 100644 --- a/packages/uni-watcher/src/artifacts/factory.json +++ b/packages/uni-watcher/src/artifacts/factory.json @@ -1,198 +1,366 @@ -[ - { - "anonymous": false, - "inputs": [ +{ + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "FeeAmountEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "createPool", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "enableFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "name": "feeAmountTickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "name": "getPool", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "parameters", + "outputs": [ + { + "internalType": "address", + "name": "factory", + "type": "address" + }, + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "storageLayout": { + "storage": [ { - "indexed": true, - "internalType": "uint24", - "name": "fee", - "type": "uint24" + "astId": 2840, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "parameters", + "offset": 0, + "slot": "0", + "type": "t_struct(Parameters)2836_storage" }, { - "indexed": true, - "internalType": "int24", - "name": "tickSpacing", - "type": "int24" - } - ], - "name": "FeeAmountEnabled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "oldOwner", - "type": "address" + "astId": 56, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "owner", + "offset": 0, + "slot": "3", + "type": "t_address" }, { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnerChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token0", - "type": "address" + "astId": 62, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "feeAmountTickSpacing", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint24,t_int24)" }, { - "indexed": true, - "internalType": "address", - "name": "token1", - "type": "address" + "astId": 72, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "getPool", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint24,t_address)))" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" }, - { - "indexed": true, - "internalType": "uint24", - "name": "fee", - "type": "uint24" + "t_int24": { + "encoding": "inplace", + "label": "int24", + "numberOfBytes": "3" }, - { - "indexed": false, - "internalType": "int24", - "name": "tickSpacing", - "type": "int24" + "t_mapping(t_address,t_mapping(t_address,t_mapping(t_uint24,t_address)))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => mapping(uint24 => address)))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_mapping(t_uint24,t_address))" }, - { - "indexed": false, - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolCreated", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" + "t_mapping(t_address,t_mapping(t_uint24,t_address))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(uint24 => address))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint24,t_address)" }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" + "t_mapping(t_uint24,t_address)": { + "encoding": "mapping", + "key": "t_uint24", + "label": "mapping(uint24 => address)", + "numberOfBytes": "32", + "value": "t_address" }, - { - "internalType": "uint24", - "name": "fee", - "type": "uint24" - } - ], - "name": "createPool", - "outputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint24", - "name": "fee", - "type": "uint24" + "t_mapping(t_uint24,t_int24)": { + "encoding": "mapping", + "key": "t_uint24", + "label": "mapping(uint24 => int24)", + "numberOfBytes": "32", + "value": "t_int24" }, - { - "internalType": "int24", - "name": "tickSpacing", - "type": "int24" - } - ], - "name": "enableFeeAmount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint24", - "name": "fee", - "type": "uint24" - } - ], - "name": "feeAmountTickSpacing", - "outputs": [ - { - "internalType": "int24", - "name": "", - "type": "int24" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "tokenA", - "type": "address" + "t_struct(Parameters)2836_storage": { + "encoding": "inplace", + "label": "struct UniswapV3PoolDeployer.Parameters", + "members": [ + { + "astId": 2827, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "factory", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 2829, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "token0", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 2831, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "token1", + "offset": 0, + "slot": "2", + "type": "t_address" + }, + { + "astId": 2833, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "fee", + "offset": 20, + "slot": "2", + "type": "t_uint24" + }, + { + "astId": 2835, + "contract": "contracts/UniswapV3Factory.sol:UniswapV3Factory", + "label": "tickSpacing", + "offset": 23, + "slot": "2", + "type": "t_int24" + } + ], + "numberOfBytes": "96" }, - { - "internalType": "address", - "name": "tokenB", - "type": "address" - }, - { - "internalType": "uint24", - "name": "fee", - "type": "uint24" + "t_uint24": { + "encoding": "inplace", + "label": "uint24", + "numberOfBytes": "3" } - ], - "name": "getPool", - "outputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "setOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + } } -] \ No newline at end of file +} diff --git a/packages/uni-watcher/src/client.ts b/packages/uni-watcher/src/client.ts index 0c643d8a..26ab3306 100644 --- a/packages/uni-watcher/src/client.ts +++ b/packages/uni-watcher/src/client.ts @@ -1,6 +1,8 @@ import { gql } from '@apollo/client/core'; import { GraphQLClient, GraphQLConfig } from '@vulcanize/ipld-eth-client'; +import { queryGetPool, queryPoolIdToPoolKey, queryPosition } from './queries'; + export class Client { _config: GraphQLConfig; _client: GraphQLClient; @@ -72,6 +74,13 @@ export class Client { liquidity tick } + + ... on IncreaseLiquidityEvent { + tokenId + liquidity + amount0 + amount1 + } } } } @@ -81,4 +90,42 @@ export class Client { } ); } + + async getPosition (blockHash: string, tokenId: bigint): Promise { + const { position } = await this._client.query( + gql(queryPosition), + { + blockHash, + tokenId: tokenId.toString() + } + ); + + return position; + } + + async poolIdToPoolKey (blockHash: string, poolId: bigint): Promise { + const { poolIdToPoolKey } = await this._client.query( + gql(queryPoolIdToPoolKey), + { + blockHash, + poolId: poolId.toString() + } + ); + + return poolIdToPoolKey; + } + + async getPool (blockHash: string, token0: string, token1: string, fee: bigint): Promise { + const { getPool } = await this._client.query( + gql(queryGetPool), + { + blockHash, + token0, + token1, + fee: fee.toString() + } + ); + + return getPool; + } } diff --git a/packages/uni-watcher/src/database.ts b/packages/uni-watcher/src/database.ts index 35be338e..cf7dba39 100644 --- a/packages/uni-watcher/src/database.ts +++ b/packages/uni-watcher/src/database.ts @@ -122,6 +122,14 @@ export class Database { .getOne(); } + async getLatestContract (kind: string): Promise { + return this._conn.getRepository(Contract) + .createQueryBuilder('contract') + .where('kind = :kind', { kind }) + .orderBy('id', 'DESC') + .getOne(); + } + async saveContract (address: string, kind: string, startingBlock: number): Promise { await this._conn.transaction(async (tx) => { const repo = tx.getRepository(Contract); diff --git a/packages/uni-watcher/src/indexer.ts b/packages/uni-watcher/src/indexer.ts index 71fedd93..420076f8 100644 --- a/packages/uni-watcher/src/indexer.ts +++ b/packages/uni-watcher/src/indexer.ts @@ -2,9 +2,10 @@ import debug from 'debug'; import { DeepPartial } from 'typeorm'; import JSONbig from 'json-bigint'; import { ethers } from 'ethers'; +import assert from 'assert'; import { EthClient } from '@vulcanize/ipld-eth-client'; -import { GetStorageAt } from '@vulcanize/solidity-mapper'; +import { GetStorageAt, getStorageValue, StorageLayout } from '@vulcanize/solidity-mapper'; import { Config } from '@vulcanize/util'; import { Database } from './database'; @@ -12,9 +13,9 @@ import { Event, UNKNOWN_EVENT_NAME } from './entity/Event'; import { BlockProgress } from './entity/BlockProgress'; import { Contract, KIND_FACTORY, KIND_POOL, KIND_NFPM } from './entity/Contract'; -import factoryABI from './artifacts/factory.json'; +import { abi as factoryABI, storageLayout as factoryStorageLayout } from './artifacts/factory.json'; +import { abi as nfpmABI, storageLayout as nfpmStorageLayout } from './artifacts/NonfungiblePositionManager.json'; import poolABI from './artifacts/pool.json'; -import nfpmABI from './artifacts/NonfungiblePositionManager.json'; // TODO: Move to config. const MAX_EVENTS_BLOCK_RANGE = 1000; @@ -33,6 +34,13 @@ type ResultEvent = { proof: string; }; +interface ValueResult { + value: any; + proof: { + data: string; + } +} + export class Indexer { _config: Config; _db: Database @@ -374,4 +382,49 @@ export class Indexer { return this._db.getEventsInRange(fromBlockNumber, toBlockNumber); } + + async position (blockHash: string, tokenId: string) { + const nfpmContract = await this._db.getLatestContract('nfpm'); + assert(nfpmContract, 'No NFPM contract watched.'); + const { value, proof } = await this._getStorageValue(nfpmStorageLayout, blockHash, nfpmContract.address, '_positions', BigInt(tokenId)); + + return { + ...value, + proof + }; + } + + async poolIdToPoolKey (blockHash: string, poolId: string) { + const nfpmContract = await this._db.getLatestContract('nfpm'); + assert(nfpmContract, 'No NFPM contract watched.'); + const { value, proof } = await this._getStorageValue(nfpmStorageLayout, blockHash, nfpmContract.address, '_poolIdToPoolKey', BigInt(poolId)); + + return { + ...value, + proof + }; + } + + async getPool (blockHash: string, token0: string, token1: string, fee: string) { + const factoryContract = await this._db.getLatestContract('factory'); + assert(factoryContract, 'No Factory contract watched.'); + const { value, proof } = await this._getStorageValue(factoryStorageLayout, blockHash, factoryContract.address, 'getPool', token0, token1, BigInt(fee)); + + return { + pool: value, + proof + }; + } + + // TODO: Move into base/class or framework package. + async _getStorageValue (storageLayout: StorageLayout, blockHash: string, token: string, variable: string, ...mappingKeys: any[]): Promise { + return getStorageValue( + storageLayout, + this._getStorageAt, + blockHash, + token, + variable, + ...mappingKeys + ); + } } diff --git a/packages/uni-watcher/src/queries.ts b/packages/uni-watcher/src/queries.ts index 8e8e84aa..0f880a3c 100644 --- a/packages/uni-watcher/src/queries.ts +++ b/packages/uni-watcher/src/queries.ts @@ -12,3 +12,49 @@ query getEvents($blockHash: String!, $token: String!) { } } `; + +export const queryPosition = gql` +query getPosition($blockHash: String!, $tokenId: String!) { + position(blockHash: $blockHash, tokenId: $tokenId) { + nonce + operator + poolId + tickLower + tickUpper + liquidity + feeGrowthInside0LastX128 + feeGrowthInside1LastX128 + tokensOwed0 + tokensOwed1 + + proof { + data + } + } +} +`; + +export const queryPoolIdToPoolKey = gql` +query poolIdToPoolKey($blockHash: String!, $poolId: String!) { + poolIdToPoolKey(blockHash: $blockHash, poolId: $poolId) { + token0 + token1 + fee + + proof { + data + } + } +} +`; + +export const queryGetPool = gql` +query getPool($blockHash: String!, $token0: String!, $token1: String!, $fee: String!) { + getPool(blockHash: $blockHash, token0: $token0, token1: $token1, fee: $fee) { + pool + proof { + data + } + } +} +`; diff --git a/packages/uni-watcher/src/resolvers.ts b/packages/uni-watcher/src/resolvers.ts index 1e02f17f..2abb06dd 100644 --- a/packages/uni-watcher/src/resolvers.ts +++ b/packages/uni-watcher/src/resolvers.ts @@ -72,6 +72,21 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch const events = await indexer.getEventsInRange(fromBlockNumber, toBlockNumber); return events.map(event => indexer.getResultEvent(event)); + }, + + position: (_: any, { blockHash, tokenId }: { blockHash: string, tokenId: string }) => { + log('position', blockHash, tokenId); + return indexer.position(blockHash, tokenId); + }, + + poolIdToPoolKey: (_: any, { blockHash, poolId }: { blockHash: string, poolId: string }) => { + log('poolIdToPoolKey', blockHash, poolId); + return indexer.poolIdToPoolKey(blockHash, poolId); + }, + + getPool: (_: any, { blockHash, token0, token1, fee }: { blockHash: string, token0: string, token1: string, fee: string }) => { + log('getPool', blockHash, token0, token1, fee); + return indexer.getPool(blockHash, token0, token1, fee); } } }; diff --git a/packages/uni-watcher/src/schema.ts b/packages/uni-watcher/src/schema.ts index 1b30751a..3b10b76e 100644 --- a/packages/uni-watcher/src/schema.ts +++ b/packages/uni-watcher/src/schema.ts @@ -202,12 +202,12 @@ type Query { position( blockHash: String! - tokenId: BigInt! + tokenId: String! ): ResultPosition poolIdToPoolKey( blockHash: String! - poolId: BigInt! + poolId: String! ): ResultPoolKey # Factory @@ -216,7 +216,7 @@ type Query { blockHash: String! token0: String! token1: String! - fee: BigInt! + fee: String! ): ResultGetPool # Pool