Explorar o código

Use SafeERC20.forceApprove in safeIncreaseAllowance and safeDecreaseAllowance (#4260)

Co-authored-by: Francisco <fg@frang.io>
Hadrien Croubois %!s(int64=2) %!d(string=hai) anos
pai
achega
25edd3cd62

+ 5 - 0
.changeset/wild-windows-trade.md

@@ -0,0 +1,5 @@
+---
+'openzeppelin-solidity': major
+---
+
+`SafeERC20`: Refactor `safeDecreaseAllowance` and `safeIncreaseAllowance` to support USDT-like tokens.

+ 2 - 2
contracts/token/ERC20/utils/SafeERC20.sol

@@ -41,7 +41,7 @@ library SafeERC20 {
      */
     function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
         uint256 oldAllowance = token.allowance(address(this), spender);
-        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
+        forceApprove(token, spender, oldAllowance + value);
     }
 
     /**
@@ -52,7 +52,7 @@ library SafeERC20 {
         unchecked {
             uint256 oldAllowance = token.allowance(address(this), spender);
             require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
-            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
+            forceApprove(token, spender, oldAllowance - value);
         }
     }
 

+ 7 - 4
test/token/ERC20/utils/SafeERC20.test.js

@@ -182,16 +182,19 @@ contract('SafeERC20', function (accounts) {
         await this.token.$_approve(this.mock.address, spender, 100);
       });
 
-      it('safeApprove can increase approval', async function () {
-        await expectRevert(this.mock.$safeIncreaseAllowance(this.token.address, spender, 10), 'USDT approval failure');
+      it('safeIncreaseAllowance works', async function () {
+        await this.mock.$safeIncreaseAllowance(this.token.address, spender, 10);
+        expect(this.token.allowance(this.mock.address, spender, 90));
       });
 
-      it('safeApprove can decrease approval', async function () {
-        await expectRevert(this.mock.$safeDecreaseAllowance(this.token.address, spender, 10), 'USDT approval failure');
+      it('safeDecreaseAllowance works', async function () {
+        await this.mock.$safeDecreaseAllowance(this.token.address, spender, 10);
+        expect(this.token.allowance(this.mock.address, spender, 110));
       });
 
       it('forceApprove works', async function () {
         await this.mock.$forceApprove(this.token.address, spender, 200);
+        expect(this.token.allowance(this.mock.address, spender, 200));
       });
     });
   });