Skip to content

Security: register_with_referral inflates meter.balance without token deposit #44

Description

@leanworld7-netizen

Vulnerability: Unfunded Referral Reward

Location

register_with_referral (L4228) → L4251: meter.balance = meter.balance.saturating_add(REFERRAL_REWARD_UNITS)

Description

register_with_referral adds REFERRAL_REWARD_UNITS = 10 to meter.balance without depositing corresponding tokens to the contract. register_meter_with_mode (L4499) correctly requires user.require_auth(), but the referral reward at L4251 is added after meter creation without any token transfer.

Impact

meter.balance represents the meter's claimable token balance. When a provider later calls claim, the contract transfers tokens from its shared pool based on meter.balance. The referral reward of 10 units is unfunded — it draws from the contract's shared token pool, which includes other users' legitimate deposits via top_up.

Attack: An attacker creates multiple accounts, each registering with a referral, inflating their meter.balance by 10 units per registration. When they claim, the contract pays out from the shared pool, effectively stealing 10 units per account from legitimate depositors.

Severity: MEDIUM

  • Requires user auth (each registration needs user.require_auth())
  • Each instance only steals 10 units (small per-transaction)
  • Scalable across many accounts

Fix

Either:

  1. Deposit actual tokens for the referral reward (transfer from a treasury)
  2. Track referral rewards separately from meter.balance
  3. Only grant referral rewards if the contract has sufficient unallocated funds

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions