From f8bfa560e9a10ffadbc278bfd4cfe8b404e5d300 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Tue, 8 Mar 2022 20:34:24 +0100 Subject: [PATCH] Use _spendAllowance in ERC20FlashMint (#3226) Co-authored-by: Francisco Giordano --- CHANGELOG.md | 1 + contracts/token/ERC20/extensions/ERC20FlashMint.sol | 4 +--- test/token/ERC20/extensions/ERC20FlashMint.test.js | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 365c4014639..31e5a191222 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * `ERC1155`: Add a `_afterTokenTransfer` hook for improved extensibility. ([#3166](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3166)) * `DoubleEndedQueue`: a new data structure that supports efficient push and pop to both front and back, useful for FIFO and LIFO queues. ([#3153](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3153)) * `Governor`: improved security of `onlyGovernance` modifier when using an external executor contract (e.g. a timelock) that can operate without necessarily going through the governance protocol. ([#3147](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3147)) + * `ERC20FlashMint`: support infinite allowance when paying back a flash loan. ([#3226](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3226)) * `Governor`: Add a way to parameterize votes. This can be used to implement voting systems such as fractionalized voting, ERC721 based voting, or any number of other systems. The `params` argument added to `_countVote` method, and included in the newly added `_getVotes` method, can be used by counting and voting modules respectively for such purposes. ### Breaking changes diff --git a/contracts/token/ERC20/extensions/ERC20FlashMint.sol b/contracts/token/ERC20/extensions/ERC20FlashMint.sol index cbcf3b60f2a..3d526c2d7d7 100644 --- a/contracts/token/ERC20/extensions/ERC20FlashMint.sol +++ b/contracts/token/ERC20/extensions/ERC20FlashMint.sol @@ -73,9 +73,7 @@ abstract contract ERC20FlashMint is ERC20, IERC3156FlashLender { receiver.onFlashLoan(msg.sender, token, amount, fee, data) == _RETURN_VALUE, "ERC20FlashMint: invalid return value" ); - uint256 currentAllowance = allowance(address(receiver), address(this)); - require(currentAllowance >= amount + fee, "ERC20FlashMint: allowance does not allow refund"); - _approve(address(receiver), address(this), currentAllowance - amount - fee); + _spendAllowance(address(receiver), address(this), amount + fee); _burn(address(receiver), amount + fee); return true; } diff --git a/test/token/ERC20/extensions/ERC20FlashMint.test.js b/test/token/ERC20/extensions/ERC20FlashMint.test.js index 97af5bb8032..0ecc056d667 100644 --- a/test/token/ERC20/extensions/ERC20FlashMint.test.js +++ b/test/token/ERC20/extensions/ERC20FlashMint.test.js @@ -67,7 +67,7 @@ contract('ERC20FlashMint', function (accounts) { const receiver = await ERC3156FlashBorrowerMock.new(true, false); await expectRevert( this.token.flashLoan(receiver.address, this.token.address, loanAmount, '0x'), - 'ERC20FlashMint: allowance does not allow refund', + 'ERC20: insufficient allowance', ); });