Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deploying executor and always true condition #616

Merged
merged 6 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 () {
novaknole marked this conversation as resolved.
Show resolved Hide resolved
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
Loading