From 1bfee1219ce9729fbfee8a3cb69e485da49b818c Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Tue, 24 Mar 2026 21:04:02 -0400 Subject: [PATCH 1/3] initial version of contract versioning doc --- CONTRACT_VERSIONING.md | 167 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 CONTRACT_VERSIONING.md diff --git a/CONTRACT_VERSIONING.md b/CONTRACT_VERSIONING.md new file mode 100644 index 00000000..5c9c6d8f --- /dev/null +++ b/CONTRACT_VERSIONING.md @@ -0,0 +1,167 @@ +# Contract Versioning Strategy + +> ⚠️ This document was initially generated with the assistance of a Large Language Model (LLM) and has been reviewed by the engineering team. + +## Overview + +This document defines the versioning strategy used across Flow Yield Vaults (FYV), Flow ALP, and DeFiActions. + +The goals are to: + +* Safely manage **non-upgradable smart contract changes** +* Maintain **mainnet stability** +* Enable **parallel development** +* Ensure **cross-repository consistency** + +--- + +## Core Model + +### Version Boundaries + +A **new version** is required when a change: + +* Breaks backward compatibility +* Modifies resource/storage layout (e.g., adding fields) +* Requires redeployment to a new name or address + +These changes are **non-upgradable** and define version boundaries. + +### Within a Version + +All changes must be: + +* Backward-compatible +* Deployable to the same contract address +* Safe for existing integrations + +--- + +## Branching Model + +Each version is represented by a Git branch. + +| Branch | Purpose | +| ------ | --------------------------------- | +| `main` | Active development (not deployed) | +| `v0` | Current deployed mainnet version | + +* `main` is free to introduce breaking changes +* `v0` is stable and represents the exact deployed contract set + +All repositories (FYV, Flow ALP, DeFiActions) must maintain aligned version branches. + +--- + +## Deployment Model + +### Development + +The `main` branch is **never deployed to a persistent network**. + +It is validated using: + +* Forked environments +* Local emulator +* Temporary/test deployments + +This enables rapid iteration without mainnet constraints. + +### Mainnet + +Persistent deployments must come from a **version branch** (e.g., `v0`). + +The FYV repository acts as the **deployment source of truth**: + +* Pins dependency commits (submodules or equivalent) +* Defines the full contract set +* Ensures reproducibility + +--- + +## Workflow + +### Feature Development + +* Develop on `main` +* Breaking changes are allowed + +### Creating a New Version + +When a non-upgradable change is introduced: + +1. Continue development on `main` +2. Introduce new contracts (new names/addresses if required) +3. Create/update a version branch (e.g., `v1` in future) +4. Align all repositories to compatible commits + +### Maintaining Current Version (`v0`) + +* Maintenance mode only +* Allowed changes: + + * Bug fixes + * Backward-compatible improvements + +### Backporting + +* Apply fixes to `main` +* Backport to `v0` only if compatible + +### Deployment Steps + +1. Checkout version branch (e.g., `v0`) +2. Use pinned dependencies +3. Deploy to network + +--- + +## Designing for Extendability + +To reduce unnecessary version bumps, contracts should be designed with extensibility in mind. + +### Extension State Pattern + +Introduce a contract-level variable of type `AnyStruct` that acts as an extensible container. + +Recommended approach: + +* Store a structured state object inside the `AnyStruct` +* Use mapping-style substructures to hold future fields/modules +* Isolate evolving state from core stable storage + +### Benefits + +* Reduces direct modification of core storage layout +* Allows additive evolution of state +* Helps delay non-upgradable changes + +### Guidelines + +* Keep core contract interfaces stable and minimal +* Prefer additive changes over structural rewrites +* Clearly document extension state usage + +### Caveat + +This pattern improves flexibility but does **not eliminate versioning**. + +Changes to: + +* Public interfaces +* Resource structures +* Deployment model + +may still require a new version. + +--- + +## Summary + +* Versions are defined by **non-upgradable changes** +* Branches represent versions (`v0`, `v1`, ...) +* `main` is development-only and not deployed +* Version branches are the only deployment source +* All repositories must stay aligned per version + +This model enables safe contract evolution while maintaining mainnet stability. From f1e92603e76e4a49a6e0244fc0cfccb59d73f541 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:53:27 -0400 Subject: [PATCH 2/3] add section for contract naming --- CONTRACT_VERSIONING.md | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/CONTRACT_VERSIONING.md b/CONTRACT_VERSIONING.md index 5c9c6d8f..ec3487d9 100644 --- a/CONTRACT_VERSIONING.md +++ b/CONTRACT_VERSIONING.md @@ -32,7 +32,7 @@ These changes are **non-upgradable** and define version boundaries. All changes must be: * Backward-compatible -* Deployable to the same contract address +* Deployable to the same contract address with the same name * Safe for existing integrations --- @@ -116,6 +116,48 @@ When a non-upgradable change is introduced: --- +## Contract Naming Conventions + +Clear and consistent contract naming is required to reinforce version boundaries and avoid ambiguity. + +### Within a Version + +* Contract names must remain **stable** +* Contracts must be deployable to the **same address** with the **same name** +* Renaming or adding suffixes (e.g., `V2`, `New`) is **not allowed** + +### Across Versions + +When introducing a new version due to non-upgradeable changes: + +* Contracts must be **redeployed under new names or addresses** +* Naming must clearly indicate version differences + +#### Recommended Patterns + +* **Suffix-based versioning:** + + * `FlowVault` → `FlowVaultV1` + * `AutoBalancer` → `AutoBalancerV1` + +### Guidelines + +* Use explicit version identifiers (`V1`, `V2`, ...) +* Avoid ambiguous names such as: + + * `New` + * `Updated` +* Keep naming consistent across FYV, Flow ALP, and DeFiActions + +### Important + +Once a version is deployed and superseded: + +* Its contracts should be treated as **immutable** +* No further modifications should be made + +--- + ## Designing for Extendability To reduce unnecessary version bumps, contracts should be designed with extensibility in mind. From bdc07858f88b72cf9be82536be6ccf7ce9f3c589 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Wed, 25 Mar 2026 13:14:23 -0400 Subject: [PATCH 3/3] format --- CONTRACT_VERSIONING.md | 165 +++++++++++++++++++++-------------------- 1 file changed, 85 insertions(+), 80 deletions(-) diff --git a/CONTRACT_VERSIONING.md b/CONTRACT_VERSIONING.md index ec3487d9..cdfbef3a 100644 --- a/CONTRACT_VERSIONING.md +++ b/CONTRACT_VERSIONING.md @@ -2,16 +2,21 @@ > ⚠️ This document was initially generated with the assistance of a Large Language Model (LLM) and has been reviewed by the engineering team. +--- + ## Overview -This document defines the versioning strategy used across Flow Yield Vaults (FYV), Flow ALP, and DeFiActions. +This document defines the versioning strategy used across: +- Flow Yield Vaults (FYV) +- Flow ALP +- DeFiActions The goals are to: -* Safely manage **non-upgradable smart contract changes** -* Maintain **mainnet stability** -* Enable **parallel development** -* Ensure **cross-repository consistency** +- Safely manage **non-upgradable smart contract changes** +- Maintain **mainnet stability** +- Enable **parallel development** +- Ensure **cross-repository consistency** --- @@ -21,9 +26,9 @@ The goals are to: A **new version** is required when a change: -* Breaks backward compatibility -* Modifies resource/storage layout (e.g., adding fields) -* Requires redeployment to a new name or address +- Breaks backward compatibility +- Modifies resource/storage layout (e.g., adding fields) +- Requires redeployment to a new name or address These changes are **non-upgradable** and define version boundaries. @@ -31,9 +36,9 @@ These changes are **non-upgradable** and define version boundaries. All changes must be: -* Backward-compatible -* Deployable to the same contract address with the same name -* Safe for existing integrations +- Backward-compatible +- Deployable to the same contract address **with the same name** +- Safe for existing integrations --- @@ -42,12 +47,12 @@ All changes must be: Each version is represented by a Git branch. | Branch | Purpose | -| ------ | --------------------------------- | +|--------|----------------------------------| | `main` | Active development (not deployed) | | `v0` | Current deployed mainnet version | -* `main` is free to introduce breaking changes -* `v0` is stable and represents the exact deployed contract set +- `main` is free to introduce breaking changes +- `v0` is stable and represents the exact deployed contract set All repositories (FYV, Flow ALP, DeFiActions) must maintain aligned version branches. @@ -61,9 +66,9 @@ The `main` branch is **never deployed to a persistent network**. It is validated using: -* Forked environments -* Local emulator -* Temporary/test deployments +- Forked environments +- Local emulator +- Temporary/test deployments This enables rapid iteration without mainnet constraints. @@ -73,9 +78,9 @@ Persistent deployments must come from a **version branch** (e.g., `v0`). The FYV repository acts as the **deployment source of truth**: -* Pins dependency commits (submodules or equivalent) -* Defines the full contract set -* Ensures reproducibility +- Pins dependency commits (submodules or equivalent) +- Defines the full contract set +- Ensures reproducibility --- @@ -83,36 +88,35 @@ The FYV repository acts as the **deployment source of truth**: ### Feature Development -* Develop on `main` -* Breaking changes are allowed +- Develop on `main` +- Breaking changes are allowed ### Creating a New Version When a non-upgradable change is introduced: -1. Continue development on `main` -2. Introduce new contracts (new names/addresses if required) -3. Create/update a version branch (e.g., `v1` in future) -4. Align all repositories to compatible commits +1. Continue development on `main` +2. Introduce new contracts (new names/addresses if required) +3. Create/update a version branch (e.g., `v1`) +4. Align all repositories to compatible commits ### Maintaining Current Version (`v0`) -* Maintenance mode only -* Allowed changes: - - * Bug fixes - * Backward-compatible improvements +- Maintenance mode only +- Allowed changes: + - Bug fixes + - Backward-compatible improvements ### Backporting -* Apply fixes to `main` -* Backport to `v0` only if compatible +- Apply fixes to `main` +- Backport to `v0` only if compatible ### Deployment Steps -1. Checkout version branch (e.g., `v0`) -2. Use pinned dependencies -3. Deploy to network +1. Checkout version branch (e.g., `v0`) +2. Use pinned dependencies +3. Deploy to network --- @@ -122,88 +126,89 @@ Clear and consistent contract naming is required to reinforce version boundaries ### Within a Version -* Contract names must remain **stable** -* Contracts must be deployable to the **same address** with the **same name** -* Renaming or adding suffixes (e.g., `V2`, `New`) is **not allowed** +- Contract names must remain **stable** +- Contracts must be deployable to the **same address with the same name** +- Renaming or adding suffixes (e.g., `V2`, `New`) is **not allowed** ### Across Versions When introducing a new version due to non-upgradeable changes: -* Contracts must be **redeployed under new names or addresses** -* Naming must clearly indicate version differences +- Contracts must be **redeployed under new names or addresses** +- Naming must clearly indicate version differences #### Recommended Patterns -* **Suffix-based versioning:** - - * `FlowVault` → `FlowVaultV1` - * `AutoBalancer` → `AutoBalancerV1` +- **Suffix-based versioning:** + - `FlowVault` → `FlowVaultV1` + - `AutoBalancer` → `AutoBalancerV1` ### Guidelines -* Use explicit version identifiers (`V1`, `V2`, ...) -* Avoid ambiguous names such as: - - * `New` - * `Updated` -* Keep naming consistent across FYV, Flow ALP, and DeFiActions +- Use explicit version identifiers (`V1`, `V2`, ...) +- Avoid ambiguous names such as: + - `New` + - `Updated` +- Keep naming consistent across FYV, Flow ALP, and DeFiActions ### Important Once a version is deployed and superseded: -* Its contracts should be treated as **immutable** -* No further modifications should be made +- Contracts should be treated as **immutable** +- No further modifications should be made --- ## Designing for Extendability -To reduce unnecessary version bumps, contracts should be designed with extensibility in mind. +### Extension State Pattern (Use with Caution) -### Extension State Pattern +An optional pattern is to include a contract-level `AnyStruct` field that can act as an extensible container for **temporary, upgrade-compatible patches** to already deployed versions. -Introduce a contract-level variable of type `AnyStruct` that acts as an extensible container. +> ⚠️ This pattern introduces **globally mutable, non-type-safe state**. It should be used sparingly and only when strictly necessary. -Recommended approach: +### Intended Use -* Store a structured state object inside the `AnyStruct` -* Use mapping-style substructures to hold future fields/modules -* Isolate evolving state from core stable storage +- Primarily for **version branches** (e.g., `v0`) to ship missing behavior without breaking upgradeability +- As an **escape hatch** when a deployed contract cannot be changed safely otherwise -### Benefits +### Usage Rules -* Reduces direct modification of core storage layout -* Allows additive evolution of state -* Helps delay non-upgradable changes +- The container **may exist on `main`**, but should be: + - **Empty** + - **Not referenced in logic** +- Do **not** rely on this pattern for normal feature development on `main` +- Prefer introducing properly typed state in the **next version** (e.g., `v1`) -### Guidelines +### Implementation Guidance -* Keep core contract interfaces stable and minimal -* Prefer additive changes over structural rewrites -* Clearly document extension state usage +If used: -### Caveat +- Store a structured value inside the `AnyStruct` +- Use mapping-style substructures for scoped additions +- Isolate it from core storage and public interfaces +- Clearly document any data written to it -This pattern improves flexibility but does **not eliminate versioning**. +### Risks -Changes to: +- Reduced type safety +- Harder reasoning about state and invariants +- Increased likelihood of bugs -* Public interfaces -* Resource structures -* Deployment model +### Recommendation -may still require a new version. +- Treat this as a **temporary compatibility mechanism**, not a design default +- When creating a new version, replace usages with **properly typed fields and resources** --- ## Summary -* Versions are defined by **non-upgradable changes** -* Branches represent versions (`v0`, `v1`, ...) -* `main` is development-only and not deployed -* Version branches are the only deployment source -* All repositories must stay aligned per version +- Versions are defined by **non-upgradable changes** +- Branches represent versions (`v0`, `v1`, ...) +- `main` is development-only and not deployed +- Version branches are the only deployment source +- All repositories must stay aligned per version This model enables safe contract evolution while maintaining mainnet stability.