Incident workspace

Share Accounting Drift In A Fictional Vault

A fictional vault mints shares from a stale asset balance after a fee path changes total assets without refreshing the denominator, creating a proportional-accounting failure.

Phase 1 · Fictional Content

Fictional data used to validate the TraceFi interface. This is not a real security incident.

Source Metadata

Code material is synthetic prototype content. No real repository, address, compiler output, or executable project is included.

Vulnerable Code Panel

Fictional stale denominator share mint. Original fictional Solidity; not runnable.

VulnerableExcerpt.solSolidity · Read-only
  1. function deposit(uint256 assets) external {
  2. uint256 cachedAssets = accountedAssets;
  3. _settleFees();
  4. uint256 shares = assets * totalSupply() / cachedAssets;
  5. _mint(msg.sender, shares);
  6. }
Loading VulnerableExcerpt.sol source
  • - This is original fictional Solidity for Phase 1.
  • - It is intentionally incomplete and not runnable.
  • - It must not be treated as a real protocol excerpt.

Before/After Code Diff

Removed vulnerable order

Vulnerable.solSolidity · Read-only
  1. function deposit(uint256 assets) external {
  2. uint256 cachedAssets = accountedAssets;
  3. _settleFees();
  4. uint256 shares = assets * totalSupply() / cachedAssets;
  5. _mint(msg.sender, shares);
  6. }
Loading Vulnerable.sol source

Added corrected order

Corrected.solSolidity · Read-only
  1. function deposit(uint256 assets) external {
  2. _settleFees();
  3. uint256 currentAssets = accountedAssets;
  4. uint256 shares = assets * totalSupply() / currentAssets;
  5. _mint(msg.sender, shares);
  6. }
Loading Corrected.sol source

Code-level Root Cause

The modeled root cause is an unsafe ordering boundary around state reads and state-changing internal calls.

Mitigation Notes

  • This is original fictional Solidity for Phase 1.
  • It is intentionally incomplete and not runnable.
  • It must not be treated as a real protocol excerpt.