diff --git a/contracts/core/ContractsRegistry.sol b/contracts/core/ContractsRegistry.sol index 83278e47..0db1108e 100644 --- a/contracts/core/ContractsRegistry.sol +++ b/contracts/core/ContractsRegistry.sol @@ -44,6 +44,22 @@ contract ContractsRegistry is IContractsRegistry, MultiOwnableContractsRegistry, _setSphereXEngine(CORE_PROPERTIES_NAME, sphereXEngine); } + function addContracts( + string[] calldata names_, + address[] calldata contractAddresses_ + ) external onlyOwner { + uint256 length = names_.length; + + require( + contractAddresses_.length == length, + "Contracts Registry: names and addresses lengths don't match" + ); + + for (uint256 i = 0; i < length; i++) { + _addContract(names_[i], contractAddresses_[i]); + } + } + function protectContractFunctions( string calldata contractName, bytes4[] calldata selectors diff --git a/deploy/2_NetworkProperties.migration.js b/deploy/2_NetworkProperties.migration.js index 89400f35..d5a927a8 100644 --- a/deploy/2_NetworkProperties.migration.js +++ b/deploy/2_NetworkProperties.migration.js @@ -5,5 +5,8 @@ const ContractsRegistry = artifacts.require("ContractsRegistry"); module.exports = async (deployer) => { const contractsRegistry = await deployer.deployed(ContractsRegistry, "proxy"); - await contractsRegistry.addContract(await contractsRegistry.NETWORK_PROPERTIES_NAME(), config.NETWORK_PROPERTIES); + await contractsRegistry.addContracts( + [await contractsRegistry.NETWORK_PROPERTIES_NAME(), await contractsRegistry.WETH_NAME()], + [config.NETWORK_PROPERTIES, config.tokens.WBNB], + ); }; diff --git a/test/core/ContractsRegistry.test.js b/test/core/ContractsRegistry.test.js index 302ad23d..2550c2fe 100644 --- a/test/core/ContractsRegistry.test.js +++ b/test/core/ContractsRegistry.test.js @@ -66,6 +66,7 @@ describe("ContractsRegistry", () => { describe("contract management", () => { it("should add and remove the contract", async () => { const USD = await ERC20Mock.new("USD", "USD", 18); + const WETH = await ERC20Mock.new("WETH", "WETH", 18); await contractsRegistry.addContract(await contractsRegistry.USD_NAME(), USD.address); @@ -76,6 +77,42 @@ describe("ContractsRegistry", () => { await truffleAssert.reverts(contractsRegistry.getUSDContract(), "ContractsRegistry: this mapping doesn't exist"); assert.isFalse(await contractsRegistry.hasContract(await contractsRegistry.USD_NAME())); + + await contractsRegistry.addContracts( + [await contractsRegistry.USD_NAME(), await contractsRegistry.WETH_NAME()], + [USD.address, WETH.address], + ); + + assert.equal(await contractsRegistry.getUSDContract(), USD.address); + assert.isTrue(await contractsRegistry.hasContract(await contractsRegistry.USD_NAME())); + assert.equal(await contractsRegistry.getWETHContract(), WETH.address); + assert.isTrue(await contractsRegistry.hasContract(await contractsRegistry.WETH_NAME())); + }); + + it("should not batch add if not owner", async () => { + const USD = await ERC20Mock.new("USD", "USD", 18); + const WETH = await ERC20Mock.new("WETH", "WETH", 18); + + await truffleAssert.reverts( + contractsRegistry.addContracts( + [await contractsRegistry.USD_NAME(), await contractsRegistry.WETH_NAME()], + [USD.address, WETH.address], + { from: SECOND }, + ), + "MultiOwnable: caller is not the owner", + ); + }); + + it("should revert on names and addresses length mismatch", async () => { + const USD = await ERC20Mock.new("USD", "USD", 18); + + await truffleAssert.reverts( + contractsRegistry.addContracts( + [await contractsRegistry.USD_NAME(), await contractsRegistry.WETH_NAME()], + [USD.address], + ), + "Contracts Registry: names and addresses lengths don't match", + ); }); it("should not add proxy contract without engine", async () => {