SignatureBouncer.test.js 9.0 KB

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