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

Plugin setup tests #21

Merged
merged 5 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"solidity.packageDefaultDependenciesDirectory": "lib",
"editor.formatOnSave": true,
"[solidity]": {
"editor.defaultFormatter": "NomicFoundation.hardhat-solidity"
"editor.defaultFormatter": "NomicFoundation.hardhat-solidity"
},
"solidity.formatter": "forge",
"solidity.compileUsingRemoteVersion": "v0.8.17"
Expand Down
29 changes: 29 additions & 0 deletions DEPLOYMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Deployment list

## Mainnet

## Sepolia

On June 6th 2024:

```
Chain ID: 11155111

Deploying from: 0x424797Ed6d902E17b9180BFcEF452658e148e0Ab
Test voting token: 0xf7A8F99a1d0AFB3C95f80770223b00e062C6Ec19
Factory contract: 0x8c99CDb5567206660CA9b77C3B26C13F6C674952

DAO contract: 0x6C477915CC803518723d4Bdd5B2170cf38A57203

- Multisig plugin: 0x0fC611670228A61824c317926f30e8a2615aa1A3
- Emergency multisig plugin: 0x619d6661eA06b917e26694f23c5Bb32fa0456773
- Optimistic token voting plugin: 0xC9304930f6a4fB2DAe74A17032426Aa1E817897A

- Multisig plugin repository: 0x841E3dA30697C8FC7224a43952041001545a2443
- Emergency multisig plugin repository: 0x6E8578B1519a04BA9262CB633B06624f636D4795
- Optimistic token voting plugin repository: 0x58CA6f90edB98f9213353f456c685ABF253edAA7

Public key registry 0xadAb459A189AAaa17D4807805e6Fab55d3fb5C44
Delegation wall 0x0cE7f031BA69abFB404fE148dD09F597db8AB3a0
```

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The Security Council has a standard multisig plugin and an emergency variant. Th

[Learn more about Aragon OSx](#protocol-overview).

See [Deploying the DAO](#deploying-the-dao) below.
See [Deploying the DAO](#deploying-the-dao) below and check out the [latest deployments](./DEPLOYMENTS.md).

## Optimistic Token Voting plugin

Expand Down
4 changes: 2 additions & 2 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ contract Deploy is Script {
);

console.log("Chain ID:", block.chainid);
console.log("Deploying from:", vm.addr(vm.envUint("DEPLOYMENT_PRIVATE_KEY")));
console.log("");
console.log("Deploying from:", vm.addr(vm.envUint("DEPLOYMENT_PRIVATE_KEY")));

TaikoDaoFactory.DeploymentSettings memory settings;
if (block.chainid == 1) {
Expand All @@ -55,6 +55,7 @@ contract Deploy is Script {

// Print summary
console.log("Factory contract:", address(factory));
console.log("");
console.log("DAO contract:", address(daoDeployment.dao));
console.log("");

Expand Down Expand Up @@ -110,7 +111,6 @@ contract Deploy is Script {
address votingToken = createTestToken(multisigMembers, taikoBridgeAddress);

console.log("Test voting token:", votingToken);
console.log("");

settings = TaikoDaoFactory.DeploymentSettings({
// Taiko contract settings
Expand Down
9 changes: 9 additions & 0 deletions src/DelegationWall.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ contract DelegationWall {

/// @dev Stores the data registered by the delegate candidates
mapping(address => Candidate) public candidates;

/// @dev Keeps track of the addresses that have been already registered, used to enumerate.
address[] public candidateAddresses;

Expand All @@ -21,6 +22,7 @@ contract DelegationWall {
/// @notice Raised when a delegate registers with an empty contentUrl
error EmptyContent();

/// @notice Registers the given data as a new delegation candidate
function register(bytes memory _contentUrl) public {
if (_contentUrl.length == 0) revert EmptyContent();

Expand All @@ -33,6 +35,13 @@ contract DelegationWall {
emit CandidateRegistered(msg.sender, _contentUrl);
}

/// @notice Returns the list of candidate addresses registered
/// @dev Use this function to get all addresses in a single call. You can still call candidateAddresses[idx] to resolve them one by one.
function getCandidateAddresses() public view returns (address[] memory) {
return candidateAddresses;
}

/// @notice Returns the number of candidate entries available
function candidateCount() public view returns (uint256) {
return candidateAddresses.length;
}
Expand Down
7 changes: 6 additions & 1 deletion src/OptimisticTokenVotingPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ contract OptimisticTokenVotingPlugin is
/// @notice A mapping between proposal IDs and proposal information.
mapping(uint256 => Proposal) internal proposals;

/// @notice A mapping to enumerate proposal ID's by index
mapping(uint256 => uint256) public proposalIds;

/// @notice Emitted when the vetoing settings are updated.
/// @param minVetoRatio The minimum veto ratio needed to defeat the proposal, as a fraction of 1_000_000.
/// @param minDuration The minimum duration of the proposal vote in seconds.
Expand Down Expand Up @@ -358,6 +361,8 @@ contract OptimisticTokenVotingPlugin is
_actions: _actions,
_allowFailureMap: _allowFailureMap
});
// Index the ID to make it enumerable. Proposal ID's contain timestamps and cannot be iterated
proposalIds[proposalCount() - 1] = proposalId;

// Store proposal related information
Proposal storage proposal_ = proposals[proposalId];
Expand Down Expand Up @@ -549,5 +554,5 @@ contract OptimisticTokenVotingPlugin is
}

/// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
uint256[45] private __gap;
uint256[44] private __gap;
}
17 changes: 14 additions & 3 deletions src/PublicKeyRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ pragma solidity ^0.8.17;
/// @author Aragon Association - 2024
/// @notice A smart contract where any wallet can register its own libsodium public key for encryption purposes
contract PublicKeyRegistry {
mapping(address => bytes32) internal publicKeys;
mapping(address => bytes32) public publicKeys;

/// @dev Allows to enumerate the wallets that have a public key registered
address[] public registeredWallets;

/// @notice Emitted when a public key is registered
event PublicKeyRegistered(address wallet, bytes32 publicKey);
Expand All @@ -19,9 +22,17 @@ contract PublicKeyRegistry {

publicKeys[msg.sender] = _publicKey;
emit PublicKeyRegistered(msg.sender, _publicKey);
registeredWallets.push(msg.sender);
}

/// @notice Returns the list of wallets that have registered a public key
/// @dev Use this function to get all addresses in a single call. You can still call registeredWallets[idx] to resolve them one by one.
function getRegisteredWallets() public view returns (address[] memory) {
return registeredWallets;
}

function getPublicKey(address _wallet) public view returns (bytes32) {
return publicKeys[_wallet];
/// @notice Returns the number of publicKey entries available
function registeredWalletCount() public view returns (uint256) {
return registeredWallets.length;
}
}
8 changes: 4 additions & 4 deletions src/setup/EmergencyMultisigPluginSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ contract EmergencyMultisigPluginSetup is PluginSetup {
external
returns (address plugin, PreparedSetupData memory preparedSetupData)
{
// Decode `_data` to extract the params needed for deploying and initializing `EmergencyMultisig` plugin.
(EmergencyMultisig.MultisigSettings memory multisigSettings) = decodeInstallationParams(_data);
// Decode `_data` to extract the parameters needed for deploying and initializing `EmergencyMultisig` plugin.
(EmergencyMultisig.MultisigSettings memory multisigSettings) = decodeInstallationParameters(_data);

// Prepare and Deploy the plugin proxy.
plugin = createERC1967Proxy(
address(multisigBase), abi.encodeCall(EmergencyMultisig.initialize, (IDAO(_dao), multisigSettings))
);

// Prepare permissions
PermissionLib.MultiTargetPermission[] memory permissions = new PermissionLib.MultiTargetPermission[](3);
PermissionLib.MultiTargetPermission[] memory permissions = new PermissionLib.MultiTargetPermission[](2);

// Set permissions to be granted.
// Grant the list of permissions of the plugin to the DAO.
Expand Down Expand Up @@ -107,7 +107,7 @@ contract EmergencyMultisigPluginSetup is PluginSetup {
}

/// @notice Decodes the given byte array into the original installation parameters
function decodeInstallationParams(bytes memory _data)
function decodeInstallationParameters(bytes memory _data)
public
pure
returns (EmergencyMultisig.MultisigSettings memory _multisigSettings)
Expand Down
61 changes: 17 additions & 44 deletions src/setup/MultisigPluginSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,21 @@ contract MultisigPluginSetup is PluginSetup {
}

/// @inheritdoc IPluginSetup
function prepareInstallation(
address _dao,
bytes calldata _data
)
function prepareInstallation(address _dao, bytes calldata _data)
external
returns (address plugin, PreparedSetupData memory preparedSetupData)
{
// Decode `_data` to extract the params needed for deploying and initializing `Multisig` plugin.
(
address[] memory members,
Multisig.MultisigSettings memory multisigSettings
) = decodeInstallationParams(_data);
// Decode `_data` to extract the parameters needed for deploying and initializing `Multisig` plugin.
(address[] memory members, Multisig.MultisigSettings memory multisigSettings) =
decodeInstallationParameters(_data);

// Prepare and Deploy the plugin proxy.
plugin = createERC1967Proxy(
address(multisigBase),
abi.encodeCall(
Multisig.initialize,
(IDAO(_dao), members, multisigSettings)
)
address(multisigBase), abi.encodeCall(Multisig.initialize, (IDAO(_dao), members, multisigSettings))
);

// Prepare permissions
PermissionLib.MultiTargetPermission[]
memory permissions = new PermissionLib.MultiTargetPermission[](3);
PermissionLib.MultiTargetPermission[] memory permissions = new PermissionLib.MultiTargetPermission[](2);

// Set permissions to be granted.
// Grant the list of permissions of the plugin to the DAO.
Expand All @@ -69,25 +59,15 @@ contract MultisigPluginSetup is PluginSetup {
}

/// @inheritdoc IPluginSetup
function prepareUpdate(
address _dao,
uint16 _currentBuild,
SetupPayload calldata _payload
)
function prepareUpdate(address _dao, uint16 _currentBuild, SetupPayload calldata _payload)
external
pure
override
returns (
bytes memory initData,
PreparedSetupData memory preparedSetupData
)
returns (bytes memory initData, PreparedSetupData memory preparedSetupData)
{}

/// @inheritdoc IPluginSetup
function prepareUninstallation(
address _dao,
SetupPayload calldata _payload
)
function prepareUninstallation(address _dao, SetupPayload calldata _payload)
external
view
returns (PermissionLib.MultiTargetPermission[] memory permissions)
Expand Down Expand Up @@ -119,27 +99,20 @@ contract MultisigPluginSetup is PluginSetup {
}

/// @notice Encodes the given installation parameters into a byte array
function encodeInstallationParameters(
address[] memory _members,
Multisig.MultisigSettings memory _multisigSettings
) external pure returns (bytes memory) {
function encodeInstallationParameters(address[] memory _members, Multisig.MultisigSettings memory _multisigSettings)
external
pure
returns (bytes memory)
{
return abi.encode(_members, _multisigSettings);
}

/// @notice Decodes the given byte array into the original installation parameters
function decodeInstallationParams(
bytes memory _data
)
function decodeInstallationParameters(bytes memory _data)
public
pure
returns (
address[] memory _members,
Multisig.MultisigSettings memory _multisigSettings
)
returns (address[] memory _members, Multisig.MultisigSettings memory _multisigSettings)
{
(_members, _multisigSettings) = abi.decode(
_data,
(address[], Multisig.MultisigSettings)
);
(_members, _multisigSettings) = abi.decode(_data, (address[], Multisig.MultisigSettings));
}
}
18 changes: 18 additions & 0 deletions test/DelegationWall.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,24 @@ contract EmergencyMultisigTest is AragonTest {
assertEq(wall.candidateAddresses(3), david, "Incorrect candidate address");
}

function test_ShouldLoadTheRegisteredAddresses() public {
vm.startPrank(alice);
wall.register("https://");
vm.startPrank(bob);
wall.register("https://taiko.xyz");
vm.startPrank(carol);
wall.register("https://x.com/carol");
vm.startPrank(david);
wall.register("https://defeat-goliath.org");

address[] memory candidates = wall.getCandidateAddresses();
assertEq(candidates.length, 4);
assertEq(candidates[0], alice);
assertEq(candidates[1], bob);
assertEq(candidates[2], carol);
assertEq(candidates[3], david);
}

function test_ShouldEmitAnEventWhenRegistering() public {
// Alice
vm.startPrank(alice);
Expand Down
Loading