DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: medium
Invalid

Settling uPnL breaks USDz collateral depositCap

Summary

The protocol breaks its deposit cap for USDz by minting tokens to its users' margin balance when unrealized profit and loss are settled.

Vulnerability Details

When a trader is profitable, the protocol pays them their due unreliazed PnL in USDz. This system of uPnL settlement causes the protocol to break its deposit cap invariant. When traders deposit collateral, the protocol always validates that the deposit cap for that collateral type is not exceeded. However, the deposit cap can't always hold for USDz because the accounts must be paid the unrealized PnL, and the way the protocol does that is by minting them USDz tokens. So if an account is already at its maximum deposit for USDz, any uPnL sent to its balance will break the deposit limitation of USDz for that account.

Areas of interest:
Traders positive uPnL are sent to their account
https://github.com/Cyfrin/2024-07-zaros/blob/69ccf428b745058bea08804b3f3d961d31406ba8/src/perpetuals/branches/SettlementBranch.sol#L481-L484

// if trader's old position had positive pnl then credit that to the trader
if (ctx.pnlUsdX18.gt(SD59x18_ZERO)) {
ctx.marginToAddX18 = ctx.pnlUsdX18.intoUD60x18();
tradingAccount.deposit(ctx.usdToken, ctx.marginToAddX18);

Deposit cap is enforced
https://github.com/Cyfrin/2024-07-zaros/blob/69ccf428b745058bea08804b3f3d961d31406ba8/src/perpetuals/branches/TradingAccountBranch.sol#L330-L340

// uint128 -> UD60x18
UD60x18 depositCapX18 = ud60x18(marginCollateralConfiguration.depositCap);
// uint256 -> UD60x18
UD60x18 totalCollateralDepositedX18 = ud60x18(marginCollateralConfiguration.totalDeposited);
// enforce converted amount > 0
_requireAmountNotZero(amountX18);
// enforce new deposit + already deposited <= deposit cap
_requireEnoughDepositCap(collateralType, amountX18, depositCapX18, totalCollateralDepositedX18);

Proof of Concept

Protocol USDz deposit limit: $1000
Trader's USDz margin balance: $900
Trader's current unrealized PnL: $200

Given the above scenario, if the trader attempts to deposit $200 worth of USDz collateral tokens, the transaction will revert because the account will be attempting to go over the maximum deposit cap.
However, if the user opens a new trade, and their uPnL is settled, their USDz margin will increase by $200 worth of USDz, effectively breaking the collateral deposit limits.

Impact

The protocol enforces this rule to keep the risk exposure of the system at a manageable level, and this setup pushes the protocol beyond their desired risk appetite.

Tools Used

Manual

Recommendations

Consider other alternative approach to settling unrealized profit and loss

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

krisrenzo Submitter
12 months ago
inallhonesty Lead Judge
12 months ago
inallhonesty Lead Judge
12 months ago
inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.