Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

Arithmetic Overflow in mintBatch Function of OWPIdentity contract due to Unbounded Input Values via fuzz testing

Summary

The overflow vulnerability in mintBatch represents a medium severity issue due to the access restriction, but it still poses risks for token distribution reliability and potential supply inflation.

Vulnerability Details

The mintBatch function in the contract allows authorized minters to mint multiple token types in a single transaction by passing arrays of ids and amounts. However, when extremely large values are passed into the amounts array, the function encounters an arithmetic overflow in the internal _mintBatch function, which can lead to incorrect token balances or total supply calculations.

Impact

Overflow may cause the contract to mint more tokens than intended, potentially inflating the token supply or violating tokenomics constraints.

Tools Used

Fuzz testing through foundry

I have created the following POC and then run forge test --fuzz-runs 2 i.e. 2 times and the output resulted in arithmetic overflow.

/ SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
import "forge-std/Test.sol";
import "../src/OWPIdentity.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract OWPIdentityTest is Test {
OWPIdentity owp;
address defaultAdmin;
address minter;
function setUp() public {
defaultAdmin = address(0xABCD);
minter = address(0xDEAD);
// Deploy the contract
owp = new OWPIdentity(defaultAdmin, minter, "https://example.com/metadata/");
// Setup roles
vm.startPrank(defaultAdmin);
owp.setURI("https://example.com/updated_metadata/");
vm.stopPrank();
}
// Fuzz test batch mint and batch burn functions with random values
function testFuzzMintBatch(address to, uint256[] memory ids, uint256[] memory amounts) public {
vm.assume(to != address(0));
vm.assume(ids.length == amounts.length);
vm.startPrank(minter);
owp.mintBatch(to, ids, amounts, "");
// Loop over ids and amounts to check for overflows
for (uint256 i = 0; i < ids.length; i++) {
require(ids[i] > 0, "Token ID must be positive");
// Ensure no overflow occurs
uint256 tokenSupply = owp.totalSupply(ids[i]); // Ensure this function exists or is implemented
require(tokenSupply + amounts[i] <= type(uint256).max, "Overflow detected");
}
// Fuzz burnBatchMultiple with random data
owp.burnBatchMultiple(createAddressArray(ids.length, to), ids, amounts);
for (uint256 i = 0; i < ids.length; i++) {
assertEq(owp.balanceOf(to, ids[i]), 0, "Batch burn amount not correct");
}
vm.stopPrank();
}
// Helper function to create an array of addresses
function createAddressArray(uint256 length, address value) internal pure returns (address[] memory) {
address[] memory array = new address[]();
for (uint256 i = 0; i < length; i++) {
array[i] = value;
}
return array;
}
}

Recommendations

Add validation to ensure that values in ids and amounts do not exceed expected limits

function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
public
onlyRole(MINTER_ROLE)
{
require(ids.length == amounts.length, "Mismatched ids and amounts length");
// Optionally add constraints to the size of each element to reduce overflow risk.
for (uint256 i = 0; i < amounts.length; i++) {
require(amounts[i] > 0, "Amount must be greater than zero");
require(amounts[i] <= MAX_MINT_AMOUNT, "Amount exceeds maximum allowed"); // Define MAX_MINT_AMOUNT
}
_mintBatch(to, ids, amounts, data);
}
Updates

Lead Judging Commences

0xbrivan2 Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
0xbrivan2 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.