diff --git a/x/rootpool/types/types.go b/x/rootpool/types/types.go new file mode 100644 index 0000000..3226d3d --- /dev/null +++ b/x/rootpool/types/types.go @@ -0,0 +1,43 @@ +package types + +import "encoding/json" + +const ( + ModuleName = "rootpool" + StoreKey = ModuleName + RouterKey = ModuleName + QuerierRoute = ModuleName +) + +// RootPool is the mesh's treasury (§5) +// Attested by Watchers, visible to every Holder. +type RootPool struct { + BalanceGrain int64 `json:"balance_grain" yaml:"balance_grain"` + LastAttestation int64 `json:"last_attestation" yaml:"last_attestation"` + QuorumMet bool `json:"quorum_met" yaml:"quorum_met"` + ReserveRatioPct uint32 `json:"reserve_ratio_pct" yaml:"reserve_ratio_pct"` +} + +// RootPoolEntry tracks incoming/outgoing Root-Pool movements +type RootPoolEntry struct { + EntryID string `json:"entry_id" yaml:"entry_id"` + Source string `json:"source" yaml:"source"` + Amount int64 `json:"amount" yaml:"amount"` + Reason string `json:"reason" yaml:"reason"` + Timestamp int64 `json:"timestamp" yaml:"timestamp"` +} + +type Params struct{} + +func DefaultParams() Params { return Params{} } + +type GenesisState struct { + Params Params `json:"params" yaml:"params"` + RootPool RootPool `json:"root_pool" yaml:"root_pool"` +} + +func DefaultGenesisState() *GenesisState { + return &GenesisState{Params: DefaultParams()} +} + +func ValidateGenesis(bz json.RawMessage) error { return nil } diff --git a/x/stash/types/types.go b/x/stash/types/types.go new file mode 100644 index 0000000..6fa391e --- /dev/null +++ b/x/stash/types/types.go @@ -0,0 +1,55 @@ +package types + +import "encoding/json" + +const ( + ModuleName = "stash" + StoreKey = ModuleName + RouterKey = ModuleName + QuerierRoute = ModuleName +) + +// Stash is a per-Holder sovereign storage (§5) +// The Holder owns it. No one else can access it without a Window (§10). +type Stash struct { + HolderID string `json:"holder_id" yaml:"holder_id"` + StashID string `json:"stash_id" yaml:"stash_id"` + CreatedAt int64 `json:"created_at" yaml:"created_at"` + LastActive int64 `json:"last_active" yaml:"last_active"` + BalanceGrain int64 `json:"balance_grain" yaml:"balance_grain"` + IsStill bool `json:"is_still" yaml:"is_still"` // Still = Holder paused partner access (§10) +} + +// StashActivity tracks Stash maturity for Freeholder signals (§9.1: 90 days, no gap >30 days) +type StashActivity struct { + StashID string `json:"stash_id" yaml:"stash_id"` + ActiveDays uint32 `json:"active_days" yaml:"active_days"` + MaxGapDays uint32 `json:"max_gap_days" yaml:"max_gap_days"` // must be ≤30 for Freeholder + LastActivityDay int64 `json:"last_activity_day" yaml:"last_activity_day"` +} + +// MaturityThreshold for Freeholder signal (§9.1: 90 days) +const MaturityThresholdDays = 90 + +// MaxGapForMaturity for Freeholder signal (§9.1: no gap > 30 days) +const MaxGapForMaturity = 30 + +// IsMature checks if Stash activity meets the Freeholder maturity threshold (§9.1) +func (a StashActivity) IsMature() bool { + return a.ActiveDays >= MaturityThresholdDays && a.MaxGapDays <= MaxGapForMaturity +} + +type Params struct{} + +func DefaultParams() Params { return Params{} } + +type GenesisState struct { + Params Params `json:"params" yaml:"params"` + Stashes []Stash `json:"stashes" yaml:"stashes"` +} + +func DefaultGenesisState() *GenesisState { + return &GenesisState{Params: DefaultParams(), Stashes: []Stash{}} +} + +func ValidateGenesis(bz json.RawMessage) error { return nil } diff --git a/x/stash/types/types_test.go b/x/stash/types/types_test.go new file mode 100644 index 0000000..4a83cdd --- /dev/null +++ b/x/stash/types/types_test.go @@ -0,0 +1,43 @@ +package types_test + +import ( + "testing" + + "github.com/oy/openyield/x/stash/types" +) + +func TestMaturityThreshold(t *testing.T) { + if types.MaturityThresholdDays != 90 { + t.Errorf("MaturityThresholdDays = %d, expected 90 (§9.1)", types.MaturityThresholdDays) + } +} + +func TestMaxGapForMaturity(t *testing.T) { + if types.MaxGapForMaturity != 30 { + t.Errorf("MaxGapForMaturity = %d, expected 30 (§9.1: no gap > 30 days)", types.MaxGapForMaturity) + } +} + +func TestStashIsMature(t *testing.T) { + mature := types.StashActivity{ActiveDays: 90, MaxGapDays: 15} + if !mature.IsMature() { + t.Error("90 days active, 15 max gap should be mature (§9.1)") + } + + notEnoughDays := types.StashActivity{ActiveDays: 89, MaxGapDays: 15} + if notEnoughDays.IsMature() { + t.Error("89 days should NOT be mature (threshold = 90)") + } + + gapTooBig := types.StashActivity{ActiveDays: 100, MaxGapDays: 31} + if gapTooBig.IsMature() { + t.Error("31-day gap should NOT be mature (max gap = 30)") + } +} + +func TestStashStillFlag(t *testing.T) { + stash := types.Stash{IsStill: true} + if !stash.IsStill { + t.Error("Stash with IsStill=true should reflect Still state (§10: Holder paused partner access)") + } +} diff --git a/x/vault/types/types.go b/x/vault/types/types.go new file mode 100644 index 0000000..38de60f --- /dev/null +++ b/x/vault/types/types.go @@ -0,0 +1,42 @@ +package types + +import "encoding/json" + +const ( + ModuleName = "vault" + StoreKey = ModuleName + RouterKey = ModuleName + QuerierRoute = ModuleName +) + +// Vault is a per-Stand governed storage (§5) +// Governed by the Stand Council (§19). Holds shared funds for a Stand. +type Vault struct { + VaultID string `json:"vault_id" yaml:"vault_id"` + StandID string `json:"stand_id" yaml:"stand_id"` + CreatedAt int64 `json:"created_at" yaml:"created_at"` + BalanceGrain int64 `json:"balance_grain" yaml:"balance_grain"` +} + +// VaultAllocation tracks sub-Vault allocations within a Stand +type VaultAllocation struct { + VaultID string `json:"vault_id" yaml:"vault_id"` + SubVaultID string `json:"sub_vault_id" yaml:"sub_vault_id"` + Percentage uint32 `json:"percentage" yaml:"percentage"` + Purpose string `json:"purpose" yaml:"purpose"` +} + +type Params struct{} + +func DefaultParams() Params { return Params{} } + +type GenesisState struct { + Params Params `json:"params" yaml:"params"` + Vaults []Vault `json:"vaults" yaml:"vaults"` +} + +func DefaultGenesisState() *GenesisState { + return &GenesisState{Params: DefaultParams(), Vaults: []Vault{}} +} + +func ValidateGenesis(bz json.RawMessage) error { return nil }