Exchange Launch Constraint During DAO Bootstrapping
Observation
The initiation of the exchange during the bootstrap phase holds critical significance, as once the process concludes without activation, subsequent attempts by the DAO to commence the exchange become impracticable, even if the DAO expresses a desire to do so.
Impact
MEDIUM
The DAO faces the inability to commence the exchange if it decides not to initiate it initially. Furthermore, there is a risk of being front-run by a malicious actor with a negative vote in the eleventh hour, potentially locking the exchange in a perpetual state of startExchangeApproved == false.
Consider the following perspective: even though voters are selected from specific staker groups (AAVE, Compounds, ...), they have the option to collaborate and, strategically, wait until the last moment to cast negative votes and consequently close the exchange.
Proof of concept
The finalizeBallot() function is used to determining whether the exchange should start or not. In the event of a negative decision, the exchange becomes unlaunchable in subsequent attempts.
Lines of code
https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/launch/BootstrapBallot.sol#L48-L86
Vulnerability details
Exchange Launch Constraint During DAO Bootstrapping
Observation
The initiation of the exchange during the bootstrap phase holds critical significance, as once the process concludes without activation, subsequent attempts by the DAO to commence the exchange become impracticable, even if the DAO expresses a desire to do so.
Impact
MEDIUM
The DAO faces the inability to commence the exchange if it decides not to initiate it initially. Furthermore, there is a risk of being front-run by a malicious actor with a negative vote in the eleventh hour, potentially locking the exchange in a perpetual state of
startExchangeApproved == false
.Consider the following perspective: even though voters are selected from specific staker groups (AAVE, Compounds, ...), they have the option to collaborate and, strategically, wait until the last moment to cast negative votes and consequently close the exchange.
Proof of concept
The
finalizeBallot()
function is used to determining whether the exchange should start or not. In the event of a negative decision, the exchange becomes unlaunchable in subsequent attempts.https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/launch/BootstrapBallot.sol#L48C2-L86C3
The function is callable only once due to the following requirement:
require( ! ballotFinalized, "Ballot has already been finalized" );
Recommended Mitigation Steps
Consider allowing the DAO the flexibility to initiate the exchange at a later time if desired.
Assessed type
Other