Multicall.test.js 2.6 KB

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