ERC1155.behavior.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. const { 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 { shouldSupportInterfaces } = require('../../introspection/SupportsInterface.behavior');
  6. const ERC1155ReceiverMock = contract.fromArtifact('ERC1155ReceiverMock');
  7. function shouldBehaveLikeERC1155 ([minter, firstTokenHolder, secondTokenHolder, multiTokenHolder, recipient, proxy]) {
  8. const firstTokenId = new BN(1);
  9. const secondTokenId = new BN(2);
  10. const unknownTokenId = new BN(3);
  11. const firstAmount = new BN(1000);
  12. const secondAmount = new BN(2000);
  13. const RECEIVER_SINGLE_MAGIC_VALUE = '0xf23a6e61';
  14. const RECEIVER_BATCH_MAGIC_VALUE = '0xbc197c81';
  15. describe('like an ERC1155', function () {
  16. describe('balanceOf', function () {
  17. it('reverts when queried about the zero address', async function () {
  18. await expectRevert(
  19. this.token.balanceOf(ZERO_ADDRESS, firstTokenId),
  20. 'ERC1155: balance query for the zero address'
  21. );
  22. });
  23. context('when accounts don\'t own tokens', function () {
  24. it('returns zero for given addresses', async function () {
  25. expect(await this.token.balanceOf(
  26. firstTokenHolder,
  27. firstTokenId
  28. )).to.be.bignumber.equal('0');
  29. expect(await this.token.balanceOf(
  30. secondTokenHolder,
  31. secondTokenId
  32. )).to.be.bignumber.equal('0');
  33. expect(await this.token.balanceOf(
  34. firstTokenHolder,
  35. unknownTokenId
  36. )).to.be.bignumber.equal('0');
  37. });
  38. });
  39. context('when accounts own some tokens', function () {
  40. beforeEach(async function () {
  41. await this.token.mint(firstTokenHolder, firstTokenId, firstAmount, '0x', {
  42. from: minter,
  43. });
  44. await this.token.mint(
  45. secondTokenHolder,
  46. secondTokenId,
  47. secondAmount,
  48. '0x',
  49. {
  50. from: minter,
  51. }
  52. );
  53. });
  54. it('returns the amount of tokens owned by the given addresses', async function () {
  55. expect(await this.token.balanceOf(
  56. firstTokenHolder,
  57. firstTokenId
  58. )).to.be.bignumber.equal(firstAmount);
  59. expect(await this.token.balanceOf(
  60. secondTokenHolder,
  61. secondTokenId
  62. )).to.be.bignumber.equal(secondAmount);
  63. expect(await this.token.balanceOf(
  64. firstTokenHolder,
  65. unknownTokenId
  66. )).to.be.bignumber.equal('0');
  67. });
  68. });
  69. });
  70. describe('balanceOfBatch', function () {
  71. it('reverts when input arrays don\'t match up', async function () {
  72. await expectRevert(
  73. this.token.balanceOfBatch(
  74. [firstTokenHolder, secondTokenHolder, firstTokenHolder, secondTokenHolder],
  75. [firstTokenId, secondTokenId, unknownTokenId]
  76. ),
  77. 'ERC1155: accounts and ids length mismatch'
  78. );
  79. });
  80. it('reverts when one of the addresses is the zero address', async function () {
  81. await expectRevert(
  82. this.token.balanceOfBatch(
  83. [firstTokenHolder, secondTokenHolder, ZERO_ADDRESS],
  84. [firstTokenId, secondTokenId, unknownTokenId]
  85. ),
  86. 'ERC1155: batch balance query for the zero address'
  87. );
  88. });
  89. context('when accounts don\'t own tokens', function () {
  90. it('returns zeros for each account', async function () {
  91. const result = await this.token.balanceOfBatch(
  92. [firstTokenHolder, secondTokenHolder, firstTokenHolder],
  93. [firstTokenId, secondTokenId, unknownTokenId]
  94. );
  95. expect(result).to.be.an('array');
  96. expect(result[0]).to.be.a.bignumber.equal('0');
  97. expect(result[1]).to.be.a.bignumber.equal('0');
  98. expect(result[2]).to.be.a.bignumber.equal('0');
  99. });
  100. });
  101. context('when accounts own some tokens', function () {
  102. beforeEach(async function () {
  103. await this.token.mint(firstTokenHolder, firstTokenId, firstAmount, '0x', {
  104. from: minter,
  105. });
  106. await this.token.mint(
  107. secondTokenHolder,
  108. secondTokenId,
  109. secondAmount,
  110. '0x',
  111. {
  112. from: minter,
  113. }
  114. );
  115. });
  116. it('returns amounts owned by each account in order passed', async function () {
  117. const result = await this.token.balanceOfBatch(
  118. [secondTokenHolder, firstTokenHolder, firstTokenHolder],
  119. [secondTokenId, firstTokenId, unknownTokenId]
  120. );
  121. expect(result).to.be.an('array');
  122. expect(result[0]).to.be.a.bignumber.equal(secondAmount);
  123. expect(result[1]).to.be.a.bignumber.equal(firstAmount);
  124. expect(result[2]).to.be.a.bignumber.equal('0');
  125. });
  126. });
  127. });
  128. describe('setApprovalForAll', function () {
  129. let logs;
  130. beforeEach(async function () {
  131. ({ logs } = await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder }));
  132. });
  133. it('sets approval status which can be queried via isApprovedForAll', async function () {
  134. expect(await this.token.isApprovedForAll(multiTokenHolder, proxy)).to.be.equal(true);
  135. });
  136. it('emits an ApprovalForAll log', function () {
  137. expectEvent.inLogs(logs, 'ApprovalForAll', { account: multiTokenHolder, operator: proxy, approved: true });
  138. });
  139. it('can unset approval for an operator', async function () {
  140. await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder });
  141. expect(await this.token.isApprovedForAll(multiTokenHolder, proxy)).to.be.equal(false);
  142. });
  143. it('reverts if attempting to approve self as an operator', async function () {
  144. await expectRevert(
  145. this.token.setApprovalForAll(multiTokenHolder, true, { from: multiTokenHolder }),
  146. 'ERC1155: setting approval status for self'
  147. );
  148. });
  149. });
  150. describe('safeTransferFrom', function () {
  151. beforeEach(async function () {
  152. await this.token.mint(multiTokenHolder, firstTokenId, firstAmount, '0x', {
  153. from: minter,
  154. });
  155. await this.token.mint(
  156. multiTokenHolder,
  157. secondTokenId,
  158. secondAmount,
  159. '0x',
  160. {
  161. from: minter,
  162. }
  163. );
  164. });
  165. it('reverts when transferring more than balance', async function () {
  166. await expectRevert(
  167. this.token.safeTransferFrom(
  168. multiTokenHolder,
  169. recipient,
  170. firstTokenId,
  171. firstAmount.addn(1),
  172. '0x',
  173. { from: multiTokenHolder },
  174. ),
  175. 'ERC1155: insufficient balance for transfer'
  176. );
  177. });
  178. it('reverts when transferring to zero address', async function () {
  179. await expectRevert(
  180. this.token.safeTransferFrom(
  181. multiTokenHolder,
  182. ZERO_ADDRESS,
  183. firstTokenId,
  184. firstAmount,
  185. '0x',
  186. { from: multiTokenHolder },
  187. ),
  188. 'ERC1155: transfer to the zero address'
  189. );
  190. });
  191. function transferWasSuccessful ({ operator, from, id, value }) {
  192. it('debits transferred balance from sender', async function () {
  193. const newBalance = await this.token.balanceOf(from, id);
  194. expect(newBalance).to.be.a.bignumber.equal('0');
  195. });
  196. it('credits transferred balance to receiver', async function () {
  197. const newBalance = await this.token.balanceOf(this.toWhom, id);
  198. expect(newBalance).to.be.a.bignumber.equal(value);
  199. });
  200. it('emits a TransferSingle log', function () {
  201. expectEvent.inLogs(this.transferLogs, 'TransferSingle', {
  202. operator,
  203. from,
  204. to: this.toWhom,
  205. id,
  206. value,
  207. });
  208. });
  209. }
  210. context('when called by the multiTokenHolder', async function () {
  211. beforeEach(async function () {
  212. this.toWhom = recipient;
  213. ({ logs: this.transferLogs } =
  214. await this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', {
  215. from: multiTokenHolder,
  216. }));
  217. });
  218. transferWasSuccessful.call(this, {
  219. operator: multiTokenHolder,
  220. from: multiTokenHolder,
  221. id: firstTokenId,
  222. value: firstAmount,
  223. });
  224. it('preserves existing balances which are not transferred by multiTokenHolder', async function () {
  225. const balance1 = await this.token.balanceOf(multiTokenHolder, secondTokenId);
  226. expect(balance1).to.be.a.bignumber.equal(secondAmount);
  227. const balance2 = await this.token.balanceOf(recipient, secondTokenId);
  228. expect(balance2).to.be.a.bignumber.equal('0');
  229. });
  230. });
  231. context('when called by an operator on behalf of the multiTokenHolder', function () {
  232. context('when operator is not approved by multiTokenHolder', function () {
  233. beforeEach(async function () {
  234. await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder });
  235. });
  236. it('reverts', async function () {
  237. await expectRevert(
  238. this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', {
  239. from: proxy,
  240. }),
  241. 'ERC1155: caller is not owner nor approved'
  242. );
  243. });
  244. });
  245. context('when operator is approved by multiTokenHolder', function () {
  246. beforeEach(async function () {
  247. this.toWhom = recipient;
  248. await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder });
  249. ({ logs: this.transferLogs } =
  250. await this.token.safeTransferFrom(multiTokenHolder, recipient, firstTokenId, firstAmount, '0x', {
  251. from: proxy,
  252. }));
  253. });
  254. transferWasSuccessful.call(this, {
  255. operator: proxy,
  256. from: multiTokenHolder,
  257. id: firstTokenId,
  258. value: firstAmount,
  259. });
  260. it('preserves operator\'s balances not involved in the transfer', async function () {
  261. const balance = await this.token.balanceOf(proxy, firstTokenId);
  262. expect(balance).to.be.a.bignumber.equal('0');
  263. });
  264. });
  265. });
  266. context('when sending to a valid receiver', function () {
  267. beforeEach(async function () {
  268. this.receiver = await ERC1155ReceiverMock.new(
  269. RECEIVER_SINGLE_MAGIC_VALUE, false,
  270. RECEIVER_BATCH_MAGIC_VALUE, false,
  271. );
  272. });
  273. context('without data', function () {
  274. beforeEach(async function () {
  275. this.toWhom = this.receiver.address;
  276. this.transferReceipt = await this.token.safeTransferFrom(
  277. multiTokenHolder,
  278. this.receiver.address,
  279. firstTokenId,
  280. firstAmount,
  281. '0x',
  282. { from: multiTokenHolder }
  283. );
  284. ({ logs: this.transferLogs } = this.transferReceipt);
  285. });
  286. transferWasSuccessful.call(this, {
  287. operator: multiTokenHolder,
  288. from: multiTokenHolder,
  289. id: firstTokenId,
  290. value: firstAmount,
  291. });
  292. it('should call onERC1155Received', async function () {
  293. await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'Received', {
  294. operator: multiTokenHolder,
  295. from: multiTokenHolder,
  296. id: firstTokenId,
  297. value: firstAmount,
  298. data: null,
  299. });
  300. });
  301. });
  302. context('with data', function () {
  303. const data = '0xf00dd00d';
  304. beforeEach(async function () {
  305. this.toWhom = this.receiver.address;
  306. this.transferReceipt = await this.token.safeTransferFrom(
  307. multiTokenHolder,
  308. this.receiver.address,
  309. firstTokenId,
  310. firstAmount,
  311. data,
  312. { from: multiTokenHolder }
  313. );
  314. ({ logs: this.transferLogs } = this.transferReceipt);
  315. });
  316. transferWasSuccessful.call(this, {
  317. operator: multiTokenHolder,
  318. from: multiTokenHolder,
  319. id: firstTokenId,
  320. value: firstAmount,
  321. });
  322. it('should call onERC1155Received', async function () {
  323. await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'Received', {
  324. operator: multiTokenHolder,
  325. from: multiTokenHolder,
  326. id: firstTokenId,
  327. value: firstAmount,
  328. data,
  329. });
  330. });
  331. });
  332. });
  333. context('to a receiver contract returning unexpected value', function () {
  334. beforeEach(async function () {
  335. this.receiver = await ERC1155ReceiverMock.new(
  336. '0x00c0ffee', false,
  337. RECEIVER_BATCH_MAGIC_VALUE, false,
  338. );
  339. });
  340. it('reverts', async function () {
  341. await expectRevert(
  342. this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', {
  343. from: multiTokenHolder,
  344. }),
  345. 'ERC1155: ERC1155Receiver rejected tokens'
  346. );
  347. });
  348. });
  349. context('to a receiver contract that reverts', function () {
  350. beforeEach(async function () {
  351. this.receiver = await ERC1155ReceiverMock.new(
  352. RECEIVER_SINGLE_MAGIC_VALUE, true,
  353. RECEIVER_BATCH_MAGIC_VALUE, false,
  354. );
  355. });
  356. it('reverts', async function () {
  357. await expectRevert(
  358. this.token.safeTransferFrom(multiTokenHolder, this.receiver.address, firstTokenId, firstAmount, '0x', {
  359. from: multiTokenHolder,
  360. }),
  361. 'ERC1155ReceiverMock: reverting on receive'
  362. );
  363. });
  364. });
  365. context('to a contract that does not implement the required function', function () {
  366. it('reverts', async function () {
  367. const invalidReceiver = this.token;
  368. await expectRevert.unspecified(
  369. this.token.safeTransferFrom(multiTokenHolder, invalidReceiver.address, firstTokenId, firstAmount, '0x', {
  370. from: multiTokenHolder,
  371. })
  372. );
  373. });
  374. });
  375. });
  376. describe('safeBatchTransferFrom', function () {
  377. beforeEach(async function () {
  378. await this.token.mint(multiTokenHolder, firstTokenId, firstAmount, '0x', {
  379. from: minter,
  380. });
  381. await this.token.mint(
  382. multiTokenHolder,
  383. secondTokenId,
  384. secondAmount,
  385. '0x',
  386. {
  387. from: minter,
  388. }
  389. );
  390. });
  391. it('reverts when transferring amount more than any of balances', async function () {
  392. await expectRevert(
  393. this.token.safeBatchTransferFrom(
  394. multiTokenHolder, recipient,
  395. [firstTokenId, secondTokenId],
  396. [firstAmount, secondAmount.addn(1)],
  397. '0x', { from: multiTokenHolder }
  398. ),
  399. 'ERC1155: insufficient balance for transfer'
  400. );
  401. });
  402. it('reverts when ids array length doesn\'t match amounts array length', async function () {
  403. await expectRevert(
  404. this.token.safeBatchTransferFrom(
  405. multiTokenHolder, recipient,
  406. [firstTokenId],
  407. [firstAmount, secondAmount],
  408. '0x', { from: multiTokenHolder }
  409. ),
  410. 'ERC1155: ids and amounts length mismatch'
  411. );
  412. });
  413. it('reverts when transferring to zero address', async function () {
  414. await expectRevert(
  415. this.token.safeBatchTransferFrom(
  416. multiTokenHolder, ZERO_ADDRESS,
  417. [firstTokenId, secondTokenId],
  418. [firstAmount, secondAmount],
  419. '0x', { from: multiTokenHolder }
  420. ),
  421. 'ERC1155: transfer to the zero address'
  422. );
  423. });
  424. function batchTransferWasSuccessful ({ operator, from, ids, values }) {
  425. it('debits transferred balances from sender', async function () {
  426. const newBalances = await this.token.balanceOfBatch(new Array(ids.length).fill(from), ids);
  427. for (const newBalance of newBalances) {
  428. expect(newBalance).to.be.a.bignumber.equal('0');
  429. }
  430. });
  431. it('credits transferred balances to receiver', async function () {
  432. const newBalances = await this.token.balanceOfBatch(new Array(ids.length).fill(this.toWhom), ids);
  433. for (let i = 0; i < newBalances.length; i++) {
  434. expect(newBalances[i]).to.be.a.bignumber.equal(values[i]);
  435. }
  436. });
  437. it('emits a TransferBatch log', function () {
  438. expectEvent.inLogs(this.transferLogs, 'TransferBatch', {
  439. operator,
  440. from,
  441. to: this.toWhom,
  442. // ids,
  443. // values,
  444. });
  445. });
  446. }
  447. context('when called by the multiTokenHolder', async function () {
  448. beforeEach(async function () {
  449. this.toWhom = recipient;
  450. ({ logs: this.transferLogs } =
  451. await this.token.safeBatchTransferFrom(
  452. multiTokenHolder, recipient,
  453. [firstTokenId, secondTokenId],
  454. [firstAmount, secondAmount],
  455. '0x', { from: multiTokenHolder }
  456. ));
  457. });
  458. batchTransferWasSuccessful.call(this, {
  459. operator: multiTokenHolder,
  460. from: multiTokenHolder,
  461. ids: [firstTokenId, secondTokenId],
  462. values: [firstAmount, secondAmount],
  463. });
  464. });
  465. context('when called by an operator on behalf of the multiTokenHolder', function () {
  466. context('when operator is not approved by multiTokenHolder', function () {
  467. beforeEach(async function () {
  468. await this.token.setApprovalForAll(proxy, false, { from: multiTokenHolder });
  469. });
  470. it('reverts', async function () {
  471. await expectRevert(
  472. this.token.safeBatchTransferFrom(
  473. multiTokenHolder, recipient,
  474. [firstTokenId, secondTokenId],
  475. [firstAmount, secondAmount],
  476. '0x', { from: proxy }
  477. ),
  478. 'ERC1155: transfer caller is not owner nor approved'
  479. );
  480. });
  481. });
  482. context('when operator is approved by multiTokenHolder', function () {
  483. beforeEach(async function () {
  484. this.toWhom = recipient;
  485. await this.token.setApprovalForAll(proxy, true, { from: multiTokenHolder });
  486. ({ logs: this.transferLogs } =
  487. await this.token.safeBatchTransferFrom(
  488. multiTokenHolder, recipient,
  489. [firstTokenId, secondTokenId],
  490. [firstAmount, secondAmount],
  491. '0x', { from: proxy },
  492. ));
  493. });
  494. batchTransferWasSuccessful.call(this, {
  495. operator: proxy,
  496. from: multiTokenHolder,
  497. ids: [firstTokenId, secondTokenId],
  498. values: [firstAmount, secondAmount],
  499. });
  500. it('preserves operator\'s balances not involved in the transfer', async function () {
  501. const balance1 = await this.token.balanceOf(proxy, firstTokenId);
  502. expect(balance1).to.be.a.bignumber.equal('0');
  503. const balance2 = await this.token.balanceOf(proxy, secondTokenId);
  504. expect(balance2).to.be.a.bignumber.equal('0');
  505. });
  506. });
  507. });
  508. context('when sending to a valid receiver', function () {
  509. beforeEach(async function () {
  510. this.receiver = await ERC1155ReceiverMock.new(
  511. RECEIVER_SINGLE_MAGIC_VALUE, false,
  512. RECEIVER_BATCH_MAGIC_VALUE, false,
  513. );
  514. });
  515. context('without data', function () {
  516. beforeEach(async function () {
  517. this.toWhom = this.receiver.address;
  518. this.transferReceipt = await this.token.safeBatchTransferFrom(
  519. multiTokenHolder, this.receiver.address,
  520. [firstTokenId, secondTokenId],
  521. [firstAmount, secondAmount],
  522. '0x', { from: multiTokenHolder },
  523. );
  524. ({ logs: this.transferLogs } = this.transferReceipt);
  525. });
  526. batchTransferWasSuccessful.call(this, {
  527. operator: multiTokenHolder,
  528. from: multiTokenHolder,
  529. ids: [firstTokenId, secondTokenId],
  530. values: [firstAmount, secondAmount],
  531. });
  532. it('should call onERC1155BatchReceived', async function () {
  533. await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', {
  534. operator: multiTokenHolder,
  535. from: multiTokenHolder,
  536. // ids: [firstTokenId, secondTokenId],
  537. // values: [firstAmount, secondAmount],
  538. data: null,
  539. });
  540. });
  541. });
  542. context('with data', function () {
  543. const data = '0xf00dd00d';
  544. beforeEach(async function () {
  545. this.toWhom = this.receiver.address;
  546. this.transferReceipt = await this.token.safeBatchTransferFrom(
  547. multiTokenHolder, this.receiver.address,
  548. [firstTokenId, secondTokenId],
  549. [firstAmount, secondAmount],
  550. data, { from: multiTokenHolder },
  551. );
  552. ({ logs: this.transferLogs } = this.transferReceipt);
  553. });
  554. batchTransferWasSuccessful.call(this, {
  555. operator: multiTokenHolder,
  556. from: multiTokenHolder,
  557. ids: [firstTokenId, secondTokenId],
  558. values: [firstAmount, secondAmount],
  559. });
  560. it('should call onERC1155Received', async function () {
  561. await expectEvent.inTransaction(this.transferReceipt.tx, ERC1155ReceiverMock, 'BatchReceived', {
  562. operator: multiTokenHolder,
  563. from: multiTokenHolder,
  564. // ids: [firstTokenId, secondTokenId],
  565. // values: [firstAmount, secondAmount],
  566. data,
  567. });
  568. });
  569. });
  570. });
  571. context('to a receiver contract returning unexpected value', function () {
  572. beforeEach(async function () {
  573. this.receiver = await ERC1155ReceiverMock.new(
  574. RECEIVER_SINGLE_MAGIC_VALUE, false,
  575. RECEIVER_SINGLE_MAGIC_VALUE, false,
  576. );
  577. });
  578. it('reverts', async function () {
  579. await expectRevert(
  580. this.token.safeBatchTransferFrom(
  581. multiTokenHolder, this.receiver.address,
  582. [firstTokenId, secondTokenId],
  583. [firstAmount, secondAmount],
  584. '0x', { from: multiTokenHolder },
  585. ),
  586. 'ERC1155: ERC1155Receiver rejected tokens'
  587. );
  588. });
  589. });
  590. context('to a receiver contract that reverts', function () {
  591. beforeEach(async function () {
  592. this.receiver = await ERC1155ReceiverMock.new(
  593. RECEIVER_SINGLE_MAGIC_VALUE, false,
  594. RECEIVER_BATCH_MAGIC_VALUE, true,
  595. );
  596. });
  597. it('reverts', async function () {
  598. await expectRevert(
  599. this.token.safeBatchTransferFrom(
  600. multiTokenHolder, this.receiver.address,
  601. [firstTokenId, secondTokenId],
  602. [firstAmount, secondAmount],
  603. '0x', { from: multiTokenHolder },
  604. ),
  605. 'ERC1155ReceiverMock: reverting on batch receive'
  606. );
  607. });
  608. });
  609. context('to a contract that does not implement the required function', function () {
  610. it('reverts', async function () {
  611. const invalidReceiver = this.token;
  612. await expectRevert.unspecified(
  613. this.token.safeBatchTransferFrom(
  614. multiTokenHolder, invalidReceiver.address,
  615. [firstTokenId, secondTokenId],
  616. [firstAmount, secondAmount],
  617. '0x', { from: multiTokenHolder },
  618. )
  619. );
  620. });
  621. });
  622. });
  623. shouldSupportInterfaces(['ERC165', 'ERC1155']);
  624. });
  625. }
  626. module.exports = {
  627. shouldBehaveLikeERC1155,
  628. };