Platform: Code4rena
Start Date: 25/10/2022
Pot Size: $50,000 USDC
Total HM: 18
Participants: 127
Period: 5 days
Judge: 0xean
Total Solo HM: 9
Id: 175
League: ETH
Rank: 5/127
Findings: 2
Award: $3,554.12
π Selected for report: 1
π Solo Findings: 1
π Selected for report: Ch_301
3397.8465 USDC - $3,397.85
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L566
Users abels to invoke forceReplenish()
when they are on liquidation position
On Market.sol
==> forceReplenish()
On this line
uint collateralValue = getCollateralValueInternal(user);
getCollateralValueInternal(user)
only return the value of the collateral
function getCollateralValueInternal(address user) internal returns (uint) { IEscrow escrow = predictEscrow(user); uint collateralBalance = escrow.balance(); return collateralBalance * oracle.getPrice(address(collateral), collateralFactorBps) / 1 ether;
So if the user have 1.5 wETH at the price of 1 ETH = 1600 USD
It will return 1.5 * 1600
and this value is the real value we canβt just check it directly with the debt like this
require(collateralValue >= debts[user], "Exceeded collateral value");
This is no longer over collateralized
protocol
The value needs to be multiplied by collateralFactorBps / 10000
collateralFactorBps
and liquidationFactorBps
the user could be in the liquidation position but he is able to invoke forceReplenish()
to cover all their dueTokensAccrued[user]
on DBR.sol
and get more DOLA
forceReplenish()
Use getCreditLimitInternal()
rather than getCollateralValueInternal()
.
#0 - 0xean
2022-11-05T22:08:42Z
I believe this warden may be correct in the fact that we should actually be adding the collateralFactor into the check
#1 - 08xmt
2022-11-14T13:22:33Z
While increasing debt beyond the Credit limit do risk creating bad debt, this bad debt is owed entirely to the protocol. If one wanted to minimise the amount of bad debt created this way, it would be possible to change the line to getCollateralValueInternal() * (10000 - liquidationIncentiveBps) / 10000;
, as this would also slightly reduce the amount of bad debt paid out to force replenishers as incentives.
#2 - c4-sponsor
2022-11-14T13:22:43Z
08xmt marked the issue as sponsor disputed
#3 - c4-sponsor
2022-11-15T12:28:02Z
08xmt marked the issue as sponsor confirmed
#4 - 08xmt
2022-11-15T12:28:54Z
#5 - c4-judge
2022-11-28T19:35:24Z
0xean marked the issue as satisfactory
#6 - c4-judge
2022-12-01T15:54:25Z
0xean marked the issue as selected for report
156.2673 USDC - $156.27
https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L313-L317 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L531-L539
The users could repay()
their debt
of DOLA
without having any amount of DBR
on their balance
When user repays his debt
. he needs to pay DBR
as an interest which is tracked on dueTokensAccrued[user]
Letβs say Alice has a 300 DOLA debt.
After T
amount of time he invokes repay()
on Market.sol
function repay(address user, uint amount) public { uint debt = debts[user]; require(debt >= amount, "Insufficient debt"); debts[user] -= amount; totalDebt -= amount; dbr.onRepay(user, amount); dola.transferFrom(msg.sender, address(this), amount); emit Repay(user, msg.sender, amount); }
This line
dbr.onRepay(user, amount);
Will execute on DBR.sol
function onRepay(address user, uint repaidDebt) public { require(markets[msg.sender], "Only markets can call onRepay"); accrueDueTokens(user); debts[user] -= repaidDebt; }
And on
accrueDueTokens(user)
Just calculate the interest
But there is no check if the user is actually has this amount of DBR
In case repay all the debts, you need to check if the user has a deficit. Here you can revert repay()
or invoke onForceReplenish()
or accept the repay with liquidate()
some collateral to pay the deficit
#0 - c4-judge
2022-11-05T18:44:09Z
0xean marked the issue as duplicate
#1 - Simon-Busch
2022-12-05T15:15:41Z
Marked satisfactory as requested by @0xean
#2 - c4-judge
2022-12-06T00:03:05Z
0xean changed the severity to 2 (Med Risk)
#3 - c4-judge
2022-12-07T08:16:07Z
Simon-Busch marked the issue as duplicate of #583