Skip to content

Marketplace fund_invoice fee is deducted from investor amount but comment claims it is collected on top #353

Description

@Mac-5

Description

contracts/marketplace/src/lib.rs lines 168–184 contain a misleading comment and potentially incorrect fee accounting:

// Collect marketplace fee from investor (on top of contribution)  ← comment says "on top"
let fee_bps: u32 = env.storage().instance().get(&DataKey::FeeBps).unwrap_or(50);
let fee = bps_of(amount, fee_bps)?;
let net = amount
    .checked_sub(fee)                    // ← fee is DEDUCTED from amount
    .ok_or(KoraError::ArithmeticOverflow)?;

token_client.transfer(&investor, &treasury, &fee);
token_client.transfer(&investor, &pool_contract, &net);

The investor transfers exactly amount tokens total (fee to treasury + net to pool). The fee is deducted from the amount, not added on top of it. This means:

  • The financing pool receives net = amount - fee, not amount.
  • The SME receives less than asking_price when the invoice is fully funded.
  • funded_amount tracks the gross amount, so funded_amount == asking_price is reached even though the pool only holds asking_price * (1 - fee_rate).

If the intent is for the SME to receive the full asking_price, the investor should pay amount + fee (true "on top" model). If the intent is for the fee to come from proceeds, the docs and SME UX must be updated to reflect that the SME receives less.

Fix

Decide on the intended fee model and implement it consistently:

Model A (fee on top — investor pays more):

token_client.transfer(&investor, &treasury, &fee);
token_client.transfer(&investor, &pool_contract, &amount); // full amount to pool

Model B (fee from proceeds — current code, fix docs only):
Update the comment and any external documentation to accurately state the SME receives asking_price * (1 - fee_rate).

Acceptance Criteria

  • Fee model is explicitly chosen and documented in code comments and docs/.
  • funded_amount accurately reflects what the pool received if Model A is chosen.
  • Tests assert the exact token balances of treasury, pool, and SME post-funding.
  • No misleading comments remain.

Complexity: Medium (150 points)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions