From 52cec16eb2b54468aa5e2c14523dc22d88218978 Mon Sep 17 00:00:00 2001 From: Steffel <2143646+steffenix@users.noreply.github.com> Date: Tue, 6 Apr 2021 01:42:07 +0200 Subject: [PATCH] chore: update to solidity 0.8 (#244) * feat: solidity 0.8 * chore: openzeppelin 4.0.0 * fix: update README.md Co-authored-by: Just some guy <3859395+fubuloubu@users.noreply.github.com> * fix: suggestions Co-authored-by: Just some guy <3859395+fubuloubu@users.noreply.github.com> fix: missed Co-authored-by: Just some guy <3859395+fubuloubu@users.noreply.github.com> * fix: fix unwanted replace * fix: missed suggestions Co-authored-by: Just some guy <3859395+fubuloubu@users.noreply.github.com> --- README.md | 4 ++-- brownie-config.yaml | 7 +++--- contracts/BaseStrategy.sol | 37 +++++++++++++--------------- contracts/BaseWrapper.sol | 40 +++++++++++++------------------ contracts/test/AffiliateToken.sol | 23 +++++++++++------- contracts/test/TestGuestList.sol | 5 ++-- contracts/test/TestStrategy.sol | 20 ++++++++-------- contracts/test/Token.sol | 30 ++++++++++++----------- contracts/yToken.sol | 23 +++++++----------- 9 files changed, 90 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index 27efe61e..8ced17d0 100644 --- a/README.md +++ b/README.md @@ -99,11 +99,11 @@ Any command `in code blocks` is meant to be executed from a Mac/Linux terminal o - If you're in Windows using WSL, type `code .` to launch VSCode - At this point install [Solidity Compiler](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) - be sure to _Install in WSL_ - Install [Vyper](https://marketplace.visualstudio.com/items?itemName=tintinweb.vscode-vyper) as well on WSL - - Open one of the .sol files, right click the code and click _Soldity: Change Workspace compiler version (Remote)_, Change to 0.6.12 + - Open one of the .sol files, right click the code and click _Solidity: Change Workspace compiler version (Remote)_, Change to 0.8.3 - Alternatively, go to File -> Preferences -> Settings - If you’re using WSL, go to the Remote [WSL] tab - Otherwise choose the Workspace tab - - Search for _Solidity_ and copy and paste _v0.6.12+commit.27d51765_ into the _Solidity: Compile Using Remote Version_ textbox + - Search for _Solidity_ and copy and paste _v0.8.3_ into the _Solidity: Compile Using Remote Version_ textbox - Set Black as the linter. - You'll see a toast notification the bottom right asking about linting, choose _black_ - If you don't see this, just go to _File_ -> _Preferences_ -> _Settings_ diff --git a/brownie-config.yaml b/brownie-config.yaml index ccb46535..e1af621b 100644 --- a/brownie-config.yaml +++ b/brownie-config.yaml @@ -6,20 +6,19 @@ autofetch_sources: true # require OpenZepplin Contracts dependencies: - - OpenZeppelin/openzeppelin-contracts@3.1.0 + - OpenZeppelin/openzeppelin-contracts@4.0.0 # path remapping to support OpenZepplin imports with NPM-style path compiler: solc: - version: 0.6.12 + version: 0.8.3 remappings: - - "@openzeppelin=OpenZeppelin/openzeppelin-contracts@3.1.0" + - "@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.0.0" reports: exclude_paths: - contracts/test/Token.sol - contracts/test/TestGuestList.sol exclude_contracts: - - SafeMath - SafeERC20 - Address diff --git a/contracts/BaseStrategy.sol b/contracts/BaseStrategy.sol index 28992e1d..e4c18744 100644 --- a/contracts/BaseStrategy.sol +++ b/contracts/BaseStrategy.sol @@ -1,10 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.6.0 <0.7.0; -pragma experimental ABIEncoderV2; +pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; -import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; struct StrategyParams { uint256 performanceFee; @@ -176,7 +175,6 @@ interface StrategyAPI { * `harvest()`, and `harvestTrigger()` for further details. */ abstract contract BaseStrategy { - using SafeMath for uint256; using SafeERC20 for IERC20; string public metadataURI; @@ -295,7 +293,7 @@ abstract contract BaseStrategy { _; } - constructor(address _vault) public { + constructor(address _vault) { _initialize(_vault, msg.sender, msg.sender, msg.sender); } @@ -316,18 +314,17 @@ abstract contract BaseStrategy { vault = VaultAPI(_vault); want = IERC20(vault.token()); - want.safeApprove(_vault, uint256(-1)); // Give Vault unlimited access (might save gas) + want.safeApprove(_vault, type(uint256).max); // Give Vault unlimited access (might save gas) strategist = _strategist; rewards = _rewards; keeper = _keeper; - // initialize variables minReportDelay = 0; maxReportDelay = 86400; profitFactor = 100; debtThreshold = 0; - vault.approve(rewards, uint256(-1)); // Allow rewards to be pulled + vault.approve(rewards, type(uint256).max); // Allow rewards to be pulled } /** @@ -374,7 +371,7 @@ abstract contract BaseStrategy { require(_rewards != address(0)); vault.approve(rewards, 0); rewards = _rewards; - vault.approve(rewards, uint256(-1)); + vault.approve(rewards, type(uint256).max); emit UpdatedRewards(_rewards); } @@ -638,10 +635,10 @@ abstract contract BaseStrategy { if (params.activation == 0) return false; // Should not trigger if we haven't waited long enough since previous harvest - if (block.timestamp.sub(params.lastReport) < minReportDelay) return false; + if ((block.timestamp - params.lastReport) < minReportDelay) return false; // Should trigger if hasn't been called in a while - if (block.timestamp.sub(params.lastReport) >= maxReportDelay) return true; + if ((block.timestamp - params.lastReport) >= maxReportDelay) return true; // If some amount is owed, pay it back // NOTE: Since debt is based on deposits, it makes sense to guard against large @@ -654,15 +651,15 @@ abstract contract BaseStrategy { // Check for profits and losses uint256 total = estimatedTotalAssets(); // Trigger if we have a loss to report - if (total.add(debtThreshold) < params.totalDebt) return true; + if ((total + debtThreshold) < params.totalDebt) return true; uint256 profit = 0; - if (total > params.totalDebt) profit = total.sub(params.totalDebt); // We've earned a profit! + if (total > params.totalDebt) profit = total - params.totalDebt; // We've earned a profit! // Otherwise, only trigger if it "makes sense" economically (gas cost // is debtOutstanding ? totalAssets : debtOutstanding); // NOTE: take up any remainder here as profit if (debtPayment > debtOutstanding) { - profit = debtPayment.sub(debtOutstanding); + profit = debtPayment - debtOutstanding; debtPayment = debtOutstanding; } } else { @@ -727,7 +724,7 @@ abstract contract BaseStrategy { uint256 amountFreed; (amountFreed, _loss) = liquidatePosition(_amountNeeded); // Send it directly back (NOTE: Using `msg.sender` saves some gas here) - want.safeTransfer(msg.sender, amountFreed); + SafeERC20.safeTransfer(want, msg.sender, amountFreed); // NOTE: Reinvest anything leftover on next `tend`/`harvest` } @@ -751,7 +748,7 @@ abstract contract BaseStrategy { require(msg.sender == address(vault) || msg.sender == governance()); require(BaseStrategy(_newStrategy).vault() == vault); prepareMigration(_newStrategy); - want.safeTransfer(_newStrategy, want.balanceOf(address(this))); + SafeERC20.safeTransfer(want, _newStrategy, want.balanceOf(address(this))); } /** @@ -814,14 +811,14 @@ abstract contract BaseStrategy { address[] memory _protectedTokens = protectedTokens(); for (uint256 i; i < _protectedTokens.length; i++) require(_token != _protectedTokens[i], "!protected"); - IERC20(_token).safeTransfer(governance(), IERC20(_token).balanceOf(address(this))); + SafeERC20.safeTransfer(IERC20(_token), governance(), IERC20(_token).balanceOf(address(this))); } } abstract contract BaseStrategyInitializable is BaseStrategy { event Cloned(address indexed clone); - constructor(address _vault) public BaseStrategy(_vault) {} + constructor(address _vault) BaseStrategy(_vault) {} function initialize( address _vault, diff --git a/contracts/BaseWrapper.sol b/contracts/BaseWrapper.sol index 1c2d7951..0ff140a7 100644 --- a/contracts/BaseWrapper.sol +++ b/contracts/BaseWrapper.sol @@ -1,11 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.6.12; -pragma experimental ABIEncoderV2; +pragma solidity >=0.8.0 <0.9.0; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; -import {Math} from "@openzeppelin/contracts/math/Math.sol"; -import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {VaultAPI} from "./BaseStrategy.sol"; @@ -21,7 +19,6 @@ interface RegistryAPI { abstract contract BaseWrapper { using Math for uint256; - using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 public token; @@ -41,7 +38,7 @@ abstract contract BaseWrapper { // VaultsAPI.depositLimit is unlimited uint256 constant UNCAPPED_DEPOSITS = type(uint256).max; - constructor(address _token, address _registry) public { + constructor(address _token, address _registry) { // Recommended to use a token with a `Registry.latestVault(_token) != address(0)` token = IERC20(_token); // Recommended to use `v2.registry.ychad.eth` @@ -96,7 +93,7 @@ abstract contract BaseWrapper { VaultAPI[] memory vaults = allVaults(); for (uint256 id = 0; id < vaults.length; id++) { - balance = balance.add(vaults[id].balanceOf(account).mul(vaults[id].pricePerShare()).div(10**uint256(vaults[id].decimals()))); + balance += (vaults[id].balanceOf(account) * vaults[id].pricePerShare()) / 10**uint256(vaults[id].decimals()); } } @@ -104,7 +101,7 @@ abstract contract BaseWrapper { VaultAPI[] memory vaults = allVaults(); for (uint256 id = 0; id < vaults.length; id++) { - assets = assets.add(vaults[id].totalAssets()); + assets += vaults[id].totalAssets(); } } @@ -118,9 +115,9 @@ abstract contract BaseWrapper { if (pullFunds) { if (amount != DEPOSIT_EVERYTHING) { - token.safeTransferFrom(depositor, address(this), amount); + SafeERC20.safeTransferFrom(token, depositor, address(this), amount); } else { - token.safeTransferFrom(depositor, address(this), token.balanceOf(depositor)); + SafeERC20.safeTransferFrom(token, depositor, address(this), token.balanceOf(depositor)); } } @@ -143,7 +140,7 @@ abstract contract BaseWrapper { } uint256 afterBal = token.balanceOf(address(this)); - deposited = beforeBal.sub(afterBal); + deposited = beforeBal - afterBal; // `receiver` now has shares of `_bestVault` as balance, converted to `token` here // Issue a refund if not everything was deposited if (depositor != address(this) && afterBal > 0) token.safeTransfer(depositor, afterBal); @@ -191,21 +188,18 @@ abstract contract BaseWrapper { if (amount != WITHDRAW_EVERYTHING) { // Compute amount to withdraw fully to satisfy the request - uint256 estimatedShares = amount - .sub(withdrawn) // NOTE: Changes every iteration - .mul(10**uint256(vaults[id].decimals())) - .div(vaults[id].pricePerShare()); // NOTE: Every Vault is different + uint256 estimatedShares = ((amount - withdrawn) * 10**uint256(vaults[id].decimals())) / vaults[id].pricePerShare(); // Limit amount to withdraw to the maximum made available to this contract // NOTE: Avoid corner case where `estimatedShares` isn't precise enough // NOTE: If `0 < estimatedShares < 1` but `availableShares > 1`, this will withdraw more than necessary if (estimatedShares > 0 && estimatedShares < availableShares) { - withdrawn = withdrawn.add(vaults[id].withdraw(estimatedShares)); + withdrawn = withdrawn + (vaults[id].withdraw(estimatedShares)); } else { - withdrawn = withdrawn.add(vaults[id].withdraw(availableShares)); + withdrawn = withdrawn + (vaults[id].withdraw(availableShares)); } } else { - withdrawn = withdrawn.add(vaults[id].withdraw()); + withdrawn += vaults[id].withdraw(); } // Check if we have fully satisfied the request @@ -218,11 +212,11 @@ abstract contract BaseWrapper { // NOTE: Invariant is `withdrawn <= amount` if (withdrawn > amount) { // Don't forget to approve the deposit - if (token.allowance(address(this), address(_bestVault)) < withdrawn.sub(amount)) { + if (token.allowance(address(this), address(_bestVault)) < (withdrawn - amount)) { token.safeApprove(address(_bestVault), UNLIMITED_APPROVAL); // Vaults are trusted } - _bestVault.deposit(withdrawn.sub(amount), sender); + _bestVault.deposit(withdrawn - amount, sender); withdrawn = amount; } @@ -254,7 +248,7 @@ abstract contract BaseWrapper { uint256 _amount = amount; if (_depositLimit < UNCAPPED_DEPOSITS && _amount < WITHDRAW_EVERYTHING) { // Can only deposit up to this amount - uint256 _depositLeft = _depositLimit.sub(_totalAssets); + uint256 _depositLeft = _depositLimit - _totalAssets; if (_amount > _depositLeft) _amount = _depositLeft; } @@ -268,7 +262,7 @@ abstract contract BaseWrapper { // NOTE: Due to the precision loss of certain calculations, there is a small inefficency // on how migrations are calculated, and this could lead to a DoS issue. Hence, this // value is made to be configurable to allow the user to specify how much is acceptable - require(withdrawn.sub(migrated) <= maxMigrationLoss); + require((withdrawn - migrated) <= maxMigrationLoss); } // else: nothing to migrate! (not a failure) } } diff --git a/contracts/test/AffiliateToken.sol b/contracts/test/AffiliateToken.sol index 8ec60621..a3a7400a 100644 --- a/contracts/test/AffiliateToken.sol +++ b/contracts/test/AffiliateToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.6.12; +pragma solidity 0.8.3; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -19,6 +19,7 @@ contract AffiliateToken is ERC20, BaseWrapper { address public affiliate; address public pendingAffiliate; + uint8 private immutable _decimals; modifier onlyAffiliate() { require(msg.sender == affiliate); @@ -30,10 +31,10 @@ contract AffiliateToken is ERC20, BaseWrapper { address _registry, string memory name, string memory symbol - ) public BaseWrapper(_token, _registry) ERC20(name, symbol) { + ) BaseWrapper(_token, _registry) ERC20(name, symbol) { DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), keccak256(bytes("1")), _getChainId(), address(this))); affiliate = msg.sender; - _setupDecimals(uint8(ERC20(address(token)).decimals())); + _decimals = uint8(ERC20(address(token)).decimals()); } function _getChainId() internal view returns (uint256) { @@ -57,34 +58,34 @@ contract AffiliateToken is ERC20, BaseWrapper { uint256 totalShares = totalSupply(); if (totalShares > 0) { - return totalVaultBalance(address(this)).mul(numShares).div(totalShares); + return (totalVaultBalance(address(this)) * numShares) / totalShares; } else { return numShares; } } function pricePerShare() external view returns (uint256) { - return totalVaultBalance(address(this)).mul(10**uint256(decimals())).div(totalSupply()); + return (totalVaultBalance(address(this)) * (10**uint256(decimals()))) / totalSupply(); } function _sharesForValue(uint256 amount) internal view returns (uint256) { // total wrapper assets before deposit (assumes deposit already occured) - uint256 totalWrapperAssets = totalVaultBalance(address(this)).sub(amount); + uint256 totalWrapperAssets = totalVaultBalance(address(this)) - amount; if (totalWrapperAssets > 0) { - return totalSupply().mul(amount).div(totalWrapperAssets); + return (totalSupply() * amount) / totalWrapperAssets; } else { return amount; } } function deposit() external returns (uint256) { - return deposit(uint256(-1)); // Deposit everything + return deposit(type(uint256).max); // Deposit everything } function deposit(uint256 amount) public returns (uint256 deposited) { deposited = _deposit(msg.sender, address(this), amount, true); // `true` = pull from `msg.sender` - uint256 shares = _sharesForValue(deposited); // NOTE: Must be calculated after deposit is handled + uint256 shares = _sharesForValue(deposited); // NOTE: Must be calculated after deposit is handled _mint(msg.sender, shares); } @@ -139,4 +140,8 @@ contract AffiliateToken is ERC20, BaseWrapper { _approve(owner, spender, amount); } + + function decimals() public virtual override view returns (uint8) { + return _decimals; + } } diff --git a/contracts/test/TestGuestList.sol b/contracts/test/TestGuestList.sol index cc5d9d2c..ff9acecf 100644 --- a/contracts/test/TestGuestList.sol +++ b/contracts/test/TestGuestList.sol @@ -1,6 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity >=0.6.0 <0.7.0; -pragma experimental ABIEncoderV2; +pragma solidity 0.8.3; /** * @notice A basic guest list contract for testing. @@ -18,7 +17,7 @@ contract TestGuestList { * @dev Note that since this is just for testing, you're unable to change * `bouncer`. */ - constructor() public { + constructor() { bouncer = msg.sender; } diff --git a/contracts/test/TestStrategy.sol b/contracts/test/TestStrategy.sol index 0cc9ac62..99e2875e 100644 --- a/contracts/test/TestStrategy.sol +++ b/contracts/test/TestStrategy.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.6.12; -pragma experimental ABIEncoderV2; +pragma solidity 0.8.3; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {BaseStrategyInitializable, StrategyParams, VaultAPI} from "../BaseStrategy.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /* * This Strategy serves as both a mock Strategy for testing, and an example @@ -19,7 +19,7 @@ contract TestStrategy is BaseStrategyInitializable { // to test `BaseStrategy.protectedTokens()` address public constant protectedToken = address(0xbad); - constructor(address _vault) public BaseStrategyInitializable(_vault) {} + constructor(address _vault) BaseStrategyInitializable(_vault) {} function name() external override view returns (string memory) { return string(abi.encodePacked("TestStrategy ", apiVersion())); @@ -40,7 +40,7 @@ contract TestStrategy is BaseStrategyInitializable { // NOTE: This is a test-only function to simulate losses function _takeFunds(uint256 amount) public { - want.safeTransfer(msg.sender, amount); + SafeERC20.safeTransfer(want, msg.sender, amount); } // NOTE: This is a test-only function to enable reentrancy on withdraw @@ -72,17 +72,17 @@ contract TestStrategy is BaseStrategyInitializable { uint256 totalDebt = vault.strategies(address(this)).totalDebt; if (totalAssets > _debtOutstanding) { _debtPayment = _debtOutstanding; - totalAssets = totalAssets.sub(_debtOutstanding); + totalAssets = totalAssets - _debtOutstanding; } else { _debtPayment = totalAssets; totalAssets = 0; } - totalDebt = totalDebt.sub(_debtPayment); + totalDebt = totalDebt - _debtPayment; if (totalAssets > totalDebt) { - _profit = totalAssets.sub(totalDebt); + _profit = totalAssets - totalDebt; } else { - _loss = totalDebt.sub(totalAssets); + _loss = totalDebt - totalAssets; } } @@ -101,11 +101,11 @@ contract TestStrategy is BaseStrategyInitializable { uint256 totalAssets = want.balanceOf(address(this)); if (_amountNeeded > totalAssets) { _liquidatedAmount = totalAssets; - _loss = _amountNeeded.sub(totalAssets); + _loss = _amountNeeded - totalAssets; } else { // NOTE: Just in case something was stolen from this contract if (totalDebt > totalAssets) { - _loss = totalDebt.sub(totalAssets); + _loss = totalDebt - totalAssets; if (_loss > _amountNeeded) _loss = _amountNeeded; } _liquidatedAmount = _amountNeeded; diff --git a/contracts/test/Token.sol b/contracts/test/Token.sol index 547dff8d..43c7dc46 100644 --- a/contracts/test/Token.sol +++ b/contracts/test/Token.sol @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.6.12; +pragma solidity 0.8.3; -import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract Token is ERC20 { mapping(address => bool) public _blocked; + uint8 private immutable _decimals; - constructor(uint8 _decimals) public ERC20("yearn.finance test token", "TEST") { - _setupDecimals(_decimals); - _mint(msg.sender, 30000 * 10**uint256(_decimals)); + constructor(uint8 decimals_) ERC20("yearn.finance test token", "TEST") { + _decimals = decimals_; + _mint(msg.sender, 30000 * 10**uint256(decimals_)); } function _setBlocked(address user, bool value) public virtual { @@ -24,11 +24,13 @@ contract Token is ERC20 { require(!_blocked[to], "Token transfer refused. Receiver is on blacklist"); super._beforeTokenTransfer(from, to, amount); } + + function decimals() public virtual override view returns (uint8) { + return _decimals; + } } contract TokenNoReturn { - using SafeMath for uint256; - string public name; string public symbol; uint8 public decimals; @@ -42,7 +44,7 @@ contract TokenNoReturn { mapping(address => bool) public _blocked; - constructor(uint8 _decimals) public { + constructor(uint8 _decimals) { name = "yearn.finance test token"; symbol = "TEST"; decimals = _decimals; @@ -56,8 +58,8 @@ contract TokenNoReturn { function transfer(address receiver, uint256 amount) external { require(!_blocked[receiver], "Token transfer refused. Receiver is on blacklist"); - balanceOf[msg.sender] = balanceOf[msg.sender].sub(amount); - balanceOf[receiver] = balanceOf[receiver].add(amount); + balanceOf[msg.sender] = balanceOf[msg.sender] - amount; + balanceOf[receiver] = balanceOf[receiver] + amount; emit Transfer(msg.sender, receiver, amount); } @@ -72,15 +74,15 @@ contract TokenNoReturn { uint256 amount ) external { require(!_blocked[receiver], "Token transfer refused. Receiver is on blacklist"); - allowance[sender][msg.sender] = allowance[sender][msg.sender].sub(amount); - balanceOf[sender] = balanceOf[sender].sub(amount); - balanceOf[receiver] = balanceOf[receiver].add(amount); + allowance[sender][msg.sender] = allowance[sender][msg.sender] - amount; + balanceOf[sender] = balanceOf[sender] - amount; + balanceOf[receiver] = balanceOf[receiver] + amount; emit Transfer(sender, receiver, amount); } } contract TokenFalseReturn is Token { - constructor(uint8 _decimals) public Token(_decimals) {} + constructor(uint8 _decimals) Token(_decimals) {} function transfer(address receiver, uint256 amount) public virtual override returns (bool) { return false; diff --git a/contracts/yToken.sol b/contracts/yToken.sol index 87afeaea..0da68151 100644 --- a/contracts/yToken.sol +++ b/contracts/yToken.sol @@ -1,20 +1,15 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.6.12; -pragma experimental ABIEncoderV2; +pragma solidity 0.8.3; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol"; -import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; - +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {VaultAPI, BaseWrapper} from "./BaseWrapper.sol"; contract yToken is IERC20, BaseWrapper { - using SafeMath for uint256; - mapping(address => mapping(address => uint256)) public override allowance; - constructor(address _token, address _registry) public BaseWrapper(_token, _registry) {} + constructor(address _token, address _registry) BaseWrapper(_token, _registry) {} function name() external view returns (string memory) { VaultAPI _bestVault = bestVault(); @@ -77,17 +72,17 @@ contract yToken is IERC20, BaseWrapper { uint256 amount ) public virtual override returns (bool) { _transfer(sender, receiver, amount); - _approve(sender, msg.sender, allowance[sender][msg.sender].sub(amount)); + _approve(sender, msg.sender, allowance[sender][msg.sender] - amount); return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { - _approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue)); + _approve(msg.sender, spender, allowance[msg.sender][spender] + addedValue); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { - _approve(msg.sender, spender, allowance[msg.sender][spender].sub(subtractedValue)); + _approve(msg.sender, spender, allowance[msg.sender][spender] - subtractedValue); return true; } @@ -106,7 +101,7 @@ contract yToken is IERC20, BaseWrapper { ) internal { require(vaults.length == signatures.length); for (uint256 i = 0; i < vaults.length; i++) { - require(vaults[i].permit(user, address(this), uint256(-1), 0, signatures[i])); + require(vaults[i].permit(user, address(this), type(uint256).max, 0, signatures[i])); } } @@ -167,7 +162,7 @@ interface IWETH { contract yWETH is ReentrancyGuard, yToken { using Address for address payable; - constructor(address _weth, address _registry) public yToken(_weth, _registry) {} + constructor(address _weth, address _registry) yToken(_weth, _registry) {} function depositETH() public payable returns (uint256) { uint256 amount = msg.value; @@ -184,7 +179,7 @@ contract yWETH is ReentrancyGuard, yToken { // NOTE: `BaseWrapper.token` is WETH IWETH(address(token)).withdraw(withdrawn); // NOTE: Any unintentionally - msg.sender.sendValue(address(this).balance); + payable(msg.sender).sendValue(address(this).balance); } receive() external payable {