Skip to content

Commit

Permalink
Merge pull request #22 from aragon/f/metadata-uri-hash
Browse files Browse the repository at this point in the history
Metadata URI hash
  • Loading branch information
carlosgj94 authored Jul 17, 2024
2 parents 4920a6b + 0f8870a commit 701ffd6
Show file tree
Hide file tree
Showing 6 changed files with 334 additions and 167 deletions.
51 changes: 38 additions & 13 deletions DEPLOYMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,53 @@

## Mainnet

## Holesly

On July 1st 2024:

```
Chain ID: 17000
Deploying from: 0x424797Ed6d902E17b9180BFcEF452658e148e0Ab
Minting test tokens for the multisig members and the bridge
Test voting token: 0xa95BADd91beB92F364905187eCB08B80220d5FA3
Factory contract: 0xFbA94606d10e807Bf6542C19a68DfEa815a4eeC3
DAO contract: 0xdA69Bd97278c409574AdC39295465A848C82CD16
- Multisig plugin: 0x2a22Fc29dE8944E62227bf75C89cA2e8CE9BA274
- Emergency multisig plugin: 0x7C36a0F03c27880C23f5704296Bc18Bfc33A7f59
- Optimistic token voting plugin: 0x40CD85d43B883C83290ed5D18400C640176A9679
- Multisig plugin repository: 0x307d009483C1b8Ef3C91F6ae748385Bf0936C59e
- Emergency multisig plugin repository: 0x8181da2e9b1a428a4cF60fF6CEFc0098c1298aaA
- Optimistic token voting plugin repository: 0x0847F2531e070353297fc3D7fFDB4656C1664c6d
Public key registry 0x7A9577A02608446022F52984435ce1ca632BA629
Delegation wall 0xE917426E10a54FbF22FDAF32A4151c90550e1cA5
```

## Sepolia

On June 6th 2024:
On June 13th 2024:

```
Chain ID: 11155111
Deploying from: 0x424797Ed6d902E17b9180BFcEF452658e148e0Ab
Test voting token: 0xf7A8F99a1d0AFB3C95f80770223b00e062C6Ec19
Factory contract: 0x8c99CDb5567206660CA9b77C3B26C13F6C674952
Test voting token: 0x7Ae1BbFfF99316922cebC74C9465d8E3Cdfc65e3
Factory contract: 0x8793E7847d4a522aE3b76b2F05AD48C390b079A6
DAO contract: 0x6C477915CC803518723d4Bdd5B2170cf38A57203
DAO contract: 0x464E808De86C90Ea0423854cABE887b6AEF85c1E
- Multisig plugin: 0x0fC611670228A61824c317926f30e8a2615aa1A3
- Emergency multisig plugin: 0x619d6661eA06b917e26694f23c5Bb32fa0456773
- Optimistic token voting plugin: 0xC9304930f6a4fB2DAe74A17032426Aa1E817897A
- Multisig plugin: 0x07d0ac4ef82cA8E799BAB1f07f5e4f1De933E88C
- Emergency multisig plugin: 0x143209C5fc8004c4B41cA7Bd27666d884B35c809
- Optimistic token voting plugin: 0x73aA4dBD85eca05542013dcd893CC9DD0c681184
- Multisig plugin repository: 0x841E3dA30697C8FC7224a43952041001545a2443
- Emergency multisig plugin repository: 0x6E8578B1519a04BA9262CB633B06624f636D4795
- Optimistic token voting plugin repository: 0x58CA6f90edB98f9213353f456c685ABF253edAA7
- Multisig plugin repository: 0xA3E9182048AE97ABd2AF3045d7690Ea87B44beAF
- Emergency multisig plugin repository: 0x1cF2c1A6075B532df0E9CEA2734AF526Ff058B19
- Optimistic token voting plugin repository: 0x44Bf21d7d7d052b67A98C924617583f8EBC8a5bC
Public key registry 0xadAb459A189AAaa17D4807805e6Fab55d3fb5C44
Delegation wall 0x0cE7f031BA69abFB404fE148dD09F597db8AB3a0
Public key registry 0xD4615654030982779AC1DD0ff3e69FCD8f8b702d
Delegation wall 0x32ccaee7288e43128C99B5505e6B9cF395ED8b64
```

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ $ forge test

1. Edit `script/multisig-members.json` with the list of addresses to set as signers
2. Run `forge build`
3. Copy `.env.example` into `.env`
4. Define the deployment settings within `.env`
3. Copy `.env.example` into `.env` and define the settings
4. Run `source .env` to load them
5. Set the RPC URL and run the deployment script

```shell
Expand Down
2 changes: 2 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ optimizer-runs = 10_000_000
solc = "0.8.17"

[rpc_endpoints]
holesky = "https://eth-holesky.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
sepolia = "https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
mainnet = "https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"

[etherscan]
holesly = { key = "${ETHERSCAN_API_KEY}" }
sepolia = { key = "${ETHERSCAN_API_KEY}" }
mainnet = { key = "${ETHERSCAN_API_KEY}" }
40 changes: 26 additions & 14 deletions src/EmergencyMultisig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
/// @param parameters The proposal-specific approve settings at the time of the proposal creation.
/// @param approvers The approves casted by the approvers.
/// @param encryptedPayloadURI The IPFS URI where a JSON with the encrypted payload is pinned
/// @param destinationActionsHash The hash of the serialized list of actions to be executed
/// @param publicMetadataUriHash The hash of the metadata IPFS URI to be created on the optimistic proposal
/// @param destinationActionsHash The hash of the serialized list of final actions to be eventually executed
/// @param destinationPlugin The address of the plugin where the proposal will be created if it passes.
struct Proposal {
bool executed;
uint16 approvals;
ProposalParameters parameters;
mapping(address => bool) approvers;
bytes encryptedPayloadURI;
bytes32 publicMetadataUriHash;
bytes32 destinationActionsHash;
OptimisticTokenVotingPlugin destinationPlugin;
}
Expand Down Expand Up @@ -93,6 +95,10 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
/// @param proposalId The ID of the proposal.
error InvalidActions(uint256 proposalId);

/// @notice Thrown if the metadata UI passed for execution doesn't match the expected hash.
/// @param proposalId The ID of the proposal.
error InvalidMetadataUri(uint256 proposalId);

/// @notice Thrown if the minimal approvals value is out of bounds (less than 1 or greater than the number of members in the address list).
/// @param limit The maximal value.
/// @param actual The actual value.
Expand All @@ -106,10 +112,7 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
/// @param proposalId The ID of the proposal.
/// @param creator The creator of the proposal.
/// @param encryptedPayloadURI The IPFS URI where the encrypted proposal data is pinned.
/// @param destinationActionsHash The hash of the serialized actions that will be executed if the proposal passes.
event ProposalCreated(
uint256 indexed proposalId, address indexed creator, bytes encryptedPayloadURI, bytes32 destinationActionsHash
);
event EmergencyProposalCreated(uint256 indexed proposalId, address indexed creator, bytes encryptedPayloadURI);

/// @notice Emitted when a proposal is approved by an approver.
/// @param proposalId The ID of the proposal.
Expand Down Expand Up @@ -161,12 +164,14 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade

/// @notice Creates a new multisig proposal.
/// @param _encryptedPayloadURI The URI where the encrypted contents of the proposal can be found.
/// @param _publicMetadataUriHash The hash of the metadata IPFS URI that will be published on the optimistic proposal.
/// @param _destinationActionsHash The hash of the serialized actions that will be executed after the proposal passes.
/// @param _destinationPlugin The address of the plugin to forward the proposal to when it passes.
/// @param _approveProposal If `true`, the sender will approve the proposal.
/// @return proposalId The ID of the proposal.
function createProposal(
bytes calldata _encryptedPayloadURI,
bytes32 _publicMetadataUriHash,
bytes32 _destinationActionsHash,
OptimisticTokenVotingPlugin _destinationPlugin,
bool _approveProposal
Expand Down Expand Up @@ -197,13 +202,13 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
proposal_.parameters.expirationDate = block.timestamp.toUint64() + EMERGENCY_MULTISIG_PROPOSAL_EXPIRATION_PERIOD;
proposal_.parameters.minApprovals = multisigSettings.minApprovals;

proposal_.publicMetadataUriHash = _publicMetadataUriHash;
proposal_.destinationActionsHash = _destinationActionsHash;

emit ProposalCreated({
emit EmergencyProposalCreated({
proposalId: proposalId,
creator: msg.sender,
encryptedPayloadURI: _encryptedPayloadURI,
destinationActionsHash: _destinationActionsHash
encryptedPayloadURI: _encryptedPayloadURI
});

if (_approveProposal) {
Expand Down Expand Up @@ -250,6 +255,7 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
/// @return approvals The number of approvals casted.
/// @return parameters The parameters of the proposal vote.
/// @return encryptedPayloadURI The URI at which the corresponding encrypted data data can be found.
/// @return publicMetadataUriHash The hash of the metadata IPFS URI to create on the optimistic plugin if the proposal passes.
/// @return destinationActionsHash The hash of the actions to be executed by the destination plugin after the proposal passes.
/// @return destinationPlugin The address of the plugin where the proposal will be forwarded to when executed.
function getProposal(uint256 _proposalId)
Expand All @@ -260,6 +266,7 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
uint16 approvals,
ProposalParameters memory parameters,
bytes memory encryptedPayloadURI,
bytes32 publicMetadataUriHash,
bytes32 destinationActionsHash,
OptimisticTokenVotingPlugin destinationPlugin
)
Expand All @@ -270,6 +277,7 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
approvals = proposal_.approvals;
parameters = proposal_.parameters;
encryptedPayloadURI = proposal_.encryptedPayloadURI;
publicMetadataUriHash = proposal_.publicMetadataUriHash;
destinationActionsHash = proposal_.destinationActionsHash;
destinationPlugin = proposal_.destinationPlugin;
}
Expand All @@ -280,18 +288,22 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade
}

/// @inheritdoc IEmergencyMultisig
function execute(uint256 _proposalId, IDAO.Action[] calldata _actions) public {
function execute(uint256 _proposalId, bytes memory _metadataUri, IDAO.Action[] calldata _actions) public {
if (!_canExecute(_proposalId)) {
revert ProposalExecutionForbidden(_proposalId);
}

if (proposals[_proposalId].destinationActionsHash != hashActions(_actions)) {
if (proposals[_proposalId].publicMetadataUriHash != keccak256(_metadataUri)) {
// This check is intentionally not part of canExecute() in order to prevent
// the the metadata from leaving the app before being executed
revert InvalidMetadataUri(_proposalId);
} else if (proposals[_proposalId].destinationActionsHash != hashActions(_actions)) {
// This check is intentionally not part of canExecute() in order to prevent
// the private actions from ever leaving the local computer before being executed
// the private actions from leaving the app before being executed
revert InvalidActions(_proposalId);
}

_execute(_proposalId, _actions);
_execute(_proposalId, _metadataUri, _actions);
}

/// @notice Computes the hash of the given list of actions
Expand All @@ -308,14 +320,14 @@ contract EmergencyMultisig is IEmergencyMultisig, IMembership, PluginUUPSUpgrade

/// @notice Internal function to execute a vote. It assumes the queried proposal exists.
/// @param _proposalId The ID of the proposal.
function _execute(uint256 _proposalId, IDAO.Action[] calldata _actions) internal {
function _execute(uint256 _proposalId, bytes memory _metadataUri, IDAO.Action[] calldata _actions) internal {
Proposal storage proposal_ = proposals[_proposalId];

proposal_.executed = true;
emit Executed(_proposalId);

proposal_.destinationPlugin.createProposal(
proposal_.encryptedPayloadURI,
_metadataUri,
_actions,
0, // allowFailureMap, no single action may fail
0 // no duration, immediate executioon
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IEmergencyMultisig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ interface IEmergencyMultisig {

/// @notice Executes a proposal.
/// @param _proposalId The ID of the proposal to be executed.
/// @param _metadataUri An IPFS URI pointing to the public content URI.
/// @param _actions the list of actions to execute.
function execute(uint256 _proposalId, IDAO.Action[] calldata _actions) external;
function execute(uint256 _proposalId, bytes memory _metadataUri, IDAO.Action[] calldata _actions) external;
}
Loading

0 comments on commit 701ffd6

Please sign in to comment.