package state import ( "errors" "math/big" "git.marketally.com/tutus-one/tutus-chain/pkg/util" "git.marketally.com/tutus-one/tutus-chain/pkg/vm/stackitem" ) // VelocityAccountStatus represents the velocity tracking account status. type VelocityAccountStatus uint8 const ( // VelocityAccountActive indicates the account is actively tracked. VelocityAccountActive VelocityAccountStatus = 0 // VelocityAccountExempt indicates the account is exempt from tribute. VelocityAccountExempt VelocityAccountStatus = 1 // VelocityAccountSuspended indicates velocity tracking is suspended. VelocityAccountSuspended VelocityAccountStatus = 2 ) // AssessmentStatus represents the status of a tribute assessment. type AssessmentStatus uint8 const ( // AssessmentPending indicates the assessment is pending collection. AssessmentPending AssessmentStatus = 0 // AssessmentCollected indicates the tribute has been collected. AssessmentCollected AssessmentStatus = 1 // AssessmentWaived indicates the assessment was waived. AssessmentWaived AssessmentStatus = 2 // AssessmentAppealed indicates the assessment is under appeal. AssessmentAppealed AssessmentStatus = 3 ) // HoardingLevel represents the severity of resource hoarding. type HoardingLevel uint8 const ( // HoardingNone indicates no hoarding detected. HoardingNone HoardingLevel = 0 // HoardingMild indicates mild hoarding (below normal velocity). HoardingMild HoardingLevel = 1 // HoardingModerate indicates moderate hoarding. HoardingModerate HoardingLevel = 2 // HoardingSevere indicates severe hoarding. HoardingSevere HoardingLevel = 3 // HoardingExtreme indicates extreme hoarding (stagnant resources). HoardingExtreme HoardingLevel = 4 ) // IncentiveType represents types of circulation incentives. type IncentiveType uint8 const ( // IncentiveVelocityBonus rewards high resource velocity. IncentiveVelocityBonus IncentiveType = 0 // IncentiveProductiveUse rewards productive resource use. IncentiveProductiveUse IncentiveType = 1 // IncentiveCommunitySupport rewards community contributions. IncentiveCommunitySupport IncentiveType = 2 // IncentiveEducationSpending rewards education investment. IncentiveEducationSpending IncentiveType = 3 // IncentiveHealthcareSpending rewards healthcare investment. IncentiveHealthcareSpending IncentiveType = 4 ) // VelocityAccount tracks resource velocity for a Vita holder. type VelocityAccount struct { VitaID uint64 // Owner's Vita token ID Owner util.Uint160 // Owner's address CurrentVelocity uint64 // Current velocity score (0-10000 basis points) AverageVelocity uint64 // Rolling average velocity LastActivityBlock uint32 // Last transaction block TotalInflow uint64 // Total resources received TotalOutflow uint64 // Total resources spent/transferred StagnantBalance uint64 // Balance considered stagnant HoardingLevel HoardingLevel // Current hoarding assessment ExemptionReason string // Reason for exemption (if any) TotalTributePaid uint64 // Lifetime tribute paid TotalIncentivesRcvd uint64 // Lifetime incentives received Status VelocityAccountStatus // Account status CreatedAt uint32 // Block height when created UpdatedAt uint32 // Last update block } // ToStackItem implements stackitem.Convertible. func (a *VelocityAccount) ToStackItem() stackitem.Item { return stackitem.NewArray([]stackitem.Item{ stackitem.NewBigInteger(new(big.Int).SetUint64(a.VitaID)), stackitem.NewByteArray(a.Owner.BytesBE()), stackitem.NewBigInteger(new(big.Int).SetUint64(a.CurrentVelocity)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.AverageVelocity)), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.LastActivityBlock))), stackitem.NewBigInteger(new(big.Int).SetUint64(a.TotalInflow)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.TotalOutflow)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.StagnantBalance)), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.HoardingLevel))), stackitem.NewByteArray([]byte(a.ExemptionReason)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.TotalTributePaid)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.TotalIncentivesRcvd)), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.Status))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.CreatedAt))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.UpdatedAt))), }) } // FromStackItem implements stackitem.Convertible. func (a *VelocityAccount) FromStackItem(item stackitem.Item) error { arr, ok := item.Value().([]stackitem.Item) if !ok || len(arr) < 15 { return errors.New("not a struct") } vitaID, err := arr[0].TryInteger() if err != nil { return err } a.VitaID = vitaID.Uint64() ownerBytes, err := arr[1].TryBytes() if err != nil { return err } a.Owner, err = util.Uint160DecodeBytesBE(ownerBytes) if err != nil { return err } currentVel, err := arr[2].TryInteger() if err != nil { return err } a.CurrentVelocity = currentVel.Uint64() avgVel, err := arr[3].TryInteger() if err != nil { return err } a.AverageVelocity = avgVel.Uint64() lastActivity, err := arr[4].TryInteger() if err != nil { return err } a.LastActivityBlock = uint32(lastActivity.Uint64()) totalIn, err := arr[5].TryInteger() if err != nil { return err } a.TotalInflow = totalIn.Uint64() totalOut, err := arr[6].TryInteger() if err != nil { return err } a.TotalOutflow = totalOut.Uint64() stagnant, err := arr[7].TryInteger() if err != nil { return err } a.StagnantBalance = stagnant.Uint64() hoardLevel, err := arr[8].TryInteger() if err != nil { return err } a.HoardingLevel = HoardingLevel(hoardLevel.Uint64()) exemptReason, err := arr[9].TryBytes() if err != nil { return err } a.ExemptionReason = string(exemptReason) totalTrib, err := arr[10].TryInteger() if err != nil { return err } a.TotalTributePaid = totalTrib.Uint64() totalInc, err := arr[11].TryInteger() if err != nil { return err } a.TotalIncentivesRcvd = totalInc.Uint64() status, err := arr[12].TryInteger() if err != nil { return err } a.Status = VelocityAccountStatus(status.Uint64()) created, err := arr[13].TryInteger() if err != nil { return err } a.CreatedAt = uint32(created.Uint64()) updated, err := arr[14].TryInteger() if err != nil { return err } a.UpdatedAt = uint32(updated.Uint64()) return nil } // TributeAssessment represents a hoarding tribute assessment. type TributeAssessment struct { ID uint64 // Unique assessment ID VitaID uint64 // Owner's Vita ID Owner util.Uint160 // Owner's address AssessmentBlock uint32 // Block when assessment made HoardingLevel HoardingLevel // Hoarding level at assessment StagnantAmount uint64 // Amount considered stagnant TributeRate uint64 // Rate applied (basis points) TributeAmount uint64 // Tribute amount due DueBlock uint32 // Block by which tribute is due CollectedBlock uint32 // Block when collected (0 if not) Status AssessmentStatus // Assessment status AppealReason string // Reason for appeal (if any) } // ToStackItem implements stackitem.Convertible. func (a *TributeAssessment) ToStackItem() stackitem.Item { return stackitem.NewArray([]stackitem.Item{ stackitem.NewBigInteger(new(big.Int).SetUint64(a.ID)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.VitaID)), stackitem.NewByteArray(a.Owner.BytesBE()), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.AssessmentBlock))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.HoardingLevel))), stackitem.NewBigInteger(new(big.Int).SetUint64(a.StagnantAmount)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.TributeRate)), stackitem.NewBigInteger(new(big.Int).SetUint64(a.TributeAmount)), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.DueBlock))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.CollectedBlock))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(a.Status))), stackitem.NewByteArray([]byte(a.AppealReason)), }) } // FromStackItem implements stackitem.Convertible. func (a *TributeAssessment) FromStackItem(item stackitem.Item) error { arr, ok := item.Value().([]stackitem.Item) if !ok || len(arr) < 12 { return errors.New("not a struct") } id, err := arr[0].TryInteger() if err != nil { return err } a.ID = id.Uint64() vitaID, err := arr[1].TryInteger() if err != nil { return err } a.VitaID = vitaID.Uint64() ownerBytes, err := arr[2].TryBytes() if err != nil { return err } a.Owner, err = util.Uint160DecodeBytesBE(ownerBytes) if err != nil { return err } assessBlock, err := arr[3].TryInteger() if err != nil { return err } a.AssessmentBlock = uint32(assessBlock.Uint64()) hoardLevel, err := arr[4].TryInteger() if err != nil { return err } a.HoardingLevel = HoardingLevel(hoardLevel.Uint64()) stagnant, err := arr[5].TryInteger() if err != nil { return err } a.StagnantAmount = stagnant.Uint64() rate, err := arr[6].TryInteger() if err != nil { return err } a.TributeRate = rate.Uint64() amount, err := arr[7].TryInteger() if err != nil { return err } a.TributeAmount = amount.Uint64() due, err := arr[8].TryInteger() if err != nil { return err } a.DueBlock = uint32(due.Uint64()) collected, err := arr[9].TryInteger() if err != nil { return err } a.CollectedBlock = uint32(collected.Uint64()) status, err := arr[10].TryInteger() if err != nil { return err } a.Status = AssessmentStatus(status.Uint64()) appealReason, err := arr[11].TryBytes() if err != nil { return err } a.AppealReason = string(appealReason) return nil } // CirculationIncentive represents a reward for resource circulation. type CirculationIncentive struct { ID uint64 // Unique incentive ID VitaID uint64 // Recipient's Vita ID Recipient util.Uint160 // Recipient's address IncentiveType IncentiveType // Type of incentive Amount uint64 // Incentive amount Reason string // Reason for incentive VelocityScore uint64 // Velocity score that triggered incentive GrantedBlock uint32 // Block when granted ClaimedBlock uint32 // Block when claimed (0 if not) Claimed bool // Whether incentive was claimed } // ToStackItem implements stackitem.Convertible. func (i *CirculationIncentive) ToStackItem() stackitem.Item { return stackitem.NewArray([]stackitem.Item{ stackitem.NewBigInteger(new(big.Int).SetUint64(i.ID)), stackitem.NewBigInteger(new(big.Int).SetUint64(i.VitaID)), stackitem.NewByteArray(i.Recipient.BytesBE()), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(i.IncentiveType))), stackitem.NewBigInteger(new(big.Int).SetUint64(i.Amount)), stackitem.NewByteArray([]byte(i.Reason)), stackitem.NewBigInteger(new(big.Int).SetUint64(i.VelocityScore)), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(i.GrantedBlock))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(i.ClaimedBlock))), stackitem.NewBool(i.Claimed), }) } // FromStackItem implements stackitem.Convertible. func (i *CirculationIncentive) FromStackItem(item stackitem.Item) error { arr, ok := item.Value().([]stackitem.Item) if !ok || len(arr) < 10 { return errors.New("not a struct") } id, err := arr[0].TryInteger() if err != nil { return err } i.ID = id.Uint64() vitaID, err := arr[1].TryInteger() if err != nil { return err } i.VitaID = vitaID.Uint64() recipBytes, err := arr[2].TryBytes() if err != nil { return err } i.Recipient, err = util.Uint160DecodeBytesBE(recipBytes) if err != nil { return err } incType, err := arr[3].TryInteger() if err != nil { return err } i.IncentiveType = IncentiveType(incType.Uint64()) amount, err := arr[4].TryInteger() if err != nil { return err } i.Amount = amount.Uint64() reason, err := arr[5].TryBytes() if err != nil { return err } i.Reason = string(reason) velScore, err := arr[6].TryInteger() if err != nil { return err } i.VelocityScore = velScore.Uint64() granted, err := arr[7].TryInteger() if err != nil { return err } i.GrantedBlock = uint32(granted.Uint64()) claimed, err := arr[8].TryInteger() if err != nil { return err } i.ClaimedBlock = uint32(claimed.Uint64()) claimedBool, err := arr[9].TryBool() if err != nil { return err } i.Claimed = claimedBool return nil } // RedistributionRecord tracks wealth redistribution events. type RedistributionRecord struct { ID uint64 // Unique record ID SourceAssessment uint64 // Source assessment ID TotalAmount uint64 // Total amount redistributed RecipientCount uint64 // Number of recipients PerCapitaAmount uint64 // Amount per recipient RedistBlock uint32 // Block when redistribution occurred TargetCategory string // Category of recipients (e.g., "low_velocity", "all_citizens") } // ToStackItem implements stackitem.Convertible. func (r *RedistributionRecord) ToStackItem() stackitem.Item { return stackitem.NewArray([]stackitem.Item{ stackitem.NewBigInteger(new(big.Int).SetUint64(r.ID)), stackitem.NewBigInteger(new(big.Int).SetUint64(r.SourceAssessment)), stackitem.NewBigInteger(new(big.Int).SetUint64(r.TotalAmount)), stackitem.NewBigInteger(new(big.Int).SetUint64(r.RecipientCount)), stackitem.NewBigInteger(new(big.Int).SetUint64(r.PerCapitaAmount)), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(r.RedistBlock))), stackitem.NewByteArray([]byte(r.TargetCategory)), }) } // FromStackItem implements stackitem.Convertible. func (r *RedistributionRecord) FromStackItem(item stackitem.Item) error { arr, ok := item.Value().([]stackitem.Item) if !ok || len(arr) < 7 { return errors.New("not a struct") } id, err := arr[0].TryInteger() if err != nil { return err } r.ID = id.Uint64() sourceAssess, err := arr[1].TryInteger() if err != nil { return err } r.SourceAssessment = sourceAssess.Uint64() total, err := arr[2].TryInteger() if err != nil { return err } r.TotalAmount = total.Uint64() recipCount, err := arr[3].TryInteger() if err != nil { return err } r.RecipientCount = recipCount.Uint64() perCapita, err := arr[4].TryInteger() if err != nil { return err } r.PerCapitaAmount = perCapita.Uint64() redistBlock, err := arr[5].TryInteger() if err != nil { return err } r.RedistBlock = uint32(redistBlock.Uint64()) targetCat, err := arr[6].TryBytes() if err != nil { return err } r.TargetCategory = string(targetCat) return nil } // TributeConfig holds configurable parameters for the Tribute system. type TributeConfig struct { VelocityThresholdMild uint64 // Velocity below this = mild hoarding (basis points) VelocityThresholdModerate uint64 // Velocity below this = moderate hoarding VelocityThresholdSevere uint64 // Velocity below this = severe hoarding VelocityThresholdExtreme uint64 // Velocity below this = extreme hoarding TributeRateMild uint64 // Tribute rate for mild hoarding (basis points) TributeRateModerate uint64 // Tribute rate for moderate hoarding TributeRateSevere uint64 // Tribute rate for severe hoarding TributeRateExtreme uint64 // Tribute rate for extreme hoarding IncentiveRateHigh uint64 // Incentive rate for high velocity IncentiveRateVeryHigh uint64 // Incentive rate for very high velocity StagnancyPeriod uint32 // Blocks before balance considered stagnant AssessmentPeriod uint32 // Blocks between assessments GracePeriod uint32 // Blocks before tribute due after assessment MinBalanceForTribute uint64 // Minimum balance to assess tribute ExemptionThreshold uint64 // Balance below which exempt from tribute } // ToStackItem implements stackitem.Convertible. func (c *TributeConfig) ToStackItem() stackitem.Item { return stackitem.NewArray([]stackitem.Item{ stackitem.NewBigInteger(new(big.Int).SetUint64(c.VelocityThresholdMild)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.VelocityThresholdModerate)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.VelocityThresholdSevere)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.VelocityThresholdExtreme)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.TributeRateMild)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.TributeRateModerate)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.TributeRateSevere)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.TributeRateExtreme)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.IncentiveRateHigh)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.IncentiveRateVeryHigh)), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(c.StagnancyPeriod))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(c.AssessmentPeriod))), stackitem.NewBigInteger(new(big.Int).SetUint64(uint64(c.GracePeriod))), stackitem.NewBigInteger(new(big.Int).SetUint64(c.MinBalanceForTribute)), stackitem.NewBigInteger(new(big.Int).SetUint64(c.ExemptionThreshold)), }) } // FromStackItem implements stackitem.Convertible. func (c *TributeConfig) FromStackItem(item stackitem.Item) error { arr, ok := item.Value().([]stackitem.Item) if !ok || len(arr) < 15 { return errors.New("not a struct") } threshMild, err := arr[0].TryInteger() if err != nil { return err } c.VelocityThresholdMild = threshMild.Uint64() threshMod, err := arr[1].TryInteger() if err != nil { return err } c.VelocityThresholdModerate = threshMod.Uint64() threshSev, err := arr[2].TryInteger() if err != nil { return err } c.VelocityThresholdSevere = threshSev.Uint64() threshExt, err := arr[3].TryInteger() if err != nil { return err } c.VelocityThresholdExtreme = threshExt.Uint64() rateMild, err := arr[4].TryInteger() if err != nil { return err } c.TributeRateMild = rateMild.Uint64() rateMod, err := arr[5].TryInteger() if err != nil { return err } c.TributeRateModerate = rateMod.Uint64() rateSev, err := arr[6].TryInteger() if err != nil { return err } c.TributeRateSevere = rateSev.Uint64() rateExt, err := arr[7].TryInteger() if err != nil { return err } c.TributeRateExtreme = rateExt.Uint64() incHigh, err := arr[8].TryInteger() if err != nil { return err } c.IncentiveRateHigh = incHigh.Uint64() incVeryHigh, err := arr[9].TryInteger() if err != nil { return err } c.IncentiveRateVeryHigh = incVeryHigh.Uint64() stagnancy, err := arr[10].TryInteger() if err != nil { return err } c.StagnancyPeriod = uint32(stagnancy.Uint64()) assessPeriod, err := arr[11].TryInteger() if err != nil { return err } c.AssessmentPeriod = uint32(assessPeriod.Uint64()) grace, err := arr[12].TryInteger() if err != nil { return err } c.GracePeriod = uint32(grace.Uint64()) minBal, err := arr[13].TryInteger() if err != nil { return err } c.MinBalanceForTribute = minBal.Uint64() exemptThresh, err := arr[14].TryInteger() if err != nil { return err } c.ExemptionThreshold = exemptThresh.Uint64() return nil }