diff --git a/contracts/access/AMultiOwnable.sol b/contracts/access/AMultiOwnable.sol index 416b8b32..3c6c5fae 100644 --- a/contracts/access/AMultiOwnable.sol +++ b/contracts/access/AMultiOwnable.sol @@ -43,6 +43,15 @@ abstract contract AMultiOwnable is IMultiOwnable, Initializable { _addOwners(msg.sender.asSingletonArray()); } + /** + * @dev Initializes the contract setting the array of initial owners. + */ + function __AMultiOwnable_init(address[] memory initialOwners_) internal onlyInitializing { + if (initialOwners_.length == 0) revert InvalidOwner(); + + _addOwners(initialOwners_); + } + /** * @notice The function to add equally rightful owners to the contract * @param newOwners_ the owners to be added diff --git a/contracts/mock/access/MultiOwnableMock.sol b/contracts/mock/access/MultiOwnableMock.sol index 673932c6..7318b1e8 100644 --- a/contracts/mock/access/MultiOwnableMock.sol +++ b/contracts/mock/access/MultiOwnableMock.sol @@ -2,14 +2,26 @@ // solhint-disable pragma solidity ^0.8.21; -import {AMultiOwnable} from "./../../access/AMultiOwnable.sol"; +import {AMultiOwnable} from "../../access/AMultiOwnable.sol"; + +import {TypeCaster} from "../../libs/utils/TypeCaster.sol"; contract MultiOwnableMock is AMultiOwnable { + using TypeCaster for address; + function __MultiOwnableMock_init() external initializer { __AMultiOwnable_init(); } + function __MultiOwnableMockMulti_init(address[] memory initialOwners_) external initializer { + __AMultiOwnable_init(initialOwners_); + } + function mockInit() external { __AMultiOwnable_init(); } + + function mockMultiInit() external { + __AMultiOwnable_init(msg.sender.asSingletonArray()); + } } diff --git a/contracts/mock/oracles/uniswap-v2/UniswapV2OracleMock.sol b/contracts/mock/oracles/uniswap-v2/UniswapV2OracleMock.sol index c1d0b2ac..2d7ed97c 100644 --- a/contracts/mock/oracles/uniswap-v2/UniswapV2OracleMock.sol +++ b/contracts/mock/oracles/uniswap-v2/UniswapV2OracleMock.sol @@ -13,11 +13,11 @@ contract UniswapV2OracleMock is AUniswapV2Oracle { address uniswapV2Factory_, uint256 timeWindow_ ) external initializer { - __OracleV2_init(uniswapV2Factory_, timeWindow_); + __AUniswapV2Oracle_init(uniswapV2Factory_, timeWindow_); } function mockInit(address uniswapV2Factory_, uint256 timeWindow_) external { - __OracleV2_init(uniswapV2Factory_, timeWindow_); + __AUniswapV2Oracle_init(uniswapV2Factory_, timeWindow_); } function addPaths(address[][] calldata paths_) external { diff --git a/contracts/oracles/AUniswapV2Oracle.sol b/contracts/oracles/AUniswapV2Oracle.sol index 5550316d..7cf613bc 100644 --- a/contracts/oracles/AUniswapV2Oracle.sol +++ b/contracts/oracles/AUniswapV2Oracle.sol @@ -54,7 +54,7 @@ abstract contract AUniswapV2Oracle is Initializable { * @param uniswapV2Factory_ the Uniswap V2 factory * @param timeWindow_ the time between oracle observations */ - function __OracleV2_init( + function __AUniswapV2Oracle_init( address uniswapV2Factory_, uint256 timeWindow_ ) internal onlyInitializing { diff --git a/test/access/MultiOwnable.test.ts b/test/access/MultiOwnable.test.ts index 49b37fef..195f69ed 100644 --- a/test/access/MultiOwnable.test.ts +++ b/test/access/MultiOwnable.test.ts @@ -30,11 +30,30 @@ describe("MultiOwnable", () => { afterEach(reverter.revert); describe("access", () => { + it("should initialize", async () => { + const multiOwnableMock = await ethers.deployContract("MultiOwnableMock"); + + await expect(multiOwnableMock.__MultiOwnableMockMulti_init([])) + .to.be.revertedWithCustomError(multiOwnable, "InvalidOwner") + .withArgs(); + + await multiOwnableMock.__MultiOwnableMockMulti_init([FIRST.address]); + + expect(await multiOwnableMock.isOwner(FIRST.address)).to.be.true; + }); + it("should not initialize twice", async () => { await expect(multiOwnable.mockInit()).to.be.revertedWithCustomError(multiOwnable, "NotInitializing").withArgs(); + await expect(multiOwnable.mockMultiInit()) + .to.be.revertedWithCustomError(multiOwnable, "NotInitializing") + .withArgs(); + await expect(multiOwnable.__MultiOwnableMock_init()) .to.be.revertedWithCustomError(multiOwnable, "InvalidInitialization") .withArgs(); + await expect(multiOwnable.__MultiOwnableMockMulti_init([FIRST.address])) + .to.be.revertedWithCustomError(multiOwnable, "InvalidInitialization") + .withArgs(); }); it("only owner should call these functions", async () => {