@wazir-dev/cli 1.0.0
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/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,711 @@
|
|
|
1
|
+
# Solidity Smart Contracts — Expertise Module
|
|
2
|
+
|
|
3
|
+
> Solidity is the dominant language for EVM-compatible smart contracts, securing over $50B in DeFi TVL across Ethereum, Arbitrum, Optimism, Base, and Polygon. The immutability of deployed bytecode and direct custody of user funds make correctness non-negotiable -- major exploits include The DAO ($60M, 2016), Poly Network ($611M, 2021), Wormhole ($320M, 2022), Ronin Bridge ($625M, 2022), and Euler Finance ($197M, 2023). This module covers Solidity 0.8.x+ with OpenZeppelin Contracts 5.x patterns, Foundry-first testing, gas optimization, upgrade safety, and DeFi primitives.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Language Fundamentals
|
|
8
|
+
|
|
9
|
+
### Compiler Version Pinning
|
|
10
|
+
|
|
11
|
+
Always pin to an exact compiler version. Floating pragmas introduce non-deterministic compilation:
|
|
12
|
+
|
|
13
|
+
```solidity
|
|
14
|
+
// CORRECT -- pinned version
|
|
15
|
+
pragma solidity 0.8.28;
|
|
16
|
+
|
|
17
|
+
// WRONG -- floating pragma, different compilers produce different bytecode
|
|
18
|
+
pragma solidity ^0.8.0;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Built-In Overflow Protection (0.8.x+)
|
|
22
|
+
|
|
23
|
+
Solidity 0.8.0+ reverts on arithmetic overflow/underflow by default. Use `unchecked` blocks only where overflow is provably impossible (e.g., loop counters):
|
|
24
|
+
|
|
25
|
+
```solidity
|
|
26
|
+
uint256 total = a + b; // Reverts if a + b > type(uint256).max
|
|
27
|
+
|
|
28
|
+
unchecked {
|
|
29
|
+
++i; // Loop counter bounded by array length
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Custom Errors Over Require Strings
|
|
34
|
+
|
|
35
|
+
Custom errors save ~200 gas per revert and enable structured error data:
|
|
36
|
+
|
|
37
|
+
```solidity
|
|
38
|
+
error InsufficientBalance(address account, uint256 requested, uint256 available);
|
|
39
|
+
error Unauthorized(address caller);
|
|
40
|
+
error ZeroAddress();
|
|
41
|
+
|
|
42
|
+
function withdraw(uint256 amount) external {
|
|
43
|
+
if (msg.sender != owner) revert Unauthorized(msg.sender);
|
|
44
|
+
if (balances[msg.sender] < amount) {
|
|
45
|
+
revert InsufficientBalance(msg.sender, amount, balances[msg.sender]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Visibility Modifiers
|
|
51
|
+
|
|
52
|
+
| Modifier | Access | Use case |
|
|
53
|
+
|----------|--------|----------|
|
|
54
|
+
| `external` | Only from outside | Public API entry points |
|
|
55
|
+
| `public` | External + internal | Getters, shared logic |
|
|
56
|
+
| `internal` | This contract + children | Inheritance hooks |
|
|
57
|
+
| `private` | This contract only | Implementation details |
|
|
58
|
+
|
|
59
|
+
Prefer `external` over `public` for functions not called internally -- `external` reads `calldata` directly, avoiding a memory copy.
|
|
60
|
+
|
|
61
|
+
### Storage, Memory, Calldata
|
|
62
|
+
|
|
63
|
+
| Location | Persistence | Cost | When to use |
|
|
64
|
+
|----------|-------------|------|-------------|
|
|
65
|
+
| `storage` | Permanent (on-chain) | 20,000 gas (cold write) | State variables |
|
|
66
|
+
| `memory` | Function scope | ~3 gas per word | Local computation, return values |
|
|
67
|
+
| `calldata` | Read-only, function scope | Cheapest | External function parameters |
|
|
68
|
+
|
|
69
|
+
```solidity
|
|
70
|
+
function processNames(string[] calldata names) external pure returns (uint256) {
|
|
71
|
+
return names.length; // calldata -- cheapest for read-only external params
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Immutable and Constant
|
|
76
|
+
|
|
77
|
+
```solidity
|
|
78
|
+
uint256 constant MAX_SUPPLY = 1_000_000e18; // Compile-time, inlined (zero storage cost)
|
|
79
|
+
|
|
80
|
+
address immutable i_owner; // Set once in constructor, stored in bytecode
|
|
81
|
+
IERC20 immutable i_token;
|
|
82
|
+
|
|
83
|
+
constructor(address token_) {
|
|
84
|
+
i_owner = msg.sender;
|
|
85
|
+
i_token = IERC20(token_);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Convention: prefix immutables with `i_` and constants with `UPPER_SNAKE_CASE`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## ERC Standard Patterns
|
|
94
|
+
|
|
95
|
+
### ERC-20: Fungible Tokens
|
|
96
|
+
|
|
97
|
+
```solidity
|
|
98
|
+
interface IERC20 {
|
|
99
|
+
event Transfer(address indexed from, address indexed to, uint256 value);
|
|
100
|
+
event Approval(address indexed owner, address indexed spender, uint256 value);
|
|
101
|
+
|
|
102
|
+
function totalSupply() external view returns (uint256);
|
|
103
|
+
function balanceOf(address account) external view returns (uint256);
|
|
104
|
+
function transfer(address to, uint256 value) external returns (bool);
|
|
105
|
+
function allowance(address owner, address spender) external view returns (uint256);
|
|
106
|
+
function approve(address spender, uint256 value) external returns (bool);
|
|
107
|
+
function transferFrom(address from, address to, uint256 value) external returns (bool);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Minimal implementation using OpenZeppelin:
|
|
112
|
+
|
|
113
|
+
```solidity
|
|
114
|
+
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
115
|
+
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
116
|
+
|
|
117
|
+
contract MyToken is ERC20, Ownable {
|
|
118
|
+
uint256 constant MAX_SUPPLY = 100_000_000e18;
|
|
119
|
+
|
|
120
|
+
constructor() ERC20("MyToken", "MTK") Ownable(msg.sender) {
|
|
121
|
+
_mint(msg.sender, MAX_SUPPLY);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function mint(address to, uint256 amount) external onlyOwner {
|
|
125
|
+
if (totalSupply() + amount > MAX_SUPPLY) revert ExceedsMaxSupply();
|
|
126
|
+
_mint(to, amount);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### ERC-721: Non-Fungible Tokens
|
|
132
|
+
|
|
133
|
+
Key functions: `ownerOf`, `safeTransferFrom`, `approve`, `setApprovalForAll`. Always use `_safeMint` to check `IERC721Receiver` on contract recipients:
|
|
134
|
+
|
|
135
|
+
```solidity
|
|
136
|
+
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
|
137
|
+
|
|
138
|
+
contract MyNFT is ERC721, Ownable {
|
|
139
|
+
uint256 private _nextTokenId;
|
|
140
|
+
|
|
141
|
+
constructor() ERC721("MyNFT", "MNFT") Ownable(msg.sender) {}
|
|
142
|
+
|
|
143
|
+
function safeMint(address to) external onlyOwner returns (uint256) {
|
|
144
|
+
uint256 tokenId = _nextTokenId;
|
|
145
|
+
unchecked { ++_nextTokenId; }
|
|
146
|
+
_safeMint(to, tokenId);
|
|
147
|
+
return tokenId;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### ERC-1155: Multi-Token Standard
|
|
153
|
+
|
|
154
|
+
Combines fungible and non-fungible tokens with batch operations:
|
|
155
|
+
|
|
156
|
+
```solidity
|
|
157
|
+
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
|
|
158
|
+
|
|
159
|
+
contract GameItems is ERC1155, Ownable {
|
|
160
|
+
uint256 public constant GOLD = 0; // Fungible
|
|
161
|
+
uint256 public constant SWORD = 1; // Non-fungible (mint qty 1)
|
|
162
|
+
|
|
163
|
+
constructor() ERC1155("https://api.game.com/items/{id}.json") Ownable(msg.sender) {}
|
|
164
|
+
|
|
165
|
+
function mintBatch(
|
|
166
|
+
address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data
|
|
167
|
+
) external onlyOwner {
|
|
168
|
+
_mintBatch(to, ids, amounts, data);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### ERC-4626: Tokenized Vault
|
|
174
|
+
|
|
175
|
+
Standard interface for yield-bearing vaults -- deposit underlying asset, receive shares:
|
|
176
|
+
|
|
177
|
+
```solidity
|
|
178
|
+
import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";
|
|
179
|
+
|
|
180
|
+
contract YieldVault is ERC4626 {
|
|
181
|
+
constructor(IERC20 asset_) ERC4626(asset_) ERC20("Yield Vault Shares", "yvTKN") {}
|
|
182
|
+
// Inherited: deposit(), withdraw(), convertToShares(), convertToAssets(), totalAssets()
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Gas Optimization
|
|
189
|
+
|
|
190
|
+
| Pattern | Gas Saved | Mechanism |
|
|
191
|
+
|---------|-----------|-----------|
|
|
192
|
+
| Storage packing | 20,000/slot | Pack variables into 32-byte slots |
|
|
193
|
+
| `calldata` over `memory` | 200-600/call | Avoid memory copy for external params |
|
|
194
|
+
| Custom errors | 200+/revert | No string encoding/storage |
|
|
195
|
+
| Unchecked math | 80-150/op | Skip overflow checks on proven-safe ops |
|
|
196
|
+
| Short-circuit evaluation | Variable | Order `&&`/`\|\|` by likelihood |
|
|
197
|
+
| Cache storage reads | 100+/read | Local variable for repeated SLOAD |
|
|
198
|
+
| Batch operations | Variable | Amortize base cost across items |
|
|
199
|
+
| Immutable/constant | 2,100/read | Zero SLOAD -- value in bytecode |
|
|
200
|
+
|
|
201
|
+
### Storage Packing
|
|
202
|
+
|
|
203
|
+
The EVM operates on 32-byte slots. Consecutive variables smaller than 32 bytes share a slot:
|
|
204
|
+
|
|
205
|
+
```solidity
|
|
206
|
+
// BAD -- 3 slots
|
|
207
|
+
uint256 amount; // slot 0
|
|
208
|
+
uint128 timestamp; // slot 1 (alone)
|
|
209
|
+
uint128 nonce; // slot 2 (alone)
|
|
210
|
+
|
|
211
|
+
// GOOD -- 2 slots
|
|
212
|
+
uint256 amount; // slot 0
|
|
213
|
+
uint128 timestamp; // slot 1 (first 16 bytes)
|
|
214
|
+
uint128 nonce; // slot 1 (next 16 bytes)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Caching Storage Reads
|
|
218
|
+
|
|
219
|
+
Each `SLOAD` costs 2,100 gas (cold) or 100 gas (warm):
|
|
220
|
+
|
|
221
|
+
```solidity
|
|
222
|
+
// BAD -- 3 SLOADs
|
|
223
|
+
function process() external {
|
|
224
|
+
require(balances[msg.sender] > 0);
|
|
225
|
+
uint256 fee = balances[msg.sender] / 100;
|
|
226
|
+
balances[msg.sender] -= fee;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// GOOD -- 1 SLOAD
|
|
230
|
+
function process() external {
|
|
231
|
+
uint256 bal = balances[msg.sender];
|
|
232
|
+
if (bal == 0) revert ZeroBalance();
|
|
233
|
+
balances[msg.sender] = bal - (bal / 100);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Unchecked Loop Counters
|
|
238
|
+
|
|
239
|
+
```solidity
|
|
240
|
+
function sum(uint256[] calldata values) external pure returns (uint256 total) {
|
|
241
|
+
uint256 len = values.length;
|
|
242
|
+
for (uint256 i; i < len;) {
|
|
243
|
+
total += values[i];
|
|
244
|
+
unchecked { ++i; }
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Upgrade Patterns
|
|
252
|
+
|
|
253
|
+
### UUPS Proxy (EIP-1822)
|
|
254
|
+
|
|
255
|
+
Upgrade logic in the implementation. Lower gas per call. Preferred by OpenZeppelin:
|
|
256
|
+
|
|
257
|
+
```solidity
|
|
258
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
259
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
260
|
+
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
|
261
|
+
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
262
|
+
|
|
263
|
+
contract MyTokenV1 is Initializable, ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable {
|
|
264
|
+
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
265
|
+
constructor() { _disableInitializers(); }
|
|
266
|
+
|
|
267
|
+
function initialize(string memory name, string memory symbol) public initializer {
|
|
268
|
+
__ERC20_init(name, symbol);
|
|
269
|
+
__Ownable_init(msg.sender);
|
|
270
|
+
__UUPSUpgradeable_init();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Transparent Proxy
|
|
278
|
+
|
|
279
|
+
Upgrade logic in the proxy (admin-only). Higher per-call gas due to admin slot check. Use when upgrade authority must be fully separated from contract logic.
|
|
280
|
+
|
|
281
|
+
### Diamond Pattern (EIP-2535)
|
|
282
|
+
|
|
283
|
+
Modular upgrade via facets -- each facet provides functions selected by 4-byte selector. Justified only when bytecode exceeds 24KB or independently upgradeable modules are required:
|
|
284
|
+
|
|
285
|
+
```solidity
|
|
286
|
+
struct FacetCut {
|
|
287
|
+
address facetAddress;
|
|
288
|
+
FacetCutAction action; // Add, Replace, Remove
|
|
289
|
+
bytes4[] functionSelectors;
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Storage Collision Prevention
|
|
294
|
+
|
|
295
|
+
**Storage gaps** -- reserve slots in base contracts:
|
|
296
|
+
|
|
297
|
+
```solidity
|
|
298
|
+
contract BaseV1 is Initializable {
|
|
299
|
+
uint256 public value;
|
|
300
|
+
uint256[49] private __gap; // Reserve 49 slots for future variables
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**EIP-7201 Namespaced Storage** -- hash-based locations eliminate collision risk:
|
|
305
|
+
|
|
306
|
+
```solidity
|
|
307
|
+
/// @custom:storage-location erc7201:myproject.storage.MyToken
|
|
308
|
+
struct MyTokenStorage {
|
|
309
|
+
mapping(address => uint256) balances;
|
|
310
|
+
uint256 totalMinted;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function _getMyTokenStorage() private pure returns (MyTokenStorage storage $) {
|
|
314
|
+
bytes32 slot = STORAGE_LOCATION;
|
|
315
|
+
assembly { $.slot := slot }
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Testing with Foundry
|
|
322
|
+
|
|
323
|
+
### Setup
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
forge init my-project && cd my-project
|
|
327
|
+
forge install OpenZeppelin/openzeppelin-contracts
|
|
328
|
+
# foundry.toml: solc = "0.8.28", optimizer = true, optimizer_runs = 200
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Unit Tests
|
|
332
|
+
|
|
333
|
+
```solidity
|
|
334
|
+
import {Test} from "forge-std/Test.sol";
|
|
335
|
+
import {MyToken} from "../src/MyToken.sol";
|
|
336
|
+
|
|
337
|
+
contract MyTokenTest is Test {
|
|
338
|
+
MyToken token;
|
|
339
|
+
address alice = makeAddr("alice");
|
|
340
|
+
address bob = makeAddr("bob");
|
|
341
|
+
|
|
342
|
+
function setUp() public {
|
|
343
|
+
token = new MyToken();
|
|
344
|
+
token.transfer(alice, 1000e18);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function test_TransferUpdatesBalances() public {
|
|
348
|
+
vm.prank(alice);
|
|
349
|
+
token.transfer(bob, 100e18);
|
|
350
|
+
assertEq(token.balanceOf(alice), 900e18);
|
|
351
|
+
assertEq(token.balanceOf(bob), 100e18);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function test_RevertWhen_TransferExceedsBalance() public {
|
|
355
|
+
vm.prank(alice);
|
|
356
|
+
vm.expectRevert();
|
|
357
|
+
token.transfer(bob, 2000e18);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Fuzz Tests
|
|
363
|
+
|
|
364
|
+
```solidity
|
|
365
|
+
function testFuzz_Transfer(address to, uint256 amount) public {
|
|
366
|
+
vm.assume(to != address(0) && to != address(token));
|
|
367
|
+
vm.assume(amount <= token.balanceOf(address(this)));
|
|
368
|
+
|
|
369
|
+
uint256 preBal = token.balanceOf(to);
|
|
370
|
+
token.transfer(to, amount);
|
|
371
|
+
assertEq(token.balanceOf(to), preBal + amount);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function testFuzz_DepositWithdrawRoundTrip(uint256 assets) public {
|
|
375
|
+
assets = bound(assets, 1, 1_000_000e18);
|
|
376
|
+
deal(address(underlying), address(this), assets);
|
|
377
|
+
underlying.approve(address(vault), assets);
|
|
378
|
+
uint256 shares = vault.deposit(assets, address(this));
|
|
379
|
+
uint256 withdrawn = vault.redeem(shares, address(this), address(this));
|
|
380
|
+
assertApproxEqAbs(withdrawn, assets, 1);
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Invariant Tests
|
|
385
|
+
|
|
386
|
+
```solidity
|
|
387
|
+
contract TokenInvariantTest is Test {
|
|
388
|
+
MyToken token;
|
|
389
|
+
Handler handler;
|
|
390
|
+
|
|
391
|
+
function setUp() public {
|
|
392
|
+
token = new MyToken();
|
|
393
|
+
handler = new Handler(token);
|
|
394
|
+
targetContract(address(handler));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function invariant_totalSupplyNeverExceedsMax() public view {
|
|
398
|
+
assertLe(token.totalSupply(), token.MAX_SUPPLY());
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Fork Tests
|
|
404
|
+
|
|
405
|
+
```solidity
|
|
406
|
+
function test_SwapOnMainnetFork() public {
|
|
407
|
+
vm.createSelectFork(vm.envString("MAINNET_RPC_URL"), 19_000_000);
|
|
408
|
+
IUniswapV2Router02 router = IUniswapV2Router02(UNISWAP_V2_ROUTER);
|
|
409
|
+
// Test against real liquidity pool state at block 19,000,000
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Hardhat Comparison
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
import { expect } from "chai";
|
|
417
|
+
import { ethers } from "hardhat";
|
|
418
|
+
|
|
419
|
+
describe("MyToken", function () {
|
|
420
|
+
it("transfers tokens", async function () {
|
|
421
|
+
const [owner, alice, bob] = await ethers.getSigners();
|
|
422
|
+
const token = await (await ethers.getContractFactory("MyToken")).deploy();
|
|
423
|
+
await token.transfer(alice.address, 1000n * 10n ** 18n);
|
|
424
|
+
await token.connect(alice).transfer(bob.address, 100n * 10n ** 18n);
|
|
425
|
+
expect(await token.balanceOf(bob.address)).to.equal(100n * 10n ** 18n);
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Foundry is preferred for Solidity-native testing (faster, fuzz/invariant built-in). Hardhat for TypeScript deployment scripts and plugin ecosystem.
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## DeFi Primitives
|
|
435
|
+
|
|
436
|
+
### AMM (Constant Product)
|
|
437
|
+
|
|
438
|
+
Formula: `x * y = k`. Price impact increases with trade size relative to reserves:
|
|
439
|
+
|
|
440
|
+
```solidity
|
|
441
|
+
function getAmountOut(
|
|
442
|
+
uint256 amountIn, uint256 reserveIn, uint256 reserveOut
|
|
443
|
+
) internal pure returns (uint256) {
|
|
444
|
+
if (amountIn == 0) revert InsufficientInput();
|
|
445
|
+
if (reserveIn == 0 || reserveOut == 0) revert InsufficientLiquidity();
|
|
446
|
+
uint256 amountInWithFee = amountIn * 997; // 0.3% fee
|
|
447
|
+
return (amountInWithFee * reserveOut) / ((reserveIn * 1000) + amountInWithFee);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function swap(uint256 amountIn, uint256 amountOutMin, uint256 deadline) external {
|
|
451
|
+
if (block.timestamp > deadline) revert DeadlineExpired();
|
|
452
|
+
uint256 amountOut = getAmountOut(amountIn, reserveA, reserveB);
|
|
453
|
+
if (amountOut < amountOutMin) revert SlippageExceeded();
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Lending (Health Factor / Liquidation)
|
|
458
|
+
|
|
459
|
+
```solidity
|
|
460
|
+
function healthFactor(address user) public view returns (uint256) {
|
|
461
|
+
uint256 collateralETH = getUserCollateralETH(user);
|
|
462
|
+
uint256 debtETH = getUserDebtETH(user);
|
|
463
|
+
if (debtETH == 0) return type(uint256).max;
|
|
464
|
+
return (collateralETH * liquidationThreshold) / (debtETH * PRECISION);
|
|
465
|
+
// Health factor < 1.0 triggers liquidation
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Flash Loans
|
|
470
|
+
|
|
471
|
+
Borrow any amount with zero collateral -- must repay within the same transaction:
|
|
472
|
+
|
|
473
|
+
```solidity
|
|
474
|
+
contract FlashBorrower is IFlashLoanReceiver {
|
|
475
|
+
function onFlashLoan(
|
|
476
|
+
address, address token, uint256 amount, uint256 fee, bytes calldata
|
|
477
|
+
) external override returns (bytes32) {
|
|
478
|
+
// Execute arbitrage, collateral swap, or self-liquidation
|
|
479
|
+
IERC20(token).approve(msg.sender, amount + fee);
|
|
480
|
+
return keccak256("ERC3156FlashBorrower.onFlashLoan");
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Yield Aggregation
|
|
486
|
+
|
|
487
|
+
Auto-compounding vaults harvest rewards and reinvest via ERC-4626:
|
|
488
|
+
|
|
489
|
+
```solidity
|
|
490
|
+
contract StrategyVault is ERC4626 {
|
|
491
|
+
IFarm immutable i_farm;
|
|
492
|
+
|
|
493
|
+
function harvest() external {
|
|
494
|
+
uint256 rewards = i_farm.claimRewards();
|
|
495
|
+
i_farm.deposit(swappedAmount); // Compound
|
|
496
|
+
emit Harvested(rewards, swappedAmount);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function totalAssets() public view override returns (uint256) {
|
|
500
|
+
return i_farm.balanceOf(address(this)) + asset.balanceOf(address(this));
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Account Abstraction (ERC-4337)
|
|
508
|
+
|
|
509
|
+
```
|
|
510
|
+
User -> UserOperation -> Bundler -> EntryPoint -> Smart Wallet
|
|
511
|
+
|
|
|
512
|
+
Paymaster (gas sponsorship)
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Smart Wallet Pattern
|
|
516
|
+
|
|
517
|
+
```solidity
|
|
518
|
+
import "@account-abstraction/contracts/core/BaseAccount.sol";
|
|
519
|
+
|
|
520
|
+
contract SmartWallet is BaseAccount {
|
|
521
|
+
address public owner;
|
|
522
|
+
IEntryPoint private immutable i_entryPoint;
|
|
523
|
+
|
|
524
|
+
function _validateSignature(
|
|
525
|
+
PackedUserOperation calldata userOp, bytes32 userOpHash
|
|
526
|
+
) internal view override returns (uint256) {
|
|
527
|
+
bytes32 hash = MessageHashUtils.toEthSignedMessageHash(userOpHash);
|
|
528
|
+
if (owner != ECDSA.recover(hash, userOp.signature)) return SIG_VALIDATION_FAILED;
|
|
529
|
+
return SIG_VALIDATION_SUCCESS;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function execute(address dest, uint256 value, bytes calldata data) external {
|
|
533
|
+
_requireFromEntryPoint();
|
|
534
|
+
(bool success,) = dest.call{value: value}(data);
|
|
535
|
+
if (!success) revert ExecutionFailed();
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**Paymaster** contracts cover gas fees for users -- verify sponsor signatures or check user eligibility in `_validatePaymasterUserOp`, enabling gasless UX.
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## Development Tooling
|
|
545
|
+
|
|
546
|
+
| Tool | Purpose | When to use |
|
|
547
|
+
|------|---------|-------------|
|
|
548
|
+
| **Foundry** (forge/cast/anvil) | Testing, deployment, local chain | Default for all Solidity projects |
|
|
549
|
+
| **Hardhat** | TypeScript scripts, plugin ecosystem | When TS tooling is required |
|
|
550
|
+
| **Slither** | Static analysis (Trail of Bits) | Every PR -- reentrancy, unused returns |
|
|
551
|
+
| **Mythril** | Symbolic execution | Pre-audit deep analysis |
|
|
552
|
+
| **Aderyn** | Rust-based static analysis (Cyfrin) | Fast CI checks |
|
|
553
|
+
| **OpenZeppelin Defender** | Monitoring, automation, upgrades | Production operations |
|
|
554
|
+
| **Tenderly** | Tx simulation, debugging, alerting | Debugging failed transactions |
|
|
555
|
+
|
|
556
|
+
### CI Pipeline
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
forge build --sizes # Contract sizes (<24KB)
|
|
560
|
+
forge test -vvv # All tests with trace
|
|
561
|
+
forge coverage # Coverage report
|
|
562
|
+
slither . --filter-paths "test|script|lib" # Static analysis
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## Security Patterns
|
|
568
|
+
|
|
569
|
+
### Reentrancy Protection (CEI + nonReentrant)
|
|
570
|
+
|
|
571
|
+
```solidity
|
|
572
|
+
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
|
|
573
|
+
|
|
574
|
+
contract Vault is ReentrancyGuard {
|
|
575
|
+
mapping(address => uint256) public balances;
|
|
576
|
+
|
|
577
|
+
function withdraw(uint256 amount) external nonReentrant {
|
|
578
|
+
if (balances[msg.sender] < amount) revert InsufficientBalance(); // Check
|
|
579
|
+
balances[msg.sender] -= amount; // Effect
|
|
580
|
+
(bool success,) = msg.sender.call{value: amount}(""); // Interaction
|
|
581
|
+
if (!success) revert TransferFailed();
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### Access Control
|
|
587
|
+
|
|
588
|
+
```solidity
|
|
589
|
+
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
590
|
+
|
|
591
|
+
contract Treasury is AccessControl {
|
|
592
|
+
bytes32 public constant TREASURER_ROLE = keccak256("TREASURER_ROLE");
|
|
593
|
+
|
|
594
|
+
constructor(address admin) { _grantRole(DEFAULT_ADMIN_ROLE, admin); }
|
|
595
|
+
|
|
596
|
+
function withdraw(address to, uint256 amount) external onlyRole(TREASURER_ROLE) {}
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Safe External Calls
|
|
601
|
+
|
|
602
|
+
```solidity
|
|
603
|
+
// NEVER use transfer()/send() -- 2300 gas limit breaks with EIP-1884
|
|
604
|
+
(bool success,) = to.call{value: amount}("");
|
|
605
|
+
if (!success) revert TransferFailed();
|
|
606
|
+
|
|
607
|
+
// For ERC-20 -- SafeERC20 handles non-standard return values
|
|
608
|
+
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
609
|
+
using SafeERC20 for IERC20;
|
|
610
|
+
token.safeTransfer(to, amount);
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
---
|
|
614
|
+
|
|
615
|
+
## Anti-Patterns & Pitfalls
|
|
616
|
+
|
|
617
|
+
### 1. `tx.origin` for Authorization
|
|
618
|
+
`tx.origin` returns the EOA, not the immediate caller -- enables phishing via intermediary contracts. Always use `msg.sender`.
|
|
619
|
+
|
|
620
|
+
### 2. Unchecked External Call Return Values
|
|
621
|
+
Low-level `.call()` returns a boolean. Ignoring it silently swallows failures. Always check `success`.
|
|
622
|
+
|
|
623
|
+
### 3. Missing Reentrancy Guards
|
|
624
|
+
Any function making external calls after state changes is vulnerable. Apply `nonReentrant` + CEI ordering.
|
|
625
|
+
|
|
626
|
+
### 4. Floating Pragma
|
|
627
|
+
`^0.8.0` compiles with any 0.8.x. Different versions produce different bytecode. Pin exact version.
|
|
628
|
+
|
|
629
|
+
### 5. `transfer()`/`send()` for ETH
|
|
630
|
+
2,300 gas limit breaks with EIP-1884 when receiver reads storage. Use `.call{value: amount}("")`.
|
|
631
|
+
|
|
632
|
+
### 6. Hardcoded Addresses
|
|
633
|
+
Addresses differ across chains. Use constructor parameters or immutables for deployable contracts.
|
|
634
|
+
|
|
635
|
+
### 7. Missing Events for State Changes
|
|
636
|
+
Events are the only way off-chain systems detect mutations:
|
|
637
|
+
```solidity
|
|
638
|
+
event FeeUpdated(uint256 oldFee, uint256 newFee);
|
|
639
|
+
function setFee(uint256 newFee) external onlyOwner {
|
|
640
|
+
emit FeeUpdated(fee, newFee);
|
|
641
|
+
fee = newFee;
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### 8. `block.timestamp` for Randomness
|
|
646
|
+
Validators influence timestamp within ~15s. Use Chainlink VRF for on-chain randomness.
|
|
647
|
+
|
|
648
|
+
### 9. Unbounded Loops
|
|
649
|
+
Iteration over unbounded arrays will exceed block gas limit. Use pull patterns:
|
|
650
|
+
```solidity
|
|
651
|
+
function claim() external {
|
|
652
|
+
uint256 owed = rewards[msg.sender];
|
|
653
|
+
if (owed == 0) revert NothingToClaim();
|
|
654
|
+
rewards[msg.sender] = 0;
|
|
655
|
+
token.safeTransfer(msg.sender, owed);
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
### 10. Missing Zero-Address Checks
|
|
660
|
+
Setting critical roles to `address(0)` bricks admin functions permanently.
|
|
661
|
+
|
|
662
|
+
### 11. Approval Race Condition (ERC-20)
|
|
663
|
+
Changing allowance from N to M lets spender front-run for N+M. Use `increaseAllowance`/`decreaseAllowance`.
|
|
664
|
+
|
|
665
|
+
### 12. Uninitialized Proxy Implementation
|
|
666
|
+
Attacker calls `initialize()` on unprotected implementation. Always `_disableInitializers()` in constructor.
|
|
667
|
+
|
|
668
|
+
### 13. Oracle Manipulation via Spot Price
|
|
669
|
+
`pool.getReserves()` is manipulable via flash loans. Use TWAP or Chainlink price feeds:
|
|
670
|
+
```solidity
|
|
671
|
+
(, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();
|
|
672
|
+
if (price <= 0) revert InvalidPrice();
|
|
673
|
+
if (block.timestamp - updatedAt > STALENESS_THRESHOLD) revert StalePrice();
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
## Decision Trees
|
|
679
|
+
|
|
680
|
+
### Which Proxy Pattern?
|
|
681
|
+
```
|
|
682
|
+
Need modular upgrades with >24KB bytecode?
|
|
683
|
+
YES --> Diamond (EIP-2535)
|
|
684
|
+
NO --> Need admin-implementation separation?
|
|
685
|
+
YES --> Transparent Proxy
|
|
686
|
+
NO --> UUPS (default -- cheapest for users)
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### Which Token Standard?
|
|
690
|
+
```
|
|
691
|
+
Every token is identical (currency, points)?
|
|
692
|
+
YES --> ERC-20
|
|
693
|
+
NO --> Every token is unique (art, identity)?
|
|
694
|
+
YES --> ERC-721
|
|
695
|
+
NO --> Mix of fungible + non-fungible?
|
|
696
|
+
YES --> ERC-1155
|
|
697
|
+
NO --> ERC-721
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### Which Testing Approach?
|
|
701
|
+
```
|
|
702
|
+
Solidity-native team, need fuzz/invariant tests?
|
|
703
|
+
YES --> Foundry (default)
|
|
704
|
+
NO --> Heavy TypeScript deployment/integration?
|
|
705
|
+
YES --> Hardhat
|
|
706
|
+
NO --> Both (Foundry for tests, Hardhat for scripts)
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
*Researched: 2026-03-12 | Sources: [Ethereum Foundation Solidity Docs 0.8.x](https://docs.soliditylang.org/en/v0.8.28/), [OpenZeppelin Contracts 5.x](https://docs.openzeppelin.com/contracts/5.x/), [Foundry Book](https://book.getfoundry.sh/), [EIP-20](https://eips.ethereum.org/EIPS/eip-20), [EIP-721](https://eips.ethereum.org/EIPS/eip-721), [EIP-1155](https://eips.ethereum.org/EIPS/eip-1155), [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626), [EIP-4337](https://eips.ethereum.org/EIPS/eip-4337), [EIP-1822 UUPS](https://eips.ethereum.org/EIPS/eip-1822), [EIP-2535 Diamond](https://eips.ethereum.org/EIPS/eip-2535), [EIP-7201 Namespaced Storage](https://eips.ethereum.org/EIPS/eip-7201), [Trail of Bits Security Reviews](https://github.com/trailofbits/publications), [Consensys Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/), [Chainlink VRF](https://docs.chain.link/vrf), [Chainlink Price Feeds](https://docs.chain.link/data-feeds), [Rekt News](https://rekt.news/leaderboard/)*
|