GSNBouncerSignature.sol 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. pragma solidity ^0.5.0;
  2. import "./GSNBouncerBase.sol";
  3. import "../../cryptography/ECDSA.sol";
  4. /**
  5. * @dev A xref:ROOT:gsn-advanced.adoc#gsn-bouncers[GSN Bouncer] that allows relayed transactions through when they are
  6. * accompanied by the signature of a trusted signer. The intent is for this signature to be generated by a server that
  7. * performs validations off-chain. Note that nothing is charged to the user in this scheme. Thus, the server should make
  8. * sure to account for this in their economic and threat model.
  9. */
  10. contract GSNBouncerSignature is GSNBouncerBase {
  11. using ECDSA for bytes32;
  12. address private _trustedSigner;
  13. enum GSNBouncerSignatureErrorCodes {
  14. INVALID_SIGNER
  15. }
  16. /**
  17. * @dev Sets the trusted signer that is going to be producing signatures to approve relayed calls.
  18. */
  19. constructor(address trustedSigner) public {
  20. _trustedSigner = trustedSigner;
  21. }
  22. /**
  23. * @dev Ensures that only transactions with a trusted signature can be relayed through the GSN.
  24. */
  25. function acceptRelayedCall(
  26. address relay,
  27. address from,
  28. bytes calldata encodedFunction,
  29. uint256 transactionFee,
  30. uint256 gasPrice,
  31. uint256 gasLimit,
  32. uint256 nonce,
  33. bytes calldata approvalData,
  34. uint256
  35. )
  36. external
  37. view
  38. returns (uint256, bytes memory)
  39. {
  40. bytes memory blob = abi.encodePacked(
  41. relay,
  42. from,
  43. encodedFunction,
  44. transactionFee,
  45. gasPrice,
  46. gasLimit,
  47. nonce, // Prevents replays on RelayHub
  48. getHubAddr(), // Prevents replays in multiple RelayHubs
  49. address(this) // Prevents replays in multiple recipients
  50. );
  51. if (keccak256(blob).toEthSignedMessageHash().recover(approvalData) == _trustedSigner) {
  52. return _approveRelayedCall();
  53. } else {
  54. return _rejectRelayedCall(uint256(GSNBouncerSignatureErrorCodes.INVALID_SIGNER));
  55. }
  56. }
  57. }