diff --git a/contracts/ERC20.sol b/contracts/ERC20.sol index e401820d2504..07f3b9c88155 100644 --- a/contracts/ERC20.sol +++ b/contracts/ERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; -import { IERC20 } from "./interfaces/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @title ERC20 diff --git a/contracts/L1LiquidityPool.sol b/contracts/L1LiquidityPool.sol index 731f4267f17b..0d38f7c3ccd9 100644 --- a/contracts/L1LiquidityPool.sol +++ b/contracts/L1LiquidityPool.sol @@ -3,7 +3,6 @@ pragma solidity >0.5.0; pragma experimental ABIEncoderV2; -import "./interfaces/IERC20.sol"; import { iL2LiquidityPool } from "./interfaces/iL2LiquidityPool.sol"; /* Library Imports */ @@ -11,11 +10,13 @@ import { OVM_CrossDomainEnabled } from "enyalabs_contracts/build/contracts/libra /* External Imports */ import '@openzeppelin/contracts/math/SafeMath.sol'; - +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; /** * @dev An L1 LiquidityPool implementation */ contract L1LiquidityPool is OVM_CrossDomainEnabled { + using SafeERC20 for IERC20; using SafeMath for uint256; uint256 constant internal SAFE_GAS_STIPEND = 2300; @@ -32,7 +33,7 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { // this is to stop attacks where caller specifies l2contractaddress // also acts as a whitelist mapping(address => address) l2ContractAddress; - + address owner; address l2LiquidityPoolAddress; uint256 fee; @@ -132,7 +133,7 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { // use with caution, can register only once require(l2ContractAddress[_erc20L1ContractAddress] == address(0), "Token Address Already Registerd"); l2ContractAddress[_erc20L1ContractAddress] = _erc20L2ContractAddress; - } + } /** * @dev Receive ETH @@ -236,14 +237,14 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { function ownerAddERC20Liquidity( uint256 _amount, address _erc20L1ContractAddress - ) + ) external - onlyOwner() - { + onlyOwner() + { require(l2ContractAddress[_erc20L1ContractAddress] != address(0), "Token L2 address not registered"); IERC20 erc20Contract = IERC20(_erc20L1ContractAddress); require(_amount <= erc20Contract.allowance(msg.sender, address(this))); - require(erc20Contract.transferFrom(msg.sender, address(this), _amount), "ERC20 token transfer was unsuccessful"); + erc20Contract.safeTransferFrom(msg.sender, address(this), _amount); // balances[_erc20L1ContractAddress] = balances[_erc20L1ContractAddress].add(_amount); @@ -264,12 +265,12 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { address _erc20L1ContractAddress ) external - { + { require(l2ContractAddress[_erc20L1ContractAddress] != address(0), "Token L2 address not registered"); IERC20 erc20Contract = IERC20(_erc20L1ContractAddress); require(_amount <= erc20Contract.allowance(msg.sender, address(this))); - require(erc20Contract.transferFrom(msg.sender, address(this), _amount), "ERC20 token transfer was unsuccessful"); - + erc20Contract.safeTransferFrom(msg.sender, address(this), _amount); + //Augment the pool size for this ERC20 uint256 _swapFee = (_amount.mul(fee)).div(100); uint256 _receivedAmount = _amount.sub(_swapFee); @@ -310,14 +311,14 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { ) external onlyOwner() - { + { if (_erc20ContractAddress != address(0)) { IERC20 erc20Contract = IERC20(_erc20ContractAddress); uint256 withdrawableLiquidity = (erc20Contract.balanceOf(address(this))).sub(fees[_erc20ContractAddress]); require(withdrawableLiquidity >= _amount, "Not enough liquidity on the pool to withdraw"); // balances[_erc20ContractAddress] = balances[_erc20ContractAddress].sub(_amount); // use safe erc20 transfer - require(erc20Contract.transfer(_to, _amount)); + erc20Contract.safeTransfer(_to, _amount); } else { uint256 withdrawableLiquidity = (address(this).balance).sub(fees[_erc20ContractAddress]); require(withdrawableLiquidity >= _amount, "Not enough liquidity on the pool to withdraw"); @@ -347,15 +348,14 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { ) external onlyOwner() - { + { if (_erc20ContractAddress != address(0)) { //we are dealing with an ERC20 IERC20 erc20Contract = IERC20(_erc20ContractAddress); require(erc20Contract.balanceOf(address(this)) >= _amount); fees[_erc20ContractAddress] = fees[_erc20ContractAddress].sub(_amount); // balances[_erc20ContractAddress] = balances[_erc20ContractAddress].sub(_amount); - // use safe erc20 transfer - require(erc20Contract.transfer(_to, _amount)); + erc20Contract.safeTransfer(_to, _amount); } else { //we are dealing with Ether //address(this).balance is not supported @@ -396,12 +396,12 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { ) external onlyFromCrossDomainAccount(address(l2LiquidityPoolAddress)) - { + { if (_erc20ContractAddress != address(0)) { //dealing with an ERC20 IERC20 erc20Contract = IERC20(_erc20ContractAddress); // balances[_erc20ContractAddress] = balances[_erc20ContractAddress].sub(_amount); - require(erc20Contract.transfer(_to, _amount)); + erc20Contract.safeTransfer(_to, _amount); } else { //this is ETH // balances[address(0)] = balances[address(0)].sub(_amount); @@ -409,7 +409,7 @@ contract L1LiquidityPool is OVM_CrossDomainEnabled { (bool sent,) = _to.call{gas: SAFE_GAS_STIPEND, value: _amount}(""); require(sent, "Failed to send Ether"); } - + emit clientPayL1_EVENT( _to, _amount, diff --git a/contracts/L2LiquidityPool.sol b/contracts/L2LiquidityPool.sol index 7bd42d1c8527..822c4e2c38f7 100644 --- a/contracts/L2LiquidityPool.sol +++ b/contracts/L2LiquidityPool.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity >0.5.0; -import "./interfaces/IERC20.sol"; import { iL1LiquidityPool } from "./interfaces/iL1LiquidityPool.sol"; /* Library Imports */ @@ -9,12 +8,15 @@ import { OVM_CrossDomainEnabled } from "enyalabs_contracts/build/contracts/libra /* External Imports */ import '@openzeppelin/contracts/math/SafeMath.sol'; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; /** * @dev An L2 LiquidityPool implementation */ contract L2LiquidityPool is OVM_CrossDomainEnabled { + using SafeERC20 for IERC20; using SafeMath for uint256; /************* @@ -54,7 +56,7 @@ contract L2LiquidityPool is OVM_CrossDomainEnabled { /******************** * Event * ********************/ - + event ownerAddERC20Liquidity_EVENT( address sender, uint256 amount, @@ -141,7 +143,7 @@ contract L2LiquidityPool is OVM_CrossDomainEnabled { require(l1ContractAddress[_erc20L2ContractAddress] == address(0), "Token Address Already Registerd"); require(!isL2Eth[_erc20L2ContractAddress], "Cannot replace Eth Address"); l1ContractAddress[_erc20L2ContractAddress] = _erc20L1ContractAddress; - } + } /** * @dev Overridable getter for the *L2* gas limit of settling the deposit, in the case it may be @@ -215,14 +217,14 @@ contract L2LiquidityPool is OVM_CrossDomainEnabled { function ownerAddERC20Liquidity( uint256 _amount, address _erc20L2ContractAddress - ) + ) external - onlyOwner() + onlyOwner() { require(l1ContractAddress[_erc20L2ContractAddress] != address(0) || isL2Eth[_erc20L2ContractAddress], "Token Address Not Registerd"); IERC20 erc20Contract = IERC20(_erc20L2ContractAddress); require(_amount <= erc20Contract.allowance(msg.sender, address(this))); - require(erc20Contract.transferFrom(msg.sender, address(this), _amount), "ERC20 token transfer was unsuccessful"); + erc20Contract.safeTransferFrom(msg.sender, address(this), _amount); // balances[_erc20L2ContractAddress] = balances[_erc20L2ContractAddress].add(_amount); @@ -247,7 +249,7 @@ contract L2LiquidityPool is OVM_CrossDomainEnabled { require(l1ContractAddress[_erc20L2ContractAddress] != address(0) || isL2Eth[_erc20L2ContractAddress], "Token Address Not Registerd"); IERC20 erc20Contract = IERC20(_erc20L2ContractAddress); require(_amount <= erc20Contract.allowance(msg.sender, address(this))); - require(erc20Contract.transferFrom(msg.sender, address(this), _amount), "ERC20 token transfer was unsuccessful"); + erc20Contract.safeTransferFrom(msg.sender, address(this), _amount); //Augment the pool size for this ERC20 uint256 _swapFee = (_amount.mul(fee)).div(100); @@ -288,13 +290,13 @@ contract L2LiquidityPool is OVM_CrossDomainEnabled { ) external onlyOwner() - { + { IERC20 erc20Contract = IERC20(_erc20ContractAddress); uint256 withdrawableLiquidity = (erc20Contract.balanceOf(address(this))).sub(fees[_erc20ContractAddress]); require(withdrawableLiquidity >= _amount, "Not enough liquidity on the pool to withdraw"); // balances[_erc20ContractAddress] = balances[_erc20ContractAddress].sub(_amount); // use safe erc20 transfer - require(erc20Contract.transfer(_to, _amount)); + erc20Contract.safeTransfer(_to, _amount); emit ownerWithdrawLiquidity_EVENT( msg.sender, @@ -323,7 +325,7 @@ contract L2LiquidityPool is OVM_CrossDomainEnabled { require(erc20Contract.balanceOf(address(this)) >= _amount); fees[_erc20ContractAddress] = fees[_erc20ContractAddress].sub(_amount); // balances[_erc20ContractAddress] = balances[_erc20ContractAddress].sub(_amount); - require(erc20Contract.transfer(_to, _amount)); + erc20Contract.safeTransfer(_to, _amount); emit ownerRecoverFee_EVENT( msg.sender, @@ -354,14 +356,14 @@ contract L2LiquidityPool is OVM_CrossDomainEnabled { { IERC20 erc20Contract = IERC20(_erc20ContractAddress); // balances[_erc20ContractAddress] = balances[_erc20ContractAddress].sub(_amount); - require(erc20Contract.transfer(_to, _amount)); + erc20Contract.safeTransfer(_to, _amount); + - emit clientPayL2_EVENT( _to, _amount, _erc20ContractAddress ); } - + } diff --git a/contracts/interfaces/IERC20.sol b/contracts/interfaces/IERC20.sol deleted file mode 100644 index 25631c46f025..000000000000 --- a/contracts/interfaces/IERC20.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >0.5.0 <0.8.0; - -/** - * @title IERC20 - */ -interface IERC20 { - /* This is a slight change to the ERC20 base standard. - function totalSupply() constant returns (uint256 supply); - is replaced with: - uint256 public totalSupply; - This automatically creates a getter function for the totalSupply. - This is moved to the base contract since public getter functions are not - currently recognised as an implementation of the matching abstract - function by the compiler. - */ - /// total amount of tokens - function totalSupply() external view returns (uint256); - - /// @param _owner The address from which the balance will be retrieved - /// @return balance The balance - function balanceOf(address _owner) external view returns (uint256 balance); - - /// @notice send `_value` token to `_to` from `msg.sender` - /// @param _to The address of the recipient - /// @param _value The amount of token to be transferred - /// @return success Whether the transfer was successful or not - function transfer(address _to, uint256 _value) external returns (bool success); - - /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from` - /// @param _from The address of the sender - /// @param _to The address of the recipient - /// @param _value The amount of token to be transferred - /// @return success Whether the transfer was successful or not - function transferFrom(address _from, address _to, uint256 _value) external returns (bool success); - - /// @notice `msg.sender` approves `_spender` to spend `_value` tokens - /// @param _spender The address of the account able to transfer the tokens - /// @param _value The amount of tokens to be approved for transfer - /// @return success Whether the approval was successful or not - function approve(address _spender, uint256 _value) external returns (bool success); - - /// @param _owner The address of the account owning tokens - /// @param _spender The address of the account able to transfer the tokens - /// @return remaining Amount of remaining tokens allowed to spent - function allowance(address _owner, address _spender) external view returns (uint256 remaining); - - // solhint-disable-next-line no-simple-event-func-name - event Transfer(address indexed _from, address indexed _to, uint256 _value); - event Approval(address indexed _owner, address indexed _spender, uint256 _value); - event Mint(address indexed _account, uint256 _amount); - event Burn(address indexed _account, uint256 _amount); -} diff --git a/contracts/interfaces/IUniswapV2ERC20.sol b/contracts/interfaces/IUniswapV2ERC20.sol deleted file mode 100644 index b713c55a868b..000000000000 --- a/contracts/interfaces/IUniswapV2ERC20.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity >=0.5.16 <0.8.0; - -interface IUniswapV2ERC20 { - event Approval(address indexed owner, address indexed spender, uint value); - event Transfer(address indexed from, address indexed to, uint value); - - function name() external view returns (string memory); - function symbol() external view returns (string memory); - function decimals() external view returns (uint8); - function totalSupply() external view returns (uint); - function balanceOf(address owner) external view returns (uint); - function allowance(address owner, address spender) external view returns (uint); - - function approve(address spender, uint value) external returns (bool); - function transfer(address to, uint value) external returns (bool); - function transferFrom(address from, address to, uint value) external returns (bool); - - function DOMAIN_SEPARATOR() external view returns (bytes32); - function PERMIT_TYPEHASH() external pure returns (bytes32); - function nonces(address owner) external view returns (uint); - - function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; -}