Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
49 changes: 49 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What This Repo Is

This is the [`onflow/flips`](https://github.com/onflow/flips) repository — a collection of Flow Improvement Proposals (FLIPs). There is no build system, tests, or code to run. All content is Markdown.

## FLIP Categories

FLIPs are organized into four directories:

- `cadence/` — Cadence language changes (managed by the Flow team)
- `protocol/` — Core Flow protocol changes (algorithms, APIs, cryptography, FVM)
- `application/` — Standards for apps built on Flow (token standards, contract interfaces, design patterns)
- `governance/` — Governance actions (staking rules, node operators, fees, service account)

## FLIP Lifecycle States

`Draft` → `Proposed` → `Accepted` / `Rejected` → `Implemented` → `Released`

Each FLIP also has a corresponding GitHub issue (used as the FLIP number) that tracks progress and is closed when the FLIP reaches `Rejected` or `Released`.

## Writing a New FLIP

1. Copy `yyyymmdd-flip-template.md` as `YYYYMMDD-descriptive-name.md` into the appropriate category directory.
2. Set the frontmatter: `status`, `flip` (GitHub issue number), `authors`, `sponsor`, `updated`.
3. Use the issue number from the GitHub issue as the FLIP number in both the filename and frontmatter.
4. If the FLIP includes images or auxiliary files, create a matching directory `YYYYMMDD-descriptive-name/`.

## FLIP Template Structure

Required sections in every FLIP:
- **Objective** — short executive summary
- **Motivation** — problem background and affected users
- **User Benefit** — headline-level value proposition
- **Design Proposal** — full proposal including: Drawbacks, Alternatives Considered, Performance Implications, Dependencies, Engineering Impact, Best Practices, Tutorials and Examples, Compatibility, User Impact
- **Related Issues**
- **Prior Art**
- **Questions and Discussion** — where community discussion will take place (PR or forum)

## Submission Process

1. Create a GitHub issue using the appropriate FLIP issue template (type: `application`, `governance`, `cadence`, or `protocol`).
2. Note the issue number — this becomes the FLIP number.
3. Submit the FLIP as a PR to this repo referencing the issue.
4. Announce in the `#developers` Discord channel.
5. Minimum two-week comment period from PR posting.
6. Sponsor shepherds through review committee.
55 changes: 38 additions & 17 deletions application/20231222-evm-vm-bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ flip: 237
title: Flow EVM VM Bridge
authors: Giovanni Sanchez (giovanni.sanchez@dapperlabs.com)
sponsor: Jerome Pimmel (jerome.pimmel@dapperlabs.com)
updated: 2023-12-22
updated: 2026-03-13
---

# FLIP 237: Flow VM Bridge
Expand Down Expand Up @@ -295,6 +295,13 @@ The task of bridging FTs & NFTs between VMs can be split into four distinct case
asset can either be Cadence- or EVM-native, and it can either be bridged from Cadence to EVM or EVM to Cadence. The
following sections outline an NFT bridge path for each case.

> :information_source: **Fee model:** Bridge fees are only charged when an operation causes the bridge account to store
> an asset long-term (e.g., escrowing a Cadence NFT or holding an ERC721 in the bridge's COA). Operations that release
> assets from existing escrow or burn assets do **not** incur a bridge fee, because they do not add to the bridge
> account's storage. Onboarding operations always incur a separate flat onboarding fee regardless of direction. For the
> full rationale and handler-by-handler breakdown, see
> [ADR-0001](https://github.com/onflow/flow-evm-bridge/blob/main/docs/adr/ADR-0001-nft-bridge-fee-model.md).

> :information_source: A note about bridge "onboarding" - assets moving from one VM to another must at minimum have
> contracts defining them in their target VM. These contracts must be deployed in a transaction preceding the movement
> of the asset as deployed contracts are not available in the Cadence's state space until the deploying transaction has
Expand All @@ -320,13 +327,13 @@ following sections outline an NFT bridge path for each case.

*Lock in Cadence & Mint/Transfer in EVM*

1. Pre-flight checks: Assert the type is supported, has been onboarded, and fee provider can provide onboarding fee
1. Pre-flight checks: Assert the type is supported, has been onboarded, and fee provider can cover the bridge fee
2. Get a URI for the NFT
- Default to project-specified URI
- If not defined, serialize the NFT as JSON data URL
3. Lock NFT in escrow
4. Calculate the bridge fee based on flat fee + storage usage
5. Withdraw onboard fee from given fee Provider & deposit to bridge Vault
4. Calculate the bridge fee based on storage consumed by escrowing the NFT in the bridge account
5. Withdraw bridge fee from given fee Provider & deposit to bridge Vault
6. Get the token's corresponding ERC721 contract address
5. Execute the bridge
- Check if the ERC721 is factory-deployed - Cadence-native: return true
Expand All @@ -341,9 +348,12 @@ following sections outline an NFT bridge path for each case.

*Unlock in Cadence & Transfer in EVM*

1. Pre-flight checks: Assert the type is supported, has been onboarded, and fee provider can provide onboarding fee
2. Withdraw the bridge fee from the given Provider & deposit to bridge Vault
3. Get the requested type's associated EVM contract address
> :information_source: No bridge fee is charged for this operation. Releasing a Cadence NFT from existing bridge escrow
> reduces storage in the bridge account rather than adding to it. The storage fee was already covered when the NFT was
> originally escrowed on the Cadence → EVM path.

1. Pre-flight checks: Assert the type is supported and has been onboarded
2. Get the requested type's associated EVM contract address
4. Assert the caller is the requested ERC721 token owner or approved
5. Execute the provided protected callback
6. Assert that now the bridge COA is the ERC721 token owner after executing the protected callback
Expand Down Expand Up @@ -374,23 +384,34 @@ following sections outline an NFT bridge path for each case.

*Mint/Unlock in Cadence & Transfer in EVM*

1. Pre-flight checks: Assert the type is supported, has been onboarded, and fee provider can provide onboarding fee
2. Withdraw the bridge fee from the given Provider & deposit to bridge Vault
3. Get the requested type's associated EVM contract address
4. Assert the caller is the requested ERC721 token owner or approved
5. Execute the provided protected callback
6. Assert that now the bridge COA is the ERC721 token owner after executing the protected callback
7. Derive the requested type's contract address & name & attempt to borrow the contract as EVMBridgeMinter
8. Get the tokenURI from the ERC721 contract
9. If the corresponding Cadence NFT is in escrow, unlock the NFT <- false in this case
10. Otherwise, mint a new NFT with the ERC721 URI & define the source contract's ERC721 ID and return
> :information_source: The steps below describe the **default path** for EVM-native NFTs without a cross-VM
> registration. For projects registered via `registerCrossVMNFT` (FLIP 318), the bridge dispatches to a dedicated
> cross-VM handler (`handleEVMNativeCrossVMNFTFromEVM`) that does not add to the bridge's Cadence storage. No bridge
> fee is charged on that path — see
> [ADR-0001](https://github.com/onflow/flow-evm-bridge/blob/main/docs/adr/ADR-0001-nft-bridge-fee-model.md) for
> details.

1. Pre-flight checks: Assert the type is supported and has been onboarded, and fee provider can cover the bridge fee
2. Get the requested type's associated EVM contract address
3. Assert the caller is the requested ERC721 token owner or approved
4. Execute the provided protected callback
5. Assert that now the bridge COA is the ERC721 token owner after executing the protected callback
6. Calculate the bridge fee based on storage consumed by holding the ERC721 in the bridge's EVM account (COA)
7. Withdraw bridge fee from the given Provider & deposit to bridge Vault
8. Derive the requested type's contract address & name & attempt to borrow the contract as EVMBridgeMinter
9. Get the tokenURI from the ERC721 contract
10. If the corresponding Cadence NFT is in escrow, unlock the NFT <- false in this case
11. Otherwise, mint a new NFT with the ERC721 URI & define the source contract's ERC721 ID and return

![Cadence-native Cadence to EVM](20231222-evm-vm-bridge-resources/evm_native_nft_from_evm.png)

#### EVM-Native: Flow -> EVM

*Lock in Flow & Transfer in EVM*

> :information_source: No bridge fee is charged for this operation. The bridge-deployed Cadence NFT is burned (step 6)
> rather than escrowed, so no new storage is added to the bridge account.

1. Assert the asset is either an NFT or FT & has been onboarded (it will be by construction)
2. Determine if asset is FT or NFT
- Check if resource is an instance of FT.Vault or NFT.NFT (excluding overlapping instances, at least for POC)
Expand Down