103 lines
4.0 KiB
Python
103 lines
4.0 KiB
Python
"""Tests for the composed MYCO system."""
|
|
|
|
import numpy as np
|
|
import pytest
|
|
from src.composed.myco_surface import MycoSystem, MycoSystemConfig
|
|
from src.composed.simulator import (
|
|
run_scenario, scenario_token_launch, scenario_bank_run,
|
|
)
|
|
from src.commitments.labor import ContributorState, attest_contribution
|
|
|
|
|
|
class TestMycoSystem:
|
|
def test_bootstrap_deposit(self):
|
|
"""First deposit should bootstrap the system."""
|
|
system = MycoSystem(MycoSystemConfig(n_reserve_assets=2))
|
|
amounts = np.array([1000.0, 1000.0])
|
|
minted, meta = system.deposit(amounts, current_time=0)
|
|
|
|
assert minted > 0
|
|
assert meta["safe"]
|
|
assert system.state.supply > 0
|
|
assert system.state.reserve_state.total_value == 2000.0
|
|
|
|
def test_deposit_and_redeem(self):
|
|
"""Deposit then partial redeem should work."""
|
|
system = MycoSystem(MycoSystemConfig(n_reserve_assets=2))
|
|
system.deposit(np.array([1000.0, 1000.0]), current_time=0)
|
|
|
|
initial_supply = system.state.supply
|
|
amounts_out, meta = system.redeem(initial_supply * 0.1, current_time=1)
|
|
|
|
assert np.sum(amounts_out) > 0
|
|
assert system.state.supply < initial_supply
|
|
|
|
def test_backing_ratio_positive(self):
|
|
"""After deposit, backing ratio should be positive and finite."""
|
|
system = MycoSystem(MycoSystemConfig(n_reserve_assets=3))
|
|
system.deposit(np.array([1000.0, 1000.0, 1000.0]), current_time=0)
|
|
metrics = system.get_metrics()
|
|
# Backing ratio depends on invariant vs total value (geometry-dependent)
|
|
assert metrics["backing_ratio"] > 0
|
|
assert metrics["backing_ratio"] < 100
|
|
|
|
def test_labor_minting(self):
|
|
"""Labor contributions should mint tokens."""
|
|
system = MycoSystem(MycoSystemConfig(n_reserve_assets=2))
|
|
# Bootstrap with financial deposit
|
|
system.deposit(np.array([1000.0, 1000.0]), current_time=0)
|
|
|
|
contrib = ContributorState(address="alice")
|
|
contrib = attest_contribution(
|
|
system.state.labor_system, contrib, "code", 5.0, current_time=1
|
|
)
|
|
contrib, tokens = system.mint_from_labor(contrib, "code", current_time=1)
|
|
assert tokens > 0
|
|
|
|
def test_multiple_deposits(self):
|
|
"""Multiple deposits should increase supply monotonically."""
|
|
system = MycoSystem(MycoSystemConfig(n_reserve_assets=2))
|
|
supplies = []
|
|
|
|
for t in range(5):
|
|
system.deposit(np.array([100.0, 100.0]), current_time=float(t))
|
|
supplies.append(system.state.supply)
|
|
|
|
for i in range(len(supplies) - 1):
|
|
assert supplies[i + 1] > supplies[i]
|
|
|
|
def test_metrics(self):
|
|
"""Metrics should be consistent."""
|
|
system = MycoSystem(MycoSystemConfig(n_reserve_assets=3))
|
|
system.deposit(np.array([1000.0, 2000.0, 3000.0]), current_time=0)
|
|
metrics = system.get_metrics()
|
|
|
|
assert metrics["supply"] > 0
|
|
assert metrics["reserve_value"] > 0
|
|
assert metrics["financial_minted"] > 0
|
|
assert len(metrics["reserve_weights"]) == 3
|
|
|
|
|
|
class TestScenarios:
|
|
def test_token_launch_runs(self):
|
|
"""Token launch scenario should complete without errors."""
|
|
result = scenario_token_launch(n_assets=2, n_depositors=10, duration=30)
|
|
assert len(result.times) > 0
|
|
assert result.supply[-1] > 0
|
|
assert result.reserve_value[-1] > 0
|
|
|
|
def test_bank_run_preserves_value(self):
|
|
"""Flow dampening should preserve some reserve during bank run."""
|
|
result = scenario_bank_run(
|
|
initial_reserve=10000, n_assets=2,
|
|
redemption_fraction=0.1, duration=50,
|
|
)
|
|
# Reserve should not go to zero (flow dampening protects)
|
|
assert result.reserve_value[-1] > 0
|
|
|
|
def test_launch_backing_ratio(self):
|
|
"""Backing ratio should stay reasonable during launch."""
|
|
result = scenario_token_launch(n_assets=2, n_depositors=10, duration=30)
|
|
# Should be positive throughout
|
|
assert all(result.backing_ratio > 0)
|