Skip to content

Commit

Permalink
deploying executor and always true condition
Browse files Browse the repository at this point in the history
  • Loading branch information
novaknole committed Oct 29, 2024
1 parent b0ca2fb commit dc79242
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 16 deletions.
22 changes: 22 additions & 0 deletions packages/contracts/deploy/new/10_framework/52_global_executor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import executorArtifact from '../../../artifacts/@aragon/osx-commons-contracts/src/executors/Executor.sol/Executor.json';
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployments, ethers} = hre;
const {deploy} = deployments;
const [deployer] = await ethers.getSigners();

await deploy('GlobalExecutor', {
contract: executorArtifact,
from: deployer.address,
args: [],
log: true,
});

hre.aragonToVerifyContracts.push({
...(await deployments.get('GlobalExecutor')),
});
};
export default func;
func.tags = ['New', 'GlobalExecutor'];
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import alwaysTrueConditionArtifact from '../../../artifacts/@aragon/osx-commons-contracts/src/permission/condition/extensions/AlwaysTrueCondition.sol/AlwaysTrueCondition.json';
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployments, ethers} = hre;
const {deploy} = deployments;
const [deployer] = await ethers.getSigners();

await deploy('AlwaysTrueCondition', {
contract: alwaysTrueConditionArtifact,
from: deployer.address,
args: [],
log: true,
});

hre.aragonToVerifyContracts.push({
...(await deployments.get('AlwaysTrueCondition')),
});
};
export default func;
func.tags = ['New', 'AlwaysTrueCondition'];
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
);
};
export default func;
func.tags = ['New', 'Conclude'];
func.tags = ['New', 'Conclude', 'ConcludeEnd'];
func.runAtTheEnd = true;
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
}
};
export default func;
func.tags = ['New', 'Verify'];
func.tags = ['New', 'Verify', 'VerifyEnd'];
func.runAtTheEnd = true;
func.skip = (hre: HardhatRuntimeEnvironment) =>
Promise.resolve(isLocal(hre.network));
28 changes: 25 additions & 3 deletions packages/contracts/src/core/dao/DAO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ import {IProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versioni
import {ProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versioning/ProtocolVersion.sol";
import {VersionComparisonLib} from "@aragon/osx-commons-contracts/src/utils/versioning/VersionComparisonLib.sol";
import {hasBit, flipBit} from "@aragon/osx-commons-contracts/src/utils/math/BitMap.sol";
import {Action} from "@aragon/osx-commons-contracts/src/executors/Executor.sol";
import {IExecutor} from "@aragon/osx-commons-contracts/src/executors/IExecutor.sol";
import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol";

import {PermissionManager} from "../permission/PermissionManager.sol";
import {CallbackHandler} from "../utils/CallbackHandler.sol";
import {IEIP4824} from "./IEIP4824.sol";

/// @title DAO
/// @author Aragon X - 2021-2023
/// @author Aragon X - 2021-2024
/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface.
/// @dev Public API of the Aragon DAO framework.
/// @custom:security-contact [email protected]
Expand All @@ -34,6 +36,7 @@ contract DAO is
IERC1271,
ERC165StorageUpgradeable,
IDAO,
IExecutor,
UUPSUpgradeable,
ProtocolVersion,
PermissionManager,
Expand Down Expand Up @@ -117,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);
Expand All @@ -134,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.
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
Expand All @@ -155,10 +170,14 @@ 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

// In addition to the current interfaceId, also support previous version of the interfaceId.
_registerInterface(type(IDAO).interfaceId ^ IExecutor.execute.selector);

_registerInterface(type(IDAO).interfaceId);
_registerInterface(type(IExecutor).interfaceId);
_registerInterface(type(IERC1271).interfaceId);
_registerInterface(type(IEIP4824).interfaceId);
_registerInterface(type(IProtocolVersion).interfaceId); // added in v1.3.0
Expand Down Expand Up @@ -198,6 +217,9 @@ contract DAO is
_who: address(this),
_permissionId: keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION")
});

_registerInterface(type(IDAO).interfaceId);
_registerInterface(type(IExecutor).interfaceId);
}
}

Expand Down Expand Up @@ -246,7 +268,7 @@ contract DAO is
_setMetadata(_metadata);
}

/// @inheritdoc IDAO
/// @inheritdoc IExecutor
function execute(
bytes32 _callId,
Action[] calldata _actions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165C
import {ProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versioning/ProtocolVersion.sol";
import {IPluginSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/IPluginSetup.sol";
import {PluginSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/PluginSetup.sol";
import {DAO, IDAO} from "../../../core/dao/DAO.sol";
import {DAO} from "../../../core/dao/DAO.sol";
import {PermissionLib} from "@aragon/osx-commons-contracts/src/permission/PermissionLib.sol";
import {PluginUUPSUpgradeable} from "@aragon/osx-commons-contracts/src/plugin/PluginUUPSUpgradeable.sol";
import {IPlugin} from "@aragon/osx-commons-contracts/src/plugin/IPlugin.sol";
Expand Down
3 changes: 3 additions & 0 deletions packages/contracts/src/test/Migration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ import {ENSSubdomainRegistrar as ENSSubdomainRegistrar_v1_3_0} from "@aragon/osx
// Integration Testing
import {ProxyFactory} from "@aragon/osx-commons-contracts/src/utils/deployment/ProxyFactory.sol";

// To show up in artifacts.
import {AlwaysTrueCondition} from "@aragon/osx-commons-contracts/src/permission/condition/extensions/AlwaysTrueCondition.sol";

/* solhint-enable no-unused-import */
64 changes: 59 additions & 5 deletions packages/contracts/test/core/dao/dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ import {
IProtocolVersion__factory,
PermissionConditionMock__factory,
PermissionConditionMock,
IExecutor__factory,
} from '../../../typechain';
import {DAO__factory as DAO_V1_0_0__factory} from '../../../typechain/@aragon/osx-v1.0.1/core/dao/DAO.sol';
import {IDAO__factory as IDAO_V1_0_0_factory} from '../../../typechain/@aragon/osx-v1.0.1/core/dao/IDAO.sol';
import {DAO__factory as DAO_V1_3_0__factory} from '../../../typechain/@aragon/osx-v1.3.0/core/dao/DAO.sol';
import {IDAO__factory as IDAO_V3_0_0_factory} from '../../../typechain/@aragon/osx-v1.3.0/core/dao/IDAO.sol';
import {ExecutedEvent} from '../../../typechain/DAO';
import {
getActions,
Expand Down Expand Up @@ -82,7 +85,7 @@ const EVENTS = {
export const VALID_ERC1271_SIGNATURE = '0x1626ba7e';
export const INVALID_ERC1271_SIGNATURE = '0xffffffff';

describe('DAO', function () {
describe.only('DAO', function () {
let signers: SignerWithAddress[];
let ownerAddress: string;
let dao: DAO;
Expand Down Expand Up @@ -142,7 +145,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 () => {
Expand Down Expand Up @@ -301,13 +304,36 @@ describe('DAO', function () {
).toNumber()
).to.equal(0);
});

it('registers IExecutor interface for versions < 1.4.0', async () => {
// Create an uninitialized DAO.
const uninitializedDao = await deployWithProxy<DAO>(DAO);

expect(
await uninitializedDao.supportsInterface(
getInterfaceId(IExecutor__factory.createInterface())
)
).to.be.false;

await uninitializedDao.initializeFrom([1, 3, 0], EMPTY_DATA);

expect(
await uninitializedDao.supportsInterface(
getInterfaceId(IExecutor__factory.createInterface())
)
).to.be.true;
});
});

describe('Upgrades', async () => {
let legacyContractFactory: ContractFactory;
let currentContractFactory: ContractFactory;
let initArgs: any;

const IExecutorInterfaceId = getInterfaceId(
IExecutor__factory.createInterface()
);

before(() => {
currentContractFactory = new DAO__factory(signers[0]);

Expand All @@ -330,10 +356,10 @@ describe('DAO', function () {
);
});

it('upgrades from v1.0.0', async () => {
it('from v1.0.0', async () => {
legacyContractFactory = new DAO_V1_0_0__factory(signers[0]);

const {fromImplementation, toImplementation} =
const {proxy, fromImplementation, toImplementation} =
await deployAndUpgradeFromToCheck(
signers[0],
signers[1],
Expand All @@ -343,6 +369,7 @@ describe('DAO', function () {
currentContractFactory,
DAO_PERMISSIONS.UPGRADE_DAO_PERMISSION_ID
);

expect(toImplementation).to.not.equal(fromImplementation);

const fromProtocolVersion = await getProtocolVersion(
Expand All @@ -357,12 +384,23 @@ describe('DAO', function () {
IMPLICIT_INITIAL_PROTOCOL_VERSION
);
expect(toProtocolVersion).to.deep.equal(osxContractsVersion());

await proxy.initializeFrom([1, 0, 0], EMPTY_DATA);

// Check that it still supports old interfaceId for backwards compatibility.
expect(
await proxy.supportsInterface(
getInterfaceId(IDAO_V1_0_0_factory.createInterface())
)
).to.be.true;

expect(await proxy.supportsInterface(IExecutorInterfaceId)).to.be.true;
});

it('from v1.3.0', async () => {
legacyContractFactory = new DAO_V1_3_0__factory(signers[0]);

const {fromImplementation, toImplementation} =
const {proxy, fromImplementation, toImplementation} =
await deployAndUpgradeFromToCheck(
signers[0],
signers[1],
Expand All @@ -384,6 +422,17 @@ describe('DAO', function () {
expect(fromProtocolVersion).to.not.deep.equal(toProtocolVersion);
expect(fromProtocolVersion).to.deep.equal([1, 3, 0]);
expect(toProtocolVersion).to.deep.equal(osxContractsVersion());

await proxy.initializeFrom([1, 3, 0], EMPTY_DATA);

// Check that it still supports old interfaceId for backwards compatibility.
expect(
await proxy.supportsInterface(
getInterfaceId(IDAO_V3_0_0_factory.createInterface())
)
).to.be.true;

expect(await proxy.supportsInterface(IExecutorInterfaceId)).to.be.true;
});
});

Expand All @@ -403,6 +452,11 @@ describe('DAO', function () {
expect(await dao.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IExecutor` interface', async () => {
const iface = IExecutor__factory.createInterface();
expect(await dao.supportsInterface(getInterfaceId(iface))).to.be.true;
});

it('supports the `IProtocolVersion` interface', async () => {
const iface = IProtocolVersion__factory.createInterface();
expect(await dao.supportsInterface(getInterfaceId(iface))).to.be.true;
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/test/test-utils/uups-upgradeable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export async function deployAndUpgradeFromToCheck(
}

// Upgrade the proxy to a new implementation from a different factory
await upgrades.upgradeProxy(proxy.address, to.connect(upgrader), {
proxy = await upgrades.upgradeProxy(proxy.address, to.connect(upgrader), {
unsafeAllow: ['constructor'],
constructorArgs: [],
});
Expand Down
6 changes: 3 additions & 3 deletions packages/contracts/utils/etherscan.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import networks from '../networks';
import {networkExtensions} from '../networks';
import fs from 'fs';
import HRE from 'hardhat';
import {file} from 'tmp-promise';
Expand All @@ -14,10 +14,10 @@ export const verifyContract = async (
) => {
const currentNetwork = HRE.network.name;

if (!Object.keys(networks).includes(currentNetwork)) {
if (!Object.keys(networkExtensions).includes(currentNetwork)) {
throw Error(
`Current network ${currentNetwork} not supported. Please change to one of the next networks: ${Object.keys(
networks
networkExtensions
).join(',')}`
);
}
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
dependencies:
tslib "^2.6.2"

"@aragon/[email protected]":
"@aragon/osx-commons-contracts@^1.4.0-alpha.5":
version "1.4.0-alpha.5"
resolved "https://registry.yarnpkg.com/@aragon/osx-commons-contracts/-/osx-commons-contracts-1.4.0-alpha.5.tgz#37a28085677c21216628ba0a05f5fe09489eb71c"
integrity sha512-F2JWWxmUNmiJsaXcTDyd6F2GUIgnc313vvWTp/cSmSVkccT2pfMleWqxIi4LIodX3ueFUYfE02rLj8Gjp1jljA==
Expand Down

0 comments on commit dc79242

Please sign in to comment.