56814 sc medium users can create unauthorized accesstoken collections by exploiting abi encodepacked collision

Submitted on Oct 20th 2025 at 21:35:01 UTC by @brivan for Audit Comp | Belongarrow-up-right

  • Report ID: #56814

  • Report Type: Smart Contract

  • Report severity: Medium

  • Target: https://github.com/belongnet/checkin-contracts/blob/main/contracts/v2/utils/SignatureVerifier.sol

  • Impacts:

    • Unauthorized minting of NFTs

    • Unintended alteration of what the NFT represents (e.g. token URI, payload, artistic content)

    • Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)

Description

Brief

Due to the unsafe use of abi.encodePacked when signing access token metadata, users can reuse a valid signature to create unauthorized NFT collections with different names and symbols.

Vulnerability Details

Users can call the factory’s produce function to create a new access token collection. A valid backend signature must authorize the collection’s metadata:

function produce(AccessTokenInfo memory accessTokenInfo, bytes32 referralCode) external returns (address nftAddress){
    FactoryParameters memory factoryParameters = _nftFactoryParameters;

    factoryParameters.signerAddress.checkAccessTokenInfo(accessTokenInfo);

    bytes32 hashedSalt = _metadataHash(accessTokenInfo.metadata.name, accessTokenInfo.metadata.symbol);

    require(getNftInstanceInfo[hashedSalt].nftAddress == address(0), TokenAlreadyExists());
}

The accessTokenInfo is verified using the following function:

The issue lies in the use of abi.encodePacked, which causes collision risks when encoding multiple dynamic types (name, symbol, and contractURI). Different concatenations of these fields can result in identical encoded outputs.

As a result, a valid signature authorizing an access token with specific metadata can be reused to create another collection with entirely different values. For example, a signature that authorizes the creation of collection with name USD Coin and symbol USDC can be used to create a collection with name USD and symbol CoinUSDC because:

This behavior is confirmed in the provided PoC.

Impact Details

This issue allows users to use signer's signature to create new access token collections that were not authorized by the signer. This clearly violates two critical impacts listed in the program:

  • Unauthorized minting of NFTs

  • Unintended alteration of what the NFT represents (e.g. token URI, payload, artistic content)

Proof of Concept

Proof of Concept (unit test)

Copy and paste the following unit test in /test/v2/platform/factory.test.ts, inside the Deploy AccessToken describe:

(End of report)

Was this helpful?