SignatureBouncer.test.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. const { shouldFail } = require('openzeppelin-test-helpers');
  2. const { getSignFor } = require('../helpers/sign');
  3. const { shouldBehaveLikePublicRole } = require('../access/roles/PublicRole.behavior');
  4. const SignatureBouncerMock = artifacts.require('SignatureBouncerMock');
  5. const UINT_VALUE = 23;
  6. const BYTES_VALUE = web3.utils.toHex('test');
  7. const INVALID_SIGNATURE = '0xabcd';
  8. contract('SignatureBouncer', function ([_, signer, otherSigner, anyone, authorizedUser, ...otherAccounts]) {
  9. beforeEach(async function () {
  10. this.sigBouncer = await SignatureBouncerMock.new({ from: signer });
  11. this.signFor = getSignFor(this.sigBouncer, signer);
  12. });
  13. describe('signer role', function () {
  14. beforeEach(async function () {
  15. this.contract = this.sigBouncer;
  16. await this.contract.addSigner(otherSigner, { from: signer });
  17. });
  18. shouldBehaveLikePublicRole(signer, otherSigner, otherAccounts, 'signer');
  19. });
  20. describe('modifiers', function () {
  21. context('plain signature', function () {
  22. it('allows valid signature for sender', async function () {
  23. await this.sigBouncer.onlyWithValidSignature(await this.signFor(authorizedUser), { from: authorizedUser });
  24. });
  25. it('does not allow invalid signature for sender', async function () {
  26. await shouldFail.reverting(
  27. this.sigBouncer.onlyWithValidSignature(INVALID_SIGNATURE, { from: authorizedUser })
  28. );
  29. });
  30. it('does not allow valid signature for other sender', async function () {
  31. await shouldFail.reverting(
  32. this.sigBouncer.onlyWithValidSignature(await this.signFor(authorizedUser), { from: anyone })
  33. );
  34. });
  35. it('does not allow valid signature for method for sender', async function () {
  36. await shouldFail.reverting(
  37. this.sigBouncer.onlyWithValidSignature(await this.signFor(authorizedUser, 'onlyWithValidSignature'),
  38. { from: authorizedUser })
  39. );
  40. });
  41. });
  42. context('method signature', function () {
  43. it('allows valid signature with correct method for sender', async function () {
  44. await this.sigBouncer.onlyWithValidSignatureAndMethod(
  45. await this.signFor(authorizedUser, 'onlyWithValidSignatureAndMethod'), { from: authorizedUser }
  46. );
  47. });
  48. it('does not allow invalid signature with correct method for sender', async function () {
  49. await shouldFail.reverting(
  50. this.sigBouncer.onlyWithValidSignatureAndMethod(INVALID_SIGNATURE, { from: authorizedUser })
  51. );
  52. });
  53. it('does not allow valid signature with correct method for other sender', async function () {
  54. await shouldFail.reverting(
  55. this.sigBouncer.onlyWithValidSignatureAndMethod(
  56. await this.signFor(authorizedUser, 'onlyWithValidSignatureAndMethod'), { from: anyone }
  57. )
  58. );
  59. });
  60. it('does not allow valid method signature with incorrect method for sender', async function () {
  61. await shouldFail.reverting(
  62. this.sigBouncer.onlyWithValidSignatureAndMethod(await this.signFor(authorizedUser, 'theWrongMethod'),
  63. { from: authorizedUser })
  64. );
  65. });
  66. it('does not allow valid non-method signature method for sender', async function () {
  67. await shouldFail.reverting(
  68. this.sigBouncer.onlyWithValidSignatureAndMethod(await this.signFor(authorizedUser), { from: authorizedUser })
  69. );
  70. });
  71. });
  72. context('method and data signature', function () {
  73. it('allows valid signature with correct method and data for sender', async function () {
  74. await this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE,
  75. await this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]), { from: authorizedUser }
  76. );
  77. });
  78. it('does not allow invalid signature with correct method and data for sender', async function () {
  79. await shouldFail.reverting(
  80. this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE, INVALID_SIGNATURE, { from: authorizedUser })
  81. );
  82. });
  83. it('does not allow valid signature with correct method and incorrect data for sender', async function () {
  84. await shouldFail.reverting(
  85. this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE + 10,
  86. await this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]),
  87. { from: authorizedUser }
  88. )
  89. );
  90. });
  91. it('does not allow valid signature with correct method and data for other sender', async function () {
  92. await shouldFail.reverting(
  93. this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE,
  94. await this.signFor(authorizedUser, 'onlyWithValidSignatureAndData', [UINT_VALUE]),
  95. { from: anyone }
  96. )
  97. );
  98. });
  99. it('does not allow valid non-method signature for sender', async function () {
  100. await shouldFail.reverting(
  101. this.sigBouncer.onlyWithValidSignatureAndData(UINT_VALUE,
  102. await this.signFor(authorizedUser), { from: authorizedUser }
  103. )
  104. );
  105. });
  106. it('does not allow msg.data shorter than SIGNATURE_SIZE', async function () {
  107. await shouldFail.reverting(
  108. this.sigBouncer.tooShortMsgData({ from: authorizedUser })
  109. );
  110. });
  111. });
  112. });
  113. context('signature validation', function () {
  114. context('plain signature', function () {
  115. it('validates valid signature for valid user', async function () {
  116. (await this.sigBouncer.checkValidSignature(authorizedUser, await this.signFor(authorizedUser)))
  117. .should.equal(true);
  118. });
  119. it('does not validate invalid signature for valid user', async function () {
  120. (await this.sigBouncer.checkValidSignature(authorizedUser, INVALID_SIGNATURE)).should.equal(false);
  121. });
  122. it('does not validate valid signature for anyone', async function () {
  123. (await this.sigBouncer.checkValidSignature(anyone, await this.signFor(authorizedUser))).should.equal(false);
  124. });
  125. it('does not validate valid signature for method for valid user', async function () {
  126. (await this.sigBouncer.checkValidSignature(
  127. authorizedUser, await this.signFor(authorizedUser, 'checkValidSignature'))
  128. ).should.equal(false);
  129. });
  130. });
  131. context('method signature', function () {
  132. it('validates valid signature with correct method for valid user', async function () {
  133. (await this.sigBouncer.checkValidSignatureAndMethod(authorizedUser,
  134. await this.signFor(authorizedUser, 'checkValidSignatureAndMethod'))
  135. ).should.equal(true);
  136. });
  137. it('does not validate invalid signature with correct method for valid user', async function () {
  138. (await this.sigBouncer.checkValidSignatureAndMethod(authorizedUser, INVALID_SIGNATURE)).should.equal(false);
  139. });
  140. it('does not validate valid signature with correct method for anyone', async function () {
  141. (await this.sigBouncer.checkValidSignatureAndMethod(anyone,
  142. await this.signFor(authorizedUser, 'checkValidSignatureAndMethod'))
  143. ).should.equal(false);
  144. });
  145. it('does not validate valid non-method signature with correct method for valid user', async function () {
  146. (await this.sigBouncer.checkValidSignatureAndMethod(authorizedUser, await this.signFor(authorizedUser))
  147. ).should.equal(false);
  148. });
  149. });
  150. context('method and data signature', function () {
  151. it('validates valid signature with correct method and data for valid user', async function () {
  152. (await this.sigBouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE,
  153. await this.signFor(authorizedUser, 'checkValidSignatureAndData', [authorizedUser, BYTES_VALUE, UINT_VALUE]))
  154. ).should.equal(true);
  155. });
  156. it('does not validate invalid signature with correct method and data for valid user', async function () {
  157. (await this.sigBouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE, INVALID_SIGNATURE)
  158. ).should.equal(false);
  159. });
  160. it('does not validate valid signature with correct method and incorrect data for valid user',
  161. async function () {
  162. (await this.sigBouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE + 10,
  163. await this.signFor(authorizedUser, 'checkValidSignatureAndData', [authorizedUser, BYTES_VALUE, UINT_VALUE]))
  164. ).should.equal(false);
  165. }
  166. );
  167. it('does not validate valid signature with correct method and data for anyone', async function () {
  168. (await this.sigBouncer.checkValidSignatureAndData(anyone, BYTES_VALUE, UINT_VALUE,
  169. await this.signFor(authorizedUser, 'checkValidSignatureAndData', [authorizedUser, BYTES_VALUE, UINT_VALUE]))
  170. ).should.equal(false);
  171. });
  172. it('does not validate valid non-method-data signature with correct method and data for valid user',
  173. async function () {
  174. (await this.sigBouncer.checkValidSignatureAndData(authorizedUser, BYTES_VALUE, UINT_VALUE,
  175. await this.signFor(authorizedUser, 'checkValidSignatureAndData'))
  176. ).should.equal(false);
  177. }
  178. );
  179. });
  180. });
  181. });