SignatureBouncer.test.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. const { assertRevert } = require('../helpers/assertRevert');
  2. const { getBouncerSigner } = require('../helpers/sign');
  3. const Bouncer = artifacts.require('SignatureBouncerMock');
  4. const BigNumber = web3.BigNumber;
  5. require('chai')
  6. .use(require('chai-bignumber')(BigNumber))
  7. .should();
  8. const UINT_VALUE = 23;
  9. const BYTES_VALUE = web3.toHex('test');
  10. const INVALID_SIGNATURE = '0xabcd';
  11. contract('Bouncer', function ([_, owner, anyone, bouncerAddress, authorizedUser]) {
  12. beforeEach(async function () {
  13. this.bouncer = await Bouncer.new({ from: owner });
  14. });
  15. context('management', function () {
  16. it('has a default owner of self', async function () {
  17. (await this.bouncer.owner()).should.equal(owner);
  18. });
  19. it('allows the owner to add a bouncer', async function () {
  20. await this.bouncer.addBouncer(bouncerAddress, { from: owner });
  21. (await this.bouncer.isBouncer(bouncerAddress)).should.equal(true);
  22. });
  23. it('does not allow adding an invalid address', async function () {
  24. await assertRevert(
  25. this.bouncer.addBouncer('0x0', { from: owner })
  26. );
  27. });
  28. it('allows the owner to remove a bouncer', async function () {
  29. await this.bouncer.addBouncer(bouncerAddress, { from: owner });
  30. await this.bouncer.removeBouncer(bouncerAddress, { from: owner });
  31. (await this.bouncer.isBouncer(bouncerAddress)).should.equal(false);
  32. });
  33. it('does not allow anyone to add a bouncer', async function () {
  34. await assertRevert(
  35. this.bouncer.addBouncer(bouncerAddress, { from: anyone })
  36. );
  37. });
  38. it('does not allow anyone to remove a bouncer', async function () {
  39. await this.bouncer.addBouncer(bouncerAddress, { from: owner });
  40. await assertRevert(
  41. this.bouncer.removeBouncer(bouncerAddress, { from: anyone })
  42. );
  43. });
  44. });
  45. context('with bouncer address', function () {
  46. beforeEach(async function () {
  47. await this.bouncer.addBouncer(bouncerAddress, { from: owner });
  48. this.signFor = getBouncerSigner(this.bouncer, bouncerAddress);
  49. });
  50. describe('modifiers', function () {
  51. context('plain signature', function () {
  52. it('allows valid signature for sender', async function () {
  53. await this.bouncer.onlyWithValidSignature(this.signFor(authorizedUser), { from: authorizedUser });
  54. });
  55. it('does not allow invalid signature for sender', async function () {
  56. await assertRevert(
  57. this.bouncer.onlyWithValidSignature(INVALID_SIGNATURE, { from: authorizedUser })
  58. );
  59. });
  60. it('does not allow valid signature for other sender', async function () {
  61. await assertRevert(
  62. this.bouncer.onlyWithValidSignature(this.signFor(authorizedUser), { from: anyone })
  63. );
  64. });
  65. it('does not allow valid signature for method for sender', async function () {
  66. await assertRevert(
  67. this.bouncer.onlyWithValidSignature(this.signFor(authorizedUser, 'onlyWithValidSignature'),
  68. { from: authorizedUser })
  69. );
  70. });
  71. });
  72. context('method signature', function () {
  73. it('allows valid signature with correct method for sender', async function () {
  74. await this.bouncer.onlyWithValidSignatureAndMethod(
  75. this.signFor(authorizedUser, 'onlyWithValidSignatureAndMethod'), { from: authorizedUser }
  76. );
  77. });
  78. it('does not allow invalid signature with correct method for sender', async function () {
  79. await assertRevert(
  80. this.bouncer.onlyWithValidSignatureAndMethod(INVALID_SIGNATURE, { from: authorizedUser })
  81. );
  82. });
  83. it('does not allow valid signature with correct method for other sender', async function () {
  84. await assertRevert(
  85. this.bouncer.onlyWithValidSignatureAndMethod(
  86. this.signFor(authorizedUser, 'onlyWithValidSignatureAndMethod'), { from: anyone }
  87. )
  88. );
  89. });
  90. it('does not allow valid method signature with incorrect method for sender', async function () {
  91. await assertRevert(
  92. this.bouncer.onlyWithValidSignatureAndMethod(this.signFor(authorizedUser, 'theWrongMethod'),
  93. { from: authorizedUser })
  94. );
  95. });
  96. it('does not allow valid non-method signature method for sender', async function () {
  97. await assertRevert(
  98. this.bouncer.onlyWithValidSignatureAndMethod(this.signFor(authorizedUser), { from: authorizedUser })
  99. );
  100. });
  101. });
  102. context('method and data signature', function () {
  103. it('allows valid signature with correct method and data for sender', async function () {
  104. await this.bouncer.onlyWithValidSignatureAndData(UINT_VALUE,
  105. this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]), { from: authorizedUser }
  106. );
  107. });
  108. it('does not allow invalid signature with correct method and data for sender', async function () {
  109. await assertRevert(
  110. this.bouncer.onlyWithValidSignatureAndData(UINT_VALUE, INVALID_SIGNATURE, { from: authorizedUser })
  111. );
  112. });
  113. it('does not allow valid signature with correct method and incorrect data for sender', async function () {
  114. await assertRevert(
  115. this.bouncer.onlyWithValidSignatureAndData(UINT_VALUE + 10,
  116. this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]),
  117. { from: authorizedUser }
  118. )
  119. );
  120. });
  121. it('does not allow valid signature with correct method and data for other sender', async function () {
  122. await assertRevert(
  123. this.bouncer.onlyWithValidSignatureAndData(UINT_VALUE,
  124. this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]),
  125. { from: anyone }
  126. )
  127. );
  128. });
  129. it('does not allow valid non-method signature for sender', async function () {
  130. await assertRevert(
  131. this.bouncer.onlyWithValidSignatureAndData(UINT_VALUE,
  132. this.signFor(authorizedUser), { from: authorizedUser }
  133. )
  134. );
  135. });
  136. });
  137. });
  138. context('signature validation', function () {
  139. context('plain signature', function () {
  140. it('validates valid signature for valid user', async function () {
  141. (await this.bouncer.checkValidSignature(authorizedUser, this.signFor(authorizedUser))).should.equal(true);
  142. });
  143. it('does not validate invalid signature for valid user', async function () {
  144. (await this.bouncer.checkValidSignature(authorizedUser, INVALID_SIGNATURE)).should.equal(false);
  145. });
  146. it('does not validate valid signature for anyone', async function () {
  147. (await this.bouncer.checkValidSignature(anyone, this.signFor(authorizedUser))).should.equal(false);
  148. });
  149. it('does not validate valid signature for method for valid user', async function () {
  150. (await this.bouncer.checkValidSignature(authorizedUser, this.signFor(authorizedUser, 'checkValidSignature'))
  151. ).should.equal(false);
  152. });
  153. });
  154. context('method signature', function () {
  155. it('validates valid signature with correct method for valid user', async function () {
  156. (await this.bouncer.checkValidSignatureAndMethod(authorizedUser,
  157. this.signFor(authorizedUser, 'checkValidSignatureAndMethod'))
  158. ).should.equal(true);
  159. });
  160. it('does not validate invalid signature with correct method for valid user', async function () {
  161. (await this.bouncer.checkValidSignatureAndMethod(authorizedUser, INVALID_SIGNATURE)).should.equal(false);
  162. });
  163. it('does not validate valid signature with correct method for anyone', async function () {
  164. (await this.bouncer.checkValidSignatureAndMethod(anyone,
  165. this.signFor(authorizedUser, 'checkValidSignatureAndMethod'))
  166. ).should.equal(false);
  167. });
  168. it('does not validate valid non-method signature with correct method for valid user', async function () {
  169. (await this.bouncer.checkValidSignatureAndMethod(authorizedUser, this.signFor(authorizedUser))
  170. ).should.equal(false);
  171. });
  172. });
  173. context('method and data signature', function () {
  174. it('validates valid signature with correct method and data for valid user', async function () {
  175. (await this.bouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE,
  176. this.signFor(authorizedUser, 'checkValidSignatureAndData', [authorizedUser, BYTES_VALUE, UINT_VALUE]))
  177. ).should.equal(true);
  178. });
  179. it('does not validate invalid signature with correct method and data for valid user', async function () {
  180. (await this.bouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE, INVALID_SIGNATURE)
  181. ).should.equal(false);
  182. });
  183. it('does not validate valid signature with correct method and incorrect data for valid user',
  184. async function () {
  185. (await this.bouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE + 10,
  186. this.signFor(authorizedUser, 'checkValidSignatureAndData', [authorizedUser, BYTES_VALUE, UINT_VALUE]))
  187. ).should.equal(false);
  188. }
  189. );
  190. it('does not validate valid signature with correct method and data for anyone', async function () {
  191. (await this.bouncer.checkValidSignatureAndData(anyone, BYTES_VALUE, UINT_VALUE,
  192. this.signFor(authorizedUser, 'checkValidSignatureAndData', [authorizedUser, BYTES_VALUE, UINT_VALUE]))
  193. ).should.equal(false);
  194. });
  195. it('does not validate valid non-method-data signature with correct method and data for valid user',
  196. async function () {
  197. (await this.bouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE,
  198. this.signFor(authorizedUser, 'checkValidSignatureAndData'))
  199. ).should.equal(false);
  200. }
  201. );
  202. });
  203. });
  204. });
  205. });