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

feat(space): export proposal id when executing #245

Merged
merged 7 commits into from
Dec 7, 2023
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
21 changes: 21 additions & 0 deletions deployments/goerli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"ActiveProposalsLimiterProposalValidationStrategy": "0x399821c9Ea977387a0DEcCF1C9692B4dF925FF38",
"AvatarExecutionStrategyImplementation": "0xecE4f6b01a2d7FF5A9765cA44162D453fC455e42",
"CompTimelockCompatibleExecutionStrategyImplementation": "0x91086017D5eAEc4BeEc86ac770b5eE672e4Be589",
"CompVotingStrategy": "0x0c2De612982Efd102803161fc7C74CcA15Db932c",
"EthSigAuthenticator": "0x5f9B7D78c9a37a439D78f801E0E339C6E711e260",
"EthTxAuthenticator": "0xBA06E6cCb877C332181A6867c05c8b746A21Aed1",
"MerkleWhitelistVotingStrategy": "0x34f0AfFF5A739bBf3E285615F50e40ddAaf2A829",
"OZVotesVotingStrategy": "0x2c8631584474E750CEdF2Fb6A904f2e84777Aefe",
"OptimisticCompTimelockCompatibleExecutionStrategyImplementation": "0x77e7Aa43b28Df1e467bd4806fE3bF26F5c3EAD27",
"OptimisticTimelockExecutionStrategyImplementation": "0x49AF19f9318d55ad8e7CE743De9Ce76ED408CE0C",
"PropositionPowerAndActiveProposalsLimiterValidationStrategy": "0x358e4Ba219CC1e1c7084A14c3a504772acfc40b1",
"PropositionPowerProposalValidationStrategy": "0x6D9d6D08EF6b26348Bd18F1FC8D953696b7cf311",
"ProxyFactory": "0x4B4F7f64Be813Ccc66AEFC3bFCe2baA01188631c",
"SpaceImplementation": "0xC3031A7d3326E47D49BfF9D374d74f364B29CE4D",
"TimelockExecutionStrategyImplementation": "0xf2A1C2f2098161af98b2Cc7E382AB7F3ba86Ebc4",
"VanillaAuthenticator": "0xb9BE0a0093933968E3B4c4fC5d939B6c1Fe45142",
"VanillaProposalValidationStrategy": "0x9A39194F870c410633C170889E9025fba2113c79",
"VanillaVotingStrategy": "0xC1245C5DCa7885C73E32294140F1e5d30688c202",
"WhitelistVotingStrategy": "0x3CEE21A33751A2722413fF62dEC3dEc48e7748A4"
}
21 changes: 21 additions & 0 deletions deployments/sepolia.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"ActiveProposalsLimiterProposalValidationStrategy": "0x399821c9Ea977387a0DEcCF1C9692B4dF925FF38",
"AvatarExecutionStrategyImplementation": "0xecE4f6b01a2d7FF5A9765cA44162D453fC455e42",
"CompTimelockCompatibleExecutionStrategyImplementation": "0x91086017D5eAEc4BeEc86ac770b5eE672e4Be589",
"CompVotingStrategy": "0x0c2De612982Efd102803161fc7C74CcA15Db932c",
"EthSigAuthenticator": "0x5f9B7D78c9a37a439D78f801E0E339C6E711e260",
"EthTxAuthenticator": "0xBA06E6cCb877C332181A6867c05c8b746A21Aed1",
"MerkleWhitelistVotingStrategy": "0x34f0AfFF5A739bBf3E285615F50e40ddAaf2A829",
"OZVotesVotingStrategy": "0x2c8631584474E750CEdF2Fb6A904f2e84777Aefe",
"OptimisticCompTimelockCompatibleExecutionStrategyImplementation": "0x77e7Aa43b28Df1e467bd4806fE3bF26F5c3EAD27",
"OptimisticTimelockExecutionStrategyImplementation": "0x49AF19f9318d55ad8e7CE743De9Ce76ED408CE0C",
"PropositionPowerAndActiveProposalsLimiterValidationStrategy": "0x358e4Ba219CC1e1c7084A14c3a504772acfc40b1",
"PropositionPowerProposalValidationStrategy": "0x6D9d6D08EF6b26348Bd18F1FC8D953696b7cf311",
"ProxyFactory": "0x4B4F7f64Be813Ccc66AEFC3bFCe2baA01188631c",
"SpaceImplementation": "0xC3031A7d3326E47D49BfF9D374d74f364B29CE4D",
"TimelockExecutionStrategyImplementation": "0xf2A1C2f2098161af98b2Cc7E382AB7F3ba86Ebc4",
"VanillaAuthenticator": "0xb9BE0a0093933968E3B4c4fC5d939B6c1Fe45142",
"VanillaProposalValidationStrategy": "0x9A39194F870c410633C170889E9025fba2113c79",
"VanillaVotingStrategy": "0xC1245C5DCa7885C73E32294140F1e5d30688c202",
"WhitelistVotingStrategy": "0x3CEE21A33751A2722413fF62dEC3dEc48e7748A4"
}
118 changes: 118 additions & 0 deletions script/Example.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.18;

import { Script } from "forge-std/Script.sol";

import { ProxyFactory } from "../src/ProxyFactory.sol";
import { Space } from "../src/Space.sol";
import { VanillaAuthenticator } from "../src/authenticators/VanillaAuthenticator.sol";
import { TimelockExecutionStrategy } from "../src/execution-strategies/timelocks/TimelockExecutionStrategy.sol";
import { Strategy, IndexedStrategy, InitializeCalldata, Choice, MetaTransaction } from "../src/types.sol";
import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";

// Example script to deploy a space, create a proposal, vote on it, and execute it.
contract Example is Script {
// Paste in the addresses from your json in the /deployments/ folder. The below are from v1.0.2 on goerli.
address public proxyFactory = address(0x4B4F7f64Be813Ccc66AEFC3bFCe2baA01188631c);
address public spaceImplementation = address(0xd9c46d5420434355d0E5Ca3e3cCb20cE7A533964);
address public vanillaVotingStrategy = address(0xC1245C5DCa7885C73E32294140F1e5d30688c202);
address public vanillaProposalValidationStrategy = address(0x9A39194F870c410633C170889E9025fba2113c79);
address public vanillaAuthenticator = address(0xb9BE0a0093933968E3B4c4fC5d939B6c1Fe45142);
address public timelockExecutionStrategyImplementation = address(0xdD5243b799759e2C64bD6CaFD7e57FcbB676f87D);

// Change the salt to deploy multiple spaces or get a 'salt already used' error
uint256 public constant saltNonce = 1234;

Check warning on line 24 in script/Example.s.sol

View workflow job for this annotation

GitHub Actions / lint

Constant name must be in capitalized SNAKE_CASE

function run() public {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);

address deployer = address(0x2842c82E20ab600F443646e1BC8550B44a513D82);

Strategy[] memory votingStrategies = new Strategy[](1);
votingStrategies[0] = Strategy(vanillaVotingStrategy, new bytes(0));

string[] memory votingStrategyMetadataURIs = new string[](1);
votingStrategyMetadataURIs[0] = "";

address[] memory authenticators = new address[](1);
authenticators[0] = vanillaAuthenticator;

string memory proposalValidationStrategyMetadataURI = "";
string memory daoURI = "";
string memory metadataURI = "";

// Deploy space
ProxyFactory(proxyFactory).deployProxy(
spaceImplementation,
abi.encodeWithSelector(
Space.initialize.selector,
InitializeCalldata(
deployer,
0,
0,
100,
Strategy(vanillaProposalValidationStrategy, new bytes(0)),
proposalValidationStrategyMetadataURI,
daoURI,
metadataURI,
votingStrategies,
votingStrategyMetadataURIs,
authenticators
)
),
saltNonce
);

address space = ProxyFactory(proxyFactory).predictProxyAddress(
spaceImplementation,
keccak256(abi.encodePacked(deployer, saltNonce))
);

// Deploy Execution Strategy with the space whitelisted
address[] memory spacesWhitelist = new address[](1);
spacesWhitelist[0] = space;
ProxyFactory(proxyFactory).deployProxy(
timelockExecutionStrategyImplementation,
abi.encodeWithSelector(
TimelockExecutionStrategy.setUp.selector,
abi.encode(deployer, deployer, spacesWhitelist, 0, 0)
),
saltNonce
);

address timelockExecutionStrategy = ProxyFactory(proxyFactory).predictProxyAddress(
timelockExecutionStrategyImplementation,
keccak256(abi.encodePacked(deployer, saltNonce))
);

// Create proposal
MetaTransaction[] memory proposalTransactions = new MetaTransaction[](1);
// Example proposal tx
proposalTransactions[0] = MetaTransaction(deployer, 0, abi.encode("hello"), Enum.Operation.Call, 0);
VanillaAuthenticator(vanillaAuthenticator).authenticate(
space,
Space.propose.selector,
abi.encode(
deployer,
"",
Strategy(timelockExecutionStrategy, abi.encode(proposalTransactions)),
new bytes(0)
)
);

// Cast vote
IndexedStrategy[] memory userVotingStrategies = new IndexedStrategy[](1);
userVotingStrategies[0] = IndexedStrategy(0, new bytes(0));
VanillaAuthenticator(vanillaAuthenticator).authenticate(
space,
Space.vote.selector,
abi.encode(deployer, 1, Choice.For, userVotingStrategies, "")
);

// Execute proposal, which queues it in the tx in timelock
Space(space).execute(1, abi.encode(proposalTransactions));

vm.stopBroadcast();
}
}
1 change: 1 addition & 0 deletions src/Space.sol
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ contract Space is ISpace, Initializable, IERC4824, UUPSUpgradeable, OwnableUpgra
proposal.finalizationStatus = FinalizationStatus.Executed;

proposal.executionStrategy.execute(
proposalId,
cachedProposal,
votePower[proposalId][Choice.For],
votePower[proposalId][Choice.Against],
Expand Down
1 change: 1 addition & 0 deletions src/execution-strategies/AvatarExecutionStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ contract AvatarExecutionStrategy is SimpleQuorumExecutionStrategy {
/// @param votesAbstain The number of abstaining votes.
/// @param payload The encoded transactions to execute.
function execute(
uint256 /* proposalId */,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we specify in the doc that there's an unused param ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the natspec comments?

Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ abstract contract EmergencyQuorumExecutionStrategy is IExecutionStrategy, SpaceM
}

function execute(
uint256 proposalId,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ abstract contract OptimisticQuorumExecutionStrategy is IExecutionStrategy, Space
}

function execute(
uint256 proposalId,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
1 change: 1 addition & 0 deletions src/execution-strategies/SimpleQuorumExecutionStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ abstract contract SimpleQuorumExecutionStrategy is IExecutionStrategy, SpaceMana
}

function execute(
uint256 proposalId,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
1 change: 1 addition & 0 deletions src/execution-strategies/VanillaExecutionStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
}

function execute(
uint256 proposalId,

Check warning on line 24 in src/execution-strategies/VanillaExecutionStrategy.sol

View workflow job for this annotation

GitHub Actions / lint

Variable "proposalId" is unused
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
uint256 votesAbstain,
bytes memory payload

Check warning on line 29 in src/execution-strategies/VanillaExecutionStrategy.sol

View workflow job for this annotation

GitHub Actions / lint

Variable "payload" is unused
) external override {
ProposalStatus proposalStatus = getProposalStatus(proposal, votesFor, votesAgainst, votesAbstain);
if ((proposalStatus != ProposalStatus.Accepted) && (proposalStatus != ProposalStatus.VotingPeriodAccepted)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ contract CompTimelockCompatibleExecutionStrategy is SimpleQuorumExecutionStrateg
/// @param votesAbstain The number of abstaining votes for the proposal.
/// @param payload The encoded payload of the proposal to execute.
function execute(
uint256 /* proposalId */,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ contract OptimisticCompTimelockCompatibleExecutionStrategy is OptimisticQuorumEx
/// @param votesAbstain The number of abstaining votes for the proposal.
/// @param payload The encoded payload of the proposal to execute.
function execute(
uint256 /* proposalId */,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ contract OptimisticTimelockExecutionStrategy is OptimisticQuorumExecutionStrateg
/// @param votesAbstain The number of abstaining votes for the proposal.
/// @param payload The proposal execution payload.
function execute(
uint256 /* proposalId */,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ contract TimelockExecutionStrategy is SimpleQuorumExecutionStrategy, IERC1155Rec
/// @param votesAbstain The number of abstaining votes for the proposal.
/// @param payload The proposal execution payload.
function execute(
uint256 /* proposalId */,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/IExecutionStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IExecutionStrategyErrors } from "./execution-strategies/IExecutionStrat
/// @title Execution Strategy Interface
interface IExecutionStrategy is IExecutionStrategyErrors {
function execute(
uint256 proposalId,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
1 change: 1 addition & 0 deletions test/EmergencyQuorumExecutionStrategy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
}

function execute(
uint256 proposalId,

Check warning on line 27 in test/EmergencyQuorumExecutionStrategy.t.sol

View workflow job for this annotation

GitHub Actions / lint

Variable "proposalId" is unused
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
uint256 votesAbstain,
bytes memory payload

Check warning on line 32 in test/EmergencyQuorumExecutionStrategy.t.sol

View workflow job for this annotation

GitHub Actions / lint

Variable "payload" is unused
) external override {
ProposalStatus proposalStatus = getProposalStatus(proposal, votesFor, votesAgainst, votesAbstain);
if ((proposalStatus != ProposalStatus.Accepted) && (proposalStatus != ProposalStatus.VotingPeriodAccepted)) {
Expand Down
1 change: 1 addition & 0 deletions test/OptimisticQuorum.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ contract OptimisticExec is OptimisticQuorumExecutionStrategy {
uint256 internal numExecuted;

function execute(
uint256 proposalId,
Proposal memory proposal,
uint256 votesFor,
uint256 votesAgainst,
Expand Down
Loading