57558 sc low front running issue in emergencycancelpayment

Submitted on Oct 27th 2025 at 08:58:37 UTC by @iehnnkta for Audit Comp | Belongarrow-up-right

  • Report ID: #57558

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts: Theft of unclaimed yield

Description

Brief/Intro

The owner-only emergencyCancelPayment(venue, promoter) is intended to claw back a promoter’s outstanding credits to the venue. If the promoter credits are transferable, the promoter can front‑run the owner’s cancel by transferring credits to another address, making the cancel call a silent no‑op (burn/mint of 0) without reverting.

Vulnerability Details

Flow:

1

Step: Alice mints venue credits

Alice mints 100 venue credits.

2

Step: Bob mints promoter credits

Bob mints 50 promoter credits; and mints another 2 promoter credits with a proxy account. Backend signs a 2‑credit payout for proxy account.

3

Step: Owner triggers emergency cancel

Owner suspects Bob1 and calls emergencyCancelPayment(venue, Bob1).

4

Step: Promoter front‑runs

Bob front‑runs by transferring 50 credits from Bob → Bob's proxy account.

5

Step: Cancel becomes a no‑op

When the owner tx executes, promoterBalance(Bob) == 0, so emergencyCancelPayment burns 0 and mints 0; it does not revert or restore any credits. Combined with signature replay, Bob's proxy account (now holding 52 credits) replays the same signed payout in a loop to withdraw all 52 credits from escrow.

Root Cause:

  • emergencyCancelPayment reads the live promoter balance and unconditionally burns that amount, lacking a require(promoterBalance > 0) or expectedAmount parameter.

  • distributePromoterPayments has no nonce/expiry, allowing the same backend signature to be replayed multiple times.

Final Result — Bob's proxy account, now holding the transferred credits, can replay the signed payout multiple times to drain the escrow.

Impact Details

  • Owner’s cancellation can be bypassed by transferring credits to another address prior to cancellation.

  • With signature replayability, an attacker can drain escrow by repeatedly redeeming the same signed payout (example: 52 USDC in the PoC).

  • Severity (author): High (loss of funds and failure of admin control).

References

https://github.com/immunefi-team/audit-comp-belong/blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v2/platform/BelongCheckIn.sol#L562-L573

Mitigation

1

Address signature replay

Add nonce/expiry to the backend-signed promoter payout messages so each signature can only be used once or before a deadline.

2

Hardening emergency cancellation against front‑running

Ensure emergencyCancelPayment cannot be trivially bypassed by transfers:

  • Consider requiring an expected amount parameter or verifying promoter balance at signature generation time.

  • Alternatively, add time-based locks on promoter withdrawals after a cancel is initiated, or check that the promoter still owns expected credits before burning/minting.

Proof of Concept

chevron-rightPoC test: emergencyCancelPayment front-run + signature replay drains escrow (add to belong-check-in-bsc-fork.test.ts)hashtag
chevron-rightPoC test run outputhashtag

Was this helpful?