ERC1155.test.js 8.7 KB

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