-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: example usage in nft testing of our foundry library and hardhat plugin (#191) #209
Open
arianejasuwienas
wants to merge
10
commits into
main
Choose a base branch
from
191-nft-examples-hardhat-foundry
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 9 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
01edc2b
feat: nft - sample usage of hedera hts forking in hardhat and foundry…
arianejasuwienas cf9da25
fix: foundry warning (#191)
arianejasuwienas 63028de
fix: foundry warning (#191)
arianejasuwienas 531d7bd
fix: using barkaneer as a sample token for tests, adding fix for the …
arianejasuwienas be1201d
fix: typo in the nft name (#191)
arianejasuwienas a3aa7d2
fix: hardhat royalty fees fixed (#191)
arianejasuwienas ffe7144
fix: hardhat royalty fees fixed (#191)
arianejasuwienas 768913d
fix: applying mr suggestions comparing to equals rather than not equa…
arianejasuwienas 7c592e7
chore: downloading hardhat plugin directly from npm (#191)
arianejasuwienas 55f3b98
feat: resolving the package for example from the github until npm ver…
arianejasuwienas File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import {Test} from "forge-std/Test.sol"; | ||
import {htsSetup} from "hedera-forking/contracts/htsSetup.sol"; | ||
import {IERC721} from "hedera-forking/contracts/IERC721.sol"; | ||
|
||
contract NFTExampleTest is Test { | ||
// https://hashscan.io/mainnet/token/0.0.5083205 | ||
address NFT_mainnet = 0x00000000000000000000000000000000004d9045; | ||
|
||
address private user; | ||
|
||
function setUp() external { | ||
htsSetup(); | ||
|
||
user = makeAddr("user"); | ||
dealERC721(NFT_mainnet, user, 3); | ||
} | ||
|
||
function test_get_owner_of_existing_account() view external { | ||
address owner = IERC721(NFT_mainnet).ownerOf(1); | ||
assertNotEq(IERC721(NFT_mainnet).ownerOf(1), address(0)); | ||
|
||
// The assertion below cannot be guaranteed, since we can only query the current owner of the NFT, | ||
// Note that the ownership of the NFT may change over time. | ||
assertEq(owner, 0x000000000000000000000000000000000006889a); | ||
} | ||
|
||
function test_dealt_nft_assigned_to_local_account() view external { | ||
assertEq(IERC721(NFT_mainnet).ownerOf(3), user); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import {Test, console} from "forge-std/Test.sol"; | ||
import {htsSetup} from "hedera-forking/contracts/htsSetup.sol"; | ||
import {IERC721} from "hedera-forking/contracts/IERC721.sol"; | ||
|
||
contract NFTConsoleExampleTest is Test { | ||
function setUp() external { | ||
htsSetup(); | ||
} | ||
|
||
function test_using_console_log() view external { | ||
// https://hashscan.io/mainnet/token/0.0.5083205 | ||
address NFT_mainnet = 0x00000000000000000000000000000000004d9045; | ||
|
||
string memory name = IERC721(NFT_mainnet).name(); | ||
string memory symbol = IERC721(NFT_mainnet).symbol(); | ||
string memory tokenURI = IERC721(NFT_mainnet).tokenURI(1); | ||
assertEq(name, "THE BARKANEERS"); | ||
assertEq(symbol, "BARKANEERS"); | ||
assertEq(tokenURI, "ipfs://bafkreif4hpsgflzzvd7c4abx5u5xwrrjl7wkimbjtndvkxodklxdam5upm"); | ||
console.log("name: %s, symbol: %s, tokenURI: %s", name, symbol, tokenURI); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import {IERC721} from "./IERC721.sol"; | ||
import {console} from "hardhat/console.sol"; | ||
|
||
contract CallNFT { | ||
function getTokenName(address tokenAddress) external view returns (string memory) { | ||
return IERC721(tokenAddress).name(); | ||
} | ||
|
||
function invokeTransferFrom(address tokenAddress, address to, uint256 serialId) external { | ||
// You can use `console.log` as usual | ||
// https://hardhat.org/tutorial/debugging-with-hardhat-network#solidity--console.log | ||
console.log("Transferring from %s to %s %s tokens", msg.sender, to, serialId); | ||
address owner = IERC721(tokenAddress).ownerOf(serialId); | ||
IERC721(tokenAddress).transferFrom(owner, to, serialId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
/** | ||
* See https://ethereum.org/en/developers/docs/standards/tokens/erc-721/#events for more information. | ||
*/ | ||
interface IERC721Events { | ||
event ApprovalForAll(address indexed owner, address indexed operator, bool approved); | ||
} | ||
|
||
/** | ||
* This interface is used to get the selectors and for testing. | ||
* | ||
* https://hips.hedera.com/hip/hip-218 | ||
* https://hips.hedera.com/hip/hip-376 | ||
*/ | ||
interface IERC721 { | ||
/** | ||
* @dev Returns the token collection name. | ||
*/ | ||
function name() external view returns (string memory); | ||
|
||
/** | ||
* @dev Returns the token collection symbol. | ||
*/ | ||
function symbol() external view returns (string memory); | ||
|
||
/** | ||
* @dev Returns the Uniform Resource Identifier (URI) for `serialId` token. | ||
*/ | ||
function tokenURI(uint256 serialId) external view returns (string memory); | ||
|
||
/** | ||
* @dev Returns the total amount of tokens stored by the contract. | ||
*/ | ||
function totalSupply() external view returns (uint256); | ||
|
||
/** | ||
* @dev Returns the number of tokens in `owner`'s account. | ||
*/ | ||
function balanceOf(address owner) external view returns (uint256 balance); | ||
|
||
/** | ||
* @dev Returns the owner of the `serialId` token. | ||
* | ||
* Requirements: | ||
* - `serialId` must exist. | ||
*/ | ||
function ownerOf(uint256 serialId) external view returns (address); | ||
|
||
/** | ||
* @dev Transfers `serialId` token from `sender` to `recipient`. | ||
* | ||
* Requirements: | ||
* - `sender` cannot be the zero address. | ||
* - `recipient` cannot be the zero address. | ||
* - `serialId` token must be owned by `sender`. | ||
* - If the caller is not `sender`, it must be approved to move this token by either {approve} or {setApprovalForAll}. | ||
* | ||
* Emits a {Transfer} event. | ||
*/ | ||
function transferFrom(address sender, address recipient, uint256 serialId) external payable; | ||
|
||
/** | ||
* @dev Gives permission to `spender` to transfer `serialId` token to another account. | ||
* The approval is cleared when the token is transferred. | ||
* | ||
* Only a single account can be approved at a time, so approving the zero address clears previous approvals. | ||
* | ||
* Requirements: | ||
* - The caller must own the token or be an approved operator. | ||
* - `serialId` must exist. | ||
* | ||
* Emits an {Approval} event. | ||
*/ | ||
function approve(address spender, uint256 serialId) external payable; | ||
|
||
/** | ||
* @dev Approve or remove `operator` as an operator for the caller. | ||
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. | ||
* | ||
* Requirements: | ||
* - The `operator` cannot be the address zero. | ||
* | ||
* Emits an {ApprovalForAll} event. | ||
*/ | ||
function setApprovalForAll(address operator, bool approved) external; | ||
|
||
/** | ||
* @dev Returns the account approved for `serialId` token. | ||
* | ||
* Requirements: | ||
* - `serialId` must exist. | ||
*/ | ||
function getApproved(uint256 serialId) external view returns (address operator); | ||
|
||
/** | ||
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. | ||
* | ||
* See {setApprovalForAll} | ||
*/ | ||
function isApprovedForAll(address owner, address operator) external view returns (bool); | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ | |
"author": "2024 Hedera Hashgraph, LLC", | ||
"license": "Apache-2.0", | ||
"devDependencies": { | ||
"@hashgraph/system-contracts-forking": "hashgraph/hedera-forking", | ||
"@hashgraph/system-contracts-forking": "^0.1.1", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as mentioned offline, given some fixes are part of this PR, for now we can continue using the package here from GitHub directly. |
||
"@nomicfoundation/hardhat-toolbox": "^5.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/*- | ||
* Hedera Hardhat Forking Plugin | ||
* | ||
* Copyright (C) 2024 Hedera Hashgraph, LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
const { expect } = require('chai'); | ||
// prettier-ignore | ||
const { ethers: { getContractAt } } = require('hardhat'); | ||
|
||
describe('NFT example -- informational', function () { | ||
it('should get name and symbol', async function () { | ||
// https://hashscan.io/mainnet/token/0.0.4970613 | ||
const nft = await getContractAt('IERC721', '0x00000000000000000000000000000000004bd875'); | ||
expect(await nft['name']()).to.be.equal('Concierge Collectibles'); | ||
expect(await nft['symbol']()).to.be.equal('Concierge Collectibles'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/*- | ||
* Hedera Hardhat Forking Plugin | ||
* | ||
* Copyright (C) 2024 Hedera Hashgraph, LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
const { expect } = require('chai'); | ||
// prettier-ignore | ||
const { ethers: { getContractAt } } = require('hardhat'); | ||
|
||
describe('NFT example -- ownerOf', function () { | ||
it('should get `ownerOf` account holder', async function () { | ||
// https://hashscan.io/mainnet/token/0.0.4970613 | ||
const nft = await getContractAt('IERC721', '0x00000000000000000000000000000000004bd875'); | ||
|
||
// The assertion below cannot be guaranteed, since we can only query the current owner of the NFT, | ||
// Note that the ownership of the NFT may change over time. | ||
expect(await nft['ownerOf'](1)).to.be.equal('0x0000000000000000000000000000000000161927'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/*- | ||
* Hedera Hardhat Forking Plugin | ||
* | ||
* Copyright (C) 2024 Hedera Hashgraph, LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
const { expect } = require('chai'); | ||
// prettier-ignore | ||
const { ethers: { getSigner, getSigners, getContractAt }, network: { provider } } = require('hardhat'); | ||
const { loadFixture } = require('@nomicfoundation/hardhat-toolbox/network-helpers'); | ||
|
||
describe('NFT example -- transferFrom', function () { | ||
async function id() { | ||
return [(await getSigners())[0]]; | ||
} | ||
|
||
it("should `transferFrom` tokens from account holder to one of Hardhat' signers", async function () { | ||
const [receiver] = await loadFixture(id); | ||
|
||
// https://hashscan.io/mainnet/token/0.0.4970613 | ||
const nft = await getContractAt('IERC721', '0x00000000000000000000000000000000004bd875'); | ||
|
||
const holderAddress = await nft['ownerOf'](1n); | ||
|
||
await provider.request({ | ||
method: 'hardhat_impersonateAccount', | ||
params: [holderAddress], | ||
}); | ||
|
||
const holder = await getSigner(holderAddress); | ||
await nft.connect(holder)['transferFrom'](holder, receiver, 1n); | ||
|
||
expect(await nft['ownerOf'](1n)).to.be.equal(receiver.address); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fallback_fee is nullable in the json response from the mirror node, but abi decode requires it to be set in order to create proper structure. That is why I set the default value here when it is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, but also there is a
vm.parseJson(json, ".custom_fees.royalty_fees")
that guards againstnull
, right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@acuarica Only when royalty_fees is null. For the barkaneer I had fallback_fee = null (substructure in the royalty fees object).