Skip to content

Commit

Permalink
Merge pull request #149 from kaleido-io/contracts
Browse files Browse the repository at this point in the history
Update to latest OpenZeppelin base contracts
  • Loading branch information
nguyer authored Mar 4, 2024
2 parents a428921 + cb34958 commit a90c44b
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 105 deletions.
2 changes: 1 addition & 1 deletion samples/solidity/contracts/ERC20NoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import '@openzeppelin/contracts/access/Ownable.sol';
* This is a sample only and NOT a reference implementation.
*/
contract ERC20NoData is Context, Ownable, ERC20, ERC20Burnable {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
constructor(string memory name, string memory symbol) ERC20(name, symbol) Ownable(msg.sender) {}

function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
Expand Down
2 changes: 1 addition & 1 deletion samples/solidity/contracts/ERC20WithData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import './IERC20WithData.sol';
* This is a sample only and NOT a reference implementation.
*/
contract ERC20WithData is Context, Ownable, ERC165, ERC20, IERC20WithData {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
constructor(string memory name, string memory symbol) ERC20(name, symbol) Ownable(msg.sender) {}

function supportsInterface(
bytes4 interfaceId
Expand Down
16 changes: 6 additions & 10 deletions samples/solidity/contracts/ERC721NoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol';
import '@openzeppelin/contracts/utils/Context.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/utils/Counters.sol';

/**
* Example ERC721 token with mint and burn.
Expand All @@ -19,18 +18,15 @@ import '@openzeppelin/contracts/utils/Counters.sol';
* This is a sample only and NOT a reference implementation.
*/
contract ERC721NoData is Context, Ownable, ERC721, ERC721Burnable {
using Counters for Counters.Counter;
uint256 private _nextTokenId = 1;

Counters.Counter private _tokenIdCounter;

constructor(string memory name, string memory symbol) ERC721(name, symbol) {
// Start counting at 1
_tokenIdCounter.increment();
}
constructor(
string memory name,
string memory symbol
) ERC721(name, symbol) Ownable(msg.sender) {}

function safeMint(address to) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
}

Expand Down
43 changes: 8 additions & 35 deletions samples/solidity/contracts/ERC721WithData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ pragma solidity ^0.8.0;
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/utils/Context.sol';
import '@openzeppelin/contracts/utils/Strings.sol';
import '@openzeppelin/contracts/utils/Counters.sol';
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol';
import './IERC721WithData.sol';

/**
Expand All @@ -24,36 +23,28 @@ import './IERC721WithData.sol';
*
* This is a sample only and NOT a reference implementation.
*/
contract ERC721WithData is Context, Ownable, ERC721, IERC721WithData {
using Counters for Counters.Counter;

Counters.Counter private _tokenIdCounter;
contract ERC721WithData is Context, Ownable, ERC721URIStorage, IERC721WithData {
uint256 private _nextTokenId = 1;
string private _baseTokenURI;

// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;

constructor(
string memory name,
string memory symbol,
string memory baseTokenURI
) ERC721(name, symbol) {
) ERC721(name, symbol) Ownable(msg.sender) {
_baseTokenURI = baseTokenURI;
// Start counting at 1
_tokenIdCounter.increment();
}

function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC721, IERC165) returns (bool) {
) public view virtual override(ERC721URIStorage, IERC165) returns (bool) {
return
interfaceId == type(IERC721WithData).interfaceId ||
super.supportsInterface(interfaceId);
}

function mintWithData(address to, bytes calldata data) public virtual onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId, data);
_setTokenURI(tokenId, string(abi.encodePacked(_baseURI(), Strings.toString(tokenId))));
}
Expand All @@ -63,8 +54,7 @@ contract ERC721WithData is Context, Ownable, ERC721, IERC721WithData {
bytes calldata data,
string memory tokenURI_
) public virtual onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId, data);

// If there is no tokenURI passed, concatenate the tokenID to the base URI
Expand Down Expand Up @@ -103,24 +93,7 @@ contract ERC721WithData is Context, Ownable, ERC721, IERC721WithData {
}

function _baseURI() internal view virtual override returns (string memory) {
bytes memory tempURITest = bytes(_baseTokenURI);
if (tempURITest.length == 0) {
return 'firefly://token/';
} else {
return _baseTokenURI;
}
}

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), 'ERC721WithData: Token does not exist');

string memory uri = _tokenURIs[tokenId];
return uri;
}

function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
require(_exists(tokenId), 'ERC721WithData: Token does not exist');
_tokenURIs[tokenId] = _tokenURI;
return _baseTokenURI;
}

function baseTokenUri() public view virtual override returns (string memory) {
Expand Down
8 changes: 4 additions & 4 deletions samples/solidity/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion samples/solidity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
"typescript": "^5.3.3"
},
"dependencies": {
"@openzeppelin/contracts": "^4.7.3"
"@openzeppelin/contracts": "^5.0.2"
}
}
14 changes: 7 additions & 7 deletions samples/solidity/test/ERC20NoData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers';
import { expect } from "chai";
import { ethers } from "hardhat";
import { expect } from 'chai';
import { ethers } from 'hardhat';
import { ERC20NoData } from '../typechain-types';

describe('ERC20NoData - Unit Tests', async function () {
Expand Down Expand Up @@ -43,9 +43,9 @@ describe('ERC20NoData - Unit Tests', async function () {
it('Mint - Non-deployer of contract should not be able to mint tokens', async function () {
expect(await deployedERC20NoData.balanceOf(signerB.address)).to.equal(0);
// Signer B mint to Signer B (Not allowed)
await expect(deployedERC20NoData.connect(signerB).mint(signerB.address, 20)).to.be.revertedWith(
'Ownable: caller is not the owner',
);
await expect(
deployedERC20NoData.connect(signerB).mint(signerB.address, 20),
).to.be.revertedWithCustomError(deployedERC20NoData, 'OwnableUnauthorizedAccount');

expect(await deployedERC20NoData.balanceOf(signerB.address)).to.equal(0);
});
Expand Down Expand Up @@ -162,11 +162,11 @@ describe('ERC20NoData - Unit Tests', async function () {
// Signer B attempts to burn tokens from Signer A wallet (not allowed)
await expect(
deployedERC20NoData.connect(signerB).burnFrom(deployerSignerA.address, 10),
).to.be.revertedWith('ERC20: insufficient allowance');
).to.be.revertedWithCustomError(deployedERC20NoData, 'ERC20InsufficientAllowance');
// Signer A attempts to burn tokens from Signer B wallet (not allowed)
await expect(
deployedERC20NoData.connect(deployerSignerA).burnFrom(signerB.address, 10),
).to.be.revertedWith('ERC20: insufficient allowance');
).to.be.revertedWithCustomError(deployedERC20NoData, 'ERC20InsufficientAllowance');

expect(await deployedERC20NoData.balanceOf(deployerSignerA.address)).to.equal(20);
expect(await deployedERC20NoData.balanceOf(signerB.address)).to.equal(20);
Expand Down
6 changes: 3 additions & 3 deletions samples/solidity/test/ERC20WithData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('ERC20WithData - Unit Tests', async function () {
// Signer B mint to Signer B (Not allowed)
await expect(
deployedERC20WithData.connect(signerB).mintWithData(signerB.address, 20, '0x00'),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(deployedERC20WithData, 'OwnableUnauthorizedAccount');

expect(await deployedERC20WithData.balanceOf(signerB.address)).to.equal(0);
});
Expand All @@ -57,7 +57,7 @@ describe('ERC20WithData - Unit Tests', async function () {
// Signer B mint to Signer B (Not allowed)
await expect(
deployedERC20WithData.connect(signerB).mintWithData(signerB.address, 20, '0x00'),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(deployedERC20WithData, 'OwnableUnauthorizedAccount');

expect(await deployedERC20WithData.balanceOf(signerB.address)).to.equal(0);
});
Expand Down Expand Up @@ -142,7 +142,7 @@ describe('ERC20WithData - Unit Tests', async function () {
deployedERC20WithData
.connect(deployerSignerA)
.transferWithData(signerB.address, signerC.address, 11, '0x00'),
).to.be.revertedWith('ERC20: insufficient allowance');
).to.be.revertedWithCustomError(deployedERC20WithData, 'ERC20InsufficientAllowance');

expect(await deployedERC20WithData.balanceOf(deployerSignerA.address)).to.equal(0);
expect(await deployedERC20WithData.balanceOf(signerB.address)).to.equal(20);
Expand Down
16 changes: 9 additions & 7 deletions samples/solidity/test/ERC721NoData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('ERC721NoData - Unit Tests', async function () {
// Signer B mint to Signer B (Not allowed)
await expect(
deployedERC721NoData.connect(signerB).safeMint(signerB.address),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(deployedERC721NoData, 'OwnableUnauthorizedAccount');

expect(await deployedERC721NoData.balanceOf(signerB.address)).to.equal(0);
});
Expand All @@ -56,7 +56,7 @@ describe('ERC721NoData - Unit Tests', async function () {
// Signer B mint token to Signer B (Not allowed)
await expect(
deployedERC721NoData.connect(signerB).safeMint(signerB.address),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(deployedERC721NoData, 'OwnableUnauthorizedAccount');

expect(await deployedERC721NoData.balanceOf(signerB.address)).to.equal(0);
});
Expand Down Expand Up @@ -136,7 +136,7 @@ describe('ERC721NoData - Unit Tests', async function () {
deployedERC721NoData
.connect(deployerSignerA)
['safeTransferFrom(address,address,uint256)'](signerB.address, signerC.address, 1),
).to.be.revertedWith('ERC721: caller is not token owner or approved');
).to.be.revertedWithCustomError(deployedERC721NoData, 'ERC721InsufficientApproval');

expect(await deployedERC721NoData.balanceOf(deployerSignerA.address)).to.equal(0);
expect(await deployedERC721NoData.balanceOf(signerB.address)).to.equal(2);
Expand Down Expand Up @@ -213,12 +213,14 @@ describe('ERC721NoData - Unit Tests', async function () {
.to.emit(deployedERC721NoData, 'Transfer')
.withArgs(ZERO_ADDRESS, signerC.address, 3);
// Signer B attempts to burn token from Signer A wallet (not allowed)
await expect(deployedERC721NoData.connect(signerB).burn(1)).to.be.revertedWith(
'ERC721: caller is not token owner or approved',
await expect(deployedERC721NoData.connect(signerB).burn(1)).to.be.revertedWithCustomError(
deployedERC721NoData,
'ERC721InsufficientApproval',
);
// Signer C attempts to burn token from Signer B wallet (not allowed)
await expect(deployedERC721NoData.connect(signerC).burn(2)).to.be.revertedWith(
'ERC721: caller is not token owner or approved',
await expect(deployedERC721NoData.connect(signerC).burn(2)).to.be.revertedWithCustomError(
deployedERC721NoData,
'ERC721InsufficientApproval',
);

expect(await deployedERC721NoData.balanceOf(deployerSignerA.address)).to.equal(1);
Expand Down
39 changes: 3 additions & 36 deletions samples/solidity/test/ERC721WithData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('ERC721WithData - Unit Tests', async function () {
it('Create - Should create a new ERC721 instance with default state', async function () {
expect(await deployedERC721WithData.name()).to.equal(contractName);
expect(await deployedERC721WithData.symbol()).to.equal(contractSymbol);
expect(await deployedERC721WithData.baseTokenUri()).to.equal('firefly://token/');
expect(await deployedERC721WithData.baseTokenUri()).to.equal('');
});

it('Mint - Should mint successfully with a custom URI', async function () {
Expand All @@ -58,7 +58,7 @@ describe('ERC721WithData - Unit Tests', async function () {
// Signer B mint token to Signer B (Not allowed)
await expect(
deployedERC721WithData.connect(signerB).mintWithData(signerB.address, '0x00'),
).to.be.revertedWith('Ownable: caller is not the owner');
).to.be.revertedWithCustomError(deployedERC721WithData, 'OwnableUnauthorizedAccount');

expect(await deployedERC721WithData.balanceOf(signerB.address)).to.equal(0);
});
Expand All @@ -73,7 +73,6 @@ describe('ERC721WithData - Unit Tests', async function () {
.to.emit(deployedERC721WithData, 'Transfer')
.withArgs(ZERO_ADDRESS, deployerSignerA.address, 1);
expect(await deployedERC721WithData.balanceOf(deployerSignerA.address)).to.equal(1);
expect(await deployedERC721WithData.tokenURI(1)).to.equal('firefly://token/1');
// Signer A transfer token to Signer B
await expect(
deployedERC721WithData
Expand Down Expand Up @@ -137,7 +136,7 @@ describe('ERC721WithData - Unit Tests', async function () {
deployedERC721WithData
.connect(deployerSignerA)
.transferWithData(signerB.address, signerC.address, 1, '0x00'),
).to.be.revertedWith('ERC721: caller is not token owner or approved');
).to.be.revertedWithCustomError(deployedERC721WithData, 'ERC721InsufficientApproval');

expect(await deployedERC721WithData.balanceOf(deployerSignerA.address)).to.equal(0);
expect(await deployedERC721WithData.balanceOf(signerB.address)).to.equal(2);
Expand Down Expand Up @@ -248,36 +247,4 @@ describe('ERC721WithData - Unit Tests', async function () {
expect(await deployedERC721WithData.balanceOf(signerB.address)).to.equal(1);
expect(await deployedERC721WithData.balanceOf(signerC.address)).to.equal(1);
});

it("URI - Minted token URIs should be 'firefly://token/<tokenId>'", async function () {
expect(await deployedERC721WithData.balanceOf(deployerSignerA.address)).to.equal(0);
expect(await deployedERC721WithData.balanceOf(signerB.address)).to.equal(0);
expect(await deployedERC721WithData.balanceOf(signerC.address)).to.equal(0);
// Signer A mints token to itself
await expect(
deployedERC721WithData.connect(deployerSignerA).mintWithData(deployerSignerA.address, '0x00'),
)
.to.emit(deployedERC721WithData, 'Transfer')
.withArgs(ZERO_ADDRESS, deployerSignerA.address, 1);
// Signer A mints token to Signer B
await expect(
deployedERC721WithData.connect(deployerSignerA).mintWithData(signerB.address, '0x00'),
)
.to.emit(deployedERC721WithData, 'Transfer')
.withArgs(ZERO_ADDRESS, signerB.address, 2);
// Signer A mints token to Signer C
await expect(
deployedERC721WithData.connect(deployerSignerA).mintWithData(signerC.address, '0x00'),
)
.to.emit(deployedERC721WithData, 'Transfer')
.withArgs(ZERO_ADDRESS, signerC.address, 3);

expect(await deployedERC721WithData.tokenURI(1)).to.equal('firefly://token/1');
expect(await deployedERC721WithData.tokenURI(2)).to.equal('firefly://token/2');
expect(await deployedERC721WithData.tokenURI(3)).to.equal('firefly://token/3');

expect(await deployedERC721WithData.balanceOf(deployerSignerA.address)).to.equal(1);
expect(await deployedERC721WithData.balanceOf(signerB.address)).to.equal(1);
expect(await deployedERC721WithData.balanceOf(signerC.address)).to.equal(1);
});
});

0 comments on commit a90c44b

Please sign in to comment.