The current logic in the finalizeBallot() function, which sets ballotFinalized to true when startExchangeNo is greater than startExchangeYes, leads to a critical issue. Once this condition is met, subsequent calls to finalizeBallot() or any other relevant functions become impossible. As a result, the contract becomes non-functional, rendering it unusable for any further interactions, including critical processes such as starting the exchange or triggering the initial distribution. This severely limits the intended functionality of the contract and will lead to a disruption of essential operations like redeploying all major contracts due to their relationship with salt token whic is being used in initialDistribution contract and initialDistribution is being used in BootstrapBallot contract,
Proof of Concept
function test_finalizeBallotFailedVoteRenderContractUseless() public {
// Voting stage (yesVotes: 0, noVotes: 2)
bytes memory sig = abi.encodePacked(aliceVotingSignature);
vm.startPrank(alice);
bootstrapBallot.vote(false, sig);
vm.stopPrank();
sig = abi.encodePacked(bobVotingSignature);
vm.startPrank(bob);
bootstrapBallot.vote(false, sig);
vm.stopPrank();
// Increase current blocktime to be greater than completionTimestamp
vm.warp(bootstrapBallot.completionTimestamp());
assertEq(salt.balanceOf(address(initialDistribution)), 100000000 ether);
// Call finalizeBallot()
bootstrapBallot.finalizeBallot();
// Verify that the InitialDistribution.distributionApproved() was called.
assertEq(salt.balanceOf(address(initialDistribution)), 100000000 ether);
vm.expectRevert("Ballot has already been finalized");
// Call finalizeBallot()
bootstrapBallot.finalizeBallot();
}
Add the above function to BootstrapBallot.t.sol and run with forge t --fork-url <rpc> -vvvvvv --mt test_finalizeBallotFailedVoteRenderContractUseless
Tools Used
Manual review and Foundry
Recommended Mitigation Steps
Revise the mechanism to enable the reset of specific state variables, ensuring the initiation of another voting round when the number of "No" votes exceeds the number of "Yes" votes. This modification aims to maintain the seamless operation of the entire protocol, eliminating the need for deploying the protocol.
Lines of code
https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/launch/BootstrapBallot.sol#L69-L84
Vulnerability details
Impact
The current logic in the finalizeBallot() function, which sets ballotFinalized to true when startExchangeNo is greater than startExchangeYes, leads to a critical issue. Once this condition is met, subsequent calls to finalizeBallot() or any other relevant functions become impossible. As a result, the contract becomes non-functional, rendering it unusable for any further interactions, including critical processes such as starting the exchange or triggering the initial distribution. This severely limits the intended functionality of the contract and will lead to a disruption of essential operations like redeploying all major contracts due to their relationship with salt token whic is being used in initialDistribution contract and initialDistribution is being used in BootstrapBallot contract,
Proof of Concept
Add the above function to BootstrapBallot.t.sol and run with forge t --fork-url <rpc> -vvvvvv --mt test_finalizeBallotFailedVoteRenderContractUseless
Tools Used
Manual review and Foundry
Recommended Mitigation Steps
Revise the mechanism to enable the reset of specific state variables, ensuring the initiation of another voting round when the number of "No" votes exceeds the number of "Yes" votes. This modification aims to maintain the seamless operation of the entire protocol, eliminating the need for deploying the protocol.
Assessed type
Other