diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 11c72005a..000000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "recommendations": [ - "esbenp.prettier-vscode", - "NomicFoundation.hardhat-solidity", - "KnisterPeter.vscode-commitizen", - "tintinweb.solidity-visual-auditor" - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index b1a9a8ac4..f1facf606 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,10 +1,3 @@ { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "prettier.documentSelectors": ["**/*.sol"], - "solidity.formatter": "prettier", - "editor.tabSize": 4, - "[markdown]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - } -} + "solidity.defaultCompiler": "remote" +} \ No newline at end of file diff --git a/packages/contracts/scripts/generate-typechain-osx.ts b/packages/contracts/scripts/generate-typechain-osx.ts index 40bb38b2b..9c32f0f80 100644 --- a/packages/contracts/scripts/generate-typechain-osx.ts +++ b/packages/contracts/scripts/generate-typechain-osx.ts @@ -14,6 +14,8 @@ async function generateTypechain(): Promise { excludedDirs.add(path.join(artifactsDir, OSX_VERSION_ALIASES[i])); } + console.log(excludedDirs) + const jsonFiles: string[] = []; console.log('Searching for files...'); @@ -28,7 +30,11 @@ async function generateTypechain(): Promise { } const dirPath = path.dirname(filePath); - if (!excludedDirs.has(dirPath)) { + + // Only arrange the contracts' paths in the current directory without previous versions. + const containsPrefix = Array.from(excludedDirs).some(prefix => dirPath.startsWith(prefix)); + + if (!containsPrefix) { jsonFiles.push(filePath); } }); @@ -37,6 +43,7 @@ async function generateTypechain(): Promise { const filesArg = jsonFiles.join(' '); + // console.log(filesArg, ' kk') if (filesArg) { await execPromise( `typechain --target ethers-v5 --out-dir ./typechain ${filesArg}` diff --git a/packages/contracts/src/core/dao/DAO.sol b/packages/contracts/src/core/dao/DAO.sol index ec0ff99d2..fdea4fc05 100644 --- a/packages/contracts/src/core/dao/DAO.sol +++ b/packages/contracts/src/core/dao/DAO.sol @@ -120,6 +120,9 @@ contract DAO is /// @notice Thrown when a function is removed but left to not corrupt the interface ID. error FunctionRemoved(); + /// @notice Thrown when initialize is called after it has already been executed. + error AlreadyInitialized(); + /// @notice Emitted when a new DAO URI is set. /// @param daoURI The new URI. event NewURI(string daoURI); @@ -137,6 +140,15 @@ contract DAO is _reentrancyStatus = _NOT_ENTERED; } + /// @notice This ensures that the initialize function cannot be called during the upgrade process. + modifier onlyCallAtInitialization() { + if (_getInitializedVersion() != 0) { + revert AlreadyInitialized(); + } + + _; + } + /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. constructor() { _disableInitializers(); @@ -157,7 +169,7 @@ contract DAO is address _initialOwner, address _trustedForwarder, string calldata daoURI_ - ) external reinitializer(3) { + ) external onlyCallAtInitialization reinitializer(3) { _reentrancyStatus = _NOT_ENTERED; // added in v1.3.0 _registerInterface(type(IDAO).interfaceId); @@ -274,8 +286,7 @@ contract DAO is msg.data ); - for (uint256 i = 0; i < _actions.length; i++) { - // TODO: Merge this loop with the below one. + for (uint256 i = 0; i < _actions.length; ) { Action calldata action = _actions[i]; bool isAllowed = hasExecutePermission; @@ -298,9 +309,7 @@ contract DAO is if (!isAllowed) { revert Unauthorized(action.to, msg.sender, permissionId); } - } - for (uint256 i = 0; i < _actions.length; ) { bool success; bytes memory data; diff --git a/packages/contracts/test/core/dao/dao.ts b/packages/contracts/test/core/dao/dao.ts index 81d24a70c..84636e971 100644 --- a/packages/contracts/test/core/dao/dao.ts +++ b/packages/contracts/test/core/dao/dao.ts @@ -147,7 +147,7 @@ describe('DAO', function () { dummyAddress1, daoExampleURI ) - ).to.be.revertedWith('Initializable: contract is already initialized'); + ).to.be.revertedWithCustomError(dao, 'AlreadyInitialized'); }); it('initializes with the correct trusted forwarder', async () => { @@ -449,7 +449,6 @@ describe('DAO', function () { it('supports the `IDAO` interface', async () => { const iface = IDAO__factory.createInterface(); - expect(getInterfaceId(iface)).to.equal('0x9385547e'); // the interfaceID from IDAO v1.0.0 expect(await dao.supportsInterface(getInterfaceId(iface))).to.be.true; }); diff --git a/packages/contracts/test/framework/plugin/plugin-setup-processor.ts b/packages/contracts/test/framework/plugin/plugin-setup-processor.ts index d241940e5..c68fa1b23 100644 --- a/packages/contracts/test/framework/plugin/plugin-setup-processor.ts +++ b/packages/contracts/test/framework/plugin/plugin-setup-processor.ts @@ -109,6 +109,8 @@ const EMPTY_DATA = '0x'; const ADDRESS_TWO = `0x${'00'.repeat(19)}02`; +const APPLY_TARGET_PERMISSION_ID = ethers.utils.id('APPLY_TARGET_PERMISSION'); + describe('PluginSetupProcessor', function () { let signers: SignerWithAddress[]; let psp: PluginSetupProcessor; @@ -579,7 +581,7 @@ describe('PluginSetupProcessor', function () { .withArgs( targetDao.address, psp.address, - '0xf40ef0af1ef5603c5d084dc17659d339ea90c8ff31545c1ffcadc8207aefa8af' + APPLY_TARGET_PERMISSION_ID ); }); @@ -1165,7 +1167,7 @@ describe('PluginSetupProcessor', function () { .withArgs( targetDao.address, psp.address, - '0xf40ef0af1ef5603c5d084dc17659d339ea90c8ff31545c1ffcadc8207aefa8af' + APPLY_TARGET_PERMISSION_ID ); }); @@ -1827,7 +1829,7 @@ describe('PluginSetupProcessor', function () { .withArgs( targetDao.address, psp.address, - '0xf40ef0af1ef5603c5d084dc17659d339ea90c8ff31545c1ffcadc8207aefa8af' + APPLY_TARGET_PERMISSION_ID ); });