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

Prevent updating if proposal is too close to voting period start #202

Closed
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 .forge-snapshots/ProposeSigComp.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
171010
171002
2 changes: 1 addition & 1 deletion .forge-snapshots/VoteSigComp.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
51977
51969
2 changes: 1 addition & 1 deletion .forge-snapshots/VoteSigCompMetadata.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
53663
53655
2 changes: 1 addition & 1 deletion .forge-snapshots/VoteTxComp.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
45218
45210
2 changes: 1 addition & 1 deletion .forge-snapshots/VoteTxCompMetadata.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
46809
46801
5 changes: 4 additions & 1 deletion src/Space.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ contract Space is ISpace, Initializable, IERC4824, UUPSUpgradeable, OwnableUpgra
/// @dev Evaluates to: `0xf2cda9b1`.
uint32 private constant NO_UPDATE_UINT32 = uint32(bytes4(keccak256(abi.encodePacked("No update"))));

/// @dev Buffer between when the voting period starts and when the proposal can be updated for the last time.
uint32 private PROPOSAL_MODIFICATION_BUFFER = 15 * 60;

/// @inheritdoc IERC4824
string public daoURI;
/// @inheritdoc ISpaceState
Expand Down Expand Up @@ -335,7 +338,7 @@ contract Space is ISpace, Initializable, IERC4824, UUPSUpgradeable, OwnableUpgra
) external override onlyAuthenticator {
Proposal storage proposal = proposals[proposalId];
if (author != proposal.author) revert InvalidCaller();
if (block.timestamp >= proposal.startTimestamp) revert VotingDelayHasPassed();
if (block.timestamp >= proposal.startTimestamp - PROPOSAL_MODIFICATION_BUFFER) revert TooLateToUpdateProposal();

proposal.executionPayloadHash = keccak256(executionStrategy.params);
proposal.executionStrategy = IExecutionStrategy(executionStrategy.addr);
Expand Down
5 changes: 3 additions & 2 deletions src/interfaces/space/ISpaceErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ interface ISpaceErrors {
/// @notice Thrown if a user attempts to finalize (execute or cancel) a proposal that has already been finalized.
error ProposalFinalized();

/// @notice Thrown if an author attempts to update their proposal after the voting delay has passed.
error VotingDelayHasPassed();
/// @notice Thrown if an author attempts to update their proposal after the voting delay has passed (or if
/// if too close to when the voting starts).
error TooLateToUpdateProposal();

/// @notice Thrown if a new proposal did not pass the proposal validation strategy for the space.
error FailedToPassProposalValidation();
Expand Down
2 changes: 1 addition & 1 deletion test/UpdateProposalMetadata.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contract UpdateProposalTest is SpaceTest {
uint256 proposalId = _createProposal(author, proposalMetadataURI, executionStrategy, new bytes(0));
vm.warp(block.timestamp + votingDelay);

vm.expectRevert(VotingDelayHasPassed.selector);
vm.expectRevert(TooLateToUpdateProposal.selector);
// Try to update metadata. Should fail.
_updateProposal(author, proposalId, newStrategy, newMetadataURI);
}
Expand Down