ERC777SenderRecipientMock.sol 4.1 KB

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