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

New position always have Funding = 0

Summary

When a new position is created, its funding will always be 0 and the entire calculation is unnecessary.

Vulnerability Details

Every time TradingAccount.getAccountMarginRequirementUsdAndUnrealizedPnlUsd() is called, it calculates the position data, but the funding of a new position will always be 0, so there are unnecessary calculations with 0 amounts.

fundingFeePerUnit will be 0 then this will be multiplied by position.size inside getAccruedFunding().

function getAccountMarginRequirementUsdAndUnrealizedPnlUsd(
Data storage self,
uint128 targetMarketId,
SD59x18 sizeDeltaX18
)
internal
view
returns (
UD60x18 requiredInitialMarginUsdX18,
UD60x18 requiredMaintenanceMarginUsdX18,
SD59x18 accountTotalUnrealizedPnlUsdX18
)
{
// if an existing position is being changed, perform some additional processing
if (targetMarketId != 0) {
// load the market's perp information
PerpMarket.Data storage perpMarket = PerpMarket.load(targetMarketId);
// load the account's position in that market
Position.Data storage position = Position.load(self.id, targetMarketId);
// calculate price impact of the change in position
UD60x18 markPrice = perpMarket.getMarkPrice(sizeDeltaX18, perpMarket.getIndexPrice());
// get funding fee per unit
SD59x18 fundingFeePerUnit =
perpMarket.getNextFundingFeePerUnit(perpMarket.getCurrentFundingRate(), markPrice);
// when dealing with the market id being settled, we simulate the new position size to get the new
// margin requirements.
UD60x18 notionalValueX18 = sd59x18(position.size).add(sizeDeltaX18).abs().intoUD60x18().mul(markPrice);
// calculate margin requirements
(UD60x18 positionInitialMarginUsdX18, UD60x18 positionMaintenanceMarginUsdX18) = Position
.getMarginRequirement(
notionalValueX18,
ud60x18(perpMarket.configuration.initialMarginRateX18),
ud60x18(perpMarket.configuration.maintenanceMarginRateX18)
);
// get unrealized pnl + accrued funding fees
SD59x18 positionUnrealizedPnl =
position.getUnrealizedPnl(markPrice).add(position.getAccruedFunding(fundingFeePerUnit));
// update cumulative outputs
requiredInitialMarginUsdX18 = requiredInitialMarginUsdX18.add(positionInitialMarginUsdX18);
requiredMaintenanceMarginUsdX18 = requiredMaintenanceMarginUsdX18.add(positionMaintenanceMarginUsdX18);
accountTotalUnrealizedPnlUsdX18 = accountTotalUnrealizedPnlUsdX18.add(positionUnrealizedPnl);
}
... MORE CODE
function getAccruedFunding(
Data storage self,
SD59x18 fundingFeePerUnit
)
internal
view
returns (SD59x18 accruedFundingUsdX18)
{
SD59x18 netFundingFeePerUnit = fundingFeePerUnit.sub(sd59x18(self.lastInteractionFundingFeePerUnit));
accruedFundingUsdX18 = sd59x18(self.size).mul(netFundingFeePerUnit);
}

Impact

Unnecessary calculations for funding, which is always 0.

Tools Used

Manual Review

Recommendations

In all these cases, check if lastInteractionFundingFeePerUnit = 0 and if so, return 0 for funding, skipping all these calculations.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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