code-423n4 / 2024-07-traitforge-findings

2 stars 1 forks source link

initializeAlphaIndices() can be overridden by writeEntropyBatch3() #1077

Closed howlbot-integration[bot] closed 2 months ago

howlbot-integration[bot] commented 2 months ago

Lines of code

https://github.com/code-423n4/2024-07-traitforge/blob/main/contracts/EntropyGenerator/EntropyGenerator.sol#L84

Vulnerability details

Impact

Currently EntropyGenerator allows anybody to write the batches by generating 78 digit number of 13 concatenated entropies. There are 3 public functions that allow to initialize all 770 slots with these huge random numbers. The problem is that the special entropy - 999999 is initialized inside of initializeAlphaIndices() and it's done when the new generation starts. And it can be potentially overridden if the new generation starts before all the batches are written.

Proof of Concept

Take a look at writeEntropyBatch3():

 function writeEntropyBatch3() public {
    require(
      lastInitializedIndex >= batchSize2 && lastInitializedIndex < maxSlotIndex,
      'Batch 3 not ready or already completed.'
    );
    unchecked {
      for (uint256 i = lastInitializedIndex; i < maxSlotIndex; i++) {
        uint256 pseudoRandomValue = uint256(
          keccak256(abi.encodePacked(block.number, i))
        ) % uint256(10) ** 78;
        entropySlots[i] = pseudoRandomValue;
      }
    }
    lastInitializedIndex = maxSlotIndex;
  }

It creates 78 digit pseudo-random value and assigns it to each slot from slots 512 to 769. So if the function initializeAlphaIndices() is called before this function, it can be overridden and there is no guarantee that this entropy would be contained in this chosen slot:

https://github.com/code-423n4/2024-07-traitforge/blob/main/contracts/EntropyGenerator/EntropyGenerator.sol#L206-216

function initializeAlphaIndices() public whenNotPaused onlyOwner {
    uint256 hashValue = uint256(
      keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp))
    );

    uint256 slotIndexSelection = (hashValue % 258) + 512;
    uint256 numberIndexSelection = hashValue % 13;

    slotIndexSelectionPoint = slotIndexSelection;
    numberIndexSelectionPoint = numberIndexSelection;
  }

Tools Used

Manual review.

Recommended Mitigation Steps

When writing the last batch, check if there is already a slot for 999999 entropy initialized.

Assessed type

Other

c4-judge commented 2 months ago

koolexcrypto changed the severity to QA (Quality Assurance)

c4-judge commented 2 months ago

koolexcrypto marked the issue as grade-c