mirror of
https://github.com/SHOGGOTH-SECTOR/sica-fondt.git
synced 2026-07-31 16:16:26 +00:00
Delete main.f90
This commit is contained in:
parent
99b2f26dbc
commit
6d4360165d
@ -1,253 +0,0 @@
|
|||||||
! M3e -- Tokenomics & macro-state sims
|
|
||||||
! Language: Fortran (SDE/VAR matrix loops, same toolchain as M3d)
|
|
||||||
! Protocol: line-delimited JSON on stdin/stdout to hub.tcl
|
|
||||||
|
|
||||||
program tokenomics_sim
|
|
||||||
implicit none
|
|
||||||
|
|
||||||
type :: BoundedPrediction
|
|
||||||
double precision :: value
|
|
||||||
double precision :: lower_bound
|
|
||||||
double precision :: upper_bound
|
|
||||||
double precision :: confidence
|
|
||||||
character(len=16) :: time_horizon
|
|
||||||
character(len=32) :: sim_type
|
|
||||||
end type
|
|
||||||
|
|
||||||
! Stock-flow state vector: L2 conservation invariant
|
|
||||||
type :: TokenState
|
|
||||||
double precision :: circulating
|
|
||||||
double precision :: staked
|
|
||||||
double precision :: locked
|
|
||||||
double precision :: burned
|
|
||||||
double precision :: total_minted
|
|
||||||
end type
|
|
||||||
|
|
||||||
! Kinked lending rate parameters (Aave-style)
|
|
||||||
type :: LendingParams
|
|
||||||
double precision :: R0
|
|
||||||
double precision :: slope1
|
|
||||||
double precision :: slope2
|
|
||||||
double precision :: U_opt
|
|
||||||
end type
|
|
||||||
|
|
||||||
call run_self_test()
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
! -- Euler-Maruyama SDE solver -------------------------------------------
|
|
||||||
! dX = f(X,t)*dt + sigma(X,t)*dW
|
|
||||||
! State vector: [circulating, staked, locked, price]
|
|
||||||
subroutine euler_maruyama_step(state, drift, diffusion, dt, n_dim, rng_z)
|
|
||||||
integer, intent(in) :: n_dim
|
|
||||||
double precision, intent(inout) :: state(n_dim)
|
|
||||||
double precision, intent(in) :: drift(n_dim), diffusion(n_dim)
|
|
||||||
double precision, intent(in) :: dt, rng_z(n_dim)
|
|
||||||
integer :: i
|
|
||||||
|
|
||||||
do i = 1, n_dim
|
|
||||||
state(i) = state(i) + drift(i) * dt + diffusion(i) * sqrt(dt) * rng_z(i)
|
|
||||||
end do
|
|
||||||
end subroutine
|
|
||||||
|
|
||||||
! -- Token supply SDE drift function -------------------------------------
|
|
||||||
! Deterministic: emission schedule minus burns
|
|
||||||
subroutine supply_drift(ts, emission_rate, burn_rate, staking_inflow, &
|
|
||||||
drift, n_dim)
|
|
||||||
type(TokenState), intent(in) :: ts
|
|
||||||
double precision, intent(in) :: emission_rate, burn_rate, staking_inflow
|
|
||||||
double precision, intent(out) :: drift(n_dim)
|
|
||||||
integer, intent(in) :: n_dim
|
|
||||||
|
|
||||||
! drift(1) = circulating: +emission -staking_inflow -burn
|
|
||||||
drift(1) = emission_rate - staking_inflow - burn_rate * ts%circulating
|
|
||||||
! drift(2) = staked: +staking_inflow
|
|
||||||
drift(2) = staking_inflow
|
|
||||||
! drift(3) = locked: 0 (no change in this simple model)
|
|
||||||
drift(3) = 0.0d0
|
|
||||||
! drift(4) = burned: +burn
|
|
||||||
if (n_dim >= 4) drift(4) = burn_rate * ts%circulating
|
|
||||||
end subroutine
|
|
||||||
|
|
||||||
! -- Stock-flow conservation check (L2 invariant) -------------------------
|
|
||||||
logical function check_conservation(ts)
|
|
||||||
type(TokenState), intent(in) :: ts
|
|
||||||
double precision :: total, eps
|
|
||||||
eps = 1.0d-8
|
|
||||||
total = ts%circulating + ts%staked + ts%locked + ts%burned
|
|
||||||
check_conservation = abs(total - ts%total_minted) < eps
|
|
||||||
end function
|
|
||||||
|
|
||||||
! -- Kinked lending rate (L3: kink at U_opt) ------------------------------
|
|
||||||
double precision function lending_rate(U, params)
|
|
||||||
double precision, intent(in) :: U
|
|
||||||
type(LendingParams), intent(in) :: params
|
|
||||||
|
|
||||||
if (U <= params%U_opt) then
|
|
||||||
lending_rate = params%R0 + params%slope1 * U
|
|
||||||
else
|
|
||||||
lending_rate = params%R0 + params%slope1 * params%U_opt &
|
|
||||||
+ params%slope2 * (U - params%U_opt)
|
|
||||||
end if
|
|
||||||
end function
|
|
||||||
|
|
||||||
! -- Liquidation cascade check --------------------------------------------
|
|
||||||
logical function check_liquidation(collateral, ltv, borrowed)
|
|
||||||
double precision, intent(in) :: collateral, ltv, borrowed
|
|
||||||
check_liquidation = (collateral * ltv) < borrowed
|
|
||||||
end function
|
|
||||||
|
|
||||||
! -- Halving event (drift discontinuity) ----------------------------------
|
|
||||||
subroutine apply_halving(emission_rate)
|
|
||||||
double precision, intent(inout) :: emission_rate
|
|
||||||
emission_rate = emission_rate * 0.5d0
|
|
||||||
end subroutine
|
|
||||||
|
|
||||||
! -- Monte Carlo token supply trajectory ----------------------------------
|
|
||||||
subroutine mc_supply_trajectory(ts0, emission0, burn_rate, staking_frac, &
|
|
||||||
dt, n_steps, n_paths, &
|
|
||||||
halving_step, final_circ)
|
|
||||||
type(TokenState), intent(in) :: ts0
|
|
||||||
double precision, intent(in) :: emission0, burn_rate, staking_frac
|
|
||||||
double precision, intent(in) :: dt
|
|
||||||
integer, intent(in) :: n_steps, n_paths, halving_step
|
|
||||||
double precision, intent(out) :: final_circ(n_paths)
|
|
||||||
|
|
||||||
type(TokenState) :: ts
|
|
||||||
double precision :: drift(3), diffusion(3), z(3), emission
|
|
||||||
integer :: p, t
|
|
||||||
|
|
||||||
diffusion = (/ 0.01d0, 0.005d0, 0.001d0 /)
|
|
||||||
|
|
||||||
do p = 1, n_paths
|
|
||||||
ts = ts0
|
|
||||||
emission = emission0
|
|
||||||
do t = 1, n_steps
|
|
||||||
if (t == halving_step) call apply_halving(emission)
|
|
||||||
|
|
||||||
call supply_drift(ts, emission, burn_rate, &
|
|
||||||
staking_frac * ts%circulating, drift, 3)
|
|
||||||
|
|
||||||
call random_number(z)
|
|
||||||
z = z * 2.0d0 - 1.0d0 ! Approximate normal via uniform (good enough for test)
|
|
||||||
|
|
||||||
ts%circulating = max(0.0d0, ts%circulating + drift(1)*dt + &
|
|
||||||
diffusion(1)*sqrt(dt)*z(1))
|
|
||||||
ts%staked = max(0.0d0, ts%staked + drift(2)*dt + &
|
|
||||||
diffusion(2)*sqrt(dt)*z(2))
|
|
||||||
ts%burned = ts%burned + burn_rate * ts%circulating * dt
|
|
||||||
ts%total_minted = ts%total_minted + emission * dt
|
|
||||||
end do
|
|
||||||
final_circ(p) = ts%circulating
|
|
||||||
end do
|
|
||||||
end subroutine
|
|
||||||
|
|
||||||
! -- BoundedPrediction constructor ----------------------------------------
|
|
||||||
function make_prediction(val, lo, hi, conf, horizon) result(bp)
|
|
||||||
double precision, intent(in) :: val, lo, hi, conf
|
|
||||||
character(len=*), intent(in) :: horizon
|
|
||||||
type(BoundedPrediction) :: bp
|
|
||||||
|
|
||||||
if (lo > val .or. val > hi) then
|
|
||||||
print *, "ERROR: invariant violation: lower <= value <= upper"
|
|
||||||
stop 1
|
|
||||||
end if
|
|
||||||
if (conf < 0.0d0 .or. conf > 10.0d0) then
|
|
||||||
print *, "ERROR: confidence must be in [0.00, 10.00]"
|
|
||||||
stop 1
|
|
||||||
end if
|
|
||||||
|
|
||||||
bp%value = val
|
|
||||||
bp%lower_bound = lo
|
|
||||||
bp%upper_bound = hi
|
|
||||||
bp%confidence = conf
|
|
||||||
bp%time_horizon = horizon
|
|
||||||
bp%sim_type = "tokenomics_macro"
|
|
||||||
end function
|
|
||||||
|
|
||||||
! -- Self-test ------------------------------------------------------------
|
|
||||||
subroutine run_self_test()
|
|
||||||
type(BoundedPrediction) :: bp
|
|
||||||
type(TokenState) :: ts
|
|
||||||
type(LendingParams) :: lp
|
|
||||||
double precision :: rate, final_circ(500)
|
|
||||||
double precision :: median_circ, lo_circ, hi_circ
|
|
||||||
integer :: i
|
|
||||||
|
|
||||||
print *, "M3e Tokenomics Macro Sim -- Fortran (gfortran)"
|
|
||||||
print *, ""
|
|
||||||
|
|
||||||
! Stock-flow conservation test
|
|
||||||
print *, "Stock-flow conservation (L2):"
|
|
||||||
ts = TokenState(circulating=1000.0d0, staked=500.0d0, locked=200.0d0, &
|
|
||||||
burned=300.0d0, total_minted=2000.0d0)
|
|
||||||
if (check_conservation(ts)) then
|
|
||||||
print *, " PASS: 1000+500+200+300 = 2000"
|
|
||||||
else
|
|
||||||
print *, " FAIL"
|
|
||||||
end if
|
|
||||||
print *, ""
|
|
||||||
|
|
||||||
! Kinked lending rate test (L3)
|
|
||||||
print *, "Kinked lending rate (L3, Aave-style):"
|
|
||||||
lp = LendingParams(R0=0.02d0, slope1=0.04d0, slope2=0.75d0, U_opt=0.80d0)
|
|
||||||
rate = lending_rate(0.50d0, lp)
|
|
||||||
write(*, '(A,F6.4)') " U=0.50: R=", rate
|
|
||||||
rate = lending_rate(0.80d0, lp)
|
|
||||||
write(*, '(A,F6.4)') " U=0.80: R=", rate
|
|
||||||
rate = lending_rate(0.95d0, lp)
|
|
||||||
write(*, '(A,F6.4)') " U=0.95: R=", rate
|
|
||||||
print *, " Kink at U_opt=0.80 verified"
|
|
||||||
print *, ""
|
|
||||||
|
|
||||||
! Liquidation cascade test
|
|
||||||
print *, "Liquidation check:"
|
|
||||||
if (check_liquidation(100.0d0, 0.75d0, 80.0d0)) then
|
|
||||||
print *, " PASS: 100*0.75=75 < 80 -> liquidation triggered"
|
|
||||||
else
|
|
||||||
print *, " FAIL"
|
|
||||||
end if
|
|
||||||
print *, ""
|
|
||||||
|
|
||||||
! Monte Carlo supply trajectory
|
|
||||||
print *, "MC supply trajectory (500 paths, halving at step 50):"
|
|
||||||
ts = TokenState(circulating=1000.0d0, staked=500.0d0, locked=200.0d0, &
|
|
||||||
burned=0.0d0, total_minted=1700.0d0)
|
|
||||||
call mc_supply_trajectory(ts, 10.0d0, 0.01d0, 0.05d0, &
|
|
||||||
0.01d0, 100, 500, 50, final_circ)
|
|
||||||
|
|
||||||
! Sort for quantiles (simple selection sort for 500 elements)
|
|
||||||
call sort_array(final_circ, 500)
|
|
||||||
median_circ = final_circ(250)
|
|
||||||
lo_circ = final_circ(13) ! 2.5th percentile
|
|
||||||
hi_circ = final_circ(488) ! 97.5th percentile
|
|
||||||
|
|
||||||
bp = make_prediction(median_circ, lo_circ, hi_circ, 8.80d0, "90d")
|
|
||||||
write(*, '(A,F8.2,A,F8.2,A,F8.2,A)') &
|
|
||||||
" supply: ", bp%value, " [", bp%lower_bound, ", ", bp%upper_bound, "]"
|
|
||||||
write(*, '(A,F5.2,A)') " confidence: ", bp%confidence, "/10.00"
|
|
||||||
print *, ""
|
|
||||||
|
|
||||||
print *, "All models operational."
|
|
||||||
end subroutine
|
|
||||||
|
|
||||||
subroutine sort_array(arr, n)
|
|
||||||
integer, intent(in) :: n
|
|
||||||
double precision, intent(inout) :: arr(n)
|
|
||||||
double precision :: tmp
|
|
||||||
integer :: i, j, min_idx
|
|
||||||
|
|
||||||
do i = 1, n - 1
|
|
||||||
min_idx = i
|
|
||||||
do j = i + 1, n
|
|
||||||
if (arr(j) < arr(min_idx)) min_idx = j
|
|
||||||
end do
|
|
||||||
if (min_idx /= i) then
|
|
||||||
tmp = arr(i)
|
|
||||||
arr(i) = arr(min_idx)
|
|
||||||
arr(min_idx) = tmp
|
|
||||||
end if
|
|
||||||
end do
|
|
||||||
end subroutine
|
|
||||||
|
|
||||||
end program tokenomics_sim
|
|
||||||
Loading…
x
Reference in New Issue
Block a user