57283 sc medium unauthorised promoter payouts due to signature replay attack

Submitted on Oct 24th 2025 at 23:17:18 UTC by @Oxv1bh4 for Audit Comp | Belongarrow-up-right

  • Report ID: #57283

  • Report Type: Smart Contract

  • Report severity: Medium

  • Target: https://github.com/immunefi-team/audit-comp-belong/blob/main/contracts/v2/utils/SignatureVerifier.sol

  • Impacts:

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

Description

Brief/Intro

The distributePromoterPayments function allows promoters to claim rewards using off-chain signatures. Since signatures do not include a nonce or unique identifier, the same signature can be reused (replayed), enabling unauthorized actions by the attackers, such as repeated claims or claiming rewards earlier than intended.

Vulnerability Details

The vulnerability exists because the signature verification in distributePromoterPayments does not include a nonce or any unique identifier to prevent reuse. Promoters can claim rewards fully or partially, with partial claims requiring multiple function calls. Since the signed payload is not unique, an attacker who obtains a valid signature can replay it, causing the function to execute the same reward claim multiple times or earlier than intended. This allows the attacker to trigger unauthorized actions by executing claims outside the intended schedule, due to insufficient replay protection in the signature validation logic.

// @audit -> Missing nonce (Unique Identifier).
function checkPromoterPaymentDistribution(address signer, PromoterInfo memory promoterInfo) external view {
        require(
            signer.isValidSignatureNow(
                keccak256(
                    abi.encodePacked(promoterInfo.promoter, promoterInfo.venue, promoterInfo.amountInUSD, block.chainid)
                ),
                promoterInfo.signature
            ),
            InvalidSignature()
        );
    }

Impact Details

The attacker cannot profit from this issue, but they can perform unauthorized actions by repeatedly calling distributePromoterPayments. This could potentially cause disruption to the promoter, especially if the payment is in LONG, since the associated swap might occur at an unfavorable time. Therefore, Medium severity is appropriate, as this constitutes griefing.

References

https://github.com/immunefi-team/audit-comp-belong/blob/main/contracts/v2/utils/SignatureVerifier.sol?utm_source=immunefi#L204-L215

Proof of Concept

chevron-rightTest case modification demonstrating the replayhashtag

Update the test case distributePromoterPayments() (partial amount) in the test/v2/platform/belong-check-in.test.ts as follows:

Run the command npm run test

Attack flow

1

Step

The promoter submits a partial reward claim requesting payment in LONG.

2

Step

An attacker replays the promoter’s valid signature and calls distributePromoterPayments at an unfavorable market moment, forcing the contract to swap USDC→LONG.

3

Step

The replayed, unauthorized transaction causes the promoter to receive less LONG due to the poor swap rate, producing a griefing impact.

Was this helpful?