Multicall.test.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. const { BN } = require('@openzeppelin/test-helpers');
  2. const { expectRevertCustomError } = require('../helpers/customError');
  3. const ERC20MulticallMock = artifacts.require('$ERC20MulticallMock');
  4. contract('Multicall', function (accounts) {
  5. const [deployer, alice, bob] = accounts;
  6. const amount = 12000;
  7. beforeEach(async function () {
  8. this.multicallToken = await ERC20MulticallMock.new('name', 'symbol');
  9. await this.multicallToken.$_mint(deployer, amount);
  10. });
  11. it('batches function calls', async function () {
  12. expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0'));
  13. expect(await this.multicallToken.balanceOf(bob)).to.be.bignumber.equal(new BN('0'));
  14. await this.multicallToken.multicall(
  15. [
  16. this.multicallToken.contract.methods.transfer(alice, amount / 2).encodeABI(),
  17. this.multicallToken.contract.methods.transfer(bob, amount / 3).encodeABI(),
  18. ],
  19. { from: deployer },
  20. );
  21. expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN(amount / 2));
  22. expect(await this.multicallToken.balanceOf(bob)).to.be.bignumber.equal(new BN(amount / 3));
  23. });
  24. it('returns an array with the result of each call', async function () {
  25. const MulticallTest = artifacts.require('MulticallTest');
  26. const multicallTest = await MulticallTest.new({ from: deployer });
  27. await this.multicallToken.transfer(multicallTest.address, amount, { from: deployer });
  28. expect(await this.multicallToken.balanceOf(multicallTest.address)).to.be.bignumber.equal(new BN(amount));
  29. const recipients = [alice, bob];
  30. const amounts = [amount / 2, amount / 3].map(n => new BN(n));
  31. await multicallTest.checkReturnValues(this.multicallToken.address, recipients, amounts);
  32. });
  33. it('reverts previous calls', async function () {
  34. expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0'));
  35. const call = this.multicallToken.multicall(
  36. [
  37. this.multicallToken.contract.methods.transfer(alice, amount).encodeABI(),
  38. this.multicallToken.contract.methods.transfer(bob, amount).encodeABI(),
  39. ],
  40. { from: deployer },
  41. );
  42. await expectRevertCustomError(call, 'ERC20InsufficientBalance', [deployer, 0, amount]);
  43. expect(await this.multicallToken.balanceOf(alice)).to.be.bignumber.equal(new BN('0'));
  44. });
  45. it('bubbles up revert reasons', async function () {
  46. const call = this.multicallToken.multicall(
  47. [
  48. this.multicallToken.contract.methods.transfer(alice, amount).encodeABI(),
  49. this.multicallToken.contract.methods.transfer(bob, amount).encodeABI(),
  50. ],
  51. { from: deployer },
  52. );
  53. await expectRevertCustomError(call, 'ERC20InsufficientBalance', [deployer, 0, amount]);
  54. });
  55. });