Skip to content

Latest commit

 

History

History
60 lines (34 loc) · 4.27 KB

File metadata and controls

60 lines (34 loc) · 4.27 KB

Polished Walnut Capybara

Medium

rebalance() and iterateRebalance() can be DOS-ed in a particular scenario

Summary

Both rebalance() and iterateBalance() are meant to be currently called by only keeper bots and in following scenarios -> when the _currentLeverageRatio is below minLeverageRatio and above the maxLeverageRatio or when the cooldown (global or exchange) has passed.

But in the contest's description, it is stated that in the future, the functions with the onlyAllowedCaller modifier (this include both the functions) may be called by anyone: Here is the bullet point present in Sherlock's contest description However in the future we might adjust the contract settings such that anyone can call these methods (any method with the onlyAllowedCaller modifier), so we would still like to know about any issue that could result in that scenario.

This presents a likely scenario in which we can DOS most or all exchanges.

Root Cause

Root cause is that in the future, it can be allowed that everyone has the ability to invoke rebalance() and iterateRebalance() and this can be detrimental to the protocol's integrity in the following way:

Let's assume that the _currentLeverageRatio is x3.05 and the maxLeverageRatio is x3 and that no TWAP will occur.

A malicious user calls rebalance() to bring back the overly leveraged position (x3.05) back to the maximum leverage (x3), (if the leverage is just a little above max, it will bring it back to the _maxLeverageRatio due to this line of code and the calculations prior to it and all of that is intended for now, BUT...

Then the malicious user will have the possibility to call _rebalance() even if the _currentLeverageRatio goes just above the x3 mark, this means that the slightest price change, he can call again _rebalance() with a different exchange and bring back the leverage again to the _maxLeverageRatio and this can continue on and on.

Let's assume that the x3 leverage ratio is when ETH price is 2500 USDC, even if it falls with a few dollars, it will bring the possibility to call the rebalance() due to the logic below.

Remember that the _coolDown will pass due to this piece of code

All of this will render the ripcord() unusable as well, because it uses the exchangeLastTradeTimestamp as well.

Internal pre-conditions

No response

External pre-conditions

maxLeverageRatio is x3 and _currentLeverageRatio is x3.05 for the example purpose, and we have 5 allowed exchanges to use in the vault and lastly, a volatile day in which ETH falls rapidly downwards and there've been not just one of those days, in which ETH falls with 3-10% for a few minutes in case of a real life event such as geopolitical events.

Attack Path

  1. Malicious Alice calls rebalance() to bring back the _currentLeverageRatio of x3.05 to the maxLeverageRatio of x3
  2. The price of ETH against USDC continues to drop and _currentLeverageRatio is x3.02, so Alice calls rebalance() once again and the _currentLeverageRatio is brought back to the maxLeverageRatio once again.
  3. Repeat this 4 more times, given that the price will drop, making the _currentLeverageRatio again x3.02, or just a little above the _maxLeverageRatio
  4. Then, the price of ETH continues to drop more and hits the incentivizedLeverageRatio , ripcord() is to be called by non-malicious Bob, it will revert due to the logic here exchangeLastTradeTimestamp

Impact

Vault will suffer more losses than intended due to ripcord() not being callable,
and all of the exchanges being blocked from the cooldown by malicious Alice

PoC

No response

Mitigation

No response