Skip to content

Commit

Permalink
data: add txs count check
Browse files Browse the repository at this point in the history
since we had a recent incident where a candidate with more than 10 txs was created
only to fail to convert to a proposal because of the tx limit proposals have
  • Loading branch information
eladmallel committed Dec 19, 2023
1 parent fd60e39 commit 9bf65a1
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ contract NounsDAOData is OwnableUpgradeable, UUPSUpgradeable, NounsDAODataEvents
}

if (propCandidates[msg.sender][keccak256(bytes(slug))]) revert SlugAlreadyUsed();
NounsDAOV3Proposals.checkProposalTxs(NounsDAOV3Proposals.ProposalTxs(targets, values, signatures, calldatas));

propCandidates[msg.sender][keccak256(bytes(slug))] = true;

Expand Down Expand Up @@ -193,6 +194,7 @@ contract NounsDAOData is OwnableUpgradeable, UUPSUpgradeable, NounsDAODataEvents
) external payable {
if (!isNouner(msg.sender) && msg.value < updateCandidateCost) revert MustBeNounerOrPaySufficientFee();
if (!propCandidates[msg.sender][keccak256(bytes(slug))]) revert SlugDoesNotExist();
NounsDAOV3Proposals.checkProposalTxs(NounsDAOV3Proposals.ProposalTxs(targets, values, signatures, calldatas));

bytes memory encodedProp = NounsDAOV3Proposals.calcProposalEncodeData(
msg.sender,
Expand Down
130 changes: 122 additions & 8 deletions packages/nouns-contracts/test/foundry/NounsDAOData.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,26 @@ abstract contract NounsDAODataBaseTest is DeployUtilsV3, SigUtils, NounsDAODataE
string memory signature,
bytes memory callData
) internal pure returns (NounsDAOV3Proposals.ProposalTxs memory) {
address[] memory targets = new address[](1);
targets[0] = target;
uint256[] memory values = new uint256[](1);
values[0] = value;
string[] memory signatures = new string[](1);
signatures[0] = signature;
bytes[] memory calldatas = new bytes[](1);
calldatas[0] = callData;
return createTxs(1, target, value, signature, callData);
}

function createTxs(
uint256 count,
address target,
uint256 value,
string memory signature,
bytes memory callData
) internal pure returns (NounsDAOV3Proposals.ProposalTxs memory) {
address[] memory targets = new address[](count);
uint256[] memory values = new uint256[](count);
string[] memory signatures = new string[](count);
bytes[] memory calldatas = new bytes[](count);
for (uint256 i = 0; i < count; i++) {
targets[i] = target;
values[i] = value;
signatures[i] = signature;
calldatas[i] = callData;
}
return NounsDAOV3Proposals.ProposalTxs(targets, values, signatures, calldatas);
}
}
Expand Down Expand Up @@ -278,6 +289,43 @@ contract NounsDAOData_CreateCandidateTest is NounsDAODataBaseTest {
'reason'
);
}

function test_createProposalCandidate_givenMoreThan10Txs_reverts() public {
vm.prank(dataAdmin);
data.setCreateCandidateCost(0);

string memory description = 'some description';
string memory slug = 'some slug';
NounsDAOV3Proposals.ProposalTxs memory txs = createTxs(11, address(0), 0, 'some signature', 'some data');

vm.expectRevert(NounsDAOV3Proposals.TooManyActions.selector);
data.createProposalCandidate(txs.targets, txs.values, txs.signatures, txs.calldatas, description, slug, 0);
}

function test_createProposalCandidate_givenZeroTxs_reverts() public {
vm.prank(dataAdmin);
data.setCreateCandidateCost(0);

string memory description = 'some description';
string memory slug = 'some slug';
NounsDAOV3Proposals.ProposalTxs memory txs = createTxs(0, address(0), 0, 'some signature', 'some data');

vm.expectRevert(NounsDAOV3Proposals.MustProvideActions.selector);
data.createProposalCandidate(txs.targets, txs.values, txs.signatures, txs.calldatas, description, slug, 0);
}

function test_createProposalCandidate_givenArityMismatch_reverts() public {
vm.prank(dataAdmin);
data.setCreateCandidateCost(0);

string memory description = 'some description';
string memory slug = 'some slug';
NounsDAOV3Proposals.ProposalTxs memory txs = createTxs(1, address(0), 0, 'some signature', 'some data');
uint256[] memory values = new uint256[](2);

vm.expectRevert(NounsDAOV3Proposals.ProposalInfoArityMismatch.selector);
data.createProposalCandidate(txs.targets, values, txs.signatures, txs.calldatas, description, slug, 0);
}
}

contract NounsDAOData_UpdateCandidateTest is NounsDAODataBaseTest {
Expand Down Expand Up @@ -465,6 +513,72 @@ contract NounsDAOData_UpdateCandidateTest is NounsDAODataBaseTest {
'reason'
);
}

function test_updateProposalCandidate_givenMoreThan10Txs_reverts() public {
vm.prank(dataAdmin);
data.setUpdateCandidateCost(0);
string memory description = 'some description';
string memory slug = 'some slug';
NounsDAOV3Proposals.ProposalTxs memory txs = createTxs(address(0), 0, 'some signature', 'some data');
data.createProposalCandidate(txs.targets, txs.values, txs.signatures, txs.calldatas, description, slug, 0);
txs = createTxs(11, address(0), 0, 'some signature', 'some data');

vm.expectRevert(NounsDAOV3Proposals.TooManyActions.selector);
data.updateProposalCandidate(
txs.targets,
txs.values,
txs.signatures,
txs.calldatas,
description,
slug,
0,
'reason'
);
}

function test_updateProposalCandidate_givenZeroTxs_reverts() public {
vm.prank(dataAdmin);
data.setUpdateCandidateCost(0);
string memory description = 'some description';
string memory slug = 'some slug';
NounsDAOV3Proposals.ProposalTxs memory txs = createTxs(address(0), 0, 'some signature', 'some data');
data.createProposalCandidate(txs.targets, txs.values, txs.signatures, txs.calldatas, description, slug, 0);
txs = createTxs(0, address(0), 0, 'some signature', 'some data');

vm.expectRevert(NounsDAOV3Proposals.MustProvideActions.selector);
data.updateProposalCandidate(
txs.targets,
txs.values,
txs.signatures,
txs.calldatas,
description,
slug,
0,
'reason'
);
}

function test_updateProposalCandidate_givenArityMismatch_reverts() public {
vm.prank(dataAdmin);
data.setUpdateCandidateCost(0);
string memory description = 'some description';
string memory slug = 'some slug';
NounsDAOV3Proposals.ProposalTxs memory txs = createTxs(address(0), 0, 'some signature', 'some data');
data.createProposalCandidate(txs.targets, txs.values, txs.signatures, txs.calldatas, description, slug, 0);
uint256[] memory values = new uint256[](2);

vm.expectRevert(NounsDAOV3Proposals.ProposalInfoArityMismatch.selector);
data.updateProposalCandidate(
txs.targets,
values,
txs.signatures,
txs.calldatas,
description,
slug,
0,
'reason'
);
}
}

contract NounsDAOData_CancelCandidateTest is NounsDAODataBaseTest {
Expand Down

0 comments on commit 9bf65a1

Please sign in to comment.