ERC777SenderRecipientMock.sol 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.6.0;
  3. import "../GSN/Context.sol";
  4. import "../token/ERC777/IERC777.sol";
  5. import "../token/ERC777/IERC777Sender.sol";
  6. import "../token/ERC777/IERC777Recipient.sol";
  7. import "../introspection/IERC1820Registry.sol";
  8. import "../introspection/ERC1820Implementer.sol";
  9. contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient, ERC1820Implementer {
  10. event TokensToSendCalled(
  11. address operator,
  12. address from,
  13. address to,
  14. uint256 amount,
  15. bytes data,
  16. bytes operatorData,
  17. address token,
  18. uint256 fromBalance,
  19. uint256 toBalance
  20. );
  21. event TokensReceivedCalled(
  22. address operator,
  23. address from,
  24. address to,
  25. uint256 amount,
  26. bytes data,
  27. bytes operatorData,
  28. address token,
  29. uint256 fromBalance,
  30. uint256 toBalance
  31. );
  32. bool private _shouldRevertSend;
  33. bool private _shouldRevertReceive;
  34. IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
  35. bytes32 constant private _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
  36. bytes32 constant private _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
  37. function tokensToSend(
  38. address operator,
  39. address from,
  40. address to,
  41. uint256 amount,
  42. bytes calldata userData,
  43. bytes calldata operatorData
  44. ) external override {
  45. if (_shouldRevertSend) {
  46. revert();
  47. }
  48. IERC777 token = IERC777(_msgSender());
  49. uint256 fromBalance = token.balanceOf(from);
  50. // when called due to burn, to will be the zero address, which will have a balance of 0
  51. uint256 toBalance = token.balanceOf(to);
  52. emit TokensToSendCalled(
  53. operator,
  54. from,
  55. to,
  56. amount,
  57. userData,
  58. operatorData,
  59. address(token),
  60. fromBalance,
  61. toBalance
  62. );
  63. }
  64. function tokensReceived(
  65. address operator,
  66. address from,
  67. address to,
  68. uint256 amount,
  69. bytes calldata userData,
  70. bytes calldata operatorData
  71. ) external override {
  72. if (_shouldRevertReceive) {
  73. revert();
  74. }
  75. IERC777 token = IERC777(_msgSender());
  76. uint256 fromBalance = token.balanceOf(from);
  77. // when called due to burn, to will be the zero address, which will have a balance of 0
  78. uint256 toBalance = token.balanceOf(to);
  79. emit TokensReceivedCalled(
  80. operator,
  81. from,
  82. to,
  83. amount,
  84. userData,
  85. operatorData,
  86. address(token),
  87. fromBalance,
  88. toBalance
  89. );
  90. }
  91. function senderFor(address account) public {
  92. _registerInterfaceForAddress(_TOKENS_SENDER_INTERFACE_HASH, account);
  93. address self = address(this);
  94. if (account == self) {
  95. registerSender(self);
  96. }
  97. }
  98. function registerSender(address sender) public {
  99. _erc1820.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, sender);
  100. }
  101. function recipientFor(address account) public {
  102. _registerInterfaceForAddress(_TOKENS_RECIPIENT_INTERFACE_HASH, account);
  103. address self = address(this);
  104. if (account == self) {
  105. registerRecipient(self);
  106. }
  107. }
  108. function registerRecipient(address recipient) public {
  109. _erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, recipient);
  110. }
  111. function setShouldRevertSend(bool shouldRevert) public {
  112. _shouldRevertSend = shouldRevert;
  113. }
  114. function setShouldRevertReceive(bool shouldRevert) public {
  115. _shouldRevertReceive = shouldRevert;
  116. }
  117. function send(IERC777 token, address to, uint256 amount, bytes memory data) public {
  118. // This is 777's send function, not the Solidity send function
  119. token.send(to, amount, data); // solhint-disable-line check-send-result
  120. }
  121. function burn(IERC777 token, uint256 amount, bytes memory data) public {
  122. token.burn(amount, data);
  123. }
  124. }