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
Complexity: Medium (150 points)
Description
contracts/marketplace/src/lib.rslines 168–184 contain a misleading comment and potentially incorrect fee accounting:The investor transfers exactly
amounttokens total (feeto treasury +netto pool). The fee is deducted from the amount, not added on top of it. This means:net = amount - fee, notamount.asking_pricewhen the invoice is fully funded.funded_amounttracks the grossamount, sofunded_amount == asking_priceis reached even though the pool only holdsasking_price * (1 - fee_rate).If the intent is for the SME to receive the full
asking_price, the investor should payamount + 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):
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
docs/.funded_amountaccurately reflects what the pool received if Model A is chosen.Complexity: Medium (150 points)