Company Simulator

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

Share Price Manipulation Allows Owner to Front-Run Investors

Author Revealed upon completion

Root + Impact

The owner can manipulate share prices by injecting funds after initial investments,
causing unfair treatment of investors who invest at different times. This creates
an exploitable economic model where early investors get dramatically better prices
than later investors for the same investment amount.

Description

  • Normal Behavior: All investors should receive shares at a fair, consistent price
    based on the company's actual value

  • Specific Issue: Share price is calculated as net_worth / issued_shares, where
    net_worth = company_balance - holding_debt. The owner can increase company_balance
    by funding the company, which artificially inflates the share price for subsequent
    investors.

// Cyfrin_Hub.vy - fund_investor() function showing the vulnerability
@payable
@internal
def fund_investor():
// ... validation checks ...
# Calculate shares based on contribution
net_worth: uint256 = 0
if self.company_balance > self.holding_debt:
net_worth = self.company_balance - self.holding_debt // @> Net worth includes owner funding
share_price: uint256 = (
net_worth // max(self.issued_shares, 1) // @> Share price = net_worth / shares
if self.issued_shares > 0
else INITIAL_SHARE_PRICE
)
new_shares: uint256 = msg.value // share_price // @> Fewer shares for same ETH
// Cyfrin_Hub.vy - fund_owner() function that enables manipulation
@payable
@internal
def fund_owner():
assert msg.sender == OWNER, "Not the owner!!!"
self.company_balance += msg.value // @> Owner can inflate company balance

Risk

Likelihood:

  • This occurs EVERY TIME the owner funds the company after investors have
    already invested

  • The owner has complete control over when to inject funds

  • No restrictions prevent the owner from front-running investor transactions

  • Owner can time their funding to maximize exploitation

Impact:

  • Early investors get dramatically better share prices (62.5x in our test)

  • Later investors get worse prices for the same investment amount

  • Owner can front-run investor transactions to maximize their own benefit

  • Complete unfairness in the investment model

  • Economic model becomes exploitable and unsustainable

Proof of Concept

// Test demonstrating share price manipulation with actual results
def test_share_price_manipulation():
// Setup: Owner and two investors
owner.fund_cyfrin(0, value=10 ether) // Initial company funding
// First investor invests 1 ETH
patrick.fund_cyfrin(1, value=1 ether)
patrick_shares = company.get_my_shares()
// Result: Patrick gets 1,000 shares (0.011 ETH per share)
// Owner manipulates share price by injecting funds
owner.fund_cyfrin(0, value=50 ether) // Inflates company balance
// Second investor invests same 1 ETH
dacian.fund_cyfrin(1, value=1 ether)
dacian_shares = company.get_my_shares()
// Result: Dacian gets only 16 shares (0.061 ETH per share)
// VULNERABILITY CONFIRMED:
// Patrick: 1 ETH → 1,000 shares
// Dacian: 1 ETH → 16 shares
// Patrick got 62.5x more shares for same investment!
assert patrick_shares > dacian_shares // VULNERABILITY CONFIRMED

EXPLANATION OF POC:
This proof of concept demonstrates the share price manipulation vulnerability:

  1. Setup Phase: Owner funds company with 10 ETH, creating initial net worth

  2. First Investment: Patrick invests 1 ETH and receives 1,000 shares based on
    initial net worth (11 ETH / 1,000 shares = 0.011 ETH per share)

  3. Owner Manipulation: Owner injects 50 ETH, inflating company balance to 61 ETH

  4. Share Price Inflation: Net worth becomes 61 ETH, share price jumps to
    0.061 ETH per share (61 ETH / 1,000 shares)

  5. Second Investment: Dacian invests same 1 ETH but receives only 16 shares
    (1 ETH / 0.061 ETH per share = 16 shares)

  6. Vulnerability Confirmation: Same investment amount results in 62.5x difference
    in share allocation

The core issue is that share price calculation includes owner funding, allowing
the owner to artificially inflate the company's perceived value and extract more
value from later investors.

Recommended Mitigation


EXPLANATION OF MITIGATION:
This fix addresses the share price manipulation by:

  1. Fixed Price: Uses a constant share price that doesn't change based on owner funding

  2. Fair Pricing: All investors get the same price regardless of timing

  3. Prevents Manipulation: Owner funding cannot affect share prices

  4. Simple Implementation: Easy to understand and maintain

+ @external
+ @view
+ def get_fixed_share_price() -> uint256:
+ // Use a fixed price that doesn't change based on owner funding
+ return INITIAL_SHARE_PRICE // 0.001 ETH per share
@payable
@internal
def fund_investor():
// ... validation checks ...
- # Calculate shares based on contribution
- net_worth: uint256 = 0
- if self.company_balance > self.holding_debt:
- net_worth = self.company_balance - self.holding_debt
-
- share_price: uint256 = (
- net_worth // max(self.issued_shares, 1)
- if self.issued_shares > 0
- else INITIAL_SHARE_PRICE
- )
+ # Use fixed share price
+ share_price: uint256 = self.get_fixed_share_price()
new_shares: uint256 = msg.value // share_price

Support

FAQs

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