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.
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.
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.