Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Invalid

Potential Overflow in Credit Delegation Calculation: Unchecked Type Conversion in getUnsettledRealizedDebt Function

Summary

A critical overflow vulnerability was identified in the credit delegation calculation function, which could lead to incorrect debt distribution and financial losses. The vulnerability occurs due to unchecked type conversions between different fixed-point arithmetic types, potentially causing overflow during the conversion from uint128 to SD59x18.

Vulnerability Details

Location:

function getUnsettledRealizedDebt(Data storage self)
internal
view
returns (SD59x18 unsettledRealizedDebtUsdX18)
{
unsettledRealizedDebtUsdX18 =
sd59x18(self.marketsRealizedDebtUsd).add(unary(ud60x18(self.depositedUsdc).intoSD59x18()));
}

Type Conversion Chain:

uint128 -> UD60x18 -> SD59x18 -> SD59x18 (final result)

Root Cause

  1. Missing Overflow Checks - No validation for depositedUsdc value size

  • No checks during type conversion operations

  • No verification of intermediate calculation results

  1. Complex Type Conversion Chain - Multiple conversion steps increase risk of overflow

  • No intermediate validation points

  • Potential for silent overflow during type conversion

Impact

  1. Financial Impact - Incorrect credit delegation calculations

  • Potential manipulation of debt distribution

  • Financial losses due to incorrect calculations

  1. System Impact - Compromise of vault system integrity

  • Potential cascade effects to connected markets

  • Loss of trust in credit delegation mechanism

Tools Used

  • Solidity compiler (0.8.25)

  • PRB Math library (UD60x18, SD59x18)

  • Manual code review

  • Static analysis

Proof of Concept

Here's a test case using Hardhat to demonstrate the vulnerability:

const { expect } = require('chai');
const { ethers } = require('hardhat');
describe('Vault', function () {
let vault;
beforeEach(async function () {
const Vault = await ethers.getContractFactory('Vault');
vault = await Vault.deploy();
});
it('should overflow when depositedUsdc is very large', async function () {
// Set a very large value for depositedUsdc
const largeValue = '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
await vault.setDepositedUsdc(largeValue);
// Attempt to calculate unsettled debt
await expect(vault.getUnsettledRealizedDebt())
.to.emit(vault, 'LogOverflow')
.withArgs(true);
});
});

Mitigation

  1. Add Overflow Checks```solidity
    function getUnsettledRealizedDebt(Data storage self)
    internal
    view
    returns (SD59x18 unsettledRealizedDebtUsdX18)
    {
    // Add overflow checks
    require(self.depositedUsdc <= type(uint128).max, "Overflow: depositedUsdc too large");

    // Break down the calculation into safer steps
    UD60x18 usdcValue = ud60x18(self.depositedUsdc);
    SD59x18 usdcAsSD59x18 = usdcValue.intoSD59x18();
    SD59x18 baseDebt = sd59x18(self.marketsRealizedDebtUsd);

    // Check for overflow in addition
    require(usdcAsSD59x18.add(baseDebt).gt(usdcAsSD59x18), "Overflow: addition would overflow");

    unsettledRealizedDebtUsdX18 = baseDebt.add(usdcAsSD59x18);
    }

2. **Alternative Implementation**```solidity
function getUnsettledRealizedDebt(Data storage self)
internal
view
returns (SD59x18 unsettledRealizedDebtUsdX18)
{
// Use a single operation to avoid intermediate overflows
return sd59x18(self.marketsRealizedDebtUsd).add(
sd59x18(self.depositedUsdc)
);
}

Recommendations

  1. Immediate Actions - Implement overflow checks in the current implementation

  • Add comprehensive test cases

  • Deploy the fix as soon as possible

  1. Long-term Improvements - Consider using a single type for all calculations

  • Add input validation for all numeric values

  • Implement comprehensive error handling

This vulnerability should be addressed immediately due to its potential impact on the financial operations of the vault system. The recommended mitigation steps provide a secure solution while maintaining the existing functionality.

Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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