Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SC-989][SC-990] Bump @openzeppelin to version 5.0.0 #97

Merged
merged 7 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .solcover.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ module.exports = {
yul: true,
yulDetails: {
optimizerSteps:
'dhfoDgvlfnTUtnIf' + // None of these can make stack problems worse
'dhfoDgvlfnTUtnIf' + // None of these can make stack problems worse
'[' +
'xa[r]EscLM' + // Turn into SSA and simplify
'cCTUtTOntnfDIl' + // Perform structural simplification
'Lcl' + // Simplify again
'Vcl [j]' + // Reverse SSA
'xa[r]EscLM' + // Turn into SSA and simplify
'cCTUtTOntnfDIl' + // Perform structural simplification
'Lcl' + // Simplify again
'Vcl [j]' + // Reverse SSA

// should have good 'compilability' property here.

'Tpel' + // Run functional expression inliner
'xa[rl]' + // Prune a bit more in SSA
'xa[r]cL' + // Turn into SSA again and simplify
// 'gvif' + // Run full inliner
'CTUca[r]LSsTFOtfDnca[r]Ilc' + // SSA plus simplify
'Tpel' + // Run functional expression inliner
'xa[rl]' + // Prune a bit more in SSA
'xa[r]cL' + // Turn into SSA again and simplify
'gvf' + // Run full inliner
'CTUca[r]LSsTFOtfDnca[r]Ilc' + // SSA plus simplify
']' +
'jml[jl] VcTOcl jml', // Make source short and pretty
'jml[jl] VcTOcl jml : fDnTOcm', // Make source short and pretty
},
},
skipFiles: [
Expand Down
14 changes: 7 additions & 7 deletions contracts/libraries/SafeERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import "../interfaces/IDaiLikePermit.sol";
import "../interfaces/IPermit2.sol";
import "../interfaces/IWETH.sol";
Expand Down Expand Up @@ -59,7 +59,7 @@ library SafeERC20 {

/**
* @notice Attempts to safely transfer tokens from one address to another.
* @dev If permit2 is true, uses the Permit2 standard; otherwise uses the standard ERC20 transferFrom.
* @dev If permit2 is true, uses the Permit2 standard; otherwise uses the standard ERC20 transferFrom.
* Either requires `true` in return data, or requires target to be smart-contract and empty return data.
* @param token The IERC20 token contract from which the tokens will be transferred.
* @param from The address from which the tokens will be transferred.
Expand Down Expand Up @@ -238,7 +238,7 @@ library SafeERC20 {
}

/**
* @notice Attempts to execute the `permit` function on the provided token with custom owner and spender parameters.
* @notice Attempts to execute the `permit` function on the provided token with custom owner and spender parameters.
* Permit type is determined automatically based on permit calldata (IERC20Permit, IDaiLikePermit, and IPermit2).
* @dev Wraps `tryPermit` function and forwards revert reason if permit fails.
* @param token The IERC20 token to execute the permit function on.
Expand All @@ -265,9 +265,9 @@ library SafeERC20 {
* @notice The function attempts to call the permit function on a given ERC20 token.
* @dev The function is designed to support a variety of permit functions, namely: IERC20Permit, IDaiLikePermit, and IPermit2.
* It accommodates both Compact and Full formats of these permit types.
* Please note, it is expected that the `expiration` parameter for the compact Permit2 and the `deadline` parameter
* Please note, it is expected that the `expiration` parameter for the compact Permit2 and the `deadline` parameter
* for the compact Permit are to be incremented by one before invoking this function. This approach is motivated by
* gas efficiency considerations; as the unlimited expiration period is likely to be the most common scenario, and
* gas efficiency considerations; as the unlimited expiration period is likely to be the most common scenario, and
* zeros are cheaper to pass in terms of gas cost. Thus, callers should increment the expiration or deadline by one
* before invocation for optimized performance.
* @param token The address of the ERC20 token on which to call the permit function.
Expand Down Expand Up @@ -349,7 +349,7 @@ library SafeERC20 {
mstore(add(ptr, 0x24), token) // store token

calldatacopy(add(ptr, 0x50), permit.offset, 0x14) // store amount = copy permit.offset 0x00..0x13
// and(0xffffffffffff, ...) - conversion to uint48
// and(0xffffffffffff, ...) - conversion to uint48
mstore(add(ptr, 0x64), and(0xffffffffffff, sub(shr(224, calldataload(add(permit.offset, 0x14))), 1))) // store expiration = ((permit.offset 0x14..0x17 - 1) & 0xffffffffffff)
mstore(add(ptr, 0x84), shr(224, calldataload(add(permit.offset, 0x18)))) // store nonce = copy permit.offset 0x18..0x1b
mstore(add(ptr, 0xa4), spender) // store spender
Expand Down Expand Up @@ -383,7 +383,7 @@ library SafeERC20 {
* @param selector The function signature that is to be called on the token contract.
* @param to The address to which the token amount will be transferred.
* @param amount The token amount to be transferred.
* @return success A boolean indicating if the call was successful. Returns 'true' on success and 'false' on failure.
* @return success A boolean indicating if the call was successful. Returns 'true' on success and 'false' on failure.
* In case of success but no returned data, validates that the contract code exists.
* In case of returned data, ensures that it's a boolean `true`.
*/
Expand Down
2 changes: 1 addition & 1 deletion contracts/mocks/ERC20PermitMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "./TokenMock.sol";

contract ERC20PermitMock is ERC20Permit, TokenMock {
Expand Down
4 changes: 2 additions & 2 deletions contracts/mocks/TokenCustomDecimalsMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";

contract TokenCustomDecimalsMock is ERC20Permit, Ownable {
uint8 internal immutable _decimals;
Expand All @@ -13,7 +13,7 @@ contract TokenCustomDecimalsMock is ERC20Permit, Ownable {
string memory symbol,
uint256 amount,
uint8 decimals_
) ERC20(name, symbol) ERC20Permit(name) {
) ERC20(name, symbol) ERC20Permit(name) Ownable(msg.sender) {
_mint(msg.sender, amount);
_decimals = decimals_;
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/mocks/TokenMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract TokenMock is ERC20, Ownable {
// solhint-disable-next-line no-empty-blocks
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
constructor(string memory name, string memory symbol) ERC20(name, symbol) Ownable(msg.sender) {}

function mint(address account, uint256 amount) external onlyOwner {
_mint(account, amount);
Expand Down
2 changes: 1 addition & 1 deletion contracts/tests/mocks/DaiLikePermitMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";

contract DaiLikePermitMock is ERC20Permit {
// bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)");
Expand Down
4 changes: 1 addition & 3 deletions contracts/tests/mocks/ERC1271WalletMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import "@openzeppelin/contracts/interfaces/IERC1271.sol";
import "../../libraries/ECDSA.sol";

contract ERC1271WalletMock is Ownable, IERC1271 {
constructor(address originalOwner) {
transferOwnership(originalOwner);
}
constructor(address originalOwner) Ownable(originalOwner) {} // solhint-disable-line no-empty-blocks

function isValidSignature(bytes32 hash, bytes calldata signature) public view override returns (bytes4 magicValue) {
return ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
Expand Down
2 changes: 1 addition & 1 deletion contracts/tests/mocks/SafeERC20Helper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "../../libraries/SafeERC20.sol";

contract ERC20ReturnFalseMock {
Expand Down
9 changes: 8 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import '@nomicfoundation/hardhat-verify';
require('solidity-coverage'); // require because no TS typings available
import dotenv from 'dotenv';
import { HardhatUserConfig } from 'hardhat/config';
import { HardhatNetworkUserConfig } from 'hardhat/types';
import networks from './hardhat.networks';

dotenv.config();
Expand All @@ -18,14 +19,20 @@ declare module 'hardhat/types/runtime' {
}
}

function getNetwork(): string {
const index = process.argv.findIndex((arg) => arg === '--network') + 1;
return index !== 0 ? process.argv[index] : 'unknown';
}

const config: HardhatUserConfig = {
solidity: {
version: '0.8.15',
version: '0.8.23',
settings: {
optimizer: {
enabled: true,
runs: 1000000,
},
evmVersion: (networks[getNetwork()] as HardhatNetworkUserConfig)?.hardfork || 'shanghai',
viaIR: true,
},
},
Expand Down
37 changes: 25 additions & 12 deletions hardhat.networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,41 @@ const networks: NetworksUserConfig = {
},
};

function register(name: string, chainId: number, url?: string, privateKey?: string) {
if (url && privateKey) {
const etherscan: { apiKey: {[key: string]: string}, customChains: [object] } = { apiKey: {}, customChains: [{}] };

function register(name: string, chainId: number, url?: string, privateKey?: string, etherscanNetworkName?: string, etherscanKey?: string, hardfork: string = 'paris') {
if (url && privateKey && etherscanNetworkName && etherscanKey) {
networks[name] = {
url,
chainId,
accounts: [privateKey],
hardfork,
};
etherscan.apiKey[etherscanNetworkName] = etherscanKey;
console.log(`Network '${name}' registered`);
} else {
console.log(`Network '${name}' not registered`);
}
}

register('mainnet', 1, process.env.MAINNET_RPC_URL, process.env.MAINNET_PRIVATE_KEY);
register('bsc', 56, process.env.BSC_RPC_URL, process.env.BSC_PRIVATE_KEY);
register('kovan', 42, process.env.KOVAN_RPC_URL, process.env.KOVAN_PRIVATE_KEY);
register('optimistic', 10, process.env.OPTIMISTIC_RPC_URL, process.env.OPTIMISTIC_PRIVATE_KEY);
register('kovan-optimistic', 69, process.env.KOVAN_OPTIMISTIC_RPC_URL, process.env.KOVAN_OPTIMISTIC_PRIVATE_KEY);
register('matic', 137, process.env.MATIC_RPC_URL, process.env.MATIC_PRIVATE_KEY);
register('arbitrum', 42161, process.env.ARBITRUM_RPC_URL, process.env.ARBITRUM_PRIVATE_KEY);
register('ropsten', 3, process.env.ROPSTEN_RPC_URL, process.env.ROPSTEN_PRIVATE_KEY);
register('xdai', 100, process.env.XDAI_RPC_URL, process.env.XDAI_PRIVATE_KEY);
register('avax', 43114, process.env.AVAX_RPC_URL, process.env.AVAX_PRIVATE_KEY);
function registerCustom(name: string, chainId: number, url?: string, privateKey?: string, etherscanKey?: string, apiURL?: string, browserURL?: string, hardfork = 'paris') {
if (url && privateKey && etherscanKey) {
register(name, chainId, hardfork, url, privateKey, name, etherscanKey);
etherscan.customChains.push({ network: name, chainId, urls: { apiURL, browserURL } });
}
}

register('mainnet', 1, process.env.MAINNET_RPC_URL, process.env.MAINNET_PRIVATE_KEY, 'mainnet', process.env.MAINNET_ETHERSCAN_KEY, 'shanghai');
register('bsc', 56, process.env.BSC_RPC_URL, process.env.BSC_PRIVATE_KEY, 'bsc', process.env.BSC_ETHERSCAN_KEY);
register('kovan', 42, process.env.KOVAN_RPC_URL, process.env.KOVAN_PRIVATE_KEY, 'kovan', process.env.KOVAN_ETHERSCAN_KEY);
register('optimistic', 10, process.env.OPTIMISTIC_RPC_URL, process.env.OPTIMISTIC_PRIVATE_KEY, 'optimisticEthereum', process.env.OPTIMISTIC_ETHERSCAN_KEY);
register('matic', 137, process.env.MATIC_RPC_URL, process.env.MATIC_PRIVATE_KEY, 'polygon', process.env.MATIC_ETHERSCAN_KEY);
register('arbitrum', 42161, process.env.ARBITRUM_RPC_URL, process.env.ARBITRUM_PRIVATE_KEY, 'arbitrumOne', process.env.ARBITRUM_ETHERSCAN_KEY);
register('xdai', 100, process.env.XDAI_RPC_URL, process.env.XDAI_PRIVATE_KEY, 'gnosis', process.env.XDAI_ETHERSCAN_KEY);
register('avax', 43114, process.env.AVAX_RPC_URL, process.env.AVAX_PRIVATE_KEY, 'avalanche', process.env.AVAX_ETHERSCAN_KEY);
register('fantom', 250, process.env.FANTOM_RPC_URL, process.env.FANTOM_PRIVATE_KEY, 'opera', process.env.FANTOM_ETHERSCAN_KEY);
register('aurora', 1313161554, process.env.AURORA_RPC_URL, process.env.AURORA_PRIVATE_KEY, 'aurora', process.env.AURORA_ETHERSCAN_KEY);
register('base', 8453, process.env.BASE_RPC_URL, process.env.BASE_PRIVATE_KEY, 'base', process.env.BASE_ETHERSCAN_KEY);
registerCustom('klaytn', 8217, process.env.KLAYTN_RPC_URL, process.env.KLAYTN_PRIVATE_KEY, process.env.KLAYTN_ETHERSCAN_KEY, 'https://scope.klaytn.com/', 'https://scope.klaytn.com/');

export default networks;
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@1inch/solidity-utils",
"version": "3.2.0",
"version": "3.3.0",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"repository": {
Expand Down Expand Up @@ -31,7 +31,7 @@
"@metamask/eth-sig-util": "6.0.0",
"@nomicfoundation/hardhat-ethers": "3.0.3",
"@nomicfoundation/hardhat-network-helpers": "1.0.8",
"@openzeppelin/contracts": "4.9.2",
"@openzeppelin/contracts": "5.0.0",
"@uniswap/permit2-sdk": "1.2.0",
"ethereumjs-util": "7.1.5",
"ethers": "6.6.3",
Expand Down
6 changes: 2 additions & 4 deletions test/Permitable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('Permitable', function () {
const deadline = block ? block.timestamp - 1000 : 1000;

const permit = await getPermit(signer1, erc20PermitMock, '1', chainId, await permitableMock.getAddress(), value.toString(), deadline.toString());
await expect(permitableMock.mockPermit(erc20PermitMock, permit)).to.be.revertedWith('ERC20Permit: expired deadline');
await expect(permitableMock.mockPermit(erc20PermitMock, permit)).to.be.revertedWithCustomError(erc20PermitMock, 'ERC2612ExpiredSignature');
});

it('should not be permitted for IERC20Permit', async function () {
Expand Down Expand Up @@ -100,9 +100,7 @@ describe('Permitable', function () {
s,
]),
);
await expect(permitableMock.mockPermit(erc20PermitMock, permit)).to.be.revertedWith(
'ERC20Permit: invalid signature',
);
await expect(permitableMock.mockPermit(erc20PermitMock, permit)).to.be.revertedWithCustomError(erc20PermitMock, 'ERC2612InvalidSigner');
});

it('should be permitted for IDaiLikePermit', async function () {
Expand Down
4 changes: 2 additions & 2 deletions test/contracts/SafestERC20.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ describe('SafeERC20', function () {
expect(received).to.be.equal(ether('1'));
if (hre.__SOLIDITY_COVERAGE_RUNNING === undefined) {
expect(await countInstructions(ethers.provider, tx.logs[0].transactionHash, ['STATICCALL', 'CALL', 'MSTORE', 'MLOAD', 'SSTORE', 'SLOAD'])).to.be.deep.equal([
0, 1, 6, 3, 1, 2,
0, 1, 6, 1, 1, 2,
]);
}
});
Expand All @@ -313,7 +313,7 @@ describe('SafeERC20', function () {
);
if (hre.__SOLIDITY_COVERAGE_RUNNING === undefined) {
expect(await countInstructions(ethers.provider, tx.hash, ['STATICCALL', 'CALL', 'MSTORE', 'MLOAD', 'SSTORE', 'SLOAD'])).to.be.deep.equal([
0, 0, 1, 1, 0, 1,
0, 0, 1, 0, 0, 1,
]);
}
});
Expand Down
14 changes: 7 additions & 7 deletions test/contracts/StringUtil.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,31 @@ describe('StringUtil', function () {

it('Uint 256', () => testGasUint256(uint256TestValue, 834));

it('Uint 256 naive', () => testGasNaiveUint256(uint256TestValue, 16277));
it('Uint 256 naive', () => testGasNaiveUint256(uint256TestValue, 16369));

it('Uint 256 as bytes', () => testGasBytes(uint256TestValue, 716));

it('Uint 256 as bytes naive', () => testGasNaiveBytes(uint256TestValue, 16159));
it('Uint 256 as bytes naive', () => testGasNaiveBytes(uint256TestValue, 16251));

it('Uint 128', () => testGasUint256(uint128TestValue, 834));

it('Uint 128 naive', () => testGasNaiveUint256(uint128TestValue, 16277));
it('Uint 128 naive', () => testGasNaiveUint256(uint128TestValue, 16369));

it('Very long byte array gas', () => testGasBytes(veryLongArray, 1766));

it('Very long byte array gas naive', () => testGasNaiveBytes(veryLongArray, 33286));
it('Very long byte array gas naive', () => testGasNaiveBytes(veryLongArray, 33483));

it('Extremely long byte array gas', () => testGasBytes(extremelyLongArray, 17009));

it('Extremely long byte array gas naive', () => testGasNaiveBytes(extremelyLongArray, 489888));
it('Extremely long byte array gas naive', () => testGasNaiveBytes(extremelyLongArray, 492884));

it('Empty bytes', () => testGasBytes(emptyBytes, 191));

it('Empty bytes naive', () => testGasNaiveBytes(emptyBytes, 499));
it('Empty bytes naive', () => testGasNaiveBytes(emptyBytes, 495));

it('Single byte', () => testGasBytes(singleByte, 716));

it('Single byte naive', () => testGasNaiveBytes(singleByte, 988));
it('Single byte naive', () => testGasNaiveBytes(singleByte, 987));

async function testGasUint256(value: string, expectedGas: number) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -824,10 +824,10 @@
"@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1"
"@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1"

"@openzeppelin/contracts@4.9.2":
version "4.9.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.2.tgz#1cb2d5e4d3360141a17dbc45094a8cad6aac16c1"
integrity sha512-mO+y6JaqXjWeMh9glYVzVu8HYPGknAAnWyxTRhGeckOruyXQMNnlcW6w/Dx9ftLeIQk6N+ZJFuVmTwF7lEIFrg==
"@openzeppelin/contracts@5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.0.tgz#ee0e4b4564f101a5c4ee398cd4d73c0bd92b289c"
integrity sha512-bv2sdS6LKqVVMLI5+zqnNrNU/CA+6z6CmwFXm/MzmOPBRSO5reEJN7z0Gbzvs0/bv/MZZXNklubpwy3v2+azsw==

"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
Expand Down
Loading