Company Simulator

First Flight #51
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: medium
Likelihood: medium

Share-Cap Trimming Steals Excess Contribution

Author Revealed upon completion

Root + Impact

Description

  • The share issuance logic should either reject or fully honor a contribution once the requested shares exceed the remaining public cap.

  • Instead the code clamps new_shares to the remaining availability but retains the full payment, so investors overpay whenever the cap is nearly exhausted.

@> if new_shares > available:
@> new_shares = available
self.shares[msg.sender] += new_shares
@> self.company_balance += msg.value

Risk

Likelihood:

  • Large contributions are common when the company is profitable, and as the cap approaches exhaustion each new depositor has a high chance of requesting more shares than remain.

  • Front-ends typically do not query the exact remaining supply prior to sending the transaction, so wallets will broadcast oversized purchases.

Impact:

  • Investors receive only a fraction of the shares they believed they purchased while losing the rest of their payment.

  • The contract silently accumulates windfall funds that should have been refunded, undermining fair distribution and opening the door to legal complaints.

Proof of Concept

  1. Let the share price be 1e15 wei with only one share slot remaining (available = 1).

  2. Call fund_investor with 1 ether, expecting roughly 1,000 shares.

  3. The contract clamps the mint to a single share but still adds the entire 1 ether to company_balance, pocketing the overpayment.

// Assume only 1 share remains while share_price == 1e15.
fund_investor{value: 1 ether}()
// new_shares initially 1000, clamped to 1, investor receives 1 share but loses 0.999 ether.

Recommended Mitigation

  • After clamping new_shares, refund the unused portion msg.value - new_shares * share_price back to the caller.

  • Alternatively, revert the transaction when new_shares > available so users cannot accidentally overpay.

  • Document the remaining capacity via view functions or events so front-ends can prevent users from sending more value than can be converted into shares.

if new_shares > available:
- new_shares = available
+ raise "Insufficient share cap!!!"

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.