SignatureBouncer.test.js 9.8 KB

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