SafeERC20.test.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. const { shouldFail } = require('openzeppelin-test-helpers');
  2. const ERC20ReturnFalseMock = artifacts.require('ERC20ReturnFalseMock');
  3. const ERC20ReturnTrueMock = artifacts.require('ERC20ReturnTrueMock');
  4. const ERC20NoReturnMock = artifacts.require('ERC20NoReturnMock');
  5. const SafeERC20Wrapper = artifacts.require('SafeERC20Wrapper');
  6. contract('SafeERC20', function ([_, hasNoCode]) {
  7. describe('with address that has no contract code', function () {
  8. beforeEach(async function () {
  9. this.wrapper = await SafeERC20Wrapper.new(hasNoCode);
  10. });
  11. shouldRevertOnAllCalls();
  12. });
  13. describe('with token that returns false on all calls', function () {
  14. beforeEach(async function () {
  15. this.wrapper = await SafeERC20Wrapper.new((await ERC20ReturnFalseMock.new()).address);
  16. });
  17. shouldRevertOnAllCalls();
  18. });
  19. describe('with token that returns true on all calls', function () {
  20. beforeEach(async function () {
  21. this.wrapper = await SafeERC20Wrapper.new((await ERC20ReturnTrueMock.new()).address);
  22. });
  23. shouldOnlyRevertOnErrors();
  24. });
  25. describe('with token that returns no boolean values', function () {
  26. beforeEach(async function () {
  27. this.wrapper = await SafeERC20Wrapper.new((await ERC20NoReturnMock.new()).address);
  28. });
  29. shouldOnlyRevertOnErrors();
  30. });
  31. });
  32. function shouldRevertOnAllCalls () {
  33. it('reverts on transfer', async function () {
  34. await shouldFail.reverting(this.wrapper.transfer());
  35. });
  36. it('reverts on transferFrom', async function () {
  37. await shouldFail.reverting(this.wrapper.transferFrom());
  38. });
  39. it('reverts on approve', async function () {
  40. await shouldFail.reverting(this.wrapper.approve(0));
  41. });
  42. it('reverts on increaseAllowance', async function () {
  43. await shouldFail.reverting(this.wrapper.increaseAllowance(0));
  44. });
  45. it('reverts on decreaseAllowance', async function () {
  46. await shouldFail.reverting(this.wrapper.decreaseAllowance(0));
  47. });
  48. }
  49. function shouldOnlyRevertOnErrors () {
  50. it('doesn\'t revert on transfer', async function () {
  51. await this.wrapper.transfer();
  52. });
  53. it('doesn\'t revert on transferFrom', async function () {
  54. await this.wrapper.transferFrom();
  55. });
  56. describe('approvals', function () {
  57. context('with zero allowance', function () {
  58. beforeEach(async function () {
  59. await this.wrapper.setAllowance(0);
  60. });
  61. it('doesn\'t revert when approving a non-zero allowance', async function () {
  62. await this.wrapper.approve(100);
  63. });
  64. it('doesn\'t revert when approving a zero allowance', async function () {
  65. await this.wrapper.approve(0);
  66. });
  67. it('doesn\'t revert when increasing the allowance', async function () {
  68. await this.wrapper.increaseAllowance(10);
  69. });
  70. it('reverts when decreasing the allowance', async function () {
  71. await shouldFail.reverting(this.wrapper.decreaseAllowance(10));
  72. });
  73. });
  74. context('with non-zero allowance', function () {
  75. beforeEach(async function () {
  76. await this.wrapper.setAllowance(100);
  77. });
  78. it('reverts when approving a non-zero allowance', async function () {
  79. await shouldFail.reverting(this.wrapper.approve(20));
  80. });
  81. it('doesn\'t revert when approving a zero allowance', async function () {
  82. await this.wrapper.approve(0);
  83. });
  84. it('doesn\'t revert when increasing the allowance', async function () {
  85. await this.wrapper.increaseAllowance(10);
  86. });
  87. it('doesn\'t revert when decreasing the allowance to a positive value', async function () {
  88. await this.wrapper.decreaseAllowance(50);
  89. });
  90. it('reverts when decreasing the allowance to a negative value', async function () {
  91. await shouldFail.reverting(this.wrapper.decreaseAllowance(200));
  92. });
  93. });
  94. });
  95. }