Denial-of-service risk where attackers can disrupt rebalance process with BasketManagerUtils.completeRebalance()
functionality
The rebalance status progresses through the following states: NOT_STARTED
, REBALANCE_PROPOSED
, TOKEN_SWAP_PROPOSED
, and then TOKEN_SWAP_EXECUTED
. To advance the status, the functions proposeRebalance()
, proposeTokenSwap()
, executeTokenSwap()
, and completeRebalance()
must be called in that order.
if (self.rebalanceStatus.status == Status.NOT_STARTED) {
revert NoRebalanceInProgress();
}
When RebalanceStatus
is either REBALANCE_PROPOSED
or TOKEN_SWAP_PROPOSED
, completeRebalance()
can be called.
if (!_isTargetWeightMet(self, baskets, afterTradeAmounts_, totalValue_, basketTargetWeights)) {
// If target weights are not met and we have not reached max retries, revert to beginning of rebalance
// to allow for additional token swaps to be proposed and increment retryCount.
self.retryCount += 1;
self.rebalanceStatus.timestamp = uint40(block.timestamp);
self.externalTradesHash = bytes32(0);
self.rebalanceStatus.status = Status.REBALANCE_PROPOSED;
return;
}
The function only checks that the status is not in the initial state (NOT_STARTED
) and silently sets an error instead of reverting. As a result, anyone can call this function as long as the status is not NOT_STARTED
and 15 minutes has passed since the rebalance was proposed. When the function is called, the status reverts back to REBALANCE_PROPOSED
. Imagine the following attack scenario:
The admin proposes a rebalance, changing the status to
REBALANCE_PROPOSED
.The admin proposes a token swap, which changes the status to
TOKEN_SWAP_PROPOSED
.Fifteen minutes after the rebalance has been proposed, the malicious user calls
completeRebalance()
, reverting the status back toREBALANCE_PROPOSED
.The admin must propose the token swap again.
Steps 2–3 are repeated to interfere with the rebalance.
As a result, the admin is unable to complete the rebalance process, forcing retries without success.
The team has stated that the attack vectors are feasible; however, they will complete rebalance within 15 minutes. We leave this section for potential future consideration, should the team decide to extend the time frame for rebalance completion, or significantly change the rebalance process.