ERC1155.test.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. const { accounts, contract } = require('@openzeppelin/test-environment');
  2. const { BN, constants, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
  3. const { ZERO_ADDRESS } = constants;
  4. const { expect } = require('chai');
  5. const { shouldBehaveLikeERC1155 } = require('./ERC1155.behavior');
  6. const ERC1155Mock = contract.fromArtifact('ERC1155Mock');
  7. describe('ERC1155', function () {
  8. const [creator, tokenHolder, tokenBatchHolder, ...otherAccounts] = accounts;
  9. const initialURI = 'https://token-cdn-domain/{id}.json';
  10. beforeEach(async function () {
  11. this.token = await ERC1155Mock.new(initialURI, { from: creator });
  12. });
  13. shouldBehaveLikeERC1155(otherAccounts);
  14. describe('internal functions', function () {
  15. const tokenId = new BN(1990);
  16. const mintAmount = new BN(9001);
  17. const burnAmount = new BN(3000);
  18. const tokenBatchIds = [new BN(2000), new BN(2010), new BN(2020)];
  19. const mintAmounts = [new BN(5000), new BN(10000), new BN(42195)];
  20. const burnAmounts = [new BN(5000), new BN(9001), new BN(195)];
  21. const data = '0xcafebabe';
  22. describe('_mint(address, uint256, uint256, bytes memory)', function () {
  23. it('reverts with a null destination address', async function () {
  24. await expectRevert(
  25. this.token.mint(ZERO_ADDRESS, tokenId, mintAmount, data),
  26. 'ERC1155: mint to the zero address'
  27. );
  28. });
  29. context('with minted tokens', function () {
  30. beforeEach(async function () {
  31. ({ logs: this.logs } = await this.token.mint(
  32. tokenHolder,
  33. tokenId,
  34. mintAmount,
  35. data,
  36. { from: creator }
  37. ));
  38. });
  39. it('emits a TransferSingle event', function () {
  40. expectEvent.inLogs(this.logs, 'TransferSingle', {
  41. operator: creator,
  42. from: ZERO_ADDRESS,
  43. to: tokenHolder,
  44. id: tokenId,
  45. value: mintAmount,
  46. });
  47. });
  48. it('credits the minted amount of tokens', async function () {
  49. expect(await this.token.balanceOf(
  50. tokenHolder,
  51. tokenId
  52. )).to.be.bignumber.equal(mintAmount);
  53. });
  54. });
  55. });
  56. describe('_mintBatch(address, uint256[] memory, uint256[] memory, bytes memory)', function () {
  57. it('reverts with a null destination address', async function () {
  58. await expectRevert(
  59. this.token.mintBatch(ZERO_ADDRESS, tokenBatchIds, mintAmounts, data),
  60. 'ERC1155: batch mint to the zero address'
  61. );
  62. });
  63. it('reverts if length of inputs do not match', async function () {
  64. await expectRevert(
  65. this.token.mintBatch(tokenBatchHolder, tokenBatchIds, mintAmounts.slice(1), data),
  66. 'ERC1155: minted IDs and values must have same lengths'
  67. );
  68. });
  69. context('with minted batch of tokens', function () {
  70. beforeEach(async function () {
  71. ({ logs: this.logs } = await this.token.mintBatch(
  72. tokenBatchHolder,
  73. tokenBatchIds,
  74. mintAmounts,
  75. data,
  76. { from: creator }
  77. ));
  78. });
  79. it('emits a TransferBatch event', function () {
  80. expectEvent.inLogs(this.logs, 'TransferBatch', {
  81. operator: creator,
  82. from: ZERO_ADDRESS,
  83. to: tokenBatchHolder,
  84. // ids: tokenBatchIds,
  85. // values: mintAmounts,
  86. });
  87. });
  88. it('credits the minted batch of tokens', async function () {
  89. const holderBatchBalances = await this.token.balanceOfBatch(
  90. new Array(tokenBatchIds.length).fill(tokenBatchHolder),
  91. tokenBatchIds
  92. );
  93. for (let i = 0; i < holderBatchBalances.length; i++) {
  94. expect(holderBatchBalances[i]).to.be.bignumber.equal(mintAmounts[i]);
  95. }
  96. });
  97. });
  98. });
  99. describe('_burn(address, uint256, uint256)', function () {
  100. it('reverts when burning the zero account\'s tokens', async function () {
  101. await expectRevert(
  102. this.token.burn(ZERO_ADDRESS, tokenId, mintAmount),
  103. 'ERC1155: attempting to burn tokens on zero account'
  104. );
  105. });
  106. it('reverts when burning a non-existent token id', async function () {
  107. await expectRevert(
  108. this.token.burn(tokenHolder, tokenId, mintAmount),
  109. 'ERC1155: attempting to burn more than balance'
  110. );
  111. });
  112. context('with minted-then-burnt tokens', function () {
  113. beforeEach(async function () {
  114. await this.token.mint(tokenHolder, tokenId, mintAmount, data);
  115. ({ logs: this.logs } = await this.token.burn(
  116. tokenHolder,
  117. tokenId,
  118. burnAmount,
  119. { from: creator }
  120. ));
  121. });
  122. it('emits a TransferSingle event', function () {
  123. expectEvent.inLogs(this.logs, 'TransferSingle', {
  124. operator: creator,
  125. from: tokenHolder,
  126. to: ZERO_ADDRESS,
  127. id: tokenId,
  128. value: burnAmount,
  129. });
  130. });
  131. it('accounts for both minting and burning', async function () {
  132. expect(await this.token.balanceOf(
  133. tokenHolder,
  134. tokenId
  135. )).to.be.bignumber.equal(mintAmount.sub(burnAmount));
  136. });
  137. });
  138. });
  139. describe('_burnBatch(address, uint256[] memory, uint256[] memory)', function () {
  140. it('reverts when burning the zero account\'s tokens', async function () {
  141. await expectRevert(
  142. this.token.burnBatch(ZERO_ADDRESS, tokenBatchIds, burnAmounts),
  143. 'ERC1155: attempting to burn batch of tokens on zero account'
  144. );
  145. });
  146. it('reverts if length of inputs do not match', async function () {
  147. await expectRevert(
  148. this.token.burnBatch(tokenBatchHolder, tokenBatchIds, burnAmounts.slice(1)),
  149. 'ERC1155: burnt IDs and values must have same lengths'
  150. );
  151. });
  152. it('reverts when burning a non-existent token id', async function () {
  153. await expectRevert(
  154. this.token.burnBatch(tokenBatchHolder, tokenBatchIds, burnAmounts),
  155. 'ERC1155: attempting to burn more than balance for some token'
  156. );
  157. });
  158. context('with minted-then-burnt tokens', function () {
  159. beforeEach(async function () {
  160. await this.token.mintBatch(tokenBatchHolder, tokenBatchIds, mintAmounts, data);
  161. ({ logs: this.logs } = await this.token.burnBatch(
  162. tokenBatchHolder,
  163. tokenBatchIds,
  164. burnAmounts,
  165. { from: creator }
  166. ));
  167. });
  168. it('emits a TransferBatch event', function () {
  169. expectEvent.inLogs(this.logs, 'TransferBatch', {
  170. operator: creator,
  171. from: tokenBatchHolder,
  172. to: ZERO_ADDRESS,
  173. // ids: tokenBatchIds,
  174. // values: burnAmounts,
  175. });
  176. });
  177. it('accounts for both minting and burning', async function () {
  178. const holderBatchBalances = await this.token.balanceOfBatch(
  179. new Array(tokenBatchIds.length).fill(tokenBatchHolder),
  180. tokenBatchIds
  181. );
  182. for (let i = 0; i < holderBatchBalances.length; i++) {
  183. expect(holderBatchBalances[i]).to.be.bignumber.equal(mintAmounts[i].sub(burnAmounts[i]));
  184. }
  185. });
  186. });
  187. });
  188. });
  189. describe('ERC1155MetadataURI', function () {
  190. const firstTokenID = new BN('42');
  191. const secondTokenID = new BN('1337');
  192. it('emits no URI event in constructor', async function () {
  193. await expectEvent.notEmitted.inConstruction(this.token, 'URI');
  194. });
  195. it('sets the initial URI for all token types', async function () {
  196. expect(await this.token.uri(firstTokenID)).to.be.equal(initialURI);
  197. expect(await this.token.uri(secondTokenID)).to.be.equal(initialURI);
  198. });
  199. describe('_setURI', function () {
  200. const newURI = 'https://token-cdn-domain/{locale}/{id}.json';
  201. it('emits no URI event', async function () {
  202. const receipt = await this.token.setURI(newURI);
  203. expectEvent.notEmitted(receipt, 'URI');
  204. });
  205. it('sets the new URI for all token types', async function () {
  206. await this.token.setURI(newURI);
  207. expect(await this.token.uri(firstTokenID)).to.be.equal(newURI);
  208. expect(await this.token.uri(secondTokenID)).to.be.equal(newURI);
  209. });
  210. });
  211. });
  212. });