diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a6157e3..af0507d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,7 +50,7 @@ jobs: - name: Install forge dependencies run: forge install - - name: Precompile using 0.8.14 and via-ir=false + - name: Precompile using 0.8.18 and via-ir=false run: yarn build - name: "Create env file" @@ -79,7 +79,7 @@ jobs: - name: Install forge dependencies run: forge install - - name: Precompile using 0.8.14 and via-ir=true + - name: Precompile using 0.8.18 and via-ir=true run: yarn build:optimized - name: Run tests diff --git a/foundry.toml b/foundry.toml index 6d98398..2a7f0d9 100644 --- a/foundry.toml +++ b/foundry.toml @@ -9,7 +9,7 @@ multiline_func_header = 'params_first' fs_permissions = [{ access = "read-write", path = "./"}] [profile.default] -solc = '0.8.14' +solc = '0.8.18' src = 'solidity' test = 'solidity/test' out = 'out' diff --git a/solidity/contracts/XERC20.sol b/solidity/contracts/XERC20.sol index 9d8df4b..8fbbf0f 100644 --- a/solidity/contracts/XERC20.sol +++ b/solidity/contracts/XERC20.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.4 <0.9.0; +pragma solidity 0.8.18; import {IXERC20} from 'interfaces/IXERC20.sol'; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import {ERC20Permit} from '@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol'; -import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; +import {Ownable2Step} from '@openzeppelin/contracts/access/Ownable2Step.sol'; import {ReentrancyGuard} from '@openzeppelin/contracts/security/ReentrancyGuard.sol'; -contract XERC20 is ERC20, Ownable, IXERC20, ERC20Permit, ReentrancyGuard { +contract XERC20 is ERC20, Ownable2Step, IXERC20, ERC20Permit, ReentrancyGuard { /** * @notice The duration it takes for the limits to fully replenish */ @@ -26,7 +26,7 @@ contract XERC20 is ERC20, Ownable, IXERC20, ERC20Permit, ReentrancyGuard { /** * @notice Maps bridge address to bridge configurations */ - mapping(address => Bridge) public bridges; + mapping(address bridgeAddress => Bridge) public bridges; /** * @notice Constructs the initial config of the XERC20 diff --git a/solidity/contracts/XERC20Factory.sol b/solidity/contracts/XERC20Factory.sol index 616f0bf..d9b5d53 100644 --- a/solidity/contracts/XERC20Factory.sol +++ b/solidity/contracts/XERC20Factory.sol @@ -1,19 +1,20 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.4 <0.9.0; +pragma solidity 0.8.18; import {XERC20} from 'contracts/XERC20.sol'; import {IXERC20Factory} from 'interfaces/IXERC20Factory.sol'; import {XERC20Lockbox} from 'contracts/XERC20Lockbox.sol'; import {CREATE3} from 'isolmate/utils/CREATE3.sol'; +import {Ownable2Step} from '@openzeppelin/contracts/access/Ownable2Step.sol'; import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; -contract XERC20Factory is IXERC20Factory { +contract XERC20Factory is Ownable2Step, IXERC20Factory { using EnumerableSet for EnumerableSet.AddressSet; /** * @notice Address of the xerc20 maps to the address of its lockbox if it has one */ - mapping(address => address) public lockboxRegistry; + mapping(address xerc20Address => address lockboxAddress) public lockboxRegistry; /** * @notice The set of registered lockboxes @@ -41,7 +42,7 @@ contract XERC20Factory is IXERC20Factory { uint256[] memory _minterLimits, uint256[] memory _burnerLimits, address[] memory _bridges - ) external returns (address _xerc20) { + ) external onlyOwner returns (address _xerc20) { _xerc20 = _deployXERC20(_name, _symbol, _minterLimits, _burnerLimits, _bridges); emit XERC20Deployed(_xerc20); @@ -59,7 +60,7 @@ contract XERC20Factory is IXERC20Factory { address _xerc20, address _baseToken, bool _isNative - ) external returns (address payable _lockbox) { + ) external onlyOwner returns (address payable _lockbox) { if (_baseToken == address(0) && !_isNative) revert IXERC20Factory_BadTokenAddress(); if (XERC20(_xerc20).owner() != msg.sender) revert IXERC20Factory_NotOwner(); @@ -158,7 +159,8 @@ contract XERC20Factory is IXERC20Factory { _xerc20 = CREATE3.deploy(_salt, _bytecode, 0); - EnumerableSet.add(_xerc20RegistryArray, _xerc20); + bool savedXErc20 = EnumerableSet.add(_xerc20RegistryArray, _xerc20); + require(savedXErc20, 'Not saved into EnumerableSet'); for (uint256 _i; _i < _bridgesLength; ++_i) { XERC20(_xerc20).setLimits(_bridges[_i], _minterLimits[_i], _burnerLimits[_i]); @@ -179,7 +181,8 @@ contract XERC20Factory is IXERC20Factory { _lockbox = payable(CREATE3.deploy(_salt, _bytecode, 0)); XERC20(_xerc20).setLockbox(address(_lockbox)); - EnumerableSet.add(_lockboxRegistryArray, _lockbox); + bool savedLockbox = EnumerableSet.add(_lockboxRegistryArray, _lockbox); + require(savedLockbox, 'Not saved into EnumerableSet'); lockboxRegistry[_xerc20] = _lockbox; } } diff --git a/solidity/contracts/XERC20Lockbox.sol b/solidity/contracts/XERC20Lockbox.sol index c91aa2a..9a6ec02 100644 --- a/solidity/contracts/XERC20Lockbox.sol +++ b/solidity/contracts/XERC20Lockbox.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.4 <0.9.0; +pragma solidity 0.8.18; import {IXERC20} from 'interfaces/IXERC20.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; diff --git a/solidity/interfaces/IXERC20.sol b/solidity/interfaces/IXERC20.sol index 4adbf9c..5ad94ae 100644 --- a/solidity/interfaces/IXERC20.sol +++ b/solidity/interfaces/IXERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.4 <0.9.0; +pragma solidity 0.8.18; interface IXERC20 { /** diff --git a/solidity/interfaces/IXERC20Factory.sol b/solidity/interfaces/IXERC20Factory.sol index 78029f1..bb1bbb3 100644 --- a/solidity/interfaces/IXERC20Factory.sol +++ b/solidity/interfaces/IXERC20Factory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.4 <0.9.0; +pragma solidity 0.8.18; interface IXERC20Factory { /** diff --git a/solidity/interfaces/IXERC20Lockbox.sol b/solidity/interfaces/IXERC20Lockbox.sol index 50ecb27..4fed673 100644 --- a/solidity/interfaces/IXERC20Lockbox.sol +++ b/solidity/interfaces/IXERC20Lockbox.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.4 <0.9.0; +pragma solidity 0.8.18; + interface IXERC20Lockbox { /** @@ -47,4 +48,4 @@ interface IXERC20Lockbox { */ function withdraw(uint256 _amount) external; -} +} \ No newline at end of file diff --git a/solidity/scripts/MultichainCreateXERC20.sol b/solidity/scripts/MultichainCreateXERC20.sol index 6d0ac6e..dc12777 100644 --- a/solidity/scripts/MultichainCreateXERC20.sol +++ b/solidity/scripts/MultichainCreateXERC20.sol @@ -53,6 +53,9 @@ contract MultichainCreateXERC20 is Script, ScriptingLibrary { ); address xerc20 = factory.deployXERC20(name, symbol, minterLimits[i], burnLimits[i], bridges[i]); + + XERC20(xerc20).acceptOwnership(); + address lockbox; if (_erc20 != address(0) && !_isNative) { lockbox = factory.deployLockbox(xerc20, _erc20, _isNative); diff --git a/solidity/scripts/MultichainDeploy.sol b/solidity/scripts/MultichainDeploy.sol index d3cbf1d..d355128 100644 --- a/solidity/scripts/MultichainDeploy.sol +++ b/solidity/scripts/MultichainDeploy.sol @@ -9,26 +9,20 @@ import {ScriptingLibrary} from './ScriptingLibrary/ScriptingLibrary.sol'; contract MultichainDeploy is Script, ScriptingLibrary { uint256 public deployer = vm.envUint('DEPLOYER_PRIVATE_KEY'); - address constant CREATE2 = 0x4e59b44847b379578588920cA78FbF26c0B4956C; string[] public chains = ['MUMBAI_RPC']; function run() public { - //TODO: Change salt from this test to prod before release - bytes32 _salt = keccak256(abi.encodePacked('xxxsdsdd23ewXERewewCewew20Factoewewry', msg.sender)); address[] memory factories = new address[](chains.length); for (uint256 i; i < chains.length; i++) { vm.createSelectFork(vm.rpcUrl(vm.envString(chains[i]))); vm.startBroadcast(deployer); - address _deployedFactory = getAddress(type(XERC20Factory).creationCode, _salt, CREATE2); - if (keccak256(_deployedFactory.code) != keccak256(type(XERC20Factory).runtimeCode)) { - new XERC20Factory{salt: _salt}(); - } + address deployedContractAddress = address(new XERC20Factory()); vm.stopBroadcast(); - console.log(chains[i], 'factory deployed to:', address(_deployedFactory)); - factories[i] = _deployedFactory; + console.log(chains[i], 'factory deployed to:', address(deployedContractAddress)); + factories[i] = deployedContractAddress; } if (chains.length > 1) {