FoundrySolidityLayer 2
7.25 ETH
Submission Details
Impact: low
Likelihood: low

`_bonusShare` and `stake` mathematical overflow limits for extremely large token supplies

Author Revealed upon completion

Description

Normal Behavior

The ConfidencePool calculates a time-weighted bonus using a formula. To maintain precision, intermediate multiplications expand token amounts (userEligible, amount) by the square of the timestamp (T * T) before dividing by the global score using OpenZeppelin's Math.mulDiv.

Specific Issue

While Math.mulDiv handles precision robustly, the preceding raw multiplication T * T * userEligible (and its equivalent during staking for sumStakeTimeSq) scales into uint256. Since T (the expiry or observation timestamp) can theoretically reach uint32.max (), T^2 scales up to . If a pool is initialized with an allowed token having an astronomical supply (greater than ), the multiplication overflows the 256-bit threshold (1.15e77), permanently blocking deposits or trapping users from claiming their funds.

// src/ConfidencePool.sol:_bonusShare()
function _bonusShare(address u, uint256 userEligible) internal view returns (uint256) {
if (riskWindowStart == 0) return 0;
uint256 T = outcomeFlaggedAt;
// @> Root cause: Intermediate raw multiplication overflows if userEligible > ~6.3e57
uint256 userPlus = T * T * userEligible + userSumStakeTimeSq[u];
uint256 userMinus = 2 * T * userSumStakeTime[u];
uint256 userScore = userPlus - userMinus;

Risk

Likelihood:

  • The factory owner explicitly whitelists a highly-diluted or extreme-decimal token (e.g., meme coins with $10^{36}$ supplies) via allowedStakeToken.

  • A user attempts to stake a volume of those tokens that brings their raw wei amount above the $6.3 \times 10^{57}$ threshold.

Impact:

  • If an extreme supply token is permitted, claims and withdrawals for massive whales will revert with arithmetic panics.

  • It forces the protocol to restrict the token whitelist exclusively to standard supply models, limiting composability with hyper-inflated tokens.

Proof of Concept

Create a new test file test/unit/POCTest.t.sol inheriting from BaseConfidencePoolTest, paste the following code inside the contract body, and run it using the command forge test --match-test test_POC_MathOverflowExtremeSupply -vvv.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {Test, console} from "forge-std/Test.sol";
import {ConfidencePool} from "src/ConfidencePool.sol";
import {ConfidencePoolFactory} from "src/ConfidencePoolFactory.sol";
import {PoolStates} from "src/libraries/PoolStates.sol";
import {BaseConfidencePoolTest} from "test/helpers/BaseConfidencePoolTest.sol";
import {MockAgreement} from "test/mocks/MockAgreement.sol";
import {IAttackRegistry} from "@battlechain/interface/IAttackRegistry.sol";
import {IAgreement} from "@battlechain/interface/IAgreement.sol";
import {IConfidencePool} from "src/interfaces/IConfidencePool.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
contract POCTest is BaseConfidencePoolTest {
function test_POC_MathOverflowExtremeSupply() external {
console.log("--- POC: Math Overflow on Extreme Supply ---");
uint256 extremeAmount = 6.3e57;
token.mint(alice, extremeAmount);
vm.prank(alice);
token.approve(address(pool), extremeAmount);
uint256 t = type(uint32).max;
vm.warp(t);
console.log("Extreme stake amount:", extremeAmount);
console.log("Timestamp (T):", t);
vm.expectRevert(); // Expect arithmetic panic
vm.prank(alice);
pool.stake(extremeAmount);
console.log("Successfully caught Arithmetic Overflow revert during intermediate multiplication before mulDiv.");
}
}

Recommended Mitigation

Since the arithmetic panic stems from the intermediate T * T * amount calculation natively overflowing the uint256 maximum, we recommend adding explicit NatSpec documentation to the allowedStakeToken mapping. This warns sponsors and factory owners to avoid whitelisting extreme-supply tokens (e.g., meme coins with supplies exceeding 6.3e57) which would otherwise trap user funds.

// Add documentation warning in the Factory for whitelist curation
+ /// @dev Warning: Tokens with supplies exceeding 6.3e57 wei should not be whitelisted.
+ /// The pool's internal k=2 bonus math intermediate multiplications (T^2 * stake)
+ /// will overflow uint256 for individual balances exceeding this bound.
mapping(address token => bool allowed) public override allowedStakeToken;

Support

FAQs

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

Give us feedback!