ERC777SenderRecipientMockUpgradeable.sol 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. import "../token/ERC777/IERC777Upgradeable.sol";
  4. import "../token/ERC777/IERC777SenderUpgradeable.sol";
  5. import "../token/ERC777/IERC777RecipientUpgradeable.sol";
  6. import "../utils/ContextUpgradeable.sol";
  7. import "../utils/introspection/IERC1820RegistryUpgradeable.sol";
  8. import "../utils/introspection/ERC1820ImplementerUpgradeable.sol";
  9. import "../proxy/utils/Initializable.sol";
  10. contract ERC777SenderRecipientMockUpgradeable is Initializable, ContextUpgradeable, IERC777SenderUpgradeable, IERC777RecipientUpgradeable, ERC1820ImplementerUpgradeable {
  11. function __ERC777SenderRecipientMock_init() internal onlyInitializing {
  12. __Context_init_unchained();
  13. __ERC1820Implementer_init_unchained();
  14. __ERC777SenderRecipientMock_init_unchained();
  15. }
  16. function __ERC777SenderRecipientMock_init_unchained() internal onlyInitializing {
  17. _erc1820 = IERC1820RegistryUpgradeable(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
  18. }
  19. event TokensToSendCalled(
  20. address operator,
  21. address from,
  22. address to,
  23. uint256 amount,
  24. bytes data,
  25. bytes operatorData,
  26. address token,
  27. uint256 fromBalance,
  28. uint256 toBalance
  29. );
  30. event TokensReceivedCalled(
  31. address operator,
  32. address from,
  33. address to,
  34. uint256 amount,
  35. bytes data,
  36. bytes operatorData,
  37. address token,
  38. uint256 fromBalance,
  39. uint256 toBalance
  40. );
  41. // Emitted in ERC777Mock. Here for easier decoding
  42. event BeforeTokenTransfer();
  43. bool private _shouldRevertSend;
  44. bool private _shouldRevertReceive;
  45. IERC1820RegistryUpgradeable private _erc1820;
  46. bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
  47. bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
  48. function tokensToSend(
  49. address operator,
  50. address from,
  51. address to,
  52. uint256 amount,
  53. bytes calldata userData,
  54. bytes calldata operatorData
  55. ) external override {
  56. if (_shouldRevertSend) {
  57. revert();
  58. }
  59. IERC777Upgradeable token = IERC777Upgradeable(_msgSender());
  60. uint256 fromBalance = token.balanceOf(from);
  61. // when called due to burn, to will be the zero address, which will have a balance of 0
  62. uint256 toBalance = token.balanceOf(to);
  63. emit TokensToSendCalled(
  64. operator,
  65. from,
  66. to,
  67. amount,
  68. userData,
  69. operatorData,
  70. address(token),
  71. fromBalance,
  72. toBalance
  73. );
  74. }
  75. function tokensReceived(
  76. address operator,
  77. address from,
  78. address to,
  79. uint256 amount,
  80. bytes calldata userData,
  81. bytes calldata operatorData
  82. ) external override {
  83. if (_shouldRevertReceive) {
  84. revert();
  85. }
  86. IERC777Upgradeable token = IERC777Upgradeable(_msgSender());
  87. uint256 fromBalance = token.balanceOf(from);
  88. // when called due to burn, to will be the zero address, which will have a balance of 0
  89. uint256 toBalance = token.balanceOf(to);
  90. emit TokensReceivedCalled(
  91. operator,
  92. from,
  93. to,
  94. amount,
  95. userData,
  96. operatorData,
  97. address(token),
  98. fromBalance,
  99. toBalance
  100. );
  101. }
  102. function senderFor(address account) public {
  103. _registerInterfaceForAddress(_TOKENS_SENDER_INTERFACE_HASH, account);
  104. address self = address(this);
  105. if (account == self) {
  106. registerSender(self);
  107. }
  108. }
  109. function registerSender(address sender) public {
  110. _erc1820.setInterfaceImplementer(address(this), _TOKENS_SENDER_INTERFACE_HASH, sender);
  111. }
  112. function recipientFor(address account) public {
  113. _registerInterfaceForAddress(_TOKENS_RECIPIENT_INTERFACE_HASH, account);
  114. address self = address(this);
  115. if (account == self) {
  116. registerRecipient(self);
  117. }
  118. }
  119. function registerRecipient(address recipient) public {
  120. _erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, recipient);
  121. }
  122. function setShouldRevertSend(bool shouldRevert) public {
  123. _shouldRevertSend = shouldRevert;
  124. }
  125. function setShouldRevertReceive(bool shouldRevert) public {
  126. _shouldRevertReceive = shouldRevert;
  127. }
  128. function send(
  129. IERC777Upgradeable token,
  130. address to,
  131. uint256 amount,
  132. bytes memory data
  133. ) public {
  134. // This is 777's send function, not the Solidity send function
  135. token.send(to, amount, data); // solhint-disable-line check-send-result
  136. }
  137. function burn(
  138. IERC777Upgradeable token,
  139. uint256 amount,
  140. bytes memory data
  141. ) public {
  142. token.burn(amount, data);
  143. }
  144. uint256[49] private __gap;
  145. }