ERC20Tornado.sol 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // https://tornado.cash
  2. /*
  3. * d888888P dP a88888b. dP
  4. * 88 88 d8' `88 88
  5. * 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
  6. * 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
  7. * 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
  8. * dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
  9. * ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
  10. */
  11. // SPDX-License-Identifier: MIT
  12. pragma solidity ^0.7.0;
  13. import "./Tornado.sol";
  14. import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
  15. import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
  16. contract ERC20Tornado is Tornado {
  17. using SafeERC20 for IERC20;
  18. IERC20 public token;
  19. constructor(
  20. IVerifier _verifier,
  21. IHasher _hasher,
  22. uint256 _denomination,
  23. uint32 _merkleTreeHeight,
  24. IERC20 _token
  25. ) Tornado(_verifier, _hasher, _denomination, _merkleTreeHeight) {
  26. token = _token;
  27. }
  28. function _processDeposit() internal override {
  29. require(msg.value == 0, "ETH value is supposed to be 0 for ERC20 instance");
  30. token.safeTransferFrom(msg.sender, address(this), denomination);
  31. }
  32. function _processWithdraw(
  33. address payable _recipient,
  34. address payable _relayer,
  35. uint256 _fee,
  36. uint256 _refund
  37. ) internal override {
  38. require(msg.value == _refund, "Incorrect refund amount received by the contract");
  39. token.safeTransfer(_recipient, denomination - _fee);
  40. if (_fee > 0) {
  41. token.safeTransfer(_relayer, _fee);
  42. }
  43. if (_refund > 0) {
  44. (bool success, ) = _recipient.call{ value: _refund }("");
  45. if (!success) {
  46. // let's return _refund back to the relayer
  47. _relayer.transfer(_refund);
  48. }
  49. }
  50. }
  51. }