From aae39cbe5e5141cd69b86b7c2519f7b13beddf7d Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 15 Jan 2024 15:45:28 +0100 Subject: [PATCH 01/12] Update dependency to 5.0.1, and add ERC4906 support --- generated/all.schema.graphql | 4 +-- generated/erc1967upgrade.subgraph.yaml | 2 +- generated/governor.schema.graphql | 4 +-- package-lock.json | 8 +++--- package.json | 2 +- src/datasources/erc1967upgrade.yaml | 2 +- src/datasources/erc721.ts | 39 ++++++++++++++++++++++++-- src/datasources/erc721.yaml | 8 +++++- src/datasources/governor.gql.json | 4 +-- src/datasources/governor.ts | 8 +++--- src/datasources/governor.yaml | 2 +- src/datasources/voting.ts | 8 +++--- src/datasources/voting.yaml | 2 +- src/fetch/governor.ts | 4 +-- 14 files changed, 68 insertions(+), 29 deletions(-) diff --git a/generated/all.schema.graphql b/generated/all.schema.graphql index 51d42ec..8e504fd 100644 --- a/generated/all.schema.graphql +++ b/generated/all.schema.graphql @@ -272,8 +272,8 @@ type Proposal @entity { governor: Governor! proposalId: BigInt! proposer: Account! - startBlock: BigInt! - endBlock: BigInt! + voteStart: BigInt! + voteEnd: BigInt! description: String! eta: BigInt canceled: Boolean! diff --git a/generated/erc1967upgrade.subgraph.yaml b/generated/erc1967upgrade.subgraph.yaml index 9c368b2..dea3a70 100644 --- a/generated/erc1967upgrade.subgraph.yaml +++ b/generated/erc1967upgrade.subgraph.yaml @@ -14,7 +14,7 @@ dataSources: - ERC1967 abis: - name: ERC1967 - file: ../node_modules/@openzeppelin/contracts/build/contracts/ERC1967Upgrade.json + file: ../node_modules/@openzeppelin/contracts/build/contracts/IERC1967.json eventHandlers: - event: AdminChanged(address,address) handler: handleAdminChanged diff --git a/generated/governor.schema.graphql b/generated/governor.schema.graphql index c52983b..e39c389 100644 --- a/generated/governor.schema.graphql +++ b/generated/governor.schema.graphql @@ -22,8 +22,8 @@ type Proposal @entity { governor: Governor! proposalId: BigInt! proposer: Account! - startBlock: BigInt! - endBlock: BigInt! + voteStart: BigInt! + voteEnd: BigInt! description: String! eta: BigInt canceled: Boolean! diff --git a/package-lock.json b/package-lock.json index d389c2a..69b52b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@amxx/graphprotocol-utils": "^1.1.0", - "@openzeppelin/contracts": "^4.8.1" + "@openzeppelin/contracts": "^5.0.1" }, "devDependencies": { "@graphprotocol/graph-cli": "^0.65.0", @@ -1169,9 +1169,9 @@ } }, "node_modules/@openzeppelin/contracts": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.1.tgz", - "integrity": "sha512-xQ6eUZl+RDyb/FiZe1h+U7qr/f4p/SrTSQcTPH2bjur3C5DbuW/zFgCU/b1P/xcIaEqJep+9ju4xDRi3rmChdQ==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.1.tgz", + "integrity": "sha512-yQJaT5HDp9hYOOp4jTYxMsR02gdFZFXhewX5HW9Jo4fsqSVqqyIO/xTHdWDaKX5a3pv1txmf076Lziz+sO7L1w==" }, "node_modules/@openzeppelin/docs-utils": { "version": "0.1.3", diff --git a/package.json b/package.json index f0a718a..22cda37 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "dependencies": { "@amxx/graphprotocol-utils": "^1.1.0", - "@openzeppelin/contracts": "^4.8.1" + "@openzeppelin/contracts": "^5.0.1" }, "devDependencies": { "@graphprotocol/graph-cli": "^0.65.0", diff --git a/src/datasources/erc1967upgrade.yaml b/src/datasources/erc1967upgrade.yaml index 8b1f21c..0aa5da6 100644 --- a/src/datasources/erc1967upgrade.yaml +++ b/src/datasources/erc1967upgrade.yaml @@ -13,7 +13,7 @@ - ERC1967 abis: - name: ERC1967 - file: {root}/node_modules/@openzeppelin/contracts/build/contracts/ERC1967Upgrade.json + file: {root}/node_modules/@openzeppelin/contracts/build/contracts/IERC1967.json eventHandlers: - event: AdminChanged(address,address) handler: handleAdminChanged diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index c4659d7..bb39702 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -1,5 +1,6 @@ import { Address, + BigInt, } from '@graphprotocol/graph-ts' import { @@ -7,11 +8,17 @@ import { } from '../../generated/schema' import { - Approval as ApprovalEvent, - ApprovalForAll as ApprovalForAllEvent, - Transfer as TransferEvent, + IERC721, + Approval as ApprovalEvent, + ApprovalForAll as ApprovalForAllEvent, + Transfer as TransferEvent, } from '../../generated/erc721/IERC721' +import { + MetadataUpdate as MetadataUpdateEvent, + BatchMetadataUpdate as BatchMetadataUpdateEvent, +} from '../../generated/erc721/IERC4906' + import { events, transactions, @@ -99,3 +106,29 @@ export function handleApprovalForAll(event: ApprovalForAllEvent): void { // ev.save() } } + +export function handleMetadataUpdate(event: MetadataUpdateEvent) : void { + let contract = fetchERC721(event.address) + if (contract != null) { + let erc721 = IERC721.bind(Address.fromBytes(contract.id)) + + let token = fetchERC721Token(contract, event.params._tokenId) + let try_tokenURI = erc721.try_tokenURI(event.params._tokenId) + token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value + token.save() + } +} + +export function handleBatchMetadataUpdate(event: BatchMetadataUpdateEvent) : void { + let contract = fetchERC721(event.address) + if (contract != null) { + let erc721 = IERC721.bind(Address.fromBytes(contract.id)) + + for (let tokenId = event.params._fromTokenId.toU64(); tokenId <= event.params._toTokenId.toU64(); ++tokenId) { + let token = fetchERC721Token(contract, BigInt.fromU64(tokenId)) + let try_tokenURI = erc721.try_tokenURI(BigInt.fromU64(tokenId)) + token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value + token.save() + } + } +} diff --git a/src/datasources/erc721.yaml b/src/datasources/erc721.yaml index e337cbd..a80507a 100644 --- a/src/datasources/erc721.yaml +++ b/src/datasources/erc721.yaml @@ -3,7 +3,7 @@ network: {chain} source: address: "{address}" - abi: IERC721 + abi: IERC4906 startBlock: {startBlock} mapping: kind: ethereum/events @@ -14,6 +14,8 @@ abis: - name: IERC721 file: {root}/node_modules/@openzeppelin/contracts/build/contracts/IERC721Metadata.json + - name: IERC4906 + file: {root}/node_modules/@openzeppelin/contracts/build/contracts/IERC4906.json eventHandlers: - event: Approval(indexed address,indexed address,indexed uint256) handler: handleApproval @@ -21,4 +23,8 @@ handler: handleApprovalForAll - event: Transfer(indexed address,indexed address,indexed uint256) handler: handleTransfer + - event: MetadataUpdate(uint256) + handler: handleMetadataUpdate + - event: BatchMetadataUpdate(uint256,uint256) + handler: handleBatchMetadataUpdate file: {file} diff --git a/src/datasources/governor.gql.json b/src/datasources/governor.gql.json index 07333f5..c669c30 100644 --- a/src/datasources/governor.gql.json +++ b/src/datasources/governor.gql.json @@ -27,8 +27,8 @@ { "name": "governor", "type": "Governor!" }, { "name": "proposalId", "type": "BigInt!" }, { "name": "proposer", "type": "Account!" }, - { "name": "startBlock", "type": "BigInt!" }, - { "name": "endBlock", "type": "BigInt!" }, + { "name": "voteStart", "type": "BigInt!" }, + { "name": "voteEnd", "type": "BigInt!" }, { "name": "description", "type": "String!" }, { "name": "eta", "type": "BigInt" }, { "name": "canceled", "type": "Boolean!" }, diff --git a/src/datasources/governor.ts b/src/datasources/governor.ts index 627137f..1e4b9ad 100644 --- a/src/datasources/governor.ts +++ b/src/datasources/governor.ts @@ -43,8 +43,8 @@ export function handleProposalCreated(event: ProposalCreatedEvent): void { let proposal = fetchProposal(governor, event.params.proposalId) proposal.proposer = fetchAccount(event.params.proposer).id - proposal.startBlock = event.params.startBlock - proposal.endBlock = event.params.endBlock + proposal.voteStart = event.params.voteStart + proposal.voteEnd = event.params.voteEnd proposal.description = event.params.description proposal.save() @@ -76,7 +76,7 @@ export function handleProposalQueued(event: ProposalQueuedEvent): void { let proposal = fetchProposal(governor, event.params.proposalId) proposal.queued = true - proposal.eta = event.params.eta + proposal.eta = event.params.etaSeconds proposal.save() let ev = new ProposalQueued(events.id(event)) @@ -85,7 +85,7 @@ export function handleProposalQueued(event: ProposalQueuedEvent): void { ev.timestamp = event.block.timestamp ev.governor = governor.id ev.proposal = proposal.id - ev.eta = event.params.eta + ev.eta = event.params.etaSeconds ev.save() } diff --git a/src/datasources/governor.yaml b/src/datasources/governor.yaml index 7c8fe44..729290d 100644 --- a/src/datasources/governor.yaml +++ b/src/datasources/governor.yaml @@ -13,7 +13,7 @@ - Governor abis: - name: Governor - file: {root}/node_modules/@openzeppelin/contracts/build/contracts/IGovernorTimelock.json + file: {root}/node_modules/@openzeppelin/contracts/build/contracts/IGovernor.json eventHandlers: - event: ProposalCanceled(uint256) handler: handleProposalCanceled diff --git a/src/datasources/voting.ts b/src/datasources/voting.ts index e779243..ae19820 100644 --- a/src/datasources/voting.ts +++ b/src/datasources/voting.ts @@ -52,8 +52,8 @@ export function handleDelegateVotesChanged(event: DelegateVotesChangedEvent): vo const total = fetchWeight(contract, null) const weigth = fetchWeight(contract, delegate) - total.value = total.value.minus(event.params.previousBalance).plus(event.params.newBalance) - weigth.value = event.params.newBalance + total.value = total.value.minus(event.params.previousVotes).plus(event.params.newVotes) + weigth.value = event.params.newVotes total.save() weigth.save() @@ -65,7 +65,7 @@ export function handleDelegateVotesChanged(event: DelegateVotesChangedEvent): vo ev.voteWeight = weigth.id ev.contract = contract.id ev.delegate = delegate.id - ev.oldValue = event.params.previousBalance - ev.newValue = event.params.newBalance + ev.oldValue = event.params.previousVotes + ev.newValue = event.params.newVotes ev.save() } diff --git a/src/datasources/voting.yaml b/src/datasources/voting.yaml index 0b5c5fc..9b1cdb1 100644 --- a/src/datasources/voting.yaml +++ b/src/datasources/voting.yaml @@ -13,7 +13,7 @@ - Voting abis: - name: Voting - file: {root}/node_modules/@openzeppelin/contracts/build/contracts/IVotes.json + file: {root}/node_modules/@openzeppelin/contracts/build/contracts/IERC5805.json eventHandlers: - event: DelegateChanged(indexed address,indexed address,indexed address) handler: handleDelegateChanged diff --git a/src/fetch/governor.ts b/src/fetch/governor.ts index 2171211..4295e51 100644 --- a/src/fetch/governor.ts +++ b/src/fetch/governor.ts @@ -54,8 +54,8 @@ export function fetchProposal(contract: Governor, proposalId: BigInt): Proposal proposal.governor = contract.id proposal.proposalId = proposalId proposal.proposer = Address.zero() - proposal.startBlock = BigInt.zero() - proposal.endBlock = BigInt.zero() + proposal.voteStart = BigInt.zero() + proposal.voteEnd = BigInt.zero() proposal.description = "" proposal.canceled = false proposal.queued = false From d8d5f78a1c7c1a5aeba5403d0b628fd3fd7fe24c Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 15 Jan 2024 15:49:51 +0100 Subject: [PATCH 02/12] add changelog entry --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c09dc31..ef49758 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ # Changelog ### Unreleased + * Update dependency to @openzeppelin/contracts version 5.0.1 * `Governor`: fix bug caused by duplicate write of immutable entity `ProposalSupport` ([#47](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/47)) + * `Governor`: rename `startBlock` to `voteStart` and `endBlock` to `voteEnd` ([#60](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/60)) + * `ERC721`: add support for `ERC4906` events ([#60](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/60)) + +Please note that this is a breaking release: some elements of the GraphQL API are renamed or removed. ### 0.1.8-5 (2022-07-29) * `AccessControl`: fix bug caused by duplicate write of immutable entity `AccessControl` ([#38](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/38)) From 62abf7f18e71c3b4f6c48c920129506b1bd91753 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 16 Jan 2024 10:17:39 +0100 Subject: [PATCH 03/12] minimize diff --- src/datasources/erc721.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index 67ef843..71d141b 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -9,9 +9,9 @@ import { import { IERC721, - Approval as ApprovalEvent, - ApprovalForAll as ApprovalForAllEvent, - Transfer as TransferEvent, + Approval as ApprovalEvent, + ApprovalForAll as ApprovalForAllEvent, + Transfer as TransferEvent, } from '../../generated/erc721/IERC721' import { From da9cda4e012a87508943c6f8372fcb855cd32f1a Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 16 Jan 2024 10:51:26 +0100 Subject: [PATCH 04/12] Set ERC721 token owner to 0 by default to avoid possible issue when updating URI for a non existing token --- src/datasources/erc721.ts | 39 ++++++++++++++++++++++++++------------- src/fetch/erc721.ts | 10 ++++++---- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index 71d141b..f28f7d8 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -135,27 +135,40 @@ export function handleApprovalForAll(event: ApprovalForAllEvent): void { } export function handleMetadataUpdate(event: MetadataUpdateEvent) : void { + let erc721 = IERC721.bind(event.address) let contract = fetchERC721(event.address) - if (contract != null) { - let erc721 = IERC721.bind(Address.fromBytes(contract.id)) - let token = fetchERC721Token(contract, event.params._tokenId) - let try_tokenURI = erc721.try_tokenURI(event.params._tokenId) - token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value - token.save() + if (contract != null) { + if (contract.supportsMetadata) { + let token = fetchERC721Token(contract, event.params._tokenId) + let try_tokenURI = erc721.try_tokenURI(event.params._tokenId) + token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value + token.save() + } else { + // add a warning ? + } } } export function handleBatchMetadataUpdate(event: BatchMetadataUpdateEvent) : void { + let erc721 = IERC721.bind(event.address) let contract = fetchERC721(event.address) - if (contract != null) { - let erc721 = IERC721.bind(Address.fromBytes(contract.id)) - for (let tokenId = event.params._fromTokenId.toU64(); tokenId <= event.params._toTokenId.toU64(); ++tokenId) { - let token = fetchERC721Token(contract, BigInt.fromU64(tokenId)) - let try_tokenURI = erc721.try_tokenURI(BigInt.fromU64(tokenId)) - token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value - token.save() + if (contract != null) { + if (contract.supportsMetadata) { + const from = event.params._fromTokenId.toU64(); + const to = event.params._toTokenId.toU64(); + // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them + if (to - from <= 5000) { + for (let tokenId =from; tokenId <= to; ++tokenId) { + let token = fetchERC721Token(contract, BigInt.fromU64(tokenId)) + let try_tokenURI = erc721.try_tokenURI(BigInt.fromU64(tokenId)) + token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value + token.save() + } + } + } else { + // add a warning ? } } } diff --git a/src/fetch/erc721.ts b/src/fetch/erc721.ts index 4b9f028..af864a6 100644 --- a/src/fetch/erc721.ts +++ b/src/fetch/erc721.ts @@ -71,10 +71,12 @@ export function fetchERC721Token(contract: ERC721Contract, identifier: BigInt): let token = ERC721Token.load(id) if (token == null) { - token = new ERC721Token(id) - token.contract = contract.id - token.identifier = identifier - token.approval = fetchAccount(Address.zero()).id + const AddressZero = fetchAccount(Address.zero()) + token = new ERC721Token(id) + token.contract = contract.id + token.identifier = identifier + token.owner = AddressZero.id + token.approval = AddressZero.id if (contract.supportsMetadata) { let erc721 = IERC721.bind(Address.fromBytes(contract.id)) From 675b7e51bcede29fb1002d8ac593673ac2ac0b04 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 16 Jan 2024 11:08:58 +0100 Subject: [PATCH 05/12] refactor --- src/datasources/erc721.ts | 186 ++++++++++++++++++++------------------ src/fetch/erc721.ts | 6 +- 2 files changed, 100 insertions(+), 92 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index f28f7d8..0ab25ef 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -4,6 +4,7 @@ import { } from '@graphprotocol/graph-ts' import { + ERC721Contract, ERC721Transfer, } from '../../generated/schema' @@ -40,34 +41,39 @@ import { export function handleTransfer(event: TransferEvent): void { let contract = fetchERC721(event.address) - if (contract != null) { - let token = fetchERC721Token(contract, event.params.tokenId) - let from = fetchAccount(event.params.from) - let to = fetchAccount(event.params.to) - - token.owner = to.id - token.approval = fetchAccount(Address.zero()).id // implicit approval reset on transfer - token.save() - - let ev = new ERC721Transfer(events.id(event)) - ev.emitter = contract.id - ev.transaction = transactions.log(event).id - ev.timestamp = event.block.timestamp - ev.contract = contract.id - ev.token = token.id - ev.from = from.id - ev.to = to.id - ev.save() - } + if (contract == null) return + + let token = fetchERC721Token(contract, event.params.tokenId) + let from = fetchAccount(event.params.from) + let to = fetchAccount(event.params.to) + + token.owner = to.id + token.approval = fetchAccount(Address.zero()).id // implicit approval reset on transfer + token.save() + + let ev = new ERC721Transfer(events.id(event)) + ev.emitter = contract.id + ev.transaction = transactions.log(event).id + ev.timestamp = event.block.timestamp + ev.contract = contract.id + ev.token = token.id + ev.from = from.id + ev.to = to.id + ev.save() } export function handleConsecutiveTransfer(event: ConsecutiveTransfer): void { let contract = fetchERC721(event.address) - if (contract != null) { - let from = fetchAccount(event.params.fromAddress) - let to = fetchAccount(event.params.toAddress) + if (contract == null) return + + let from = fetchAccount(event.params.fromAddress) + let to = fetchAccount(event.params.toAddress) + let fromTokenId = event.params.fromTokenId.toU64() + let toTokenId = event.params.toTokenId.toU64() - for (let tokenId = event.params.fromTokenId.toU64(); tokenId <= event.params.toTokenId.toU64(); ++tokenId) { + // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them + if (toTokenId - fromTokenId <= 5000) { + for (let tokenId = fromTokenId; tokenId <= toTokenId; ++tokenId) { let token = fetchERC721Token(contract, BigInt.fromU64(tokenId)) token.owner = to.id token.approval = fetchAccount(Address.zero()).id // implicit approval reset on transfer @@ -88,87 +94,89 @@ export function handleConsecutiveTransfer(event: ConsecutiveTransfer): void { export function handleApproval(event: ApprovalEvent): void { let contract = fetchERC721(event.address) - if (contract != null) { - let token = fetchERC721Token(contract, event.params.tokenId) - let owner = fetchAccount(event.params.owner) - let approved = fetchAccount(event.params.approved) - - token.owner = owner.id // this should not be necessary, owner changed is signaled by a transfer event - token.approval = approved.id - - token.save() - owner.save() - approved.save() - - // let ev = new Approval(events.id(event)) - // ev.emitter = contract.id - // ev.transaction = transactions.log(event).id - // ev.timestamp = event.block.timestamp - // ev.token = token.id - // ev.owner = owner.id - // ev.approved = approved.id - // ev.save() - } + if (contract == null) return + + let token = fetchERC721Token(contract, event.params.tokenId) + let owner = fetchAccount(event.params.owner) + let approved = fetchAccount(event.params.approved) + + token.owner = owner.id // this should not be necessary, owner changed is signaled by a transfer event + token.approval = approved.id + + token.save() + owner.save() + approved.save() + + // let ev = new Approval(events.id(event)) + // ev.emitter = contract.id + // ev.transaction = transactions.log(event).id + // ev.timestamp = event.block.timestamp + // ev.token = token.id + // ev.owner = owner.id + // ev.approved = approved.id + // ev.save() } export function handleApprovalForAll(event: ApprovalForAllEvent): void { let contract = fetchERC721(event.address) - if (contract != null) { - let owner = fetchAccount(event.params.owner) - let operator = fetchAccount(event.params.operator) - let delegation = fetchERC721Operator(contract, owner, operator) - - delegation.approved = event.params.approved - - delegation.save() - - // let ev = new ApprovalForAll(events.id(event)) - // ev.emitter = contract.id - // ev.transaction = transactions.log(event).id - // ev.timestamp = event.block.timestamp - // ev.delegation = delegation.id - // ev.owner = owner.id - // ev.operator = operator.id - // ev.approved = event.params.approved - // ev.save() - } + if (contract == null) return + + let owner = fetchAccount(event.params.owner) + let operator = fetchAccount(event.params.operator) + let delegation = fetchERC721Operator(contract, owner, operator) + + delegation.approved = event.params.approved + + delegation.save() + + // let ev = new ApprovalForAll(events.id(event)) + // ev.emitter = contract.id + // ev.transaction = transactions.log(event).id + // ev.timestamp = event.block.timestamp + // ev.delegation = delegation.id + // ev.owner = owner.id + // ev.operator = operator.id + // ev.approved = event.params.approved + // ev.save() } export function handleMetadataUpdate(event: MetadataUpdateEvent) : void { - let erc721 = IERC721.bind(event.address) let contract = fetchERC721(event.address) + if (contract == null) return - if (contract != null) { - if (contract.supportsMetadata) { - let token = fetchERC721Token(contract, event.params._tokenId) - let try_tokenURI = erc721.try_tokenURI(event.params._tokenId) - token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value - token.save() - } else { - // add a warning ? - } + if (contract.supportsMetadata) { + _updateURI(contract, event.params._tokenId) + } else { + // add a warning ? } } export function handleBatchMetadataUpdate(event: BatchMetadataUpdateEvent) : void { - let erc721 = IERC721.bind(event.address) let contract = fetchERC721(event.address) - - if (contract != null) { - if (contract.supportsMetadata) { - const from = event.params._fromTokenId.toU64(); - const to = event.params._toTokenId.toU64(); - // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them - if (to - from <= 5000) { - for (let tokenId =from; tokenId <= to; ++tokenId) { - let token = fetchERC721Token(contract, BigInt.fromU64(tokenId)) - let try_tokenURI = erc721.try_tokenURI(BigInt.fromU64(tokenId)) - token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value - token.save() - } + if (contract == null) return + + if (contract.supportsMetadata) { + let fromTokenId = event.params._fromTokenId.toU64() + let toTokenId = event.params._toTokenId.toU64() + // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them + if (toTokenId - fromTokenId <= 5000) { + for (let tokenId = fromTokenId; tokenId <= toTokenId; ++tokenId) { + _updateURI(contract, BigInt.fromU64(tokenId)) } - } else { - // add a warning ? } + } else { + // add a warning ? + } +} + +function _updateURI(contract: ERC721Contract, tokenId: BigInt) : void { + let erc721 = IERC721.bind(Address.fromBytes(contract.id)) + let token = fetchERC721Token(contract, tokenId) + let try_tokenURI = erc721.try_tokenURI(tokenId) + token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value + // If token was never minted (transfered) then the owner was set to 0 by default in `fetchERC721Token` + // In that case we don't want to save to token to the database. + if (token.owner != Address.zero()) { + token.save() } } diff --git a/src/fetch/erc721.ts b/src/fetch/erc721.ts index af864a6..a07603d 100644 --- a/src/fetch/erc721.ts +++ b/src/fetch/erc721.ts @@ -71,12 +71,12 @@ export function fetchERC721Token(contract: ERC721Contract, identifier: BigInt): let token = ERC721Token.load(id) if (token == null) { - const AddressZero = fetchAccount(Address.zero()) + fetchAccount(Address.zero()) token = new ERC721Token(id) token.contract = contract.id token.identifier = identifier - token.owner = AddressZero.id - token.approval = AddressZero.id + token.owner = Address.zero() + token.approval = Address.zero() if (contract.supportsMetadata) { let erc721 = IERC721.bind(Address.fromBytes(contract.id)) From dafed787dc05c7ae89315b5e353c556ee6ed729c Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Fri, 1 Mar 2024 22:26:16 +0100 Subject: [PATCH 06/12] update dependencies --- package-lock.json | 431 +++------------------------------------------- package.json | 8 +- 2 files changed, 29 insertions(+), 410 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69b52b5..8552d1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,12 @@ "license": "MIT", "dependencies": { "@amxx/graphprotocol-utils": "^1.1.0", - "@openzeppelin/contracts": "^5.0.1" + "@openzeppelin/contracts": "^5.0.2" }, "devDependencies": { - "@graphprotocol/graph-cli": "^0.65.0", - "@graphprotocol/graph-ts": "^0.32.0", - "@openzeppelin/docs-utils": "^0.1.3", + "@graphprotocol/graph-cli": "^0.68.5", + "@graphprotocol/graph-ts": "^0.33.0", + "@openzeppelin/docs-utils": "^0.1.5", "jq.node": "^2.4.0" } }, @@ -709,9 +709,9 @@ } }, "node_modules/@graphprotocol/graph-cli": { - "version": "0.65.0", - "resolved": "https://registry.npmjs.org/@graphprotocol/graph-cli/-/graph-cli-0.65.0.tgz", - "integrity": "sha512-LY8slQGMVcoPc0nlolXlFrwNGCWCxN/3F7AXycCOOXDMHXHQ5qtkiYBnOoWp1EzPRo+y7Q04/gI6vE3Dy9WPyg==", + "version": "0.68.5", + "resolved": "https://registry.npmjs.org/@graphprotocol/graph-cli/-/graph-cli-0.68.5.tgz", + "integrity": "sha512-3GY2pYr5LksO6JY6s5nvePnSKVdtzDEn1CUGezyjCMR1uq9YIXMPXKqcnrzCX/DLugioEabiEi2+yOg9+rnFDQ==", "dev": true, "dependencies": { "@float-capital/float-subgraph-uncrashable": "^0.0.0-alpha.4", @@ -728,14 +728,13 @@ "dockerode": "2.5.8", "fs-extra": "9.1.0", "glob": "9.3.5", - "gluegun": "5.1.2", + "gluegun": "5.1.6", "graphql": "15.5.0", "immutable": "4.2.1", "ipfs-http-client": "55.0.0", "jayson": "4.0.0", "js-yaml": "3.14.1", "prettier": "3.0.3", - "request": "2.88.2", "semver": "7.4.0", "sync-request": "6.1.0", "tmp-promise": "3.0.3", @@ -793,9 +792,9 @@ } }, "node_modules/@graphprotocol/graph-ts": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.32.0.tgz", - "integrity": "sha512-YfKLT2w+ItXD/VPYQiAKtINQONVsAOkcqVFMHlhUy0fcEBVWuFBT53hJNI0/l5ujQa4TSxtzrKW/7EABAdgI8g==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.33.0.tgz", + "integrity": "sha512-HBUVblHUdjQZ/MEjjYPzVgmh+SiuF9VV0D8KubYfFAtzkqpVJlvdyk+RZTAJUiu8hpyYy0EVIcAnLEPtKlwMGQ==", "dev": true, "dependencies": { "assemblyscript": "0.19.10" @@ -1169,14 +1168,14 @@ } }, "node_modules/@openzeppelin/contracts": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.1.tgz", - "integrity": "sha512-yQJaT5HDp9hYOOp4jTYxMsR02gdFZFXhewX5HW9Jo4fsqSVqqyIO/xTHdWDaKX5a3pv1txmf076Lziz+sO7L1w==" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", + "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==" }, "node_modules/@openzeppelin/docs-utils": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.3.tgz", - "integrity": "sha512-O/iJ4jEi5ryNc/T74G9gbnFwQ8QaQ2bpAVoYXLPknZJyK52GEAvxC12UMP33KodTNV3rMzeeQrSBIdI8skjDJg==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.5.tgz", + "integrity": "sha512-GfqXArKmdq8rv+hsP+g8uS1VEkvMIzWs31dCONffzmqFwJ+MOsaNQNZNXQnLRgUkzk8i5mTNDjJuxDy+aBZImQ==", "dev": true, "dependencies": { "@frangio/servbot": "^0.2.5", @@ -1514,22 +1513,6 @@ "node": ">=0.4.0" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/ambi": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ambi/-/ambi-3.2.0.tgz", @@ -1663,15 +1646,6 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/asn1js": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", @@ -1705,15 +1679,6 @@ "url": "https://opencollective.com/assemblyscript" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -1744,21 +1709,6 @@ "node": ">= 4.0.0" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true - }, "node_modules/axios": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", @@ -1803,21 +1753,6 @@ } ] }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2352,18 +2287,6 @@ "node": ">= 8" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2536,16 +2459,6 @@ "url": "https://bevry.me/fund" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/editions": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/editions/-/editions-2.3.1.tgz", @@ -2878,12 +2791,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "node_modules/extendr": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/extendr/-/extendr-3.5.0.tgz", @@ -2918,15 +2825,6 @@ "url": "https://bevry.me/fund" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -2942,12 +2840,6 @@ "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", "dev": true }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", @@ -2970,12 +2862,6 @@ "node": ">=8.6.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, "node_modules/fast-levenshtein": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", @@ -3102,15 +2988,6 @@ } } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -3276,15 +3153,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -3338,9 +3206,9 @@ } }, "node_modules/gluegun": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/gluegun/-/gluegun-5.1.2.tgz", - "integrity": "sha512-Cwx/8S8Z4YQg07a6AFsaGnnnmd8mN17414NcPS3OoDtZRwxgsvwRNJNg69niD6fDa8oNwslCG0xH7rEpRNNE/g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/gluegun/-/gluegun-5.1.6.tgz", + "integrity": "sha512-9zbi4EQWIVvSOftJWquWzr9gLX2kaDgPkNR5dYWbM53eVvCI3iKuxLlnKoHC0v4uPoq+Kr/+F569tjoFbA4DSA==", "dev": true, "dependencies": { "apisauce": "^2.1.5", @@ -3349,7 +3217,7 @@ "colors": "1.4.0", "cosmiconfig": "7.0.1", "cross-spawn": "7.0.3", - "ejs": "3.1.6", + "ejs": "3.1.8", "enquirer": "2.3.6", "execa": "5.1.1", "fs-jetpack": "4.3.1", @@ -3379,12 +3247,12 @@ } }, "node_modules/gluegun/node_modules/ejs": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", - "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", "dev": true, "dependencies": { - "jake": "^10.6.1" + "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" @@ -3432,29 +3300,6 @@ "graphql": "*" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3567,21 +3412,6 @@ "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", "dev": true }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -3973,12 +3803,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -4021,12 +3845,6 @@ "ws": "*" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, "node_modules/it-all": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", @@ -4287,30 +4105,12 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -4382,21 +4182,6 @@ "node": "*" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/keccak": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", @@ -4992,15 +4777,6 @@ "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "dev": true }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5355,12 +5131,6 @@ "node": ">=0.12" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -5435,21 +5205,6 @@ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", "dev": true }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/pvtsutils": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", @@ -5581,57 +5336,6 @@ "esprima": "~4.0.0" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5950,37 +5654,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, "node_modules/stream-to-it": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/stream-to-it/-/stream-to-it-0.2.4.tgz", @@ -6316,19 +5989,6 @@ "node": ">=8.0" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -6384,18 +6044,6 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -6476,15 +6124,6 @@ "node": ">= 10.0.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/urlpattern-polyfill": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", @@ -6524,26 +6163,6 @@ "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", "dev": true }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/package.json b/package.json index 22cda37..6a602f0 100644 --- a/package.json +++ b/package.json @@ -30,12 +30,12 @@ }, "dependencies": { "@amxx/graphprotocol-utils": "^1.1.0", - "@openzeppelin/contracts": "^5.0.1" + "@openzeppelin/contracts": "^5.0.2" }, "devDependencies": { - "@graphprotocol/graph-cli": "^0.65.0", - "@graphprotocol/graph-ts": "^0.32.0", - "@openzeppelin/docs-utils": "^0.1.3", + "@graphprotocol/graph-cli": "^0.68.5", + "@graphprotocol/graph-ts": "^0.33.0", + "@openzeppelin/docs-utils": "^0.1.5", "jq.node": "^2.4.0" } } From 97cf1c58f78e8587c4ce9d81a61f7497787bdd70 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 5 Mar 2024 13:34:58 +0100 Subject: [PATCH 07/12] avoid revert if ERC4906 tokenId are bigger than u64 --- src/datasources/erc721.ts | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index 0ab25ef..75e2930 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -66,29 +66,29 @@ export function handleConsecutiveTransfer(event: ConsecutiveTransfer): void { let contract = fetchERC721(event.address) if (contract == null) return - let from = fetchAccount(event.params.fromAddress) - let to = fetchAccount(event.params.toAddress) - let fromTokenId = event.params.fromTokenId.toU64() - let toTokenId = event.params.toTokenId.toU64() - // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them - if (toTokenId - fromTokenId <= 5000) { - for (let tokenId = fromTokenId; tokenId <= toTokenId; ++tokenId) { - let token = fetchERC721Token(contract, BigInt.fromU64(tokenId)) - token.owner = to.id - token.approval = fetchAccount(Address.zero()).id // implicit approval reset on transfer - token.save() - - let ev = new ERC721Transfer(events.id(event).concat('-').concat(tokenId.toString())) - ev.emitter = contract.id - ev.transaction = transactions.log(event).id - ev.timestamp = event.block.timestamp - ev.contract = contract.id - ev.token = token.id - ev.from = from.id - ev.to = to.id - ev.save() - } + if (event.params.toTokenId.minus(event.params.fromTokenId) > BigInt.fromI32(5000)) return; + + let from = fetchAccount(event.params.fromAddress) + let to = fetchAccount(event.params.toAddress) + let count = event.params.toTokenId.minus(event.params.fromTokenId).toI32(); // This is <=5000 so won't revert + + for (let index = 0; index <= count; ++index) { + let tokenId = event.params.fromTokenId.plus(BigInt.fromI32(index)) + let token = fetchERC721Token(contract, tokenId) + token.owner = to.id + token.approval = fetchAccount(Address.zero()).id // implicit approval reset on transfer + token.save() + + let ev = new ERC721Transfer(events.id(event).concat('-').concat(tokenId.toString())) + ev.emitter = contract.id + ev.transaction = transactions.log(event).id + ev.timestamp = event.block.timestamp + ev.contract = contract.id + ev.token = token.id + ev.from = from.id + ev.to = to.id + ev.save() } } From 562bddb79067dcb8e4f652c91f2c2e11f8e5ffc3 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 5 Mar 2024 13:43:23 +0100 Subject: [PATCH 08/12] return really --- src/datasources/erc721.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index 75e2930..17f8d4b 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -63,12 +63,12 @@ export function handleTransfer(event: TransferEvent): void { } export function handleConsecutiveTransfer(event: ConsecutiveTransfer): void { - let contract = fetchERC721(event.address) - if (contract == null) return - // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them if (event.params.toTokenId.minus(event.params.fromTokenId) > BigInt.fromI32(5000)) return; + let contract = fetchERC721(event.address) + if (contract == null) return + let from = fetchAccount(event.params.fromAddress) let to = fetchAccount(event.params.toAddress) let count = event.params.toTokenId.minus(event.params.fromTokenId).toI32(); // This is <=5000 so won't revert From ffc91f4d2a99fa6e172ac34d1f9d3d00319c4cce Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 5 Mar 2024 13:45:42 +0100 Subject: [PATCH 09/12] update --- src/datasources/erc721.ts | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index 17f8d4b..32ba798 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -142,30 +142,22 @@ export function handleApprovalForAll(event: ApprovalForAllEvent): void { export function handleMetadataUpdate(event: MetadataUpdateEvent) : void { let contract = fetchERC721(event.address) - if (contract == null) return + if (contract == null || !contract.supportsMetadata) return - if (contract.supportsMetadata) { - _updateURI(contract, event.params._tokenId) - } else { - // add a warning ? - } + _updateURI(contract, event.params._tokenId) } export function handleBatchMetadataUpdate(event: BatchMetadataUpdateEvent) : void { let contract = fetchERC721(event.address) - if (contract == null) return + if (contract == null || !contract.supportsMetadata) return - if (contract.supportsMetadata) { - let fromTokenId = event.params._fromTokenId.toU64() - let toTokenId = event.params._toTokenId.toU64() - // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them - if (toTokenId - fromTokenId <= 5000) { - for (let tokenId = fromTokenId; tokenId <= toTokenId; ++tokenId) { - _updateURI(contract, BigInt.fromU64(tokenId)) - } + let fromTokenId = event.params._fromTokenId.toU64() + let toTokenId = event.params._toTokenId.toU64() + // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them + if (toTokenId - fromTokenId <= 5000) { + for (let tokenId = fromTokenId; tokenId <= toTokenId; ++tokenId) { + _updateURI(contract, BigInt.fromU64(tokenId)) } - } else { - // add a warning ? } } From 2b795138ceef1eea41f22f57a4e371ad0cb8390e Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 5 Mar 2024 13:50:06 +0100 Subject: [PATCH 10/12] batch size limit in metadata update --- src/datasources/erc721.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index 32ba798..9e8398f 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -64,14 +64,14 @@ export function handleTransfer(event: TransferEvent): void { export function handleConsecutiveTransfer(event: ConsecutiveTransfer): void { // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them - if (event.params.toTokenId.minus(event.params.fromTokenId) > BigInt.fromI32(5000)) return; + if (event.params.toTokenId.minus(event.params.fromTokenId) > BigInt.fromI32(5000)) return let contract = fetchERC721(event.address) if (contract == null) return let from = fetchAccount(event.params.fromAddress) let to = fetchAccount(event.params.toAddress) - let count = event.params.toTokenId.minus(event.params.fromTokenId).toI32(); // This is <=5000 so won't revert + let count = event.params.toTokenId.minus(event.params.fromTokenId).toI32() // This is <=5000 so won't revert for (let index = 0; index <= count; ++index) { let tokenId = event.params.fromTokenId.plus(BigInt.fromI32(index)) @@ -148,16 +148,16 @@ export function handleMetadataUpdate(event: MetadataUpdateEvent) : void { } export function handleBatchMetadataUpdate(event: BatchMetadataUpdateEvent) : void { + // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them + if (event.params._toTokenId.minus(event.params._fromTokenId) > BigInt.fromI32(5000)) return + let contract = fetchERC721(event.address) if (contract == null || !contract.supportsMetadata) return - let fromTokenId = event.params._fromTokenId.toU64() - let toTokenId = event.params._toTokenId.toU64() - // Updates of blocks larger than 5000 tokens may DoS the subgraph, we skip them - if (toTokenId - fromTokenId <= 5000) { - for (let tokenId = fromTokenId; tokenId <= toTokenId; ++tokenId) { - _updateURI(contract, BigInt.fromU64(tokenId)) - } + let count = event.params._toTokenId.minus(event.params._fromTokenId).toI32(); // This is <=5000 so won't revert + + for (let index = 0; index <= count; ++index) { + _updateURI(contract, event.params._fromTokenId.plus(BigInt.fromI32(index))) } } From 01c6220a45434b3441fe546bc5e80281d9aa7954 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 5 Mar 2024 13:56:35 +0100 Subject: [PATCH 11/12] refactor --- src/datasources/erc721.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/datasources/erc721.ts b/src/datasources/erc721.ts index 9e8398f..5705744 100644 --- a/src/datasources/erc721.ts +++ b/src/datasources/erc721.ts @@ -162,13 +162,12 @@ export function handleBatchMetadataUpdate(event: BatchMetadataUpdateEvent) : voi } function _updateURI(contract: ERC721Contract, tokenId: BigInt) : void { - let erc721 = IERC721.bind(Address.fromBytes(contract.id)) - let token = fetchERC721Token(contract, tokenId) - let try_tokenURI = erc721.try_tokenURI(tokenId) - token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value // If token was never minted (transfered) then the owner was set to 0 by default in `fetchERC721Token` // In that case we don't want to save to token to the database. - if (token.owner != Address.zero()) { - token.save() - } + let token = fetchERC721Token(contract, tokenId) + if (token.owner == Address.zero()) return + + let try_tokenURI = IERC721.bind(Address.fromBytes(contract.id)).try_tokenURI(tokenId) + token.uri = try_tokenURI.reverted ? '' : try_tokenURI.value + token.save() } From 6b43c1f51a106de1c0211c4b0027e9cab4bcc0d3 Mon Sep 17 00:00:00 2001 From: ernestognw Date: Thu, 7 Mar 2024 12:09:39 -0600 Subject: [PATCH 12/12] Format CHANGELOG --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81fa474..27be347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,11 @@ * Update dependency to @graphprotocol/graph-ts version 0.32.x * Update dependency to @openzeppelin/contracts version 5.0.1 * `Governor`: fix bug caused by duplicate write of immutable entity `ProposalSupport` ([#47](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/47)) - * `Governor`: rename `startBlock` to `voteStart` and `endBlock` to `voteEnd` ([#60](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/60)) * `ERC721`: add support for `ERC4906` events ([#60](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/60)) - * `ERC20`: remove approval tracking as it cannot be consistently tracked during `transferFrom` calls ([#59](https://github.com/OpenZeppelin/openzeppelin-subgraphs/ -Please note that this is a breaking release: some elements of the GraphQL API are renamed or removed. +#### Breaking Changes + * `Governor`: rename `startBlock` to `voteStart` and `endBlock` to `voteEnd` ([#60](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/60)) + * `ERC20`: remove approval tracking as it cannot be consistently tracked during `transferFrom` calls ([#59](https://github.com/OpenZeppelin/openzeppelin-subgraphs/)) ### 0.1.8-5 (2022-07-29) * `AccessControl`: fix bug caused by duplicate write of immutable entity `AccessControl` ([#38](https://github.com/OpenZeppelin/openzeppelin-subgraphs/pull/38))