15,000 USDC
View results
Submission Details
Severity: medium

Underflow/overflow

Summary:

Underflow/Overflow be the reason of unforeseen issues that may lead to financial losses or exploitation.

Vulnerability Details:

Running 2 tests for test/fuzz/Invariants.t.sol:Invariants
[FAIL. Reason: Arithmetic over/underflow]
[Sequence]
sender=0xd86058389f129a2fd561b6c72516547b0a74357c addr=[test/fuzz/Handler.t.sol:Handler]0x2a9e8fa175f45b235efddd97d2727741ef4eee63 calldata=mintDsc(uint256,uint256), args=[5108, 955]
sender=0x0000000000000000000000000000000000000006 addr=[test/fuzz/Handler.t.sol:Handler]0x2a9e8fa175f45b235efddd97d2727741ef4eee63 calldata=failed():(bool), args=[]
sender=0x000000000000000000000000000000000000121c addr=[test/fuzz/Handler.t.sol:Handler]0x2a9e8fa175f45b235efddd97d2727741ef4eee63 calldata=depositCollateral(uint256,uint256), args=[71008135593495683486405164711 [7.1e28], 3124842406 [3.124e9]]

Affected code:

function mintDsc(uint256 amount, uint256 addressSeed) public {
if (usersWithCollateralDeposited.length == 0) {
return;
}
address sender = usersWithCollateralDeposited[addressSeed % usersWithCollateralDeposited.length];
(uint256 totalDscMinted, uint256 collateralValueInUsd) = dsce.getAccountInformation(sender);

    int256 maxDscToMint = (int256(collateralValueInUsd) / 2) - int256(totalDscMinted);

    if (maxDscToMint < 0) {
        return;
    }
    amount = bound(amount, 0, uint256(maxDscToMint));
    if (amount == 0) {
        return;
    }
    vm.startPrank(sender);
    dsce.mintDsc(amount);
    vm.stopPrank();
    timesMintIsCalled++;
}

Impact: An attacker might exploit such vulnerabilities to mint an excessive number of DSC tokens, leading to inflation and devaluation of the token value.

Tools Used:

forge test.

Recommendations:

remove the unnecessary casting of collateralValueInUsd to int256 as it's not required for the calculations. We also added the bound helper function to ensure that amount is kept within the safe range, avoiding potential underflow/overflow issues.
You can write the code like this.

function mintDsc(uint256 amount, uint256 addressSeed) public {
if (usersWithCollateralDeposited.length == 0) {
return;
}
address sender = usersWithCollateralDeposited[addressSeed % usersWithCollateralDeposited.length];
(uint256 totalDscMinted, uint256 collateralValueInUsd) = dsce.getAccountInformation(sender);

// Prevent overflow
uint256 maxDscToMint = (collateralValueInUsd / 2) - totalDscMinted;

// Check if maxDscToMint is negative or zero to avoid underflow
if (maxDscToMint == 0) {
    return;
}

// Ensure 'amount' doesn't cause an overflow
amount = bound(amount, 0, maxDscToMint);

// Check if amount is zero after bounding to avoid underflow
if (amount == 0) {
    return;
}

vm.startPrank(sender);
dsce.mintDsc(amount);
vm.stopPrank();
timesMintIsCalled++;

}

// Helper function to bound a value between a minimum and maximum
function bound(uint256 value, uint256 minValue, uint256 maxValue) internal pure returns (uint256) {
if (value < minValue) {
return minValue;
}
if (value > maxValue) {
return maxValue;
}
return value;
}

Support

FAQs

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