28858 - [SC - Insight] Execution of SortedCpds while command may cause...
Submitted on Feb 29th 2024 at 01:10:58 UTC by @cryptoticky for Boost | eBTC
Report ID: #28858
Report type: Smart Contract
Report severity: Insight
Target: https://github.com/ebtc-protocol/ebtc/blob/release-0.7/packages/contracts/contracts/SortedCdps.sol
Impacts:
Unbounded gas consumption
Description
Brief/Intro
Execution of SortedCpd's while command may cause excessive gas consumption.
Vulnerability Details
The codes below can result in significant gas costs.
CdpManager.sol:373-376 lines
while (currentBorrower != address(0) && getSyncedICR(_cId, totals.price) < MCR) {
_cId = sortedCdps.getPrev(_cId);
currentBorrower = sortedCdps.getOwnerAddress(_cId);
}HintHelpers.sol:68-74 lines
If there are a significant number of CDPs with ICRs smaller than MCRs, the user must pay a significant gas cost and out of gas exception can occur, resulting in gas loss. In the worst-case scenario, the gas cost may exceed the block gas limit and the protocol will not be able to operate normally. However, the latter is theoretically possible, but will not happen in reality.
In this report, the former is explained and solutions are presented.
Let's look at the cases (no CDP and 100 CDPs) : ICR < MCR
You can create PoC_CDPManager.redemptions.gaslimit.t.sol file in foundry_test folder.
And run this in terminal.
forge test -vvvv --match-contract PoC_CDPManagerRedemptionsGasLimitTest.
It can be seen that when there are 100 CDPs with ICR < MCR, the gas cost is about 3.7 times higher than when there is no. If 1000 CDPs were present, it would take about 37 times more gas.
Impact Details
1. The user has to pay a considerable fee for gas.
2. It is easy to cause gas loss due to out of gas exception.
As you can see, the gas amount is 1066824 with 100 CDPs (ICR < MCR).
This transaction is created at Feb-28-2024 06:25:23 PM +UTC.
https://etherscan.io/tx/0x86cbd747180c6c7ce935fbdf853b87e0addfa3046633071e16cb9ed941e4e21c
The gas price is 139.797022618 Gwei.
1066824 * 139.797022618 Gwei = 149,138,818,857,425,232
ether price is $3,350 so gas cost = $3,350 * 0.149 = $499.15
This increases arithmetic with more CDP (ICR < MCR).
If there are 1000 CDPs, the gas cost is about $5,000. :)
Recommend
Solution 1: Binary search engine
Binary search engineI recommend you use binary search engine to search the FirstCDP (ICR >= MCR) in the code.
Fortunately, Openzeppelin provides useful library for our problem.
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/utils/Arrays.sol
The number of calculations is log2(n).
n is number of items in array.
Solution 2
Every time a liquidation is made, we can store last CDP (ICR < MCR) position.
When price is changed, the IRC and last CDP would be changed.
But based on the stored last CDP, the search can be carried out back and forth.
This does not require many modifications to SortedCDPs contact than Solution 1, and will also drastically reduce the number of computations. It may be more effective to update this variable whenever there is a change in CDP due to various operations.
Proof of Concept
Let's look at the cases (no CDP and 100 CDPs) : ICR < MCR
You can create PoC_CDPManager.redemptions.gaslimit.t.sol file in foundry_test folder.
And run this in terminal.
forge test -vvvv --match-contract PoC_CDPManagerRedemptionsGasLimitTest.
It can be seen that when there are 100 CDPs with ICR < MCR, the gas cost is about 3.7 times higher than when there is no. If 1000 CDPs were present, it would take about 37 times more gas.
Impact Details
1. The user has to pay a considerable fee for gas.
2. It is easy to cause gas loss due to out of gas exception.
As you can see, the gas amount is 1066824 with 100 CDPs (ICR < MCR).
This transaction is created at Feb-28-2024 06:25:23 PM +UTC.
https://etherscan.io/tx/0x86cbd747180c6c7ce935fbdf853b87e0addfa3046633071e16cb9ed941e4e21c
The gas price is 139.797022618 Gwei.
1066824 * 139.797022618 Gwei = 149,138,818,857,425,232
ether price is $3,350 so gas cost = $3,350 * 0.149 = $499.15
This increases arithmetic with more CDP (ICR < MCR).
If there are 1000 CDPs, the gas cost is about $5,000.
Last updated
Was this helpful?