ERC777SenderRecipientMock.sol 4.1 KB

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