SafeERC20Helper.sol 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. import "../utils/Context.sol";
  4. import "../token/ERC20/IERC20.sol";
  5. import "../token/ERC20/extensions/ERC20Permit.sol";
  6. import "../token/ERC20/utils/SafeERC20.sol";
  7. contract ERC20ReturnFalseMock is Context {
  8. uint256 private _allowance;
  9. // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
  10. // we write to a dummy state variable.
  11. uint256 private _dummy;
  12. function transfer(address, uint256) public returns (bool) {
  13. _dummy = 0;
  14. return false;
  15. }
  16. function transferFrom(address, address, uint256) public returns (bool) {
  17. _dummy = 0;
  18. return false;
  19. }
  20. function approve(address, uint256) public returns (bool) {
  21. _dummy = 0;
  22. return false;
  23. }
  24. function allowance(address, address) public view returns (uint256) {
  25. require(_dummy == 0); // Dummy read from a state variable so that the function is view
  26. return 0;
  27. }
  28. }
  29. contract ERC20ReturnTrueMock is Context {
  30. mapping(address => uint256) private _allowances;
  31. // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
  32. // we write to a dummy state variable.
  33. uint256 private _dummy;
  34. function transfer(address, uint256) public returns (bool) {
  35. _dummy = 0;
  36. return true;
  37. }
  38. function transferFrom(address, address, uint256) public returns (bool) {
  39. _dummy = 0;
  40. return true;
  41. }
  42. function approve(address, uint256) public returns (bool) {
  43. _dummy = 0;
  44. return true;
  45. }
  46. function setAllowance(uint256 allowance_) public {
  47. _allowances[_msgSender()] = allowance_;
  48. }
  49. function allowance(address owner, address) public view returns (uint256) {
  50. return _allowances[owner];
  51. }
  52. }
  53. contract ERC20NoReturnMock is Context {
  54. mapping(address => uint256) private _allowances;
  55. // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
  56. // we write to a dummy state variable.
  57. uint256 private _dummy;
  58. function transfer(address, uint256) public {
  59. _dummy = 0;
  60. }
  61. function transferFrom(address, address, uint256) public {
  62. _dummy = 0;
  63. }
  64. function approve(address, uint256) public {
  65. _dummy = 0;
  66. }
  67. function setAllowance(uint256 allowance_) public {
  68. _allowances[_msgSender()] = allowance_;
  69. }
  70. function allowance(address owner, address) public view returns (uint256) {
  71. return _allowances[owner];
  72. }
  73. }
  74. contract ERC20PermitNoRevertMock is
  75. ERC20("ERC20PermitNoRevertMock", "ERC20PermitNoRevertMock"),
  76. ERC20Permit("ERC20PermitNoRevertMock")
  77. {
  78. function getChainId() external view returns (uint256) {
  79. return block.chainid;
  80. }
  81. function permitThatMayRevert(
  82. address owner,
  83. address spender,
  84. uint256 value,
  85. uint256 deadline,
  86. uint8 v,
  87. bytes32 r,
  88. bytes32 s
  89. ) public {
  90. super.permit(owner, spender, value, deadline, v, r, s);
  91. }
  92. function permit(
  93. address owner,
  94. address spender,
  95. uint256 value,
  96. uint256 deadline,
  97. uint8 v,
  98. bytes32 r,
  99. bytes32 s
  100. ) public override {
  101. try this.permitThatMayRevert(owner, spender, value, deadline, v, r, s) {
  102. // do nothing
  103. } catch {
  104. // do nothing
  105. }
  106. }
  107. }
  108. contract SafeERC20Wrapper is Context {
  109. using SafeERC20 for IERC20;
  110. IERC20 private _token;
  111. constructor(IERC20 token) {
  112. _token = token;
  113. }
  114. function transfer() public {
  115. _token.safeTransfer(address(0), 0);
  116. }
  117. function transferFrom() public {
  118. _token.safeTransferFrom(address(0), address(0), 0);
  119. }
  120. function approve(uint256 amount) public {
  121. _token.safeApprove(address(0), amount);
  122. }
  123. function increaseAllowance(uint256 amount) public {
  124. _token.safeIncreaseAllowance(address(0), amount);
  125. }
  126. function decreaseAllowance(uint256 amount) public {
  127. _token.safeDecreaseAllowance(address(0), amount);
  128. }
  129. function permit(
  130. address owner,
  131. address spender,
  132. uint256 value,
  133. uint256 deadline,
  134. uint8 v,
  135. bytes32 r,
  136. bytes32 s
  137. ) public {
  138. SafeERC20.safePermit(IERC20Permit(address(_token)), owner, spender, value, deadline, v, r, s);
  139. }
  140. function setAllowance(uint256 allowance_) public {
  141. ERC20ReturnTrueMock(address(_token)).setAllowance(allowance_);
  142. }
  143. function allowance() public view returns (uint256) {
  144. return _token.allowance(address(0), address(0));
  145. }
  146. }