code-423n4 / 2024-01-salty-findings

11 stars 6 forks source link

finalizeBallot() Function Renders Contract Unusable on Certain Conditions #962

Closed c4-bot-9 closed 9 months ago

c4-bot-9 commented 9 months ago

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

 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.

Assessed type

Other

c4-judge commented 9 months ago

Picodes marked the issue as duplicate of #606

c4-judge commented 8 months ago

Picodes changed the severity to QA (Quality Assurance)