Closed sherlock-admin2 closed 4 months ago
From the README:
Are there any off-chain mechanisms or off-chain procedures for the protocol (keeper bots, arbitrage bots, etc.)? We have a liquidation bot that monitors the health of the protocol's accounts and calls the liquidate function.
This issue is invalid because the liquidation bot from the protocol will liquidate all unhealthy positions regardless of the potential profit/losses.
Escalate
This would still cause loss of funds for the liquidator bots or any liquidator in general. The protocol will be deployed on ethereum where gas fees are high. This loss would be substantial especially if many accounts do this.
I believe this should be a valid Medium.
Escalate
This would still cause loss of funds for the liquidator bots or any liquidator in general. The protocol will be deployed on ethereum where gas fees are high. This loss would be substantial especially if many accounts do this.
I believe this should be a valid Medium.
You've created a valid escalation!
To remove the escalation from consideration: Delete your comment.
You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final.
I still believe this issue is invalid based on my initial comment.
I disagree with the escalation.
The impact of this issue is that the protocol will accrue bad debts because there will be no one to liquidate very small positions. But this is not true because bots will be used to take care of this:
We have a liquidation bot that monitors the health of the protocol's accounts and calls the liquidate function.
You are right that for very small positions, it is possible to have some losses when bots liquidate positions, but this is Low severity. However, the main impact of the issue is that the protocol will have bad debt, which is invalid.
Planning to reject the escalation and leave the issue as is.
You are right that for very small positions, it is possible to have some losses when bots liquidate positions, but this is Low severity. However, the main impact of the issue is that the protocol will have bad debt, which is invalid.
There is no barrier to creating many small positions that become unhealthy.
Liquidating many of these positions will cause the loss to be significant
Normal Liquidators will take on this loss if they liquidate the position.
Let's say they don't, protocol liquidation bots will take the loss.
I believe liquidation bots get funded by their owners, so if they lose money, then it is actually their owners that lose
I think it's an issue, but it is Low Severity. The main impact is that the protocol can get bad debt, which is invalid. The bots won't allow that.
One more thing that further decreases the severity of this issue is that "Griefing for gas" is an invalid issue, according to the Sherlock documentation.
I think this is at least Medium severity because liquidators and protocol liquidation bots will lose funds
Imagine an attacker opening many $5 positions on Ethereum, where gas fees for liquidating a position is $20. By liquidating each of those position, liquidator or protocol loses $15.
Also, here is a link to a similar Sherlock issue that was judged as Medium, despite the protocol being deployed to chains where gas fees are really low: https://github.com/sherlock-audit/2024-02-perpetual-judging/issues/115
@Emedudu The issue you mentioned was accepted as medium severity because the Perpetual protocol didn't have any liquidation bots themselves so the risk of bad debt was real. In this case, the liquidation bot of Exactly will prevent the creation of bad debt.
Hello @santipu03 ,
Protocol's liquidation bot or not, the issue is that anyone that liquidates such positions will lose funds.
Isn't that a criteria for issue validity on Sherlock?
I think we can at least agree that:
Therefore,severity should be at least a medium
(Which of the above do you disagree with?)
Given that the only impact now is increased gas costs on liquidations, this report now is a gas optimization issue, and thus should be invalid according to the Sherlock guidelines:
VII. List of Issue categories that are not considered valid:
- Gas optimizations: The user/protocol ends up paying a little extra gas because of this issue.
I completely agree with the lead judge's comments.
The only impact is that the bots will lose money if the positions are smaller than the cost of the gas.
Their loss will be the "Gas - position".
Apart from the fact that the impact is Low, this is also in the "Griefing for gas" category and is invalid.
To all this, we can add this rule:
Gas optimizations: The user/protocol ends up paying a little extra gas because of this issue.
I stand by my initial decision to reject the escalation.
This is not "a little extra gas".
Say gas fees on ethereum is $20 Attacker can open 100 $5 positions on ethereum, which will make protocol lose 15*100 = $1500.
Can we call this a small loss?
This can be used to waste as much funds as the attacker wants.
Impact of this is obviously not low Likelihood is obviously high.
I still believe this is at least a medium severity issue
We all know what Sherlock means by a gas optimization issue
It is easy to know a gas optimization bug when you see one.
This issue is obviously not a gas optimization issue.
Why should a gas optimization issue have a potential to waste up to tens of thousands of dollars?
Your calculation is not correct. Let's look at the official statistics:
This is Ethereum Average Gas Price: https://etherscan.io/chart/gasprice
Here, we can use a calculator: https://coinbrain.com/converter/eth-0x29e683aeafd03bb6c02055c3ca8b6edb4bb9bae5/usd
We can also use this chart that is easier to visualize the days - https://ycharts.com/indicators/ethereum_average_gas_price
If we take the data for 23 May, the average gas price is $2.35. There is no problem. Even the bots are profitable. However, I agree that there were days in the year when the average price was $10+.
Let's see Sherlock documentation:
Invalid: Gas optimizations: The user/protocol ends up paying a little extra gas because of this issue.
Let's also see what impact you had on the issue itself:
Since liquidating tiny unhealthy positions would result in loss for liquidator. Liquidators won't want to liquidate them, leading to accrual of bad debt->insolvency
This is not true because bots will be used to take care of unhealthy positions.
These are the reasons why I think this issue is Low severity.
Your calculation is not correct. Let's look at the official statistics: This is Ethereum Average Gas Price: https://etherscan.io/chart/gasprice Here, we can use a calculator: https://coinbrain.com/converter/eth-0x29e683aeafd03bb6c02055c3ca8b6edb4bb9bae5/usd We can also use this chart that is easier to visualize the days - https://ycharts.com/indicators/ethereum_average_gas_price If we take the data for 23 May, the average gas price is $2.35. There is no problem. Even the bots are profitable. However, I agree that there were days in the year when the average price was $10+.
To calculate the gas cost(in gwei) for a transaction, we do:
gas cost
=gas units spent on the transaction
*average gas price in gwei
Since 1 eth=1_000_000_000 gwei, 1 gwei to USD=eth price/1_000_000_000.
Now, let's calculate gas cost for liquidation:
So, gas cost in gwei for executing liquidate
=15.57*597344 = ~9_300_000 gwei
Since 1 eth= $3700(at time of writing), 1 gwei=3700/1_000_000_000=$0.0000037
Therefore, $ gas cost for executing liquidate
=0.0000037*9300000=$34.41.
Let's see Sherlock documentation: Invalid: Gas optimizations: The user/protocol ends up paying a little extra gas because of this issue.
If attacker opens a position of $5, and it costs $34 to liquidate it, liquidation bots loses $29. If he opens 100 $5 positions, loss=$2900 I don't believe this is "a little extra gas". Plus in general, gas optimization issues are usually about the protocol spending a higher number of gas units than they ought to. This issue is not about that.
Let's also see what impact you had on the issue itself: Since liquidating tiny unhealthy positions would result in loss for liquidator. Liquidators won't want to liquidate them, leading to accrual of bad debt->insolvency This is not true because bots will be used to take care of unhealthy positions.
It is true that the report's impact did not acknowledge the fact that there are liquidation bots. But the core issue still remains that: anyone(including the protocol's liquidation bots) that liquidates those positions opened by the attacker will be disincentivized.
@Emedudu With that calculation, you showed, and with the average loss of $30 per position, I tend to agree that this does not fall under the "Gas optimizations issue" and is more Medium than Low.
I plan to accept the escalation and make this issue a valid Medium.
@Emedudu's analysis is too simplistic. The cost of opening these positions also has to be considered. An attacker needs to deposit and borrow using multiple wallets. So the cost of deposit + borrow must be considered. Then, opening 1000 positions or something will increase gas fees as the fee model is based on utilization. And finally, the gas price may vary since the attacker created the positions, it has no guarantee that the gas price will be higher when liquidating. In fact, this argument alone should be able to invalidate the finding. Due to these reasons, this is essentially a griefing attack where someone is fighting against the owner to see who has more funds, which is not valid. If the watson proves that somehow this attack is heavily (because gas price may change) favoured towards the attacker, I agree it may be valid.
As a note I was curious and calculated gas costs myself. deposit + borrow = 408727 gas deposit + enterMarket = 224770 gas borrow = 241952 gas liquidate = 388886 gas It's true that the borrower may deposit in several markets and borrow in just one, so it's not as simple. Also, the liquidator may not need to seize every single market, in reality less markets should be enough.
He also has to enter markets in each of the markets, or it will not count as collateral. so in reality it's deposit + enterMarket, for each market + borrow on one market If we have a large number of markets, the discrepancy may become bigger. Still, I think the gas costs are too similar for this to be viable.
Here are the average gas units: deposit=150441 borrow=167523 liquidate=384973 enterMarket=23675
Let's say there are 3 markets
In total, cost for liquidation bots=5*cost for attacker
@Emedudu the difference in gas price can not be considered, as the attacker can not possibly know what it will be at the time of liquidation. The attacker has to predict the gas fees to add as collateral in each market. If the predicted gas fees are higher than the real at the time of liquidation, the liquidation is still worth it.
Additionally, we have to consider that such small positions, where each position is at most the size of the gas fees required to liquidate (which can not be predicted), will require much more funds from the attacker size. If the deposit / liquidate gas fees ratio is 0.5, then the attacker is adding 2 wei of collateral for each 1 of gas spent. So if he gets a total collateral of 1 ETH, it's costing 0.5 ETH of gas fees. This means that in case the attacker is indeed liquidated, even at a higher gas price (impossible to predict), the losses are very close.
My judgement is that given these 2 arguments, the cost to the attacker is very close to the cost to the protocol and the attack is not worthy of medium severity.
I think even in your scenario, the attacker loses more than the liquidator. I assumed the attacker deposit gas fees equivalent to the liquidation cost at 10 gwei, to have some margin, as gas prices average 15, so 10 is more likely to be below the actual gas price. Assumed adjust factor of 0.9 for the debt borrowed.
attacker cost = 571496*4 = 2285984
attacker total collateral = 384973*3*10
bot cost = 384973*2*15 = 11549190
attacker seized collateral = 384973*2*10
attacker debt = 384973*3*10*0.9*0.9 = 9354843
attacker loss = collateral + gas fees - debt = 384973*10*3 + 2285984 - 9354843 = 4480331
bot loss = gas cost - collateral seize = 384973*2*15 - 384973*2*10 = 384973*2*5 = 3849730
Given an entity who has the will to choose when to call a function, and another entity who urgently needs to call a function depending on the current market conditions, I think the former is more likely to be favoured by gasPrices.
We can remodify the above calculation:
attacker cost = 571496*4 = 2285984
attacker total collateral = 250000*3*10
bot cost = 384973*3*15 = 17323785
attacker seized collateral = 250000*3*10
attacker debt = 250000*3*10*0.9*0.9 = 6075000
attacker loss = total collateral + gas fees - debt=250000*10*3 + 2285984 - 6075000 = 3710984
bot loss = gas cost - collateral seize = 384973*3*15 - 250000*3*10 = 9823785
So he's opening positions of 6075000e-9 ETH debt = 22.5 USD at 3700 USD / ETH For this to become significant for liquidations to be rushed, you would need like 1000 positions? 22500 USD. This would require 2285984×1000/30000000 76 blocks. It would probably be the biggest block stuffing event ever and would drive gas prices crazy. Thus, if the collateral in the positions is too small, too much gas is required and the attack becomes inviable. If too much collateral is placed, liquidators still have incentive.
Also the positions required to liquidate were changed from 2 to 3 which seems less likely.
This attack seems too theoretical and involves a set of conditions that may or may not be true. I leave this up to the judge.
Given an entity who has the will to choose when to call a function, and another entity who urgently needs to call a function depending on the current market conditions, I think the former is more likely to be favoured by gasPrices.
The debt is too low for this to be true and the attacker has to predict gas prices.
Summing up The attack path is not clearly favoured towards the attacker. The bot is trusted to clear some organic bad debt (not much, in the Perennial contest it involved leverage which increases the number of lower sized positions).
So he's opening positions of 6075000e-9 ETH debt = 22.5 USD at 3700 USD / ETH For this to become significant for liquidations to be rushed, you would need like 1000 positions? 22500 USD. This would require 2285984×1000/30000000 76 blocks. It would probably be the biggest block stuffing event ever and would drive gas prices crazy. Thus, if the collateral in the positions is too small, too much gas is required and the attack becomes inviable. If too much collateral is placed, liquidators still have incentive.
100 positions , as stated in my example, is enough to demonstrate this. Plus, the attacker doesn't have to open all at the same time, so no need for block stuffing
Also the positions required to liquidate were changed from 2 to 3 which seems less likely.
Yeah I had to modify some parameters, for example, attacker is depositing into each market, less than gas cost of liquidate. That's the point of the attack.
This attack seems too theoretical and involves a set of conditions that may or may not be true. I leave this up to the judge.
Please state the conditions you don't agree with
Summing up The attack path is not clearly favoured towards the attacker. The bot is trusted to clear some organic bad debt (not much, in the Perennial contest it involved leverage which increases the number of lower sized positions).
This report is about liquidators losing funds from liquidating positions opened by attacker, which I think I've been able to prove.
100 positions , as stated in my example, is enough to demonstrate this.
100 positions is just 2250 debt, which is not enough for the liquidator to rush liquidations.
Plus, the attacker doesn't have to open all at the same time, so no need for block stuffing
If it's not at once, then it's no longer an attack because they can just be liquidated over time too. They will not be all liquidatable at the same time and the gas price can not be played with.
The reason I say this is theoretical is because 1) the gas prices may rise too much due to opening positions, 2) we can not know if the liquidation is in fact rushed or not for debt values such as 2250 USD, thus accounting for gas price diff is unreliable, 3) the attacker has to be able to predict gas prices and the attack may fail horribly. 4) the losses for both parties are too close for the attacker to execute such an attack, which has too many unknowns. 5) we do not know how many markets need to be liquidated.
For these reasons I think it is completely theoretical.
I think this falls under the rule:
Griefing for gas (frontrunning a transaction to fail, even if can be done perpetually) is considered a DoS of a single block, hence only if the function is clearly time-sensitive, it can be a Medium severity issue.
The attacker is not profiting for this as the gas spent is too much in comparison to the opened position. In your example, the attacker has a debt of 6075000
while it costs 2285984
to open the position, almost 40% upfront cost. Perhaps with leverage these numbers would be more relevant, as was the case in the Perennial contest.
I agree with the last comments of @0x73696d616f. The attack is very difficult to do because we don't know what the cost of the gas will be at the time of liquidation. Therefore, the attack may not be profitable at all.
Even if it is profitable, it will be by a small margin and will be in the "Griefing for gas" or "Gas optimizations" category:
The user/protocol ends up paying a little extra gas because of this issue.
To these points, I will add that the Impact described in the issue itself is invalid because the bots will take care of it.
So, I decided to reject the escalation and leave the issue as it is.
Result: Invalid Unique
Emmanuel
medium
User can open borrow positions that would cause liquidators to be disincentivized from liquidating it due to gas fees
Summary
Opening borrow positions with collateral less than average gas fees on that network, would disincentivize liquidators from liquidating it. Attacker can open many of these positions with multiple accounts, which is equivalent to a large borrow position.
Vulnerability Detail
There is no minimum borrow position that a user is required to open. User can open positions backed by
<gasfees
collateral, and if it gets liquidatable, liquidators won't want to liquidate it which could lead to insolvency.In addition, user can deposit
<gasFees
collateral in each of the markets, and borrow up togasFees
*numberOfMarkets/collateralRatio. Since liquidators have to specify the market to seize from, and user collateral in each market is<gasFees
, seizing from any of the markets would result in loss for the liquidator.Note that protocol will be deployed on ethereum mainnet, where gas fees are very high.
Impact
Since liquidating tiny unhealthy positions would result in loss for liquidator. Liquidators won't want to liquidate them, leading to accrual of bad debt->insolvency
Code Snippet
https://github.com/sherlock-audit/2024-04-interest-rate-model/blob/main/protocol/contracts/Market.sol#L140 https://github.com/sherlock-audit/2024-04-interest-rate-model/blob/main/protocol/contracts/Market.sol#L281
Tool used
Manual Review
Recommendation
borrow,borrowAtMaturity,withdraw,withdrawAtMaturity should enforce a minimum amount of borrow positions that should be opened.