Platform: Code4rena
Start Date: 24/10/2023
Pot Size: $149,725 USDC
Total HM: 7
Participants: 52
Period: 21 days
Judge: ronnyx2017
Total Solo HM: 2
Id: 300
League: ETH
Rank: 7/52
Findings: 2
Award: $4,658.25
๐ Selected for report: 1
๐ Solo Findings: 0
๐ Selected for report: Stormy
Also found by: SpicyMeatball
4505.4922 USDC - $4,505.49
Users can use LeverageMacro contracts to aggregate and execute multiple operations like taking a flashloan, swapping tokens and opening a CDP in one transaction. There are currently two types of macros:
function _openCdpCallback(bytes memory data) internal { OpenCdpOperation memory flData = abi.decode(data, (OpenCdpOperation)); /** * Open CDP and Emit event */ bytes32 _cdpId = borrowerOperations.openCdp( flData.eBTCToMint, flData._upperHint, flData._lowerHint, flData.stETHToDeposit ); }
If this CDP is later liquidated or redeemed, the surplus will only be available to the borrower
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L257 https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L337
Unfortunately it is pretty much impossible to call claimSurplusCollShares
from the LeverageMacroReference
users can try to encode the call in one of the SwapOperations
to execute it with excessivelySafeCall
, but first they need to use one of the required operations, which is not very practical
As a result the surplus received from redeeming/liquidating will be unavailable to the user.
See above
Manual review
Include address borrower
into OpenCdpOperation struct
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LeverageMacroBase.sol#L313
thus user can specify his address as a borrower and make LeverageMacroReference his approved position manager. Later he will be able to claim surplus using his EOA wallet.
Also it will be a good idea to allow approved position managers to claim surplus on borrowers behalf.
Context
#0 - c4-pre-sort
2023-11-17T07:28:35Z
bytes032 marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-11-17T07:28:44Z
bytes032 marked the issue as duplicate of #323
#2 - c4-judge
2023-11-27T09:06:41Z
jhsagd76 changed the severity to 3 (High Risk)
#3 - c4-judge
2023-11-27T09:06:56Z
jhsagd76 marked the issue as satisfactory
#4 - CodingNameKiki
2023-12-05T21:57:19Z
Hey @jhsagd76 , l was going over the selected reports and their duplicates for a final look and l came across this report, l am not very up to date with the latest c4 rules around issues so l wanted to mention it to you.
Basically as stated in the selected report our issue arrives from the fact that LeverageMacro canโt make a call to borrower operations in order for the LeverageMacro to claim the surplus coll. This is a fact as in the function excessivelySafeCall the LeverageMacro specifically performs couple of checks to ensure that any calls made to the ebtc contracts are reverted.
users can try to encode the call in one of the SwapOperations to execute it with excessivelySafeCall, but first they need to use one of the required operations, which is not very practical
However if we look at the statement above in this report, we can see that the warden didnโt find the core issue that the LeverageMacro canโt make a call to the ebtc contracts to claim the surplus but rather reported it as there is no functionality for that and which is why l think this issue was originally reported as a medium.
#5 - jhsagd76
2023-12-06T01:37:55Z
Nice catch! This report missed the most important check in the _ensureNotSystem
function https://github.com/code-423n4/2023-10-badger/blob/2bacb215bf3257320e4f6dd7dcb039f1f06f3214/packages/contracts/contracts/LeverageMacroBase.sol#L401-L415 , change to 25% rewards. Because it pointed out a part of the issue.
#6 - c4-judge
2023-12-06T01:38:38Z
jhsagd76 marked the issue as partial-25
๐ Selected for report: SpicyMeatball
Also found by: 0xBeirao, 7ashraf, LokiThe5th, OMEN, TrungOre, alexzoid, alpha, bdmcbri, ether_sky, fatherOfBlocks, ge6a, hihen, hunter_w3b, jasonxiale, ladboy233, lsaudit, niroh, nobody2018, nonseodion, peanuts, prapandey031, shaka, twcctop, twicek, wangxx2026
152.7604 USDC - $152.76
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L863
_redistributeDebt
will never be called if debt = 0
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/LiquidationLibrary.sol#L525-L527
PriceFeed contract inherits from BaseMath but doesn't use it's single constant DECIMAL_PRECISION, so it's possible to remove it.
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/EBTCToken.sol#L323
this modifier is not used in EBTCTokem.sol
recipient != address(0)
Before transferring tokens we invoke _requireValidRecipient
, where among many checks we check that recipient != address(0),
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/EBTCToken.sol#L297
same check is made inside _transfer
function
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/EBTCToken.sol#L248
Authorized users can change beta
value
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L830
if it's set to zero. we'll divide by zero here
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManager.sol#L624
arrayIndex
value is not deleted when we remove cpdhttps://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManagerStorage.sol#L269-L274
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/CdpManagerStorage.sol#L471
When we remove cpd, we zero all it's values, but arrayIndex
remains.
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L963
Borrower
can approve operations to the PositionManager
, UpdateManager
is not mentioned anywhere in the contract. _requireBorrowerOrPositionManagerApproval
would be more clear.
keccak256( "PermitPositionManagerApproval(address borrower,address positionManager,uint8 status,uint256 nonce,uint256 deadline)" );
but in permitPositionManagerApproval
we use approval
instead of status
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L709
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L826 https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L831
status == ICdpManagerData.Status.active
status == ICdpManagerData.Status.nonExistent
syncGlobalAccountingAndGracePeriod
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L1146 https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L1157 https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L1168
Here we update global system parameters but we use syncGlobalAccounting
which doesn't trigger recovery mode if TCR becomes less than CCR, unlike syncGlobalAccountingAndGracePeriod
.
function syncGlobalAccounting() external { _requireCallerIsBorrowerOperations(); _syncGlobalAccounting(); }
function syncGlobalAccountingAndGracePeriod() public { _syncGlobalAccounting(); // Apply // Could trigger RM _syncGracePeriod(); // Synch Grace Period }
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/Dependencies/AuthNoOwner.sol#L33-L34 https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/Dependencies/AuthNoOwner.sol#L39-L40
sending EBTC directly to a Liquity
CR is associated with collateral ratio, however in this function we use NICR values to find a hint
https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/PriceFeed.sol#L784 https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/PriceFeed.sol#L786 should be stETH-ETH feed
should be stETH-BTC
#0 - c4-pre-sort
2023-11-17T13:26:32Z
bytes032 marked the issue as sufficient quality report
#1 - c4-judge
2023-11-27T10:26:12Z
jhsagd76 marked the issue as grade-a
#2 - jhsagd76
2023-11-28T10:14:54Z
8L+8N + 2S -6 = 31
25
#3 - c4-judge
2023-11-28T10:15:01Z
jhsagd76 marked the issue as selected for report
#4 - jhsagd76
2023-11-28T10:21:36Z
This one is invalid:
UpdateManager? https://github.com/code-423n4/2023-10-badger/blob/main/packages/contracts/contracts/BorrowerOperations.sol#L963 Borrower can approve operations to the PositionManager, UpdateManager is not mentioned anywhere in the contract. _requireBorrowerOrPositionManagerApproval would be more clear.
This one is for gas op, out of scope
Double checking recipient != address(0)
The 8 issues in the section "Typos, wrong comments and naming" is NC. Other issues are L.
#5 - jhsagd76
2023-11-28T10:26:06Z
There are some other QA issues downgraded from H/M can be also added to the report: #159, #244, #224, #73, #70 , #185, #151, #112, #17 , #261, #150