SafeERC20Helper.sol 4.8 KB

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