ERC1155Utils.test.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. const { ethers } = require('hardhat');
  2. const { expect } = require('chai');
  3. const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
  4. const { RevertType } = require('../../../helpers/enums');
  5. const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic');
  6. const firstTokenId = 1n;
  7. const secondTokenId = 2n;
  8. const firstTokenValue = 1000n;
  9. const secondTokenValue = 1000n;
  10. const RECEIVER_SINGLE_MAGIC_VALUE = '0xf23a6e61';
  11. const RECEIVER_BATCH_MAGIC_VALUE = '0xbc197c81';
  12. const deployReceiver = (
  13. revertType,
  14. returnValueSingle = RECEIVER_SINGLE_MAGIC_VALUE,
  15. returnValueBatched = RECEIVER_BATCH_MAGIC_VALUE,
  16. ) => ethers.deployContract('$ERC1155ReceiverMock', [returnValueSingle, returnValueBatched, revertType]);
  17. const fixture = async () => {
  18. const [eoa, operator, owner] = await ethers.getSigners();
  19. const utils = await ethers.deployContract('$ERC1155Utils');
  20. const receivers = {
  21. correct: await deployReceiver(RevertType.None),
  22. invalid: await deployReceiver(RevertType.None, '0xdeadbeef', '0xdeadbeef'),
  23. message: await deployReceiver(RevertType.RevertWithMessage),
  24. empty: await deployReceiver(RevertType.RevertWithoutMessage),
  25. customError: await deployReceiver(RevertType.RevertWithCustomError),
  26. panic: await deployReceiver(RevertType.Panic),
  27. nonReceiver: await ethers.deployContract('CallReceiverMock'),
  28. eoa,
  29. };
  30. return { operator, owner, utils, receivers };
  31. };
  32. describe('ERC1155Utils', function () {
  33. beforeEach(async function () {
  34. Object.assign(this, await loadFixture(fixture));
  35. });
  36. describe('onERC1155Received', function () {
  37. it('succeeds when called by an EOA', async function () {
  38. await expect(
  39. this.utils.$checkOnERC1155Received(
  40. this.operator,
  41. this.owner,
  42. this.receivers.eoa,
  43. firstTokenId,
  44. firstTokenValue,
  45. '0x',
  46. ),
  47. ).to.not.be.reverted;
  48. });
  49. it('succeeds when data is passed', async function () {
  50. const data = '0x12345678';
  51. await expect(
  52. this.utils.$checkOnERC1155Received(
  53. this.operator,
  54. this.owner,
  55. this.receivers.correct,
  56. firstTokenId,
  57. firstTokenValue,
  58. data,
  59. ),
  60. ).to.not.be.reverted;
  61. });
  62. it('succeeds when data is empty', async function () {
  63. await expect(
  64. this.utils.$checkOnERC1155Received(
  65. this.operator,
  66. this.owner,
  67. this.receivers.correct,
  68. firstTokenId,
  69. firstTokenValue,
  70. '0x',
  71. ),
  72. ).to.not.be.reverted;
  73. });
  74. it('reverts when receiver returns invalid value', async function () {
  75. await expect(
  76. this.utils.$checkOnERC1155Received(
  77. this.operator,
  78. this.owner,
  79. this.receivers.invalid,
  80. firstTokenId,
  81. firstTokenValue,
  82. '0x',
  83. ),
  84. )
  85. .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver')
  86. .withArgs(this.receivers.invalid);
  87. });
  88. it('reverts when receiver reverts with message', async function () {
  89. await expect(
  90. this.utils.$checkOnERC1155Received(
  91. this.operator,
  92. this.owner,
  93. this.receivers.message,
  94. firstTokenId,
  95. firstTokenValue,
  96. '0x',
  97. ),
  98. ).to.be.revertedWith('ERC1155ReceiverMock: reverting on receive');
  99. });
  100. it('reverts when receiver reverts without message', async function () {
  101. await expect(
  102. this.utils.$checkOnERC1155Received(
  103. this.operator,
  104. this.owner,
  105. this.receivers.empty,
  106. firstTokenId,
  107. firstTokenValue,
  108. '0x',
  109. ),
  110. )
  111. .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver')
  112. .withArgs(this.receivers.empty);
  113. });
  114. it('reverts when receiver reverts with custom error', async function () {
  115. await expect(
  116. this.utils.$checkOnERC1155Received(
  117. this.operator,
  118. this.owner,
  119. this.receivers.customError,
  120. firstTokenId,
  121. firstTokenValue,
  122. '0x',
  123. ),
  124. )
  125. .to.be.revertedWithCustomError(this.receivers.customError, 'CustomError')
  126. .withArgs(RECEIVER_SINGLE_MAGIC_VALUE);
  127. });
  128. it('reverts when receiver panics', async function () {
  129. await expect(
  130. this.utils.$checkOnERC1155Received(
  131. this.operator,
  132. this.owner,
  133. this.receivers.panic,
  134. firstTokenId,
  135. firstTokenValue,
  136. '0x',
  137. ),
  138. ).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO);
  139. });
  140. it('reverts when receiver does not implement onERC1155Received', async function () {
  141. await expect(
  142. this.utils.$checkOnERC1155Received(
  143. this.operator,
  144. this.owner,
  145. this.receivers.nonReceiver,
  146. firstTokenId,
  147. firstTokenValue,
  148. '0x',
  149. ),
  150. )
  151. .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver')
  152. .withArgs(this.receivers.nonReceiver);
  153. });
  154. });
  155. describe('onERC1155BatchReceived', function () {
  156. it('succeeds when called by an EOA', async function () {
  157. await expect(
  158. this.utils.$checkOnERC1155BatchReceived(
  159. this.operator,
  160. this.owner,
  161. this.receivers.eoa,
  162. [firstTokenId, secondTokenId],
  163. [firstTokenValue, secondTokenValue],
  164. '0x',
  165. ),
  166. ).to.not.be.reverted;
  167. });
  168. it('succeeds when data is passed', async function () {
  169. const data = '0x12345678';
  170. await expect(
  171. this.utils.$checkOnERC1155BatchReceived(
  172. this.operator,
  173. this.owner,
  174. this.receivers.correct,
  175. [firstTokenId, secondTokenId],
  176. [firstTokenValue, secondTokenValue],
  177. data,
  178. ),
  179. ).to.not.be.reverted;
  180. });
  181. it('succeeds when data is empty', async function () {
  182. await expect(
  183. this.utils.$checkOnERC1155BatchReceived(
  184. this.operator,
  185. this.owner,
  186. this.receivers.correct,
  187. [firstTokenId, secondTokenId],
  188. [firstTokenValue, secondTokenValue],
  189. '0x',
  190. ),
  191. ).to.not.be.reverted;
  192. });
  193. it('reverts when receiver returns invalid value', async function () {
  194. await expect(
  195. this.utils.$checkOnERC1155BatchReceived(
  196. this.operator,
  197. this.owner,
  198. this.receivers.invalid,
  199. [firstTokenId, secondTokenId],
  200. [firstTokenValue, secondTokenValue],
  201. '0x',
  202. ),
  203. )
  204. .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver')
  205. .withArgs(this.receivers.invalid);
  206. });
  207. it('reverts when receiver reverts with message', async function () {
  208. await expect(
  209. this.utils.$checkOnERC1155BatchReceived(
  210. this.operator,
  211. this.owner,
  212. this.receivers.message,
  213. [firstTokenId, secondTokenId],
  214. [firstTokenValue, secondTokenValue],
  215. '0x',
  216. ),
  217. ).to.be.revertedWith('ERC1155ReceiverMock: reverting on batch receive');
  218. });
  219. it('reverts when receiver reverts without message', async function () {
  220. await expect(
  221. this.utils.$checkOnERC1155BatchReceived(
  222. this.operator,
  223. this.owner,
  224. this.receivers.empty,
  225. [firstTokenId, secondTokenId],
  226. [firstTokenValue, secondTokenValue],
  227. '0x',
  228. ),
  229. )
  230. .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver')
  231. .withArgs(this.receivers.empty);
  232. });
  233. it('reverts when receiver reverts with custom error', async function () {
  234. await expect(
  235. this.utils.$checkOnERC1155BatchReceived(
  236. this.operator,
  237. this.owner,
  238. this.receivers.customError,
  239. [firstTokenId, secondTokenId],
  240. [firstTokenValue, secondTokenValue],
  241. '0x',
  242. ),
  243. )
  244. .to.be.revertedWithCustomError(this.receivers.customError, 'CustomError')
  245. .withArgs(RECEIVER_SINGLE_MAGIC_VALUE);
  246. });
  247. it('reverts when receiver panics', async function () {
  248. await expect(
  249. this.utils.$checkOnERC1155BatchReceived(
  250. this.operator,
  251. this.owner,
  252. this.receivers.panic,
  253. [firstTokenId, secondTokenId],
  254. [firstTokenValue, secondTokenValue],
  255. '0x',
  256. ),
  257. ).to.be.revertedWithPanic(PANIC_CODES.DIVISION_BY_ZERO);
  258. });
  259. it('reverts when receiver does not implement onERC1155BatchReceived', async function () {
  260. await expect(
  261. this.utils.$checkOnERC1155BatchReceived(
  262. this.operator,
  263. this.owner,
  264. this.receivers.nonReceiver,
  265. [firstTokenId, secondTokenId],
  266. [firstTokenValue, secondTokenValue],
  267. '0x',
  268. ),
  269. )
  270. .to.be.revertedWithCustomError(this.utils, 'ERC1155InvalidReceiver')
  271. .withArgs(this.receivers.nonReceiver);
  272. });
  273. });
  274. });