@wowok/agent-mcp 3.1.3 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/config-audit.spec.d.ts +1 -0
- package/dist/config/config-audit.spec.js +1 -0
- package/dist/config/exposure.d.ts +108 -0
- package/dist/config/exposure.js +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +1 -1
- package/dist/config/judgment.d.ts +1228 -0
- package/dist/config/judgment.js +1 -0
- package/dist/config/judgment.spec.d.ts +1 -0
- package/dist/config/judgment.spec.js +1 -0
- package/dist/config/rule-engine.d.ts +299 -0
- package/dist/config/rule-engine.js +1 -0
- package/dist/config/rule-engine.spec.d.ts +1 -0
- package/dist/config/rule-engine.spec.js +1 -0
- package/dist/config/severity.d.ts +7 -0
- package/dist/config/severity.js +1 -0
- package/dist/customer/order-monitor.d.ts +3 -1
- package/dist/customer/order-monitor.js +1 -1
- package/dist/evaluation/acceptance.d.ts +1 -0
- package/dist/evaluation/acceptance.js +1 -1
- package/dist/evaluation/arbitration-game.js +1 -1
- package/dist/evaluation/builtins/demand-match.js +1 -1
- package/dist/evaluation/builtins/graph-service.js +1 -1
- package/dist/evaluation/builtins/graph-service.spec.js +1 -1
- package/dist/evaluation/engine.js +1 -1
- package/dist/evaluation/game-strategy.d.ts +2 -2
- package/dist/evaluation/game-strategy.js +1 -1
- package/dist/evaluation/match-operation.d.ts +2 -2
- package/dist/evaluation/match-operation.js +1 -1
- package/dist/evaluation/standards.d.ts +3 -25
- package/dist/evaluation/standards.js +1 -1
- package/dist/evaluation/types.d.ts +2 -1
- package/dist/experience/realtime-feedback.js +1 -1
- package/dist/extensions/business-modules.js +1 -1
- package/dist/extensions/custom-registry-file.js +1 -1
- package/dist/extensions/industry-audit.spec.d.ts +1 -0
- package/dist/extensions/industry-audit.spec.js +1 -0
- package/dist/extensions/industry-layers.d.ts +8 -0
- package/dist/extensions/industry-layers.js +1 -1
- package/dist/extensions/industry-pack.d.ts +2 -0
- package/dist/extensions/industry-pack.js +1 -1
- package/dist/extensions/mode-evaluator.js +1 -1
- package/dist/extensions/modes.js +1 -1
- package/dist/graph/onchain/analyze.d.ts +3 -1
- package/dist/graph/onchain/analyze.js +1 -1
- package/dist/graph/onchain/analyze.spec.js +1 -1
- package/dist/graph/onchain/edge-schema.d.ts +1 -0
- package/dist/graph/onchain/edge-schema.js +1 -1
- package/dist/graph/onchain/expand.js +1 -1
- package/dist/graph/onchain/exploration.d.ts +28 -0
- package/dist/graph/onchain/exploration.js +1 -0
- package/dist/graph/onchain/exploration.spec.d.ts +1 -0
- package/dist/graph/onchain/exploration.spec.js +1 -0
- package/dist/graph/onchain/exposure.d.ts +18 -0
- package/dist/graph/onchain/exposure.js +1 -0
- package/dist/graph/onchain/exposure.spec.d.ts +1 -0
- package/dist/graph/onchain/exposure.spec.js +1 -0
- package/dist/graph/onchain/graph-policy.spec.d.ts +1 -0
- package/dist/graph/onchain/graph-policy.spec.js +1 -0
- package/dist/graph/onchain/index.d.ts +6 -0
- package/dist/graph/onchain/index.js +1 -1
- package/dist/graph/onchain/interest.js +1 -1
- package/dist/graph/onchain/interest.spec.js +1 -1
- package/dist/graph/onchain/names.js +1 -1
- package/dist/graph/onchain/names.spec.js +1 -1
- package/dist/graph/onchain/policy.d.ts +8 -0
- package/dist/graph/onchain/policy.js +1 -0
- package/dist/graph/onchain/proposal-graph.js +1 -1
- package/dist/graph/onchain/proposal-graph.spec.js +1 -1
- package/dist/graph/onchain/synthesis.d.ts +20 -0
- package/dist/graph/onchain/synthesis.js +1 -0
- package/dist/graph/onchain/synthesis.spec.d.ts +1 -0
- package/dist/graph/onchain/synthesis.spec.js +1 -0
- package/dist/graph/onchain/types.d.ts +11 -1
- package/dist/keeper/keeper.spec.js +1 -1
- package/dist/knowledge/alloc-audit-policy.spec.d.ts +1 -0
- package/dist/knowledge/alloc-audit-policy.spec.js +1 -0
- package/dist/knowledge/allocation-ledger.js +1 -1
- package/dist/knowledge/allocation-puzzle.d.ts +1 -1
- package/dist/knowledge/allocation-puzzle.js +1 -1
- package/dist/knowledge/allocation-risk.d.ts +4 -1
- package/dist/knowledge/allocation-risk.js +1 -1
- package/dist/knowledge/allocation-templates.js +1 -1
- package/dist/knowledge/arb-risk.d.ts +6 -5
- package/dist/knowledge/arb-risk.js +1 -1
- package/dist/knowledge/arbitration-ledger.d.ts +4 -4
- package/dist/knowledge/arbitration-ledger.js +1 -1
- package/dist/knowledge/arbitration-puzzle.d.ts +1 -1
- package/dist/knowledge/arbitration-puzzle.js +1 -1
- package/dist/knowledge/arbitration-risk.d.ts +4 -1
- package/dist/knowledge/arbitration-risk.js +1 -1
- package/dist/knowledge/arbitration-templates.js +1 -1
- package/dist/knowledge/baselines/judgment-baselines.json +289 -0
- package/dist/knowledge/baselines/risk-baselines.spec.js +1 -1
- package/dist/knowledge/baselines/rules/alloc_audit.json +290 -0
- package/dist/knowledge/baselines/rules/allocation.json +492 -0
- package/dist/knowledge/baselines/rules/arb.json +155 -0
- package/dist/knowledge/baselines/rules/arbitration.json +366 -0
- package/dist/knowledge/baselines/rules/bridge.json +197 -0
- package/dist/knowledge/baselines/rules/contact.json +152 -0
- package/dist/knowledge/baselines/rules/demand.json +158 -0
- package/dist/knowledge/baselines/rules/graph.json +453 -0
- package/dist/knowledge/baselines/rules/guard.json +981 -0
- package/dist/knowledge/baselines/rules/machine.json +706 -0
- package/dist/knowledge/baselines/rules/order.json +549 -0
- package/dist/knowledge/baselines/rules/payment.json +205 -0
- package/dist/knowledge/baselines/rules/permission.json +330 -0
- package/dist/knowledge/baselines/rules/personal.json +139 -0
- package/dist/knowledge/baselines/rules/progress.json +346 -0
- package/dist/knowledge/baselines/rules/proof.json +158 -0
- package/dist/knowledge/baselines/rules/registrar.json +159 -0
- package/dist/knowledge/baselines/rules/repository.json +244 -0
- package/dist/knowledge/baselines/rules/resource.json +117 -0
- package/dist/knowledge/baselines/rules/reward.json +471 -0
- package/dist/knowledge/baselines/rules/service.json +595 -0
- package/dist/knowledge/baselines/rules/treasury.json +440 -0
- package/dist/knowledge/baselines/rules/util.json +101 -0
- package/dist/knowledge/bridge-risk.d.ts +6 -5
- package/dist/knowledge/bridge-risk.js +1 -1
- package/dist/knowledge/builtin-templates.d.ts +26 -0
- package/dist/knowledge/builtin-templates.js +1 -0
- package/dist/knowledge/contact-risk.d.ts +6 -5
- package/dist/knowledge/contact-risk.js +1 -1
- package/dist/knowledge/demand-risk.d.ts +6 -5
- package/dist/knowledge/demand-risk.js +1 -1
- package/dist/knowledge/event-semantics.js +1 -1
- package/dist/knowledge/facts-sync.spec.d.ts +1 -0
- package/dist/knowledge/facts-sync.spec.js +1 -0
- package/dist/knowledge/getting-started.js +1 -1
- package/dist/knowledge/guard-design-patterns.js +1 -1
- package/dist/knowledge/guard-field-cognition.d.ts +1 -1
- package/dist/knowledge/guard-field-cognition.js +1 -1
- package/dist/knowledge/guard-ledger.js +1 -1
- package/dist/knowledge/guard-risk.d.ts +4 -1
- package/dist/knowledge/guard-risk.js +1 -1
- package/dist/knowledge/guard-templates.js +1 -1
- package/dist/knowledge/guard-translation.js +1 -1
- package/dist/knowledge/index.d.ts +10 -2
- package/dist/knowledge/index.js +1 -1
- package/dist/knowledge/industry-registry.js +1 -1
- package/dist/knowledge/industry-strategy.js +1 -1
- package/dist/knowledge/jsonrpc-enum.js +1 -1
- package/dist/knowledge/machine-ledger.js +1 -1
- package/dist/knowledge/machine-risk.d.ts +4 -1
- package/dist/knowledge/machine-risk.js +1 -1
- package/dist/knowledge/machine-templates.js +1 -1
- package/dist/knowledge/machine-translation.js +1 -1
- package/dist/knowledge/migration-preflight.js +1 -1
- package/dist/knowledge/operation-dictionary.js +1 -1
- package/dist/knowledge/order-ledger.js +1 -1
- package/dist/knowledge/order-puzzle.d.ts +3 -3
- package/dist/knowledge/order-puzzle.js +1 -1
- package/dist/knowledge/order-risk.d.ts +6 -3
- package/dist/knowledge/order-risk.js +1 -1
- package/dist/knowledge/order-templates.js +1 -1
- package/dist/knowledge/passport-ledger.js +1 -1
- package/dist/knowledge/passport-templates.js +1 -1
- package/dist/knowledge/payment-risk.d.ts +8 -6
- package/dist/knowledge/payment-risk.js +1 -1
- package/dist/knowledge/payment-tracker.js +1 -1
- package/dist/knowledge/permission-ledger.js +1 -1
- package/dist/knowledge/permission-puzzle.d.ts +12 -12
- package/dist/knowledge/permission-puzzle.js +1 -1
- package/dist/knowledge/permission-risk.d.ts +4 -7
- package/dist/knowledge/permission-risk.js +1 -1
- package/dist/knowledge/permission-templates.js +1 -1
- package/dist/knowledge/personal-risk.d.ts +6 -5
- package/dist/knowledge/personal-risk.js +1 -1
- package/dist/knowledge/progress-ledger.js +1 -1
- package/dist/knowledge/progress-puzzle.d.ts +2 -2
- package/dist/knowledge/progress-puzzle.js +1 -1
- package/dist/knowledge/progress-risk.d.ts +4 -1
- package/dist/knowledge/progress-risk.js +1 -1
- package/dist/knowledge/progress-templates.js +1 -1
- package/dist/knowledge/proof-risk.d.ts +6 -5
- package/dist/knowledge/proof-risk.js +1 -1
- package/dist/knowledge/puzzle-projections.js +1 -1
- package/dist/knowledge/recipient-constraint.d.ts +20 -1
- package/dist/knowledge/recipient-constraint.js +1 -1
- package/dist/knowledge/registrar-risk.d.ts +6 -5
- package/dist/knowledge/registrar-risk.js +1 -1
- package/dist/knowledge/repository-risk.d.ts +7 -6
- package/dist/knowledge/repository-risk.js +1 -1
- package/dist/knowledge/resource-risk.d.ts +6 -5
- package/dist/knowledge/resource-risk.js +1 -1
- package/dist/knowledge/reward-ledger.d.ts +1 -1
- package/dist/knowledge/reward-ledger.js +1 -1
- package/dist/knowledge/reward-puzzle.d.ts +2 -2
- package/dist/knowledge/reward-puzzle.js +1 -1
- package/dist/knowledge/reward-risk.d.ts +4 -1
- package/dist/knowledge/reward-risk.js +1 -1
- package/dist/knowledge/rule-node-analyzers.spec.js +1 -1
- package/dist/knowledge/rule-outcome.js +1 -1
- package/dist/knowledge/scenario-modes.d.ts +2 -2
- package/dist/knowledge/scenario-modes.js +1 -1
- package/dist/knowledge/scenario-topology.js +1 -1
- package/dist/knowledge/service-allocator-audit-node.js +1 -1
- package/dist/knowledge/service-ledger.js +1 -1
- package/dist/knowledge/service-puzzle.d.ts +2 -2
- package/dist/knowledge/service-puzzle.js +1 -1
- package/dist/knowledge/service-risk-node.js +1 -1
- package/dist/knowledge/service-risk.d.ts +4 -1
- package/dist/knowledge/service-risk.js +1 -1
- package/dist/knowledge/service-templates.js +1 -1
- package/dist/knowledge/strategy-manuals.d.ts +1 -1
- package/dist/knowledge/strategy-manuals.js +1 -1
- package/dist/knowledge/template-loader.d.ts +84 -0
- package/dist/knowledge/template-loader.js +1 -0
- package/dist/knowledge/template-loader.spec.d.ts +1 -0
- package/dist/knowledge/template-loader.spec.js +1 -0
- package/dist/knowledge/template-registry.js +1 -1
- package/dist/knowledge/template-scanner.d.ts +17 -0
- package/dist/knowledge/template-scanner.js +1 -0
- package/dist/knowledge/template-scanner.spec.d.ts +1 -0
- package/dist/knowledge/template-scanner.spec.js +1 -0
- package/dist/knowledge/tools-reference.js +1 -1
- package/dist/knowledge/treasury-ledger.d.ts +1 -1
- package/dist/knowledge/treasury-ledger.js +1 -1
- package/dist/knowledge/treasury-puzzle.d.ts +3 -3
- package/dist/knowledge/treasury-puzzle.js +1 -1
- package/dist/knowledge/treasury-risk.d.ts +4 -1
- package/dist/knowledge/treasury-risk.js +1 -1
- package/dist/knowledge/treasury-templates.js +1 -1
- package/dist/knowledge/util-risk.d.ts +6 -5
- package/dist/knowledge/util-risk.js +1 -1
- package/dist/knowledge/workflow-guidance.d.ts +4 -0
- package/dist/knowledge/workflow-guidance.js +1 -1
- package/dist/knowledge/workspace-lists.js +1 -1
- package/dist/monitor/MonitorLoop.js +1 -1
- package/dist/participation/arbitrator-interest.js +1 -1
- package/dist/participation/radar-core.js +1 -1
- package/dist/persona/analyzer.js +1 -1
- package/dist/persona/index.js +1 -1
- package/dist/persona/model.js +1 -1
- package/dist/persona/persona-audit.spec.d.ts +1 -0
- package/dist/persona/persona-audit.spec.js +1 -0
- package/dist/persona/types.d.ts +2 -0
- package/dist/playbooks/service-build/business-puzzle.js +1 -1
- package/dist/playbooks/service-build/facet-money.d.ts +11 -0
- package/dist/playbooks/service-build/facet-money.js +1 -1
- package/dist/playbooks/service-build/machine-panorama.d.ts +17 -0
- package/dist/playbooks/service-build/machine-panorama.js +1 -1
- package/dist/playbooks/service-build/merchant-guide.d.ts +2 -2
- package/dist/playbooks/service-build/migration-planner.d.ts +43 -0
- package/dist/playbooks/service-build/migration-planner.js +1 -0
- package/dist/playbooks/service-build/object-panorama.d.ts +42 -1
- package/dist/playbooks/service-build/object-panorama.js +1 -1
- package/dist/playbooks/service-build/participation-radar.js +1 -1
- package/dist/playbooks/service-build/pipeline-actions.d.ts +1 -1
- package/dist/playbooks/service-build/reverse-mapping.d.ts +1 -0
- package/dist/playbooks/service-build/reverse-mapping.js +1 -1
- package/dist/playbooks/service-build/risk-aggregator.d.ts +2 -1
- package/dist/playbooks/service-build/risk-aggregator.js +1 -1
- package/dist/playbooks/service-build/semantic-graph.js +1 -1
- package/dist/playbooks/service-build/service-panorama.d.ts +53 -1
- package/dist/playbooks/service-build/service-panorama.js +1 -1
- package/dist/playbooks/service-build/topology-evaluation.spec.js +1 -1
- package/dist/playbooks/service-build/topology-query.js +1 -1
- package/dist/playbooks/service-build/workflow-design-assessment.d.ts +2 -2
- package/dist/playbooks/service-build/workflow-design-assessment.js +1 -1
- package/dist/relationship/registry.js +1 -1
- package/dist/review/machine.js +1 -1
- package/dist/review/order.js +1 -1
- package/dist/review/service.js +1 -1
- package/dist/review/types.d.ts +7 -0
- package/dist/safety/confirm-gate.js +1 -1
- package/dist/schema/benchmark-migration/index.d.ts +207 -0
- package/dist/schema/benchmark-migration/index.js +1 -0
- package/dist/schema/call/allocation.d.ts +1 -1
- package/dist/schema/call/allocation.js +1 -1
- package/dist/schema/call/arbitration.d.ts +1 -1
- package/dist/schema/call/arbitration.js +1 -1
- package/dist/schema/call/base.d.ts +5 -5
- package/dist/schema/call/base.js +1 -1
- package/dist/schema/call/contact.d.ts +1 -1
- package/dist/schema/call/demand.d.ts +1 -1
- package/dist/schema/call/guard.d.ts +3 -3
- package/dist/schema/call/machine.d.ts +5 -5
- package/dist/schema/call/order.d.ts +3 -3
- package/dist/schema/call/payment.js +1 -1
- package/dist/schema/call/permission-handler.d.ts +1 -1
- package/dist/schema/call/permission-handler.js +1 -1
- package/dist/schema/call/permission.d.ts +16 -16
- package/dist/schema/call/permission.js +1 -1
- package/dist/schema/call/personal.d.ts +8 -8
- package/dist/schema/call/personal.js +1 -1
- package/dist/schema/call/progress.d.ts +3 -3
- package/dist/schema/call/repository.d.ts +11 -11
- package/dist/schema/call/repository.js +1 -1
- package/dist/schema/call/reward.d.ts +1 -1
- package/dist/schema/call/semantic.js +1 -1
- package/dist/schema/call/service.d.ts +7 -7
- package/dist/schema/call/service.js +1 -1
- package/dist/schema/call/treasury.d.ts +1 -1
- package/dist/schema/common/index.d.ts +6 -6
- package/dist/schema/common/index.js +1 -1
- package/dist/schema/config/index.d.ts +50 -1
- package/dist/schema/config/index.js +1 -1
- package/dist/schema/evaluation/index.d.ts +27 -11
- package/dist/schema/evaluation/index.js +1 -1
- package/dist/schema/goal/index.d.ts +5 -5
- package/dist/schema/goal/planning.d.ts +15 -15
- package/dist/schema/goal/planning.js +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -1
- package/dist/schema/interaction/index.d.ts +1 -1
- package/dist/schema/local/index.js +1 -1
- package/dist/schema/messenger/index.d.ts +26 -26
- package/dist/schema/operations.d.ts +33 -33
- package/dist/schema/operations.js +1 -1
- package/dist/schema/persona/index.d.ts +4708 -0
- package/dist/schema/persona/index.js +1 -1
- package/dist/schema/query/bi.d.ts +232 -25
- package/dist/schema/query/bi.js +1 -1
- package/dist/schema/query/index.d.ts +35 -35
- package/dist/schema/query/index.js +1 -1
- package/dist/schema/schema-version.js +1 -1
- package/dist/schema/workflow/index.d.ts +1 -1
- package/dist/schema-query-impl/index.d.ts +9 -0
- package/dist/schema-query-impl/index.js +1 -1
- package/dist/schemas/benchmark_migration_operation.output.json +793 -0
- package/dist/schemas/benchmark_migration_operation.schema.json +83 -0
- package/dist/schemas/bridge_operation.schema.json +5 -5
- package/dist/schemas/config_operation.output.json +252 -0
- package/dist/schemas/config_operation.schema.json +21 -1
- package/dist/schemas/evaluation_operation.output.json +22 -10
- package/dist/schemas/goal_operation.schema.json +8 -8
- package/dist/schemas/guard2file.schema.json +1 -1
- package/dist/schemas/index.json +7 -1
- package/dist/schemas/machineNode2file.schema.json +1 -1
- package/dist/schemas/messenger_operation.schema.json +24 -12
- package/dist/schemas/onchain_events.output.json +1 -1
- package/dist/schemas/onchain_operations.output.json +4 -2
- package/dist/schemas/onchain_operations.schema.json +189 -139
- package/dist/schemas/onchain_operations_allocation.schema.json +13 -11
- package/dist/schemas/onchain_operations_arbitration.schema.json +10 -8
- package/dist/schemas/onchain_operations_contact.schema.json +7 -5
- package/dist/schemas/onchain_operations_demand.schema.json +7 -5
- package/dist/schemas/onchain_operations_gen_passport.schema.json +5 -3
- package/dist/schemas/onchain_operations_gen_proof.schema.json +1 -1
- package/dist/schemas/onchain_operations_guard.schema.json +5 -3
- package/dist/schemas/onchain_operations_machine.schema.json +22 -18
- package/dist/schemas/onchain_operations_order.schema.json +11 -7
- package/dist/schemas/onchain_operations_payment.schema.json +3 -3
- package/dist/schemas/onchain_operations_permission.schema.json +19 -11
- package/dist/schemas/onchain_operations_personal.schema.json +16 -10
- package/dist/schemas/onchain_operations_progress.schema.json +11 -7
- package/dist/schemas/onchain_operations_proof.schema.json +5 -3
- package/dist/schemas/onchain_operations_repository.schema.json +12 -8
- package/dist/schemas/onchain_operations_reward.schema.json +11 -9
- package/dist/schemas/onchain_operations_service.schema.json +28 -22
- package/dist/schemas/onchain_operations_treasury.schema.json +11 -9
- package/dist/schemas/onchain_table_data.output.json +27 -17
- package/dist/schemas/persona_operation.output.json +15875 -1
- package/dist/schemas/persona_operation.schema.json +3056 -478
- package/dist/schemas/query_toolkit.output.json +343 -63
- package/dist/schemas/query_toolkit.schema.json +1 -1
- package/dist/schemas/workflow_operation.schema.json +4 -2
- package/dist/strategy/scorecard.js +1 -1
- package/dist/tools/handlers/benchmark-migration.d.ts +2 -0
- package/dist/tools/handlers/benchmark-migration.js +1 -0
- package/dist/tools/handlers/config.js +1 -1
- package/dist/tools/handlers/industry-pack.js +1 -1
- package/dist/tools/handlers/onchain.js +1 -1
- package/dist/tools/handlers/query.js +1 -1
- package/dist/tools/handlers/schema-query.js +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/move-fn-index.gen.d.ts +3 -0
- package/dist/tools/move-fn-index.gen.js +1 -0
- package/dist/tools/registry/business.js +1 -1
- package/dist/tools/registry/config.js +1 -1
- package/dist/tools/registry/evaluation.js +1 -1
- package/dist/tools/registry/onchain.js +1 -1
- package/dist/tools/sanitize-output.d.ts +3 -0
- package/dist/tools/sanitize-output.js +1 -0
- package/dist/tools/sanitize-output.spec.d.ts +1 -0
- package/dist/tools/sanitize-output.spec.js +1 -0
- package/package.json +9 -4
- package/dist/knowledge/baselines/evaluation-baselines.json +0 -79
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comment": "Treasury rule pack (R-T) — declarative form of the retired in-code Treasury risk rules. Facts are produced by the kernel extractor (treasury-risk.ts, bound to the treasury-puzzle chain limits); rules only reference fact names. Levels/wording can be retuned per rule and rules can be disabled (enabled=false, trace left) via the judgment document — factory rules can never be deleted or invented here.",
|
|
3
|
+
"facts": {
|
|
4
|
+
"description_length": "Length of the requested Treasury description (undefined when the context carries none).",
|
|
5
|
+
"max_description_length": "KERNEL CONSTANT — description cap (MAX_DESCRIPTION_LENGTH from treasury-puzzle).",
|
|
6
|
+
"description_over_limit": "description_length exceeds MAX_DESCRIPTION_LENGTH (chain-limit comparison sunk into the extractor).",
|
|
7
|
+
"external_deposit_guard_adding": "Number of guards added by an external_deposit_guard 'add' op (undefined for other ops).",
|
|
8
|
+
"external_deposit_guard_current": "Existing external_deposit_guard count at 'add' time (0 when the context carries none).",
|
|
9
|
+
"max_external_deposit_guard_count": "KERNEL CONSTANT — external deposit guard cap (MAX_EXTERNAL_DEPOSIT_GUARD_COUNT).",
|
|
10
|
+
"external_deposit_guard_over_limit": "An 'add' op would push the external_deposit_guard list over MAX_EXTERNAL_DEPOSIT_GUARD_COUNT.",
|
|
11
|
+
"external_withdraw_guard_adding": "Number of guards added by an external_withdraw_guard 'add' op (undefined for other ops).",
|
|
12
|
+
"external_withdraw_guard_current": "Existing external_withdraw_guard count at 'add' time (0 when the context carries none).",
|
|
13
|
+
"max_external_withdraw_guard_count": "KERNEL CONSTANT — external withdraw guard cap (MAX_EXTERNAL_WITHDRAW_GUARD_COUNT).",
|
|
14
|
+
"external_withdraw_guard_over_limit": "An 'add' op would push the external_withdraw_guard list over MAX_EXTERNAL_WITHDRAW_GUARD_COUNT.",
|
|
15
|
+
"external_withdraw_missing_identifier_guard": "First mounted (add/set) external_withdraw_guard entry whose required u8 identifier is absent (undefined when all entries carry one).",
|
|
16
|
+
"deposit_external_guard_name": "Requested external_deposit guard name (by_external_deposit_guard), only when the external deposit path is taken.",
|
|
17
|
+
"deposit_guard_list_empty": "External deposit requested while the Treasury's external_deposit_guard list is empty (count 0) — E_EXTERNAL_DEPOSIT_GUARD_NOT_FOUND ahead.",
|
|
18
|
+
"withdraw_external_guard_name": "Requested external_withdraw guard name (amount_by_external_withdraw_guard), only when the external withdraw path is taken.",
|
|
19
|
+
"withdraw_guard_list_empty": "External withdraw requested while the Treasury's external_withdraw_guard list is empty (count 0) — E_EXTERNAL_WITHDRAW_GUARD_NOT_FOUND ahead.",
|
|
20
|
+
"deposit_external_and_perm_252": "External deposit path requested while Permission index TREASURY_DEPOSIT (252) is also granted (mixed access paths).",
|
|
21
|
+
"external_deposit_split_refund": "External deposit with a coin value attached — values above the guard-specified amount are split and refunded.",
|
|
22
|
+
"external_deposit_coin_balance": "Coin balance attached to the external deposit (only when both the external path and a balance are present).",
|
|
23
|
+
"withdraw_via_guard_present": "The external withdraw path (amount_by_external_withdraw_guard) is requested.",
|
|
24
|
+
"external_withdraw_sender": "Transaction sender address, when resolvable at analysis time.",
|
|
25
|
+
"external_withdraw_sender_known": "The transaction sender is known (truthy) for this analysis.",
|
|
26
|
+
"external_withdraw_recipient": "Requested external_withdraw recipient (undefined when unset).",
|
|
27
|
+
"external_withdraw_recipient_unset": "Rendered external_withdraw recipient — '(unset)' when the context carries none (description display form).",
|
|
28
|
+
"withdraw_recipient_unknown": "Rendered withdraw recipient — '?' when the context carries none (evidence display form).",
|
|
29
|
+
"withdraw_recipient_word": "Rendered withdraw recipient — 'recipient' when the context carries none (description display form).",
|
|
30
|
+
"external_withdraw_recipient_mismatch": "Sender is known and the recipient is not the sender (case-insensitive compare) — guaranteed on-chain abort (treasury code 10).",
|
|
31
|
+
"external_withdraw_advisory": "External withdraw requested while the sender is not resolvable — advisory invariant reminder.",
|
|
32
|
+
"withdraw_amount_fixed": "Fixed (permissioned) withdraw amount requested.",
|
|
33
|
+
"perm_252_and_254": "Both TREASURY_DEPOSIT (252) and TREASURY_WITHDRAW (254) are granted — separation-of-duties review.",
|
|
34
|
+
"perm_has_255": "TREASURY_EXTERNAL_DEPOSIT_GUARD (255) is granted.",
|
|
35
|
+
"perm_has_256": "TREASURY_EXTERNAL_WITHDRAW_GUARD (256) is granted.",
|
|
36
|
+
"um_present": "The UM field is set in the context (set or revoked — not absent).",
|
|
37
|
+
"um_is_null": "The UM field is explicitly null (revocation).",
|
|
38
|
+
"um_value": "The UM value being set (undefined on revocation/absence).",
|
|
39
|
+
"external_withdraw_guard_mounted": "An external_withdraw_guard add/set op mounts release Guards (the Guard becomes a real fund gate).",
|
|
40
|
+
"external_deposit_guard_mounted": "An external_deposit_guard add/set op mounts deposit Guards.",
|
|
41
|
+
"withdraw_mount_guards": "Comma-space-joined guard addresses of the mounted external_withdraw_guard list.",
|
|
42
|
+
"deposit_mount_guards": "Comma-space-joined guard addresses of the mounted external_deposit_guard list.",
|
|
43
|
+
"shared_with_service": "The Treasury is shared with a Service via a common Permission object.",
|
|
44
|
+
"shared_allocator_display": "Rendered shared_with_allocator flag ('true'/'false'/'undefined') for evidence display.",
|
|
45
|
+
"shared_arbitration_display": "Rendered shared_with_arbitration flag ('true'/'false'/'undefined') for evidence display.",
|
|
46
|
+
"treasury_receive_253_missing": "Treasury is referenced by Allocator/Arbitration but no entity holds TREASURY_RECEIVE (253).",
|
|
47
|
+
"stale_treasury_indexes": "Granted permission indexes in the stale 259/260 range (R-T-01 regression scan; undefined when no index list is present).",
|
|
48
|
+
"stale_treasury_indexes_csv_sp": "Stale indexes joined with ', ' (description display form).",
|
|
49
|
+
"stale_treasury_indexes_csv": "Stale indexes joined with ',' (evidence display form)."
|
|
50
|
+
},
|
|
51
|
+
"rules": [
|
|
52
|
+
{
|
|
53
|
+
"rule_id": "R-T-1-01",
|
|
54
|
+
"dimension": "structural",
|
|
55
|
+
"trigger": "Description length exceeds MAX_DESCRIPTION_LENGTH (4000)",
|
|
56
|
+
"cases": [
|
|
57
|
+
{
|
|
58
|
+
"when": { "field": "description_over_limit", "op": "eq", "value": true },
|
|
59
|
+
"level": "high",
|
|
60
|
+
"title": "Description length exceeds limit",
|
|
61
|
+
"description": "Description length ${description_length} exceeds MAX_DESCRIPTION_LENGTH ${max_description_length}",
|
|
62
|
+
"scenario": "Setting a description longer than 4000 characters",
|
|
63
|
+
"mitigation": "Truncate description to fit within 4000 characters",
|
|
64
|
+
"evidence": "length=${description_length}",
|
|
65
|
+
"stakeholders": ["owner", "admin"]
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"rule_id": "R-T-1-02",
|
|
71
|
+
"dimension": "structural",
|
|
72
|
+
"trigger": "external_deposit_guard count exceeds MAX_EXTERNAL_DEPOSIT_GUARD_COUNT (100)",
|
|
73
|
+
"cases": [
|
|
74
|
+
{
|
|
75
|
+
"when": { "field": "external_deposit_guard_over_limit", "op": "eq", "value": true },
|
|
76
|
+
"level": "high",
|
|
77
|
+
"title": "external_deposit_guard count exceeds limit",
|
|
78
|
+
"description": "Adding ${external_deposit_guard_adding} guards to existing ${external_deposit_guard_current} would exceed MAX_EXTERNAL_DEPOSIT_GUARD_COUNT ${max_external_deposit_guard_count}",
|
|
79
|
+
"scenario": "Adding too many external deposit guards",
|
|
80
|
+
"mitigation": "Remove unused guards before adding new ones, or use 'set' to replace the list",
|
|
81
|
+
"evidence": "current=${external_deposit_guard_current}, adding=${external_deposit_guard_adding}, limit=${max_external_deposit_guard_count}",
|
|
82
|
+
"stakeholders": ["owner"]
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"rule_id": "R-T-1-03",
|
|
88
|
+
"dimension": "structural",
|
|
89
|
+
"trigger": "external_withdraw_guard count exceeds MAX_EXTERNAL_WITHDRAW_GUARD_COUNT (200)",
|
|
90
|
+
"cases": [
|
|
91
|
+
{
|
|
92
|
+
"when": { "field": "external_withdraw_guard_over_limit", "op": "eq", "value": true },
|
|
93
|
+
"level": "high",
|
|
94
|
+
"title": "external_withdraw_guard count exceeds limit",
|
|
95
|
+
"description": "Adding ${external_withdraw_guard_adding} guards to existing ${external_withdraw_guard_current} would exceed MAX_EXTERNAL_WITHDRAW_GUARD_COUNT ${max_external_withdraw_guard_count}",
|
|
96
|
+
"scenario": "Adding too many external withdraw guards",
|
|
97
|
+
"mitigation": "Remove unused guards before adding new ones, or use 'set' to replace the list",
|
|
98
|
+
"evidence": "current=${external_withdraw_guard_current}, adding=${external_withdraw_guard_adding}, limit=${max_external_withdraw_guard_count}",
|
|
99
|
+
"stakeholders": ["owner"]
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"rule_id": "R-T-1-04",
|
|
105
|
+
"dimension": "structural",
|
|
106
|
+
"trigger": "external_withdraw_guard.identifier is missing (required u8, not Option)",
|
|
107
|
+
"cases": [
|
|
108
|
+
{
|
|
109
|
+
"when": { "field": "external_withdraw_missing_identifier_guard", "op": "present" },
|
|
110
|
+
"level": "high",
|
|
111
|
+
"title": "external_withdraw_guard.identifier missing",
|
|
112
|
+
"description": "Guard ${external_withdraw_missing_identifier_guard} missing required identifier. AmountFromWithdrawGuard.identifier is u8 (not Option<u8>); withdraw amount must come from Guard table.",
|
|
113
|
+
"scenario": "Configuring external withdraw guard without amount source",
|
|
114
|
+
"mitigation": "Set identifier to the Guard table index that provides the withdraw amount (must be a number-type field)",
|
|
115
|
+
"evidence": "guard=${external_withdraw_missing_identifier_guard}, identifier=undefined",
|
|
116
|
+
"stakeholders": ["owner", "external_operator"]
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"rule_id": "R-T-2-01",
|
|
122
|
+
"dimension": "semantic",
|
|
123
|
+
"trigger": "External operation (deposit/withdraw) requested without corresponding guard configured",
|
|
124
|
+
"cases": [
|
|
125
|
+
{
|
|
126
|
+
"when": { "field": "deposit_guard_list_empty", "op": "eq", "value": true },
|
|
127
|
+
"level": "medium",
|
|
128
|
+
"title": "External deposit guard list is empty",
|
|
129
|
+
"description": "Requesting external_deposit via guard ${deposit_external_guard_name}, but Treasury has no external_deposit_guard configured. Operation will abort with E_EXTERNAL_DEPOSIT_GUARD_NOT_FOUND.",
|
|
130
|
+
"scenario": "External deposit attempted before guard_add",
|
|
131
|
+
"mitigation": "Register an external-deposit guard first (Permission index 255) for guard ${deposit_external_guard_name}",
|
|
132
|
+
"evidence": "guard=${deposit_external_guard_name}, current_count=0",
|
|
133
|
+
"stakeholders": ["external_operator", "owner"]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"when": { "field": "withdraw_guard_list_empty", "op": "eq", "value": true },
|
|
137
|
+
"level": "medium",
|
|
138
|
+
"title": "External withdraw guard list is empty",
|
|
139
|
+
"description": "Requesting external_withdraw via guard ${withdraw_external_guard_name}, but Treasury has no external_withdraw_guard configured. Operation will abort with E_EXTERNAL_WITHDRAW_GUARD_NOT_FOUND.",
|
|
140
|
+
"scenario": "External withdraw attempted before guard_add",
|
|
141
|
+
"mitigation": "Register an external-withdraw guard first (Permission index 256) for guard ${withdraw_external_guard_name}",
|
|
142
|
+
"evidence": "guard=${withdraw_external_guard_name}, current_count=0",
|
|
143
|
+
"stakeholders": ["external_operator", "owner"]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"rule_id": "R-T-2-02",
|
|
149
|
+
"dimension": "semantic",
|
|
150
|
+
"trigger": "External operation paired with Permission path (confused access control)",
|
|
151
|
+
"cases": [
|
|
152
|
+
{
|
|
153
|
+
"when": { "field": "deposit_external_and_perm_252", "op": "eq", "value": true },
|
|
154
|
+
"level": "low",
|
|
155
|
+
"title": "Both Permission deposit and external deposit guard configured",
|
|
156
|
+
"description": "Treasury has both TREASURY_DEPOSIT (252) granted and external_deposit_guard configured. While not an error, mixing access paths complicates audit.",
|
|
157
|
+
"scenario": "Hybrid internal+external deposit setup",
|
|
158
|
+
"mitigation": "Document which path each depositor should use; consider splitting into separate Treasury objects for clarity",
|
|
159
|
+
"evidence": "has_perm_252=true, has_external_deposit_guard=true",
|
|
160
|
+
"stakeholders": ["owner", "admin"]
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"rule_id": "R-T-2-03",
|
|
166
|
+
"dimension": "semantic",
|
|
167
|
+
"trigger": "external_deposit amount exceeds guard-specified value (split-and-refund path)",
|
|
168
|
+
"cases": [
|
|
169
|
+
{
|
|
170
|
+
"when": { "field": "external_deposit_split_refund", "op": "eq", "value": true },
|
|
171
|
+
"level": "low",
|
|
172
|
+
"title": "External deposit may trigger split-and-refund",
|
|
173
|
+
"description": "If coin value (${external_deposit_coin_balance}) exceeds guard-specified amount, the excess will be split and refunded to sender. Verify intent.",
|
|
174
|
+
"scenario": "External deposit with coin value > guard limit",
|
|
175
|
+
"mitigation": "Pre-split the coin to exact guard-specified amount, or accept the refund behavior",
|
|
176
|
+
"evidence": "coin_balance=${external_deposit_coin_balance}",
|
|
177
|
+
"stakeholders": ["external_operator"]
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"rule_id": "R-T-2-04",
|
|
183
|
+
"dimension": "semantic",
|
|
184
|
+
"trigger": "external_withdraw destination is not the transaction sender — guaranteed on-chain abort (treasury code 10) when the sender is known; advisory otherwise",
|
|
185
|
+
"cases": [
|
|
186
|
+
{
|
|
187
|
+
"when": { "field": "external_withdraw_recipient_mismatch", "op": "eq", "value": true },
|
|
188
|
+
"level": "high",
|
|
189
|
+
"title": "external_withdraw recipient is not the sender",
|
|
190
|
+
"description": "external_withdraw pays only the transaction sender (the guard authorizes release but no predicate can constrain the destination). Recipient ${external_withdraw_recipient_unset} != sender ${external_withdraw_sender}; the call will abort with EEXTERNAL_RECIPIENT_NOT_SIGNER (treasury code 10).",
|
|
191
|
+
"scenario": "Guard-driven withdraw to an address other than the signer",
|
|
192
|
+
"mitigation": "Set recipient to the sender address, or use the permissioned withdraw (amount.fixed, index 254) to pay another address.",
|
|
193
|
+
"evidence": "guard=${withdraw_external_guard_name}, recipient=${withdraw_recipient_unknown}, sender=${external_withdraw_sender}",
|
|
194
|
+
"stakeholders": ["owner", "external_operator"]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"when": { "field": "external_withdraw_advisory", "op": "eq", "value": true },
|
|
198
|
+
"level": "medium",
|
|
199
|
+
"title": "external_withdraw pays only the transaction sender",
|
|
200
|
+
"description": "external_withdraw via guard ${withdraw_external_guard_name} releases funds only to the transaction sender (Move truth, code 10). The sender is not known in this analysis, so verify recipient == sender before executing.",
|
|
201
|
+
"scenario": "Guard-driven withdraw planned before the signer is resolved",
|
|
202
|
+
"mitigation": "Ensure recipient equals the sender, or use the permissioned withdraw (amount.fixed) for a different destination.",
|
|
203
|
+
"evidence": "guard=${withdraw_external_guard_name}, recipient=${withdraw_recipient_unknown}",
|
|
204
|
+
"stakeholders": ["owner", "external_operator"]
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"rule_id": "R-T-3-01",
|
|
210
|
+
"dimension": "authority",
|
|
211
|
+
"trigger": "Same address holds both TREASURY_DEPOSIT (252) and TREASURY_WITHDRAW (254)",
|
|
212
|
+
"cases": [
|
|
213
|
+
{
|
|
214
|
+
"when": { "field": "perm_252_and_254", "op": "eq", "value": true },
|
|
215
|
+
"level": "medium",
|
|
216
|
+
"title": "Deposit and withdraw permissions both present (review separation)",
|
|
217
|
+
"description": "Both TREASURY_DEPOSIT (252) and TREASURY_WITHDRAW (254) are granted. Verify they are assigned to different entities to enforce separation of duties.",
|
|
218
|
+
"scenario": "Single role can both add and remove funds",
|
|
219
|
+
"mitigation": "Assign 252 to depositor role, 254 to withdrawer role; use separate Permission objects if needed",
|
|
220
|
+
"evidence": "has_252=true, has_254=true",
|
|
221
|
+
"stakeholders": ["owner", "depositor", "withdrawer"]
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"rule_id": "R-T-3-02",
|
|
227
|
+
"dimension": "authority",
|
|
228
|
+
"trigger": "TREASURY_EXTERNAL_DEPOSIT_GUARD (255) granted to non-owner (admin-level risk)",
|
|
229
|
+
"cases": [
|
|
230
|
+
{
|
|
231
|
+
"when": { "field": "perm_has_255", "op": "eq", "value": true },
|
|
232
|
+
"level": "medium",
|
|
233
|
+
"title": "External deposit guard management permission granted",
|
|
234
|
+
"description": "TREASURY_EXTERNAL_DEPOSIT_GUARD (255) is granted. Managing external_deposit_guard list controls who can externally deposit. Verify assignment scope.",
|
|
235
|
+
"scenario": "Guard management delegated to operator",
|
|
236
|
+
"mitigation": "Restrict 255 to owner/admin only; guard list changes affect external access policy",
|
|
237
|
+
"evidence": "has_perm_255=true",
|
|
238
|
+
"stakeholders": ["owner", "admin"]
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"rule_id": "R-T-3-03",
|
|
244
|
+
"dimension": "authority",
|
|
245
|
+
"trigger": "TREASURY_EXTERNAL_WITHDRAW_GUARD (256) granted — high-impact permission",
|
|
246
|
+
"cases": [
|
|
247
|
+
{
|
|
248
|
+
"when": { "field": "perm_has_256", "op": "eq", "value": true },
|
|
249
|
+
"level": "high",
|
|
250
|
+
"title": "External withdraw guard management permission granted",
|
|
251
|
+
"description": "TREASURY_EXTERNAL_WITHDRAW_GUARD (256) is granted. Managing external_withdraw_guard list controls who can externally withdraw (irreversible). Tightly restrict.",
|
|
252
|
+
"scenario": "External withdraw guard management delegated",
|
|
253
|
+
"mitigation": "Restrict 256 to owner only; consider multi-sig for production Treasury",
|
|
254
|
+
"evidence": "has_perm_256=true",
|
|
255
|
+
"stakeholders": ["owner", "withdrawer"],
|
|
256
|
+
"exposure": {
|
|
257
|
+
"loss_parties": [
|
|
258
|
+
{ "role": "merchant", "basis": "The Treasury balance is exposed to permission-free external_withdraw release: whoever holds 256 can remount the release Guards, opening the gate to addresses they control." }
|
|
259
|
+
],
|
|
260
|
+
"gain_paths": [
|
|
261
|
+
{
|
|
262
|
+
"role": "collaborator",
|
|
263
|
+
"path": "A non-owner 256 holder replaces the external_withdraw_guard list with a permissive Guard, then pulls funds via external_withdraw from any address that satisfies it — the release pays the transaction sender directly.",
|
|
264
|
+
"viability": "viable",
|
|
265
|
+
"gate": "Holding 256 implies guard-list write power ('set' replaces the whole list) and the withdraw itself involves no Treasury Permission; verify the holder's address set and guard-list history to confirm the abuse path."
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"rule_id": "R-T-4-01",
|
|
274
|
+
"dimension": "lifecycle",
|
|
275
|
+
"trigger": "Internal withdraw (fixed amount) — irreversible fund operation",
|
|
276
|
+
"cases": [
|
|
277
|
+
{
|
|
278
|
+
"when": { "field": "withdraw_amount_fixed", "op": "truthy" },
|
|
279
|
+
"level": "critical",
|
|
280
|
+
"title": "Internal withdraw is irreversible",
|
|
281
|
+
"description": "Fixed withdraw of ${withdraw_amount_fixed} to ${withdraw_recipient_word}. Once executed, funds cannot be recovered without recipient cooperation.",
|
|
282
|
+
"scenario": "Permission-authorized withdraw (254)",
|
|
283
|
+
"mitigation": "1) Verify recipient address twice. 2) Confirm amount. 3) Check balance sufficiency. 4) Record Payment object for audit.",
|
|
284
|
+
"evidence": "amount=${withdraw_amount_fixed}, recipient=${withdraw_recipient_unknown}",
|
|
285
|
+
"stakeholders": ["owner", "withdrawer"]
|
|
286
|
+
}
|
|
287
|
+
]
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"rule_id": "R-T-4-02",
|
|
291
|
+
"dimension": "lifecycle",
|
|
292
|
+
"trigger": "External withdraw (via guard) — irreversible fund operation",
|
|
293
|
+
"cases": [
|
|
294
|
+
{
|
|
295
|
+
"when": { "field": "withdraw_via_guard_present", "op": "eq", "value": true },
|
|
296
|
+
"level": "critical",
|
|
297
|
+
"title": "External withdraw is irreversible",
|
|
298
|
+
"description": "External withdraw via guard ${withdraw_external_guard_name} to ${withdraw_recipient_word}. Amount is determined by the Guard table identifier; the guard only authorizes release and cannot constrain the destination. Move truth: external_withdraw pays only the transaction sender (abort code 10); paying another address requires the permissioned withdraw (amount.fixed, index 254).",
|
|
299
|
+
"scenario": "Guard-authorized external withdraw",
|
|
300
|
+
"mitigation": "1) Verify Guard rules match business intent. 2) Ensure recipient == transaction sender (or switch to the permissioned fixed withdraw to pay someone else). 3) Ensure the Guard identifier points to the correct amount field. 4) Test on testnet first.",
|
|
301
|
+
"evidence": "guard=${withdraw_external_guard_name}, recipient=${withdraw_recipient_unknown}",
|
|
302
|
+
"stakeholders": ["owner", "external_operator", "withdrawer"]
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"rule_id": "R-T-4-03",
|
|
308
|
+
"dimension": "lifecycle",
|
|
309
|
+
"trigger": "UM set or revoked — object-linker core binding change",
|
|
310
|
+
"cases": [
|
|
311
|
+
{
|
|
312
|
+
"when": { "all": [
|
|
313
|
+
{ "field": "um_present", "op": "eq", "value": true },
|
|
314
|
+
{ "field": "um_is_null", "op": "eq", "value": true }
|
|
315
|
+
] },
|
|
316
|
+
"level": "low",
|
|
317
|
+
"title": "UM revocation",
|
|
318
|
+
"description": "Revoking UM disaffiliates the Contact from Treasury via the object-linker unbinding. Existing contact bindings become orphaned.",
|
|
319
|
+
"scenario": "Owner revokes UM (sets it to none)",
|
|
320
|
+
"mitigation": "Verify no active business process depends on UM before revoking",
|
|
321
|
+
"evidence": "um=null",
|
|
322
|
+
"stakeholders": ["owner"]
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"when": { "all": [
|
|
326
|
+
{ "field": "um_present", "op": "eq", "value": true },
|
|
327
|
+
{ "field": "um_is_null", "op": "eq", "value": false }
|
|
328
|
+
] },
|
|
329
|
+
"level": "low",
|
|
330
|
+
"title": "UM delegation",
|
|
331
|
+
"description": "Setting UM to ${um_value}. UM (Contact object) gains binding with Treasury via the object-linker affiliation binding.",
|
|
332
|
+
"scenario": "Owner delegates UM (sets it to a Contact)",
|
|
333
|
+
"mitigation": "Verify UM address is a valid Contact object (not a user wallet)",
|
|
334
|
+
"evidence": "um=${um_value}",
|
|
335
|
+
"stakeholders": ["owner"]
|
|
336
|
+
}
|
|
337
|
+
]
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
"rule_id": "R-T-4-04",
|
|
341
|
+
"dimension": "lifecycle",
|
|
342
|
+
"trigger": "Mounting an external deposit/withdraw Guard (add/set) — the Guard becomes a real fund gate; owner due diligence before it goes live",
|
|
343
|
+
"cases": [
|
|
344
|
+
{
|
|
345
|
+
"when": { "field": "external_withdraw_guard_mounted", "op": "eq", "value": true },
|
|
346
|
+
"level": "medium",
|
|
347
|
+
"title": "Mounting external withdraw Guards — verify the release gate before going live",
|
|
348
|
+
"description": "Each mounted Guard (${withdraw_mount_guards}) becomes a permission-free release gate on external_withdraw: any external party whose transaction makes the Guard predicate pass can trigger fund release, with no Treasury Permission involved. The withdraw amount is read from the Guard table at the identifier slot — verify the Guard predicate constrains that slot. Move truth: the destination is forced to the transaction sender (abort code 10 on mismatch), so this gate cannot pay a third party; paying staff or another address must use the permissioned withdraw (amount.fixed, index 254).",
|
|
349
|
+
"scenario": "Owner mounts external withdraw Guards during Treasury configuration",
|
|
350
|
+
"mitigation": "1) Review the full Guard definition (root and table) and confirm the predicate matches the intended release policy. 2) Confirm every mounted entry has the correct identifier for the amount slot. 3) Regress on testnet: a recipient other than the sender must abort with code 10; a sender self-pull must succeed. 4) Keep permission 256 owner-only.",
|
|
351
|
+
"evidence": "mount=withdraw, guards=[${withdraw_mount_guards}]",
|
|
352
|
+
"stakeholders": ["owner", "external_operator"],
|
|
353
|
+
"exposure": {
|
|
354
|
+
"loss_parties": [
|
|
355
|
+
{ "role": "merchant", "basis": "Each mounted Guard is a permission-free release gate over the Treasury balance: any external party whose transaction satisfies the Guard predicate can pull funds out to themselves, with no Treasury Permission involved." }
|
|
356
|
+
],
|
|
357
|
+
"gain_paths": [
|
|
358
|
+
{
|
|
359
|
+
"role": "collaborator",
|
|
360
|
+
"path": "An external operator whose address satisfies a mounted Guard (${withdraw_mount_guards}) triggers external_withdraw and receives the release directly — the destination is forced to the transaction sender.",
|
|
361
|
+
"viability": "unverifiable",
|
|
362
|
+
"gate": "The deciding facts sit in the Guard predicate internals (who can make it pass and what the amount slot reads) — audit the full Guard definition before the gate goes live."
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"when": { "all": [
|
|
369
|
+
{ "field": "external_deposit_guard_mounted", "op": "eq", "value": true },
|
|
370
|
+
{ "not": { "field": "external_withdraw_guard_mounted", "op": "eq", "value": true } }
|
|
371
|
+
] },
|
|
372
|
+
"level": "low",
|
|
373
|
+
"title": "Mounting external deposit Guards — the Guard becomes a permission-free deposit gate",
|
|
374
|
+
"description": "Each mounted Guard (${deposit_mount_guards}) becomes a permission-free gate on external_deposit: any external party whose transaction makes the Guard predicate pass can deposit without a Treasury Permission. The deposited Coin is a transaction argument, so value can only come from the transaction sender — the flow direction is safe; store_from_id, when set, only resolves an address for record-keeping.",
|
|
375
|
+
"scenario": "Owner mounts external deposit Guards during Treasury configuration",
|
|
376
|
+
"mitigation": "1) Review the Guard definition and confirm the predicate matches the intended deposit policy. 2) Confirm store_from_id is used for record-keeping only, not as a destination. 3) Regress on testnet first.",
|
|
377
|
+
"evidence": "mount=deposit, guards=[${deposit_mount_guards}]",
|
|
378
|
+
"stakeholders": ["owner", "external_operator"]
|
|
379
|
+
}
|
|
380
|
+
]
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"rule_id": "R-T-5-01",
|
|
384
|
+
"dimension": "cross_object",
|
|
385
|
+
"trigger": "Treasury shared with Service via common Permission — verify alignment",
|
|
386
|
+
"cases": [
|
|
387
|
+
{
|
|
388
|
+
"when": { "field": "shared_with_service", "op": "truthy" },
|
|
389
|
+
"level": "medium",
|
|
390
|
+
"title": "Treasury-Service Permission sharing — verify index alignment",
|
|
391
|
+
"description": "Treasury and Service share a Permission object. Ensure Treasury indexes (250-258) and Service indexes (300-320) are assigned to intended entities; cross-object admin changes affect both.",
|
|
392
|
+
"scenario": "Single Permission for both Treasury and Service",
|
|
393
|
+
"mitigation": "Document which entities hold which indexes across both objects; review admin list changes for cross-impact",
|
|
394
|
+
"evidence": "shared_with_service=true",
|
|
395
|
+
"stakeholders": ["owner", "admin"]
|
|
396
|
+
}
|
|
397
|
+
]
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"rule_id": "R-T-5-02",
|
|
401
|
+
"dimension": "cross_object",
|
|
402
|
+
"trigger": "Treasury referenced by Allocator/Arbitration — receive (253) must be granted",
|
|
403
|
+
"cases": [
|
|
404
|
+
{
|
|
405
|
+
"when": { "field": "treasury_receive_253_missing", "op": "eq", "value": true },
|
|
406
|
+
"level": "high",
|
|
407
|
+
"title": "Treasury referenced by Allocator/Arbitration but TREASURY_RECEIVE (253) not granted",
|
|
408
|
+
"description": "Allocator/Arbitration will send CoinWrapper/Payment to Treasury, but no entity has TREASURY_RECEIVE (253) to call receive and convert to balance. Funds will accumulate as received objects without entering balance.",
|
|
409
|
+
"scenario": "Revenue collection setup without receive permission",
|
|
410
|
+
"mitigation": "Grant TREASURY_RECEIVE (253) to a trusted operator (or owner) who will regularly call receive to convert CoinWrapper to balance",
|
|
411
|
+
"evidence": "shared_allocator=${shared_allocator_display}, shared_arbitration=${shared_arbitration_display}, has_253=false",
|
|
412
|
+
"stakeholders": ["owner", "system"],
|
|
413
|
+
"exposure": {
|
|
414
|
+
"loss_parties": [
|
|
415
|
+
{ "role": "merchant", "basis": "Allocator/Arbitration payouts are sent to this Treasury, but with no TREASURY_RECEIVE (253) holder the received CoinWrappers are never converted to balance — revenue accumulates inaccessible and can be neither withdrawn nor redeployed." }
|
|
416
|
+
],
|
|
417
|
+
"gain_paths": []
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
]
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"rule_id": "R-T-0-01",
|
|
424
|
+
"dimension": "structural",
|
|
425
|
+
"trigger": "Permission index in 259-260 range detected (regression check for R-T-01)",
|
|
426
|
+
"cases": [
|
|
427
|
+
{
|
|
428
|
+
"when": { "field": "stale_treasury_indexes", "op": "truthy" },
|
|
429
|
+
"level": "critical",
|
|
430
|
+
"title": "Stale Treasury permission index 259/260 detected (R-T-01 regression)",
|
|
431
|
+
"description": "Permission indexes 259/260 are no longer valid Treasury indexes (SDK fixed to use 255-258 matching Move). Found: ${stale_treasury_indexes_csv_sp}",
|
|
432
|
+
"scenario": "SDK regression reintroducing off-by-2 divergence",
|
|
433
|
+
"mitigation": "Use canonical indexes: 255=EXTERNAL_DEPOSIT_GUARD, 256=EXTERNAL_WITHDRAW_GUARD, 257=OWNER_RECEIVE, 258=UM",
|
|
434
|
+
"evidence": "stale_indexes=${stale_treasury_indexes_csv}",
|
|
435
|
+
"stakeholders": ["owner", "admin", "system"]
|
|
436
|
+
}
|
|
437
|
+
]
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comment": "Util rule pack (R-UTIL) — declarative form of the retired in-code Util risk rules. Facts are produced by the kernel extractor (util-risk.ts, bound to the on-chain address layout); rules only reference fact names. Levels/wording can be retuned per rule and rules can be disabled (enabled=false, trace left) via the judgment document — factory rules can never be deleted or invented here.",
|
|
3
|
+
"facts": {
|
|
4
|
+
"uses_typo_function_name": "The caller invokes the published child-object address check by its misspelled published name (the name is immutable on-chain, so the typo must be routed around, not fixed).",
|
|
5
|
+
"assumes_stable_address_bytes": "The caller assumes the address first-byte classification will stay valid across future protocol upgrades.",
|
|
6
|
+
"large_util_import": "The caller pulls a large fraction of the SDK utility module (single ~50KB file — navigation and coupling concern).",
|
|
7
|
+
"expects_util_events": "The caller expects the utility library to emit observability events (it is pure — it emits none).",
|
|
8
|
+
"bcs_manually_synced": "The caller maintains BCS layouts by hand instead of generating them from the on-chain struct layouts (drift risk).",
|
|
9
|
+
"address_byte_user": "KERNEL CONSTANT — first byte classifying user addresses in the on-chain address layout.",
|
|
10
|
+
"address_byte_object_regular": "KERNEL CONSTANT — first byte marking a regular/child object address.",
|
|
11
|
+
"address_byte_typed_min": "KERNEL CONSTANT — lower bound of the first-byte range marking typed business objects.",
|
|
12
|
+
"address_byte_typed_max": "KERNEL CONSTANT — upper bound of the first-byte range marking typed business objects."
|
|
13
|
+
},
|
|
14
|
+
"rules": [
|
|
15
|
+
{
|
|
16
|
+
"rule_id": "R-UTIL-01",
|
|
17
|
+
"dimension": "semantic",
|
|
18
|
+
"trigger": "caller uses the misspelled published child-object address check name",
|
|
19
|
+
"cases": [
|
|
20
|
+
{
|
|
21
|
+
"when": { "field": "uses_typo_function_name", "op": "eq", "value": true },
|
|
22
|
+
"level": "low",
|
|
23
|
+
"title": "The child-object address check was published with a misspelled name ('chiild') — cannot be renamed post-publish",
|
|
24
|
+
"description": "The Move layer defines the child-object address-byte check with a misspelled name (note the 'chiild' typo). The function is already published on mainnet, so the name cannot be fixed without a breaking package upgrade. Callers must use the misspelled name exactly; SDK wrappers should expose a correctly-spelled alias and route to the typo function.",
|
|
25
|
+
"scenario": "Caller writes is_child_object_address_byte; Move linker cannot resolve the symbol",
|
|
26
|
+
"mitigation": "SDK should expose isChildObjectAddressByte as the public API and internally call the typo'd Move function. Document the typo so future maintainers don't 'fix' it.",
|
|
27
|
+
"evidence": "uses_typo_function_name=true (must use 'chiild')",
|
|
28
|
+
"stakeholders": ["caller"]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"rule_id": "R-UTIL-02",
|
|
34
|
+
"dimension": "semantic",
|
|
35
|
+
"trigger": "caller assumes address-byte thresholds survive protocol upgrades",
|
|
36
|
+
"cases": [
|
|
37
|
+
{
|
|
38
|
+
"when": { "field": "assumes_stable_address_bytes", "op": "eq", "value": true },
|
|
39
|
+
"level": "medium",
|
|
40
|
+
"title": "Address-byte thresholds are hardcoded — Wow protocol upgrades could invalidate them",
|
|
41
|
+
"description": "Addresses are classified by first byte: user (${address_byte_user}), object (${address_byte_object_regular} for regular/child, or ${address_byte_typed_min}..${address_byte_typed_max} for typed business objects). These thresholds are hardcoded as Move constants, not configurable. If a future Wow protocol upgrade changes the address byte layout (e.g. reserves a new prefix), Util would silently misclassify addresses until the Move code is upgraded.",
|
|
42
|
+
"scenario": "Wow protocol upgrade introduces a new address prefix; Util misclassifies it as user",
|
|
43
|
+
"mitigation": "Track Wow protocol upgrades that touch address layout. When a change ships, upgrade the Move package and the SDK in lockstep. Add a sync test that asserts the byte values.",
|
|
44
|
+
"evidence": "assumes_stable_address_bytes=true (hardcoded ${address_byte_user}/${address_byte_object_regular}/${address_byte_typed_min}..${address_byte_typed_max})",
|
|
45
|
+
"stakeholders": ["caller", "system"]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"rule_id": "R-UTIL-03",
|
|
51
|
+
"dimension": "structural",
|
|
52
|
+
"trigger": "caller pulls a large fraction of the ~50KB SDK utility module",
|
|
53
|
+
"cases": [
|
|
54
|
+
{
|
|
55
|
+
"when": { "field": "large_util_import", "op": "eq", "value": true },
|
|
56
|
+
"level": "low",
|
|
57
|
+
"title": "util.ts is ~50KB — over-concentrated, hard to navigate",
|
|
58
|
+
"description": "The SDK util.ts is ~50428 bytes, mixing BCS structure definitions, query condition builders, Guard query helpers, and address utilities. The size makes it hard to navigate and increases the risk of accidental circular imports. New contributors often import the wrong symbol because so many are exported from one file.",
|
|
59
|
+
"scenario": "Developer imports ProgressHistoryFindConditionsBCS and accidentally pulls in unrelated code",
|
|
60
|
+
"mitigation": "Consider splitting util.ts into focused sub-modules (bcs.ts, query.ts, address.ts). Until then, prefer named imports over namespace imports to keep bundles lean.",
|
|
61
|
+
"evidence": "large_util_import=true (consider sub-modules)",
|
|
62
|
+
"stakeholders": ["caller", "system"]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"rule_id": "R-UTIL-04",
|
|
68
|
+
"dimension": "lifecycle",
|
|
69
|
+
"trigger": "caller expects observability events from the pure utility library",
|
|
70
|
+
"cases": [
|
|
71
|
+
{
|
|
72
|
+
"when": { "field": "expects_util_events", "op": "eq", "value": true },
|
|
73
|
+
"level": "low",
|
|
74
|
+
"title": "Util emits no events — tool-call observability is caller's responsibility",
|
|
75
|
+
"description": "Util functions are pure: they neither emit nor consume events. Callers cannot rely on an event stream to trace Util invocations. For audit and debugging, the calling module must record its own log entries around Util calls.",
|
|
76
|
+
"scenario": "Auditor expects Util-call events; none exist, the call chain is invisible",
|
|
77
|
+
"mitigation": "Callers should emit their own events or write logs around Util calls when auditability is required. Treat Util as an opaque library function.",
|
|
78
|
+
"evidence": "expects_util_events=true (none emitted)",
|
|
79
|
+
"stakeholders": ["caller"]
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"rule_id": "R-UTIL-05",
|
|
85
|
+
"dimension": "cross_object",
|
|
86
|
+
"trigger": "BCS layouts maintained by hand while on-chain structs evolve",
|
|
87
|
+
"cases": [
|
|
88
|
+
{
|
|
89
|
+
"when": { "field": "bcs_manually_synced", "op": "eq", "value": true },
|
|
90
|
+
"level": "medium",
|
|
91
|
+
"title": "SDK BCS structures must stay in sync with Move structs — drift breaks queries",
|
|
92
|
+
"description": "util.ts defines BCS structures for Progress History / Session / Forward / Record query conditions. These must match the Move struct layouts byte-for-byte. If a Move struct adds a field and the SDK BCS is not regenerated, query submissions will deserialize incorrectly on-chain, producing silent failures or aborts.",
|
|
93
|
+
"scenario": "Progress struct adds a field; SDK BCS is stale; queries return wrong results",
|
|
94
|
+
"mitigation": "Generate BCS structures from Move source via codegen, or run a sync test that compares SDK BCS layouts against Move structs on every release.",
|
|
95
|
+
"evidence": "bcs_manually_synced=true (drift risk)",
|
|
96
|
+
"stakeholders": ["caller", "system"]
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { type Facts } from "../config/rule-engine.js";
|
|
2
|
+
export type BridgeRiskLevel = "critical" | "high" | "medium" | "low" | "info";
|
|
2
3
|
export type BridgeRiskCategory = "structural" | "lifecycle" | "permission" | "cross_object" | "knowledge";
|
|
3
4
|
export type BridgeStakeholder = "user" | "committee" | "operator" | "system";
|
|
4
5
|
export interface BridgeRisk {
|
|
@@ -27,9 +28,9 @@ export interface BridgeRiskCheckContext {
|
|
|
27
28
|
versioned_upgrade_in_progress?: boolean;
|
|
28
29
|
constants_synced?: boolean;
|
|
29
30
|
}
|
|
30
|
-
export declare
|
|
31
|
-
rule: BridgeRisk;
|
|
32
|
-
check: (ctx: BridgeRiskCheckContext) => BridgeRisk | null;
|
|
33
|
-
}[];
|
|
31
|
+
export declare function bridgeRiskFacts(ctx: BridgeRiskCheckContext): Facts;
|
|
34
32
|
export declare const BRIDGE_RISK_VERSION = "1.0.0";
|
|
33
|
+
export declare const BRIDGE_RISK_RULES: Array<BridgeRisk & {
|
|
34
|
+
trigger?: string;
|
|
35
|
+
}>;
|
|
35
36
|
export declare function checkBridgeRisks(ctx: BridgeRiskCheckContext): BridgeRisk[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{BRIDGE_MESSAGE_VERSION,BRIDGE_EVM_ADDRESS_LENGTH,BRIDGE_CURRENT_VERSION}from'@wowok/wowok';const SUPPORTED_TOKENS=['ETH','WETH','WBTC','USDC','USDT'],MAX_IDEMPOTENCY_KEY_LENGTH=0x80,BRIDGE_ERROR_CODE_COUNT=0x14,R_B_01={'rule':{'id':'R-BRIDGE-01','level':'CRITICAL','category':'permission','title':'Cross-chain\x20asset\x20security\x20—\x20committee\x20signature\x20verification\x20is\x20the\x20single\x20trust\x20root','description':'Bridge\x20committee\x20signatures\x20are\x20the\x20only\x20thing\x20preventing\x20forged\x20cross-chain\x20messages\x20'+'from\x20minting\x20tokens\x20out\x20of\x20thin\x20air\x20(bridge.move:60).\x20If\x20a\x20committee\x20key\x20is\x20'+'compromised,\x20or\x20if\x20the\x20verification\x20logic\x20has\x20a\x20bug,\x20an\x20attacker\x20can\x20claim\x20arbitrary\x20'+'amounts\x20of\x20ETH/WETH/WBTC/USDC/USDT.\x20The\x20TransferLimiter\x20caps\x20single-transfer\x20amounts\x20'+'but\x20does\x20not\x20prevent\x20repeated\x20small\x20attacks.','affected_stakeholders':['user','committee','system'],'scenario':'Committee\x20private\x20key\x20leaks;\x20attacker\x20forges\x20an\x20approved\x20transfer\x20and\x20claims\x20funds','mitigation':'Committee\x20members\x20MUST\x20use\x20HSM-backed\x20multi-sig.\x20Rotate\x20keys\x20on\x20a\x20schedule.\x20Audit\x20'+'committee\x20membership\x20and\x20signature\x20verification\x20logic\x20on\x20every\x20release.\x20Monitor\x20'+'limiter\x20utilization\x20for\x20suspicious\x20patterns.\x20Have\x20an\x20EmergencyOp\x20pause\x20plan\x20ready.','auto_fixable':![]},'check':a=>{if(!a['assumes_committee_infallible'])return null;return{...R_B_01['rule'],'evidence':'assumes_committee_infallible=true\x20(trust\x20root\x20is\x20single-point)'};}},R_B_02={'rule':{'id':'R-BRIDGE-02','level':'HIGH','category':'cross_object','title':'Bridge\x20is\x20mainnet-only\x20—\x20testnet\x20operations\x20will\x20fail','description':'The\x20Bridge\x20is\x20only\x20configured\x20on\x20mainnet.\x20testnet\x20nodes\x20do\x20not\x20have\x20the\x20bridge\x20'+'role\x20configured,\x20so\x20any\x20cross-chain\x20operation\x20(cross_chain_wow_to_evm,\x20'+'cross_chain_evm_to_wow,\x20claim_wow_to_evm,\x20etc.)\x20will\x20abort.\x20Developers\x20who\x20test\x20on\x20'+'testnet\x20will\x20see\x20EBridgeUnavailable\x20(8)\x20and\x20may\x20misdiagnose\x20it\x20as\x20a\x20code\x20bug.','affected_stakeholders':['user','operator'],'scenario':'Developer\x20runs\x20cross_chain_wow_to_evm\x20on\x20testnet;\x20aborts\x20with\x20EBridgeUnavailable','mitigation':'MCP\x20layer\x20MUST\x20validate\x20mainnet\x20environment\x20before\x20submitting\x20Bridge\x20ops.\x20Document\x20'+'the\x20mainnet-only\x20restriction\x20prominently.\x20For\x20testing,\x20use\x20mainnet\x20small-amount\x20'+'transactions\x20or\x20fork\x20tests.','related_move_error':'EBridgeUnavailable\x20(8)','auto_fixable':![]},'check':a=>{if(!a['is_non_mainnet'])return null;return{...R_B_02['rule'],'evidence':'is_non_mainnet=true\x20(Bridge\x20unavailable)'};}},R_B_03={'rule':{'id':'R-BRIDGE-03','level':'HIGH','category':'structural','title':'TransferLimiter\x20caps\x20single\x20and\x20cumulative\x20transfer\x20amounts\x20—\x20large\x20transfers\x20reject','description':'The\x20TransferLimiter\x20(bridge.move:64)\x20enforces\x20both\x20per-transfer\x20and\x20cumulative\x20'+'transfer\x20caps\x20per\x20token\x20type.\x20A\x20transfer\x20that\x20exceeds\x20the\x20cap\x20aborts\x20with\x20'+'ETokenAlreadyClaimedOrHitLimit\x20(15)\x20or\x20similar.\x20Users\x20attempting\x20large\x20cross-chain\x20'+'moves\x20will\x20see\x20their\x20transactions\x20rejected\x20and\x20may\x20misdiagnose\x20it\x20as\x20a\x20bug.','affected_stakeholders':['user'],'scenario':'User\x20attempts\x20to\x20bridge\x201000\x20ETH;\x20limiter\x20rejects\x20the\x20transfer','mitigation':'Document\x20the\x20limiter\x20semantics.\x20Before\x20submitting,\x20query\x20the\x20current\x20limiter\x20'+'utilization.\x20For\x20large\x20amounts,\x20split\x20into\x20batches\x20across\x20multiple\x20transactions\x20'+'and/or\x20time\x20windows.\x20Surface\x20the\x20remaining\x20cap\x20in\x20the\x20UI.','related_move_error':'ETokenAlreadyClaimedOrHitLimit\x20(15)','auto_fixable':![]},'check':a=>null},R_B_04={'rule':{'id':'R-BRIDGE-04','level':'MEDIUM','category':'permission','title':'activeEvmAccount\x20is\x20a\x20single\x20global\x20EVM\x20account\x20—\x20key\x20leak\x20affects\x20all\x20assets','description':'Bridge\x20uses\x20a\x20single\x20global\x20activeEvmAccount\x20that\x20is\x20auto-generated\x20and\x20transparent\x20'+'to\x20users.\x20All\x20cross-chain\x20EVM-side\x20operations\x20flow\x20through\x20this\x20one\x20account.\x20If\x20its\x20'+'private\x20key\x20leaks,\x20every\x20supported\x20token\x20(ETH/WETH/WBTC/USDC/USDT)\x20on\x20every\x20'+'supported\x20chain\x20is\x20at\x20risk.\x20There\x20is\x20no\x20per-user\x20EVM\x20account\x20isolation.','affected_stakeholders':['user','system'],'scenario':'activeEvmAccount\x20private\x20key\x20leaks;\x20attacker\x20drains\x20all\x20bridged\x20EVM\x20assets','mitigation':'Store\x20the\x20activeEvmAccount\x20key\x20in\x20an\x20HSM.\x20Rotate\x20the\x20key\x20on\x20a\x20schedule\x20and\x20via\x20'+'Versioned\x20upgrade.\x20Monitor\x20EVM-side\x20balances\x20for\x20anomalous\x20outflows.\x20Have\x20an\x20'+'EmergencyOp\x20pause\x20plan\x20ready.','auto_fixable':![]},'check':a=>{if(!a['assumes_per_user_evm_account'])return null;return{...R_B_04['rule'],'evidence':'assumes_per_user_evm_account=true\x20(it\x20is\x20global)'};}},R_B_05={'rule':{'id':'R-BRIDGE-05','level':'MEDIUM','category':'cross_object','title':'Public\x20EVM\x20RPCs\x20may\x20rate-limit\x20(HTTP\x20429)\x20—\x20cross-chain\x20ops\x20stall','description':'Bridge\x20ops\x20that\x20query\x20EVM\x20state\x20(query_active_evm_account,\x20query_supported_evm_chains,\x20'+'query_transfer_status,\x20etc.)\x20depend\x20on\x20an\x20EVM\x20RPC.\x20Public\x20RPCs\x20(e.g.\x20Infura\x20free\x20tier,\x20'+'Alchemy\x20free\x20tier)\x20frequently\x20return\x20HTTP\x20429\x20under\x20load.\x20A\x20429\x20mid-flow\x20stalls\x20the\x20'+'cross-chain\x20operation\x20and\x20may\x20confuse\x20the\x20user.\x20manage_evm_rpc\x20supports\x20multi-RPC\x20'+'rotation,\x20but\x20it\x20must\x20be\x20configured\x20in\x20advance.','affected_stakeholders':['user','operator'],'scenario':'User\x20queries\x20transfer\x20status;\x20public\x20RPC\x20returns\x20429;\x20UI\x20shows\x20generic\x20error','mitigation':'Configure\x20multiple\x20EVM\x20RPCs\x20via\x20manage_evm_rpc\x20and\x20enable\x20failover.\x20Use\x20a\x20paid\x20RPC\x20'+'tier\x20for\x20production.\x20Surface\x20429\x20as\x20\x27RPC\x20busy,\x20retry\x27\x20rather\x20than\x20\x27operation\x20failed\x27.','auto_fixable':![]},'check':a=>{if(!a['uses_public_evm_rpc'])return null;return{...R_B_05['rule'],'evidence':'uses_public_evm_rpc=true\x20(429\x20risk)'};}},R_B_06={'rule':{'id':'R-BRIDGE-06','level':'MEDIUM','category':'lifecycle','title':'EmergencyOp\x20can\x20pause\x20the\x20Bridge\x20—\x20assets\x20lock\x20during\x20pause','description':'EmergencyOp\x20(bridge.move:89-91)\x20can\x20pause\x20the\x20entire\x20Bridge.\x20While\x20paused,\x20no\x20'+'cross-chain\x20operations\x20proceed\x20—\x20assets\x20in\x20flight\x20cannot\x20be\x20claimed,\x20new\x20transfers\x20'+'cannot\x20be\x20initiated.\x20The\x20pause\x20is\x20intended\x20for\x20incident\x20response,\x20but\x20a\x20prolonged\x20'+'pause\x20locks\x20user\x20funds\x20for\x20the\x20duration.','affected_stakeholders':['user','operator'],'scenario':'Bridge\x20is\x20paused\x20for\x20incident\x20response;\x20users\x20cannot\x20claim\x20in-flight\x20transfers','mitigation':'Document\x20the\x20pause\x20scenario\x20and\x20the\x20emergency\x20plan.\x20Provide\x20a\x20status\x20page\x20showing\x20'+'pause\x20state.\x20Set\x20expectations\x20on\x20pause\x20duration\x20and\x20recovery.\x20Operators\x20should\x20'+'practice\x20un-pause\x20drills.','auto_fixable':![]},'check':a=>{if(!a['is_paused'])return null;return{...R_B_06['rule'],'evidence':'is_paused=true\x20(assets\x20locked)'};}},R_B_07={'rule':{'id':'R-BRIDGE-07','level':'LOW','category':'structural','title':'Only\x20'+SUPPORTED_TOKENS['length']+'\x20tokens\x20supported\x20—\x20unsupported\x20tokens\x20cannot\x20bridge','description':'Bridge\x20supports\x20exactly\x20'+SUPPORTED_TOKENS['length']+'\x20tokens:\x20'+SUPPORTED_TOKENS['join'](',\x20')+'.\x20'+'Any\x20other\x20token\x20(e.g.\x20DAI,\x20LINK,\x20custom\x20tokens)\x20cannot\x20be\x20bridged.\x20Users\x20holding\x20'+'unsupported\x20tokens\x20will\x20see\x20their\x20transfer\x20rejected\x20with\x20EUnexpectedTokenType\x20(3).','affected_stakeholders':['user'],'scenario':'User\x20attempts\x20to\x20bridge\x20DAI;\x20aborts\x20with\x20EUnexpectedTokenType','mitigation':'Document\x20the\x20supported\x20token\x20list\x20prominently.\x20UI\x20should\x20filter\x20the\x20token\x20picker\x20to\x20'+'supported\x20tokens\x20only.\x20For\x20unsupported\x20tokens,\x20recommend\x20an\x20alternative\x20bridge.','related_move_error':'EUnexpectedTokenType\x20(3)','auto_fixable':![]},'check':a=>{if(!a['unsupported_token'])return null;return{...R_B_07['rule'],'evidence':'unsupported_token='+a['unsupported_token']+'\x20(supported:\x20'+SUPPORTED_TOKENS['join'](',')+')'};}},R_B_08={'rule':{'id':'R-BRIDGE-08','level':'MEDIUM','category':'structural','title':'Idempotency\x20key\x20max\x20'+MAX_IDEMPOTENCY_KEY_LENGTH+'\x20chars\x20—\x20long\x20keys\x20truncate\x20or\x20reject','description':'BridgeIdempotencyKeySchema\x20accepts\x20strings\x20of\x20length\x201-'+MAX_IDEMPOTENCY_KEY_LENGTH+'.\x20'+'Callers\x20who\x20generate\x20idempotency\x20keys\x20from\x20long\x20sources\x20(e.g.\x20full\x20JSON\x20payloads,\x20'+'UUIDs\x20with\x20prefixes)\x20may\x20exceed\x20the\x20limit\x20and\x20see\x20the\x20operation\x20rejected.\x20The\x20limit\x20'+'exists\x20to\x20keep\x20on-chain\x20storage\x20bounded.','affected_stakeholders':['user'],'scenario':'Caller\x20uses\x20a\x20200-char\x20idempotency\x20key;\x20operation\x20rejected','mitigation':'Generate\x20idempotency\x20keys\x20from\x20a\x20hash\x20(e.g.\x20keccak256\x20of\x20the\x20payload,\x20hex-encoded\x20=\x20'+'66\x20chars)\x20or\x20a\x20UUID\x20(36\x20chars).\x20Validate\x20length\x20client-side\x20before\x20submission.','auto_fixable':!![]},'check':a=>{if(a['idempotency_key_length']===undefined)return null;if(a['idempotency_key_length']<=MAX_IDEMPOTENCY_KEY_LENGTH)return null;return{...R_B_08['rule'],'evidence':'idempotency_key_length='+a['idempotency_key_length']+',\x20limit='+MAX_IDEMPOTENCY_KEY_LENGTH};}},R_B_09={'rule':{'id':'R-BRIDGE-09','level':'LOW','category':'structural','title':BRIDGE_ERROR_CODE_COUNT+'\x20error\x20codes\x20—\x20debugging\x20requires\x20a\x20lookup\x20table','description':'Bridge\x20defines\x20'+BRIDGE_ERROR_CODE_COUNT+'\x20error\x20codes\x20(EUnexpectedMessageType=0\x20'+'through\x20ETokenValueIsZero=19).\x20Debugging\x20an\x20abort\x20requires\x20mapping\x20the\x20numeric\x20code\x20'+'back\x20to\x20its\x20name\x20and\x20meaning.\x20New\x20contributors\x20often\x20misread\x20codes\x20because\x20they\x20'+'are\x20not\x20enumerated\x20in\x20the\x20abort\x20message.','affected_stakeholders':['user','operator'],'scenario':'Bridge\x20aborts\x20with\x20code\x2015;\x20developer\x20does\x20not\x20know\x20what\x20ETokenAlreadyClaimedOrHitLimit\x20means','mitigation':'Publish\x20an\x20error-code\x20lookup\x20table\x20in\x20the\x20docs.\x20SDK\x20should\x20decode\x20abort\x20codes\x20into\x20'+'human-readable\x20strings.\x20MCP\x20layer\x20should\x20surface\x20the\x20decoded\x20name\x20in\x20error\x20messages.','auto_fixable':![]},'check':a=>{if(!a['expects_simple_error_codes'])return null;return{...R_B_09['rule'],'evidence':'expects_simple_error_codes=true\x20(there\x20are\x20'+BRIDGE_ERROR_CODE_COUNT+')'};}},R_B_10={'rule':{'id':'R-BRIDGE-10','level':'MEDIUM','category':'lifecycle','title':'Versioned\x20upgrade\x20(current='+BRIDGE_CURRENT_VERSION+')\x20can\x20brick\x20the\x20Bridge\x20if\x20botched','description':'Bridge\x20uses\x20Versioned\x20to\x20wrap\x20BridgeInner\x20(bridge.move:49),\x20supporting\x20schema\x20upgrades.\x20'+('The\x20current\x20version\x20is\x20BRIDGE_CURRENT_VERSION='+BRIDGE_CURRENT_VERSION+'.\x20An\x20upgrade\x20')+'that\x20mishandles\x20the\x20inner\x20version\x20migration\x20can\x20permanently\x20brick\x20the\x20Bridge\x20—\x20'+'funds\x20in\x20flight\x20would\x20be\x20locked,\x20and\x20recovery\x20requires\x20a\x20new\x20package\x20version.\x20The\x20'+('message_version\x20(current='+BRIDGE_MESSAGE_VERSION+')\x20and\x20EVM\x20address\x20length\x20')+('('+BRIDGE_EVM_ADDRESS_LENGTH+'\x20bytes)\x20are\x20also\x20versioned.'),'affected_stakeholders':['user','operator','system'],'scenario':'Upgrade\x20mishandles\x20BridgeInner\x20migration;\x20Bridge\x20becomes\x20unusable','mitigation':'Test\x20upgrades\x20on\x20a\x20fork\x20with\x20full\x20state\x20replay.\x20Keep\x20a\x20rollback\x20package\x20version\x20'+'ready.\x20Stage\x20upgrades\x20with\x20a\x20pause\x20window\x20so\x20users\x20can\x20complete\x20in-flight\x20ops.\x20'+'Audit\x20message_version\x20and\x20EVM\x20address\x20length\x20compatibility\x20on\x20every\x20upgrade.','related_move_error':'EWrongInnerVersion\x20(7)','auto_fixable':![]},'check':a=>{if(!a['versioned_upgrade_in_progress'])return null;return{...R_B_10['rule'],'evidence':'versioned_upgrade_in_progress=true\x20(current='+BRIDGE_CURRENT_VERSION+')'};}};export const BRIDGE_RISK_RULES=[R_B_01,R_B_02,R_B_03,R_B_04,R_B_05,R_B_06,R_B_07,R_B_08,R_B_09,R_B_10];export const BRIDGE_RISK_VERSION='1.0.0';export function checkBridgeRisks(a){const b=[];for(const c of BRIDGE_RISK_RULES){const d=c['check'](a);if(d)b['push'](d);}return!b['find'](e=>e['id']==='R-BRIDGE-03')&&b['push'](R_B_03['rule']),b;}
|
|
1
|
+
import{getJudgmentDoc,factoryRulePack}from'../config/judgment.js';import{evaluateRuleBook,interpolate}from'../config/rule-engine.js';import{BRIDGE_MESSAGE_VERSION,BRIDGE_EVM_ADDRESS_LENGTH,BRIDGE_CURRENT_VERSION}from'@wowok/wowok';const SUPPORTED_TOKENS=['ETH','WETH','WBTC','USDC','USDT'],MAX_IDEMPOTENCY_KEY_LENGTH=0x80,BRIDGE_ERROR_CODE_COUNT=0x14,AUTO_FIXABLE_RULES=new Set(['R-BRIDGE-08']);export function bridgeRiskFacts(a){return{'assumes_committee_infallible':a['assumes_committee_infallible'],'is_non_mainnet':a['is_non_mainnet'],'transfer_amount':a['transfer_amount'],'assumes_per_user_evm_account':a['assumes_per_user_evm_account'],'uses_public_evm_rpc':a['uses_public_evm_rpc'],'is_paused':a['is_paused'],'unsupported_token':a['unsupported_token'],'idempotency_key_length':a['idempotency_key_length'],'idempotency_key_over_limit':a['idempotency_key_length']!==undefined&&a['idempotency_key_length']>MAX_IDEMPOTENCY_KEY_LENGTH,'expects_simple_error_codes':a['expects_simple_error_codes'],'versioned_upgrade_in_progress':a['versioned_upgrade_in_progress'],'constants_synced':a['constants_synced'],'supported_token_count':SUPPORTED_TOKENS['length'],'supported_tokens_display':SUPPORTED_TOKENS['join'](',\x20'),'supported_tokens_csv':SUPPORTED_TOKENS['join'](','),'max_idempotency_key_length':MAX_IDEMPOTENCY_KEY_LENGTH,'error_code_count':BRIDGE_ERROR_CODE_COUNT,'bridge_message_version':BRIDGE_MESSAGE_VERSION,'bridge_current_version':BRIDGE_CURRENT_VERSION,'bridge_evm_address_length':BRIDGE_EVM_ADDRESS_LENGTH,'always_true':!![]};}function bridgeRuleBook(){const a=getJudgmentDoc()['rules']['domains']['bridge'];if(!a)throw new Error('factory\x20rule\x20pack\x20\x27bridge\x27\x20missing\x20—\x20broken\x20installation');return a['rules'];}function findingToBridgeRisk(a){return{'id':a['rule_id'],'level':a['level'],'category':a['dimension']??'structural','title':a['title'],'description':a['description'],'affected_stakeholders':a['stakeholders']??[],'scenario':a['scenario']??'','mitigation':a['mitigation']??'','evidence':a['evidence'],'auto_fixable':AUTO_FIXABLE_RULES['has'](a['rule_id'])};}export const BRIDGE_RISK_VERSION='1.0.0';export const BRIDGE_RISK_RULES=((()=>{const a=factoryRulePack('bridge');if(!a)return[];const b=bridgeRiskFacts({});return a['rules']['map'](d=>{const e=d['cases'][0x0];return{'id':d['rule_id'],'level':e['level'],'category':d['dimension']??'structural','title':interpolate(e['title'],b),'description':interpolate(e['description'],b),'affected_stakeholders':e['stakeholders']??[],'scenario':e['scenario']===undefined?'':interpolate(e['scenario'],b),'mitigation':e['mitigation']===undefined?'':interpolate(e['mitigation'],b),'auto_fixable':AUTO_FIXABLE_RULES['has'](d['rule_id']),...d['trigger']===undefined?{}:{'trigger':d['trigger']}};});})());export function checkBridgeRisks(a){const {findings:b}=evaluateRuleBook(bridgeRuleBook(),bridgeRiskFacts(a));return b['map'](findingToBridgeRisk);}
|