From 8660a2c6f62b07a7060557f29ca0f629e42cbdd8 Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Tue, 16 Oct 2018 12:37:47 +0530 Subject: [PATCH] suggested changes done --- contracts/mocks/SafeERC20Helper.sol | 31 ++++++++++++++++---- contracts/token/ERC20/IERC20.sol | 6 ---- contracts/token/ERC20/ISafeERC20.sol | 43 ++++++++++++++++++++++++++++ contracts/token/ERC20/SafeERC20.sol | 36 +++++++++++++++++------ 4 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 contracts/token/ERC20/ISafeERC20.sol diff --git a/contracts/mocks/SafeERC20Helper.sol b/contracts/mocks/SafeERC20Helper.sol index c020df7dc..52f618b05 100644 --- a/contracts/mocks/SafeERC20Helper.sol +++ b/contracts/mocks/SafeERC20Helper.sol @@ -1,9 +1,10 @@ pragma solidity ^0.4.24; -import "../token/ERC20/IERC20.sol"; +import "../token/ERC20/ISafeERC20.sol"; import "../token/ERC20/SafeERC20.sol"; -contract ERC20FailingMock is IERC20 { +contract ERC20FailingMock is ISafeERC20 { + uint256 private _allowance; function totalSupply() public view returns (uint256) { return 0; } @@ -35,10 +36,18 @@ contract ERC20FailingMock is IERC20 { function allowance(address, address) public view returns (uint256) { return 0; } + + function setAllowance(uint256 value) public { + _allowance = value; + } } -contract ERC20SucceedingMock { - uint256 private _allowance; +contract ERC20SucceedingMock is ISafeERC20 { + uint256 private _allowance; + + function totalSupply() public view returns (uint256) { + return 0; + } function transfer(address, uint256) public returns (bool) { return true; @@ -65,15 +74,26 @@ contract ERC20SucceedingMock { } function allowance(address, address) public view returns (uint256) { - return 10; //non-zero allowance + return _allowance; + } + + function setAllowance(uint256 value) public { + _allowance = value; } } contract SafeERC20Helper { +<<<<<<< b40c76d0b1e2fc356c63a01d0d6eb1abd0196a73 using SafeERC20 for IERC20; IERC20 private _failing; IERC20 private _succeeding; +======= + using SafeERC20 for ISafeERC20; + + ISafeERC20 private _failing; + ISafeERC20 private _succeeding; +>>>>>>> suggested changes done constructor () public { _failing = IERC20(new ERC20FailingMock()); @@ -141,6 +161,7 @@ contract SafeERC20Helper { } function doFailingApproveByValue() public { + _succeeding.setAllowance(10); _succeeding.safeApprove(address(0), 10); } diff --git a/contracts/token/ERC20/IERC20.sol b/contracts/token/ERC20/IERC20.sol index 96c689463..ac2d85331 100644 --- a/contracts/token/ERC20/IERC20.sol +++ b/contracts/token/ERC20/IERC20.sol @@ -17,12 +17,6 @@ interface IERC20 { function transferFrom(address from, address to, uint256 value) external returns (bool); - function increaseAllowance(address spender, uint256 addedValue) - external returns (bool); - - function decreaseAllowance(address spender, uint256 subtractedValue) - external returns (bool); - event Transfer( address indexed from, address indexed to, diff --git a/contracts/token/ERC20/ISafeERC20.sol b/contracts/token/ERC20/ISafeERC20.sol new file mode 100644 index 000000000..b04e010df --- /dev/null +++ b/contracts/token/ERC20/ISafeERC20.sol @@ -0,0 +1,43 @@ +pragma solidity ^0.4.24; + +/** + * @title SafeERC20 interface + * @dev ERC20 operations with allowance operations. For ERC20, see https://github.com/ethereum/EIPs/issues/20 + */ +interface ISafeERC20 { + function totalSupply() external view returns (uint256); + + function balanceOf(address who) external view returns (uint256); + + function allowance(address owner, address spender) + external view returns (uint256); + + function transfer(address to, uint256 value) external returns (bool); + + function approve(address spender, uint256 value) + external returns (bool); + + function transferFrom(address from, address to, uint256 value) + external returns (bool); + + function increaseAllowance(address spender, uint256 addedValue) + external returns (bool); + + function decreaseAllowance(address spender, uint256 subtractedValue) + external returns (bool); + + function setAllowance(uint256 value) + external returns (bool); + + event Transfer( + address indexed from, + address indexed to, + uint256 value + ); + + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); +} diff --git a/contracts/token/ERC20/SafeERC20.sol b/contracts/token/ERC20/SafeERC20.sol index 473c2c431..1b91e8236 100644 --- a/contracts/token/ERC20/SafeERC20.sol +++ b/contracts/token/ERC20/SafeERC20.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.24; -import "./IERC20.sol"; -import "../../math/SafeMath.sol"; +import "./ERC20.sol"; +import "./ISafeERC20.sol"; /** * @title SafeERC20 @@ -10,25 +10,43 @@ import "../../math/SafeMath.sol"; * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { - using SafeMath for uint256; + function safeTransfer( + ISafeERC20 token, + address to, + uint256 value + ) + internal + { + require(token.transfer(to, value)); + } - function safeTransfer(IERC20 token, address to, uint256 value) internal { - require(token.transfer(to, value)); - } + function safeTransferFrom( + ISafeERC20 token, + address from, + address to, + uint256 value + ) + internal + { + require(token.transferFrom(from, to, value)); + } function safeApprove( - IERC20 token, + ISafeERC20 token, address spender, uint256 value ) internal { + // safeApprove should only be called when setting an initial allowance, + // or when resetting it to zero. To increase and decrease it, use + // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require((value == 0) || (token.allowance(msg.sender, spender) == 0)); require(token.approve(spender, value)); } function safeIncreaseAllowance( - IERC20 token, + ISafeERC20 token, address spender, uint256 addedValue ) @@ -38,7 +56,7 @@ library SafeERC20 { } function safeDecreaseAllowance( - IERC20 token, + ISafeERC20 token, address spender, uint256 subtractedValue )