Skip to content

Instantly share code, notes, and snippets.

@novaknole
Created October 25, 2021 13:59
Show Gist options
  • Save novaknole/2652767709c9839b9c2bda092734384a to your computer and use it in GitHub Desktop.
Save novaknole/2652767709c9839b9c2bda092734384a to your computer and use it in GitHub Desktop.
/*
* SPDX-License-Identifier: GPL-3.0
*/
pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;
import "@aragon/govern-core/contracts/GovernRegistry.sol";
import "@aragon/govern-token/contracts/GovernTokenFactory.sol";
import "@aragon/govern-token/contracts/interfaces/IERC20.sol";
import "@aragon/govern-token/contracts/GovernMinter.sol";
import "@aragon/govern-token/contracts/libraries/TokenLib.sol";
import "./core-factories/GovernFactory.sol";
import "./core-factories/GovernQueueFactory.sol";
contract ANDAOFactory {
address internal constant ANY_ADDR = address(-1);
GovernFactory public governFactory;
GovernQueueFactory public queueFactory;
GovernTokenFactory public tokenFactory;
GovernRegistry public registry;
Govern public mainDAOExecutor;
event SubDAOsDeployed(Govern compGovern, GovernQueue indexed compQueue, Govern execGovern, GovernQueue indexed execQueue);
constructor(
GovernRegistry _registry,
GovernFactory _governFactory,
GovernQueueFactory _queueFactory,
Govern _mainDAOExecutor
) public {
governFactory = _governFactory;
queueFactory = _queueFactory;
registry = _registry;
mainDAOExecutor = _mainDAOExecutor;
}
function _setConfig(GovernQueue queue, Govern govern, ERC3000Data.Config memory tmpConfig, ERC3000Data.Config memory config) internal {
ERC3000Data.Action[] memory actions = new ERC3000Data.Action[](1);
actions[0] = ERC3000Data.Action({
to: address(govern),
value: 0,
data: abi.encodeWithSelector(queue.configure.selector, config)
});
ERC3000Data.Container memory container = ERC3000Data.Container({
payload: ERC3000Data.Payload({
nonce: 1,
executionTime: block.timestamp,
submitter: msg.sender,
executor: govern,
actions: actions,
allowFailuresMap: bytes32(0),
proof: "SETUP"
}),
config: tmpConfig
});
queue.schedule(container);
queue.execute(container);
}
function _grantPermissions(Govern govern, GovernQueue queue, ERC3000Data.Config memory config, Govern vetoExecutor) internal {
// Queue permissions
uint256 bulkSize = 7;
if (address(vetoExecutor) != address(0)) {
bulkSize = 8;
}
ACLData.BulkItem[] memory queueItems = new ACLData.BulkItem[](bulkSize);
queueItems[0] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.execute.selector, ANY_ADDR);
queueItems[1] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.challenge.selector, ANY_ADDR);
queueItems[2] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.configure.selector, address(govern));
queueItems[3] = ACLData.BulkItem(ACLData.BulkOp.Revoke, queue.ROOT_ROLE(), address(this));
queueItems[4] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.ROOT_ROLE(), address(govern));
queueItems[5] = ACLData.BulkItem(ACLData.BulkOp.Freeze, queue.ROOT_ROLE(), address(0));
queueItems[6] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.schedule.selector, ANY_ADDR);
if (address(vetoExecutor) != address(0)) {
queueItems[0] = ACLData.BulkItem(ACLData.BulkOp.Grant, queue.veto.selector, address(vetoExecutor));
}
queue.bulk(queueItems);
ERC3000Data.Action[] memory actions = new ERC3000Data.Action[](1);
actions[0] = ERC3000Data.Action({
to: address(govern),
value: 0,
data: abi.encodeWithSelector(govern.grant.selector, govern.exec.selector, mainDAOExecutor)
});
// Grant execute permission to main ANDAO
ERC3000Data.Container memory container = ERC3000Data.Container({
payload: ERC3000Data.Payload({
nonce: 0,
executionTime: block.timestamp,
submitter: msg.sender,
executor: govern,
actions: actions,
allowFailuresMap: bytes32(0),
proof: "SETUP"
}),
config: config
});
queue.schedule(container);
queue.execute(container);
}
function _createGovern(IERC20 token, string memory name, ERC3000Data.Config memory config, Govern vetoExecutor) internal returns (Govern govern, GovernQueue queue) {
ERC3000Data.Config memory tmpConfig = ERC3000Data.Config({
executionDelay: 0, // executionDelay
scheduleDeposit: ERC3000Data.Collateral({ // scheduleDeposit
token: config.scheduleDeposit.token,
amount: 0
}),
challengeDeposit: ERC3000Data.Collateral({ // challengeDeposit
token: config.challengeDeposit.token,
amount: 0
}),
resolver: address(0x45c9B693D98f19BC92626BbCb571C3Bd405810Be),
rules: "bafybeic5mm377nlwbgc25wjadcozlji4ncfnoit35uz5hpuryeltg6naq4",
maxCalldataSize: 100000
});
queue = queueFactory.newQueue(
address(this),
tmpConfig,
keccak256(abi.encodePacked(name))
);
govern = governFactory.newGovern(queue, keccak256(abi.encodePacked(name)));
_grantPermissions(govern, queue, tmpConfig, vetoExecutor);
_setConfig(queue, govern, tmpConfig, config);
registry.register(govern, queue, token, address(-1), name, "");
}
function deployExecutiveCommittee(Govern compGovern) internal returns (Govern govern, GovernQueue queue) {
return _createGovern(
IERC20(0),// DEFINE COMMITTEE TOKEN
"AN_EXEC_DAO",
ERC3000Data.Config({
executionDelay: 604800,
scheduleDeposit: ERC3000Data.Collateral({
token: address(0xa117000000f279D81A1D3cc75430fAA017FA5A2e),
amount: 50
}),
challengeDeposit: ERC3000Data.Collateral({
token: address(0xa117000000f279D81A1D3cc75430fAA017FA5A2e),
amount: 50
}),
resolver: address(0x45c9B693D98f19BC92626BbCb571C3Bd405810Be),
rules: "bafybeic5mm377nlwbgc25wjadcozlji4ncfnoit35uz5hpuryeltg6naq4",
maxCalldataSize: 100000
}),
compGovern
);
}
function deployComplianceCommittee() internal returns (Govern govern, GovernQueue queue) {
return _createGovern(
IERC20(0),// DEFINE COMMITTEE TOKEN
"AN_COMPLIANCE_DAO",
ERC3000Data.Config({
executionDelay: 10800,
scheduleDeposit: ERC3000Data.Collateral({
token: address(0xa117000000f279D81A1D3cc75430fAA017FA5A2e),
amount: 50
}),
challengeDeposit: ERC3000Data.Collateral({
token: address(0xa117000000f279D81A1D3cc75430fAA017FA5A2e),
amount: 50
}),
resolver: address(0x45c9B693D98f19BC92626BbCb571C3Bd405810Be),
rules: "bafybeic5mm377nlwbgc25wjadcozlji4ncfnoit35uz5hpuryeltg6naq4",
maxCalldataSize: 100000
}),
Govern(0)
);
}
function deployANSubDAOs() external returns (Govern compGovern, GovernQueue compQueue, Govern execGovern, GovernQueue execQueue) {
(compGovern, compQueue) = deployComplianceCommittee();
(execGovern, execQueue) = deployExecutiveCommittee(compGovern);
emit SubDAOsDeployed(compGovern, compQueue, execGovern, execQueue);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment